diff --git a/CHANGELOG.md b/CHANGELOG.md index 20732486..3b9aa2ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2.1.11 (Jan 5, 2018) + +* Fixed issue with multiple grids on same vm (#134) (thanks [Suen](https://github.com/sunzongzheng)) +* Fixed issue with layout update on reassignment (#130) (thanks [daizengyu](https://github.com/daizengyu123)) + ## 2.1.10 (Dec 15, 2017) * Fixed possible bug related with #119 diff --git a/README.md b/README.md index 7f62c265..a0ed850a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ vue-grid-layout is a grid layout system, like [Gridster](http://dsmorse.github.io/gridster.js/), for Vue.js. **Heavily inspired in [React-Grid-Layout](https://github.com/STRML/react-grid-layout)** -### **Current version:** 2.1.10 (Supports Vue 2.2+) +### **Current version:** 2.1.11 (Supports Vue 2.2+) ### **For Vue 2.1.10 and below use version [2.1.3](https://github.com/jbaysolutions/vue-grid-layout/tree/2.1.3)** ### **For Vue 1 use version [1.0.3](https://github.com/jbaysolutions/vue-grid-layout/tree/1.0.3)** diff --git a/dist/vue-grid-layout.js b/dist/vue-grid-layout.js index 333b3b30..8398b1dc 100644 --- a/dist/vue-grid-layout.js +++ b/dist/vue-grid-layout.js @@ -7,7 +7,7 @@ exports["VueGridLayout"] = factory(); else root["VueGridLayout"] = factory(); -})(typeof self !== 'undefined' ? self : this, function() { +})(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; @@ -70,7 +70,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 10); +/******/ return __webpack_require__(__webpack_require__.s = 9); /******/ }) /************************************************************************/ /******/ ([ @@ -78,13 +78,13 @@ return /******/ (function(modules) { // webpackBootstrap /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("/* WEBPACK VAR INJECTION */(function(process) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.bottom = bottom;\nexports.cloneLayout = cloneLayout;\nexports.cloneLayoutItem = cloneLayoutItem;\nexports.collides = collides;\nexports.compact = compact;\nexports.compactItem = compactItem;\nexports.correctBounds = correctBounds;\nexports.getLayoutItem = getLayoutItem;\nexports.getFirstCollision = getFirstCollision;\nexports.getAllCollisions = getAllCollisions;\nexports.getStatics = getStatics;\nexports.moveElement = moveElement;\nexports.moveElementAwayFromCollision = moveElementAwayFromCollision;\nexports.perc = perc;\nexports.setTransform = setTransform;\nexports.setTransformRtl = setTransformRtl;\nexports.setTopLeft = setTopLeft;\nexports.setTopRight = setTopRight;\nexports.sortLayoutItemsByRowCol = sortLayoutItemsByRowCol;\nexports.validateLayout = validateLayout;\nexports.autoBindHandlers = autoBindHandlers;\nexports.createMarkup = createMarkup;\nexports.addPx = addPx;\nexports.hyphenate = hyphenate;\nexports.findItemInArray = findItemInArray;\nexports.findAndRemove = findAndRemove;\n// @flow\n/*:: export type LayoutItemRequired = {w: number, h: number, x: number, y: number, i: string};*/\n/*:: export type LayoutItem = LayoutItemRequired &\n {minW?: number, minH?: number, maxW?: number, maxH?: number,\n moved?: boolean, static?: boolean,\n isDraggable?: ?boolean, isResizable?: ?boolean};*/\n/*:: export type Layout = Array;*/\n/*:: export type Position = {left: number, top: number, width: number, height: number};*/\n/*:: export type DragCallbackData = {\n node: HTMLElement,\n x: number, y: number,\n deltaX: number, deltaY: number,\n lastX: number, lastY: number\n};*/\n/*:: export type DragEvent = {e: Event} & DragCallbackData;*/\n/*:: export type Size = {width: number, height: number};*/\n/*:: export type ResizeEvent = {e: Event, node: HTMLElement, size: Size};*/\n\n\nvar isProduction = process.env.NODE_ENV === 'production';\n/**\n * Return the bottom coordinate of the layout.\n *\n * @param {Array} layout Layout array.\n * @return {Number} Bottom coordinate.\n */\nfunction bottom(layout /*: Layout*/) /*: number*/ {\n var max = 0,\n bottomY = void 0;\n for (var _i = 0, len = layout.length; _i < len; _i++) {\n bottomY = layout[_i].y + layout[_i].h;\n if (bottomY > max) max = bottomY;\n }\n return max;\n}\n\nfunction cloneLayout(layout /*: Layout*/) /*: Layout*/ {\n var newLayout = Array(layout.length);\n for (var _i2 = 0, len = layout.length; _i2 < len; _i2++) {\n newLayout[_i2] = cloneLayoutItem(layout[_i2]);\n }\n return newLayout;\n}\n\n// Fast path to cloning, since this is monomorphic\nfunction cloneLayoutItem(layoutItem /*: LayoutItem*/) /*: LayoutItem*/ {\n /*return {\n w: layoutItem.w, h: layoutItem.h, x: layoutItem.x, y: layoutItem.y, i: layoutItem.i,\n minW: layoutItem.minW, maxW: layoutItem.maxW, minH: layoutItem.minH, maxH: layoutItem.maxH,\n moved: Boolean(layoutItem.moved), static: Boolean(layoutItem.static),\n // These can be null\n isDraggable: layoutItem.isDraggable, isResizable: layoutItem.isResizable\n };*/\n return JSON.parse(JSON.stringify(layoutItem));\n}\n\n/**\n * Given two layoutitems, check if they collide.\n *\n * @return {Boolean} True if colliding.\n */\nfunction collides(l1 /*: LayoutItem*/, l2 /*: LayoutItem*/) /*: boolean*/ {\n if (l1 === l2) return false; // same element\n if (l1.x + l1.w <= l2.x) return false; // l1 is left of l2\n if (l1.x >= l2.x + l2.w) return false; // l1 is right of l2\n if (l1.y + l1.h <= l2.y) return false; // l1 is above l2\n if (l1.y >= l2.y + l2.h) return false; // l1 is below l2\n return true; // boxes overlap\n}\n\n/**\n * Given a layout, compact it. This involves going down each y coordinate and removing gaps\n * between items.\n *\n * @param {Array} layout Layout.\n * @param {Boolean} verticalCompact Whether or not to compact the layout\n * vertically.\n * @return {Array} Compacted Layout.\n */\nfunction compact(layout /*: Layout*/, verticalCompact /*: Boolean*/) /*: Layout*/ {\n // Statics go in the compareWith array right away so items flow around them.\n var compareWith = getStatics(layout);\n // We go through the items by row and column.\n var sorted = sortLayoutItemsByRowCol(layout);\n // Holding for new items.\n var out = Array(layout.length);\n\n for (var _i3 = 0, len = sorted.length; _i3 < len; _i3++) {\n var l = sorted[_i3];\n\n // Don't move static elements\n if (!l.static) {\n l = compactItem(compareWith, l, verticalCompact);\n\n // Add to comparison array. We only collide with items before this one.\n // Statics are already in this array.\n compareWith.push(l);\n }\n\n // Add to output array to make sure they still come out in the right order.\n out[layout.indexOf(l)] = l;\n\n // Clear moved flag, if it exists.\n l.moved = false;\n }\n\n return out;\n}\n\n/**\n * Compact an item in the layout.\n */\nfunction compactItem(compareWith /*: Layout*/, l /*: LayoutItem*/, verticalCompact /*: boolean*/) /*: LayoutItem*/ {\n if (verticalCompact) {\n // Move the element up as far as it can go without colliding.\n while (l.y > 0 && !getFirstCollision(compareWith, l)) {\n l.y--;\n }\n }\n\n // Move it down, and keep moving it down if it's colliding.\n var collides = void 0;\n while (collides = getFirstCollision(compareWith, l)) {\n l.y = collides.y + collides.h;\n }\n return l;\n}\n\n/**\n * Given a layout, make sure all elements fit within its bounds.\n *\n * @param {Array} layout Layout array.\n * @param {Number} bounds Number of columns.\n */\nfunction correctBounds(layout /*: Layout*/, bounds /*: {cols: number}*/) /*: Layout*/ {\n var collidesWith = getStatics(layout);\n for (var _i4 = 0, len = layout.length; _i4 < len; _i4++) {\n var l = layout[_i4];\n // Overflows right\n if (l.x + l.w > bounds.cols) l.x = bounds.cols - l.w;\n // Overflows left\n if (l.x < 0) {\n l.x = 0;\n l.w = bounds.cols;\n }\n if (!l.static) collidesWith.push(l);else {\n // If this is static and collides with other statics, we must move it down.\n // We have to do something nicer than just letting them overlap.\n while (getFirstCollision(collidesWith, l)) {\n l.y++;\n }\n }\n }\n return layout;\n}\n\n/**\n * Get a layout item by ID. Used so we can override later on if necessary.\n *\n * @param {Array} layout Layout array.\n * @param {String} id ID\n * @return {LayoutItem} Item at ID.\n */\nfunction getLayoutItem(layout /*: Layout*/, id /*: string*/) /*: ?LayoutItem*/ {\n for (var _i5 = 0, len = layout.length; _i5 < len; _i5++) {\n if (layout[_i5].i === id) return layout[_i5];\n }\n}\n\n/**\n * Returns the first item this layout collides with.\n * It doesn't appear to matter which order we approach this from, although\n * perhaps that is the wrong thing to do.\n *\n * @param {Object} layoutItem Layout item.\n * @return {Object|undefined} A colliding layout item, or undefined.\n */\nfunction getFirstCollision(layout /*: Layout*/, layoutItem /*: LayoutItem*/) /*: ?LayoutItem*/ {\n for (var _i6 = 0, len = layout.length; _i6 < len; _i6++) {\n if (collides(layout[_i6], layoutItem)) return layout[_i6];\n }\n}\n\nfunction getAllCollisions(layout /*: Layout*/, layoutItem /*: LayoutItem*/) /*: Array*/ {\n return layout.filter(function (l) {\n return collides(l, layoutItem);\n });\n}\n\n/**\n * Get all static elements.\n * @param {Array} layout Array of layout objects.\n * @return {Array} Array of static layout items..\n */\nfunction getStatics(layout /*: Layout*/) /*: Array*/ {\n //return [];\n return layout.filter(function (l) {\n return l.static;\n });\n}\n\n/**\n * Move an element. Responsible for doing cascading movements of other elements.\n *\n * @param {Array} layout Full layout to modify.\n * @param {LayoutItem} l element to move.\n * @param {Number} [x] X position in grid units.\n * @param {Number} [y] Y position in grid units.\n * @param {Boolean} [isUserAction] If true, designates that the item we're moving is\n * being dragged/resized by th euser.\n */\nfunction moveElement(layout /*: Layout*/, l /*: LayoutItem*/, x /*: Number*/, y /*: Number*/, isUserAction /*: Boolean*/) /*: Layout*/ {\n if (l.static) return layout;\n\n // Short-circuit if nothing to do.\n //if (l.y === y && l.x === x) return layout;\n\n var movingUp = y && l.y > y;\n // This is quite a bit faster than extending the object\n if (typeof x === 'number') l.x = x;\n if (typeof y === 'number') l.y = y;\n l.moved = true;\n\n // If this collides with anything, move it.\n // When doing this comparison, we have to sort the items we compare with\n // to ensure, in the case of multiple collisions, that we're getting the\n // nearest collision.\n var sorted = sortLayoutItemsByRowCol(layout);\n if (movingUp) sorted = sorted.reverse();\n var collisions = getAllCollisions(sorted, l);\n\n // Move each item that collides away from this element.\n for (var _i7 = 0, len = collisions.length; _i7 < len; _i7++) {\n var collision = collisions[_i7];\n // console.log('resolving collision between', l.i, 'at', l.y, 'and', collision.i, 'at', collision.y);\n\n // Short circuit so we can't infinite loop\n if (collision.moved) continue;\n\n // This makes it feel a bit more precise by waiting to swap for just a bit when moving up.\n if (l.y > collision.y && l.y - collision.y > collision.h / 4) continue;\n\n // Don't move static items - we have to move *this* element away\n if (collision.static) {\n layout = moveElementAwayFromCollision(layout, collision, l, isUserAction);\n } else {\n layout = moveElementAwayFromCollision(layout, l, collision, isUserAction);\n }\n }\n\n return layout;\n}\n\n/**\n * This is where the magic needs to happen - given a collision, move an element away from the collision.\n * We attempt to move it up if there's room, otherwise it goes below.\n *\n * @param {Array} layout Full layout to modify.\n * @param {LayoutItem} collidesWith Layout item we're colliding with.\n * @param {LayoutItem} itemToMove Layout item we're moving.\n * @param {Boolean} [isUserAction] If true, designates that the item we're moving is being dragged/resized\n * by the user.\n */\nfunction moveElementAwayFromCollision(layout /*: Layout*/, collidesWith /*: LayoutItem*/, itemToMove /*: LayoutItem*/, isUserAction /*: ?boolean*/) /*: Layout*/ {\n\n // If there is enough space above the collision to put this element, move it there.\n // We only do this on the main collision as this can get funky in cascades and cause\n // unwanted swapping behavior.\n if (isUserAction) {\n // Make a mock item so we don't modify the item here, only modify in moveElement.\n var fakeItem /*: LayoutItem*/ = {\n x: itemToMove.x,\n y: itemToMove.y,\n w: itemToMove.w,\n h: itemToMove.h,\n i: '-1'\n };\n fakeItem.y = Math.max(collidesWith.y - itemToMove.h, 0);\n if (!getFirstCollision(layout, fakeItem)) {\n return moveElement(layout, itemToMove, undefined, fakeItem.y);\n }\n }\n\n // Previously this was optimized to move below the collision directly, but this can cause problems\n // with cascading moves, as an item may actually leapflog a collision and cause a reversal in order.\n return moveElement(layout, itemToMove, undefined, itemToMove.y + 1);\n}\n\n/**\n * Helper to convert a number to a percentage string.\n *\n * @param {Number} num Any number\n * @return {String} That number as a percentage.\n */\nfunction perc(num /*: number*/) /*: string*/ {\n return num * 100 + '%';\n}\n\nfunction setTransform(top, left, width, height) /*: Object*/ {\n // Replace unitless items with px\n var translate = \"translate3d(\" + left + \"px,\" + top + \"px, 0)\";\n return {\n transform: translate,\n WebkitTransform: translate,\n MozTransform: translate,\n msTransform: translate,\n OTransform: translate,\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n/**\n * Just like the setTransform method, but instead it will return a negative value of right.\n *\n * @param top\n * @param right\n * @param width\n * @param height\n * @returns {{transform: string, WebkitTransform: string, MozTransform: string, msTransform: string, OTransform: string, width: string, height: string, position: string}}\n */\nfunction setTransformRtl(top, right, width, height) /*: Object*/ {\n // Replace unitless items with px\n var translate = \"translate3d(\" + right * -1 + \"px,\" + top + \"px, 0)\";\n return {\n transform: translate,\n WebkitTransform: translate,\n MozTransform: translate,\n msTransform: translate,\n OTransform: translate,\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n\nfunction setTopLeft(top, left, width, height) /*: Object*/ {\n return {\n top: top + \"px\",\n left: left + \"px\",\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n/**\n * Just like the setTopLeft method, but instead, it will return a right property instead of left.\n *\n * @param top\n * @param right\n * @param width\n * @param height\n * @returns {{top: string, right: string, width: string, height: string, position: string}}\n */\nfunction setTopRight(top, right, width, height) /*: Object*/ {\n return {\n top: top + \"px\",\n right: right + \"px\",\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n\n/**\n * Get layout items sorted from top left to right and down.\n *\n * @return {Array} Array of layout objects.\n * @return {Array} Layout, sorted static items first.\n */\nfunction sortLayoutItemsByRowCol(layout /*: Layout*/) /*: Layout*/ {\n return [].concat(layout).sort(function (a, b) {\n if (a.y > b.y || a.y === b.y && a.x > b.x) {\n return 1;\n }\n return -1;\n });\n}\n\n/**\n * Generate a layout using the initialLayout and children as a template.\n * Missing entries will be added, extraneous ones will be truncated.\n *\n * @param {Array} initialLayout Layout passed in through props.\n * @param {String} breakpoint Current responsive breakpoint.\n * @param {Boolean} verticalCompact Whether or not to compact the layout vertically.\n * @return {Array} Working layout.\n */\n/*\nexport function synchronizeLayoutWithChildren(initialLayout: Layout, children: Array|React.Element,\n cols: number, verticalCompact: boolean): Layout {\n // ensure 'children' is always an array\n if (!Array.isArray(children)) {\n children = [children];\n }\n initialLayout = initialLayout || [];\n\n // Generate one layout item per child.\n let layout: Layout = [];\n for (let i = 0, len = children.length; i < len; i++) {\n let newItem;\n const child = children[i];\n\n // Don't overwrite if it already exists.\n const exists = getLayoutItem(initialLayout, child.key || \"1\" /!* FIXME satisfies Flow *!/);\n if (exists) {\n newItem = exists;\n } else {\n const g = child.props._grid;\n\n // Hey, this item has a _grid property, use it.\n if (g) {\n if (!isProduction) {\n validateLayout([g], 'ReactGridLayout.children');\n }\n // Validated; add it to the layout. Bottom 'y' possible is the bottom of the layout.\n // This allows you to do nice stuff like specify {y: Infinity}\n if (verticalCompact) {\n newItem = cloneLayoutItem({...g, y: Math.min(bottom(layout), g.y), i: child.key});\n } else {\n newItem = cloneLayoutItem({...g, y: g.y, i: child.key});\n }\n }\n // Nothing provided: ensure this is added to the bottom\n else {\n newItem = cloneLayoutItem({w: 1, h: 1, x: 0, y: bottom(layout), i: child.key || \"1\"});\n }\n }\n layout[i] = newItem;\n }\n\n // Correct the layout.\n layout = correctBounds(layout, {cols: cols});\n layout = compact(layout, verticalCompact);\n\n return layout;\n}\n*/\n\n/**\n * Validate a layout. Throws errors.\n *\n * @param {Array} layout Array of layout items.\n * @param {String} [contextName] Context name for errors.\n * @throw {Error} Validation error.\n */\nfunction validateLayout(layout /*: Layout*/, contextName /*: string*/) /*: void*/ {\n contextName = contextName || \"Layout\";\n var subProps = ['x', 'y', 'w', 'h'];\n if (!Array.isArray(layout)) throw new Error(contextName + \" must be an array!\");\n for (var _i8 = 0, len = layout.length; _i8 < len; _i8++) {\n var item = layout[_i8];\n for (var j = 0; j < subProps.length; j++) {\n if (typeof item[subProps[j]] !== 'number') {\n throw new Error('VueGridLayout: ' + contextName + '[' + _i8 + '].' + subProps[j] + ' must be a number!');\n }\n }\n if (item.i && typeof item.i !== 'string') {\n throw new Error('VueGridLayout: ' + contextName + '[' + _i8 + '].i must be a string!');\n }\n if (item.static !== undefined && typeof item.static !== 'boolean') {\n throw new Error('VueGridLayout: ' + contextName + '[' + _i8 + '].static must be a boolean!');\n }\n }\n}\n\n// Flow can't really figure this out, so we just use Object\nfunction autoBindHandlers(el /*: Object*/, fns /*: Array*/) /*: void*/ {\n fns.forEach(function (key) {\n return el[key] = el[key].bind(el);\n });\n}\n\n/**\n * Convert a JS object to CSS string. Similar to React's output of CSS.\n * @param obj\n * @returns {string}\n */\nfunction createMarkup(obj) {\n var keys = Object.keys(obj);\n if (!keys.length) return '';\n var i,\n len = keys.length;\n var result = '';\n\n for (i = 0; i < len; i++) {\n var key = keys[i];\n var val = obj[key];\n result += hyphenate(key) + ':' + addPx(key, val) + ';';\n }\n\n return result;\n}\n\n/* The following list is defined in React's core */\nvar IS_UNITLESS = exports.IS_UNITLESS = {\n animationIterationCount: true,\n boxFlex: true,\n boxFlexGroup: true,\n boxOrdinalGroup: true,\n columnCount: true,\n flex: true,\n flexGrow: true,\n flexPositive: true,\n flexShrink: true,\n flexNegative: true,\n flexOrder: true,\n gridRow: true,\n gridColumn: true,\n fontWeight: true,\n lineClamp: true,\n lineHeight: true,\n opacity: true,\n order: true,\n orphans: true,\n tabSize: true,\n widows: true,\n zIndex: true,\n zoom: true,\n\n // SVG-related properties\n fillOpacity: true,\n stopOpacity: true,\n strokeDashoffset: true,\n strokeOpacity: true,\n strokeWidth: true\n};\n\n/**\n * Will add px to the end of style values which are Numbers.\n * @param name\n * @param value\n * @returns {*}\n */\nfunction addPx(name, value) {\n if (typeof value === 'number' && !IS_UNITLESS[name]) {\n return value + 'px';\n } else {\n return value;\n }\n}\n\n/**\n * Hyphenate a camelCase string.\n *\n * @param {String} str\n * @return {String}\n */\n\nvar hyphenateRE = exports.hyphenateRE = /([a-z\\d])([A-Z])/g;\n\nfunction hyphenate(str) {\n return str.replace(hyphenateRE, '$1-$2').toLowerCase();\n}\n\nfunction findItemInArray(array, property, value) {\n for (var i = 0; i < array.length; i++) {\n if (array[i][property] == value) return true;\n }return false;\n}\n\nfunction findAndRemove(array, property, value) {\n array.forEach(function (result, index) {\n if (result[property] === value) {\n //Remove from array\n array.splice(index, 1);\n }\n });\n}\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5)))\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvdXRpbHMuanM/MmZmOCJdLCJuYW1lcyI6WyJib3R0b20iLCJjbG9uZUxheW91dCIsImNsb25lTGF5b3V0SXRlbSIsImNvbGxpZGVzIiwiY29tcGFjdCIsImNvbXBhY3RJdGVtIiwiY29ycmVjdEJvdW5kcyIsImdldExheW91dEl0ZW0iLCJnZXRGaXJzdENvbGxpc2lvbiIsImdldEFsbENvbGxpc2lvbnMiLCJnZXRTdGF0aWNzIiwibW92ZUVsZW1lbnQiLCJtb3ZlRWxlbWVudEF3YXlGcm9tQ29sbGlzaW9uIiwicGVyYyIsInNldFRyYW5zZm9ybSIsInNldFRyYW5zZm9ybVJ0bCIsInNldFRvcExlZnQiLCJzZXRUb3BSaWdodCIsInNvcnRMYXlvdXRJdGVtc0J5Um93Q29sIiwidmFsaWRhdGVMYXlvdXQiLCJhdXRvQmluZEhhbmRsZXJzIiwiY3JlYXRlTWFya3VwIiwiYWRkUHgiLCJoeXBoZW5hdGUiLCJmaW5kSXRlbUluQXJyYXkiLCJmaW5kQW5kUmVtb3ZlIiwiaXNQcm9kdWN0aW9uIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwibGF5b3V0IiwibWF4IiwiYm90dG9tWSIsImkiLCJsZW4iLCJsZW5ndGgiLCJ5IiwiaCIsIm5ld0xheW91dCIsIkFycmF5IiwibGF5b3V0SXRlbSIsIkpTT04iLCJwYXJzZSIsInN0cmluZ2lmeSIsImwxIiwibDIiLCJ4IiwidyIsInZlcnRpY2FsQ29tcGFjdCIsImNvbXBhcmVXaXRoIiwic29ydGVkIiwib3V0IiwibCIsInN0YXRpYyIsInB1c2giLCJpbmRleE9mIiwibW92ZWQiLCJib3VuZHMiLCJjb2xsaWRlc1dpdGgiLCJjb2xzIiwiaWQiLCJmaWx0ZXIiLCJpc1VzZXJBY3Rpb24iLCJtb3ZpbmdVcCIsInJldmVyc2UiLCJjb2xsaXNpb25zIiwiY29sbGlzaW9uIiwiaXRlbVRvTW92ZSIsImZha2VJdGVtIiwiTWF0aCIsInVuZGVmaW5lZCIsIm51bSIsInRvcCIsImxlZnQiLCJ3aWR0aCIsImhlaWdodCIsInRyYW5zbGF0ZSIsInRyYW5zZm9ybSIsIldlYmtpdFRyYW5zZm9ybSIsIk1velRyYW5zZm9ybSIsIm1zVHJhbnNmb3JtIiwiT1RyYW5zZm9ybSIsInBvc2l0aW9uIiwicmlnaHQiLCJjb25jYXQiLCJzb3J0IiwiYSIsImIiLCJjb250ZXh0TmFtZSIsInN1YlByb3BzIiwiaXNBcnJheSIsIkVycm9yIiwiaXRlbSIsImoiLCJlbCIsImZucyIsImZvckVhY2giLCJrZXkiLCJiaW5kIiwib2JqIiwia2V5cyIsIk9iamVjdCIsInJlc3VsdCIsInZhbCIsIklTX1VOSVRMRVNTIiwiYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQiLCJib3hGbGV4IiwiYm94RmxleEdyb3VwIiwiYm94T3JkaW5hbEdyb3VwIiwiY29sdW1uQ291bnQiLCJmbGV4IiwiZmxleEdyb3ciLCJmbGV4UG9zaXRpdmUiLCJmbGV4U2hyaW5rIiwiZmxleE5lZ2F0aXZlIiwiZmxleE9yZGVyIiwiZ3JpZFJvdyIsImdyaWRDb2x1bW4iLCJmb250V2VpZ2h0IiwibGluZUNsYW1wIiwibGluZUhlaWdodCIsIm9wYWNpdHkiLCJvcmRlciIsIm9ycGhhbnMiLCJ0YWJTaXplIiwid2lkb3dzIiwiekluZGV4Iiwiem9vbSIsImZpbGxPcGFjaXR5Iiwic3RvcE9wYWNpdHkiLCJzdHJva2VEYXNob2Zmc2V0Iiwic3Ryb2tlT3BhY2l0eSIsInN0cm9rZVdpZHRoIiwibmFtZSIsInZhbHVlIiwiaHlwaGVuYXRlUkUiLCJzdHIiLCJyZXBsYWNlIiwidG9Mb3dlckNhc2UiLCJhcnJheSIsInByb3BlcnR5IiwiaW5kZXgiLCJzcGxpY2UiXSwibWFwcGluZ3MiOiI7Ozs7O1FBeUJnQkEsTSxHQUFBQSxNO1FBU0FDLFcsR0FBQUEsVztRQVNBQyxlLEdBQUFBLGU7UUFnQkFDLFEsR0FBQUEsUTtRQWtCQUMsTyxHQUFBQSxPO1FBaUNBQyxXLEdBQUFBLFc7UUFzQkFDLGEsR0FBQUEsYTtRQThCQUMsYSxHQUFBQSxhO1FBY0FDLGlCLEdBQUFBLGlC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QXhDLEVBQStDO0FBQ2xESyxRQUFNM0MsT0FBTixDQUFjLFVBQVVNLE1BQVYsRUFBa0J1QyxLQUFsQixFQUF5QjtBQUNuQyxRQUFJdkMsT0FBT3NDLFFBQVAsTUFBcUJOLEtBQXpCLEVBQWdDO0FBQzVCO0FBQ0FLLFlBQU1HLE1BQU4sQ0FBYUQsS0FBYixFQUFvQixDQUFwQjtBQUNIO0FBQ0osR0FMRDtBQU1ILEMiLCJmaWxlIjoiMC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5leHBvcnQgdHlwZSBMYXlvdXRJdGVtUmVxdWlyZWQgPSB7dzogbnVtYmVyLCBoOiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyLCBpOiBzdHJpbmd9O1xuZXhwb3J0IHR5cGUgTGF5b3V0SXRlbSA9IExheW91dEl0ZW1SZXF1aXJlZCAmXG4gICAgICAgICAgICAgICAgICAgICAgICAge21pblc/OiBudW1iZXIsIG1pbkg/OiBudW1iZXIsIG1heFc/OiBudW1iZXIsIG1heEg/OiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1vdmVkPzogYm9vbGVhbiwgc3RhdGljPzogYm9vbGVhbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaXNEcmFnZ2FibGU/OiA/Ym9vbGVhbiwgaXNSZXNpemFibGU/OiA/Ym9vbGVhbn07XG5leHBvcnQgdHlwZSBMYXlvdXQgPSBBcnJheTxMYXlvdXRJdGVtPjtcbmV4cG9ydCB0eXBlIFBvc2l0aW9uID0ge2xlZnQ6IG51bWJlciwgdG9wOiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyfTtcbmV4cG9ydCB0eXBlIERyYWdDYWxsYmFja0RhdGEgPSB7XG4gIG5vZGU6IEhUTUxFbGVtZW50LFxuICB4OiBudW1iZXIsIHk6IG51bWJlcixcbiAgZGVsdGFYOiBudW1iZXIsIGRlbHRhWTogbnVtYmVyLFxuICBsYXN0WDogbnVtYmVyLCBsYXN0WTogbnVtYmVyXG59O1xuZXhwb3J0IHR5cGUgRHJhZ0V2ZW50ID0ge2U6IEV2ZW50fSAmIERyYWdDYWxsYmFja0RhdGE7XG5leHBvcnQgdHlwZSBTaXplID0ge3dpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyfTtcbmV4cG9ydCB0eXBlIFJlc2l6ZUV2ZW50ID0ge2U6IEV2ZW50LCBub2RlOiBIVE1MRWxlbWVudCwgc2l6ZTogU2l6ZX07XG5cbmNvbnN0IGlzUHJvZHVjdGlvbiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbic7XG4vKipcbiAqIFJldHVybiB0aGUgYm90dG9tIGNvb3JkaW5hdGUgb2YgdGhlIGxheW91dC5cbiAqXG4gKiBAcGFyYW0gIHtBcnJheX0gbGF5b3V0IExheW91dCBhcnJheS5cbiAqIEByZXR1cm4ge051bWJlcn0gICAgICAgQm90dG9tIGNvb3JkaW5hdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBib3R0b20obGF5b3V0OiBMYXlvdXQpOiBudW1iZXIge1xuICBsZXQgbWF4ID0gMCwgYm90dG9tWTtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGJvdHRvbVkgPSBsYXlvdXRbaV0uIHkgKyBsYXlvdXRbaV0uaDtcbiAgICBpZiAoYm90dG9tWSA+IG1heCkgbWF4ID0gYm90dG9tWTtcbiAgfVxuICByZXR1cm4gbWF4O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2xvbmVMYXlvdXQobGF5b3V0OiBMYXlvdXQpOiBMYXlvdXQge1xuICBjb25zdCBuZXdMYXlvdXQgPSBBcnJheShsYXlvdXQubGVuZ3RoKTtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIG5ld0xheW91dFtpXSA9IGNsb25lTGF5b3V0SXRlbShsYXlvdXRbaV0pO1xuICB9XG4gIHJldHVybiBuZXdMYXlvdXQ7XG59XG5cbi8vIEZhc3QgcGF0aCB0byBjbG9uaW5nLCBzaW5jZSB0aGlzIGlzIG1vbm9tb3JwaGljXG5leHBvcnQgZnVuY3Rpb24gY2xvbmVMYXlvdXRJdGVtKGxheW91dEl0ZW06IExheW91dEl0ZW0pOiBMYXlvdXRJdGVtIHtcbiAgLypyZXR1cm4ge1xuICAgIHc6IGxheW91dEl0ZW0udywgaDogbGF5b3V0SXRlbS5oLCB4OiBsYXlvdXRJdGVtLngsIHk6IGxheW91dEl0ZW0ueSwgaTogbGF5b3V0SXRlbS5pLFxuICAgIG1pblc6IGxheW91dEl0ZW0ubWluVywgbWF4VzogbGF5b3V0SXRlbS5tYXhXLCBtaW5IOiBsYXlvdXRJdGVtLm1pbkgsIG1heEg6IGxheW91dEl0ZW0ubWF4SCxcbiAgICBtb3ZlZDogQm9vbGVhbihsYXlvdXRJdGVtLm1vdmVkKSwgc3RhdGljOiBCb29sZWFuKGxheW91dEl0ZW0uc3RhdGljKSxcbiAgICAvLyBUaGVzZSBjYW4gYmUgbnVsbFxuICAgIGlzRHJhZ2dhYmxlOiBsYXlvdXRJdGVtLmlzRHJhZ2dhYmxlLCBpc1Jlc2l6YWJsZTogbGF5b3V0SXRlbS5pc1Jlc2l6YWJsZVxuICB9OyovXG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobGF5b3V0SXRlbSkpO1xufVxuXG4vKipcbiAqIEdpdmVuIHR3byBsYXlvdXRpdGVtcywgY2hlY2sgaWYgdGhleSBjb2xsaWRlLlxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59ICAgVHJ1ZSBpZiBjb2xsaWRpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb2xsaWRlcyhsMTogTGF5b3V0SXRlbSwgbDI6IExheW91dEl0ZW0pOiBib29sZWFuIHtcbiAgaWYgKGwxID09PSBsMikgcmV0dXJuIGZhbHNlOyAvLyBzYW1lIGVsZW1lbnRcbiAgaWYgKGwxLnggKyBsMS53IDw9IGwyLngpIHJldHVybiBmYWxzZTsgLy8gbDEgaXMgbGVmdCBvZiBsMlxuICBpZiAobDEueCA+PSBsMi54ICsgbDIudykgcmV0dXJuIGZhbHNlOyAvLyBsMSBpcyByaWdodCBvZiBsMlxuICBpZiAobDEueSArIGwxLmggPD0gbDIueSkgcmV0dXJuIGZhbHNlOyAvLyBsMSBpcyBhYm92ZSBsMlxuICBpZiAobDEueSA+PSBsMi55ICsgbDIuaCkgcmV0dXJuIGZhbHNlOyAvLyBsMSBpcyBiZWxvdyBsMlxuICByZXR1cm4gdHJ1ZTsgLy8gYm94ZXMgb3ZlcmxhcFxufVxuXG4vKipcbiAqIEdpdmVuIGEgbGF5b3V0LCBjb21wYWN0IGl0LiBUaGlzIGludm9sdmVzIGdvaW5nIGRvd24gZWFjaCB5IGNvb3JkaW5hdGUgYW5kIHJlbW92aW5nIGdhcHNcbiAqIGJldHdlZW4gaXRlbXMuXG4gKlxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCBMYXlvdXQuXG4gKiBAcGFyYW0gIHtCb29sZWFufSB2ZXJ0aWNhbENvbXBhY3QgV2hldGhlciBvciBub3QgdG8gY29tcGFjdCB0aGUgbGF5b3V0XG4gKiAgIHZlcnRpY2FsbHkuXG4gKiBAcmV0dXJuIHtBcnJheX0gICAgICAgQ29tcGFjdGVkIExheW91dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBhY3QobGF5b3V0OiBMYXlvdXQsIHZlcnRpY2FsQ29tcGFjdDogQm9vbGVhbik6IExheW91dCB7XG4gICAgLy8gU3RhdGljcyBnbyBpbiB0aGUgY29tcGFyZVdpdGggYXJyYXkgcmlnaHQgYXdheSBzbyBpdGVtcyBmbG93IGFyb3VuZCB0aGVtLlxuICBjb25zdCBjb21wYXJlV2l0aCA9IGdldFN0YXRpY3MobGF5b3V0KTtcbiAgLy8gV2UgZ28gdGhyb3VnaCB0aGUgaXRlbXMgYnkgcm93IGFuZCBjb2x1bW4uXG4gIGNvbnN0IHNvcnRlZCA9IHNvcnRMYXlvdXRJdGVtc0J5Um93Q29sKGxheW91dCk7XG4gIC8vIEhvbGRpbmcgZm9yIG5ldyBpdGVtcy5cbiAgY29uc3Qgb3V0ID0gQXJyYXkobGF5b3V0Lmxlbmd0aCk7XG5cbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHNvcnRlZC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGxldCBsID0gc29ydGVkW2ldO1xuXG4gICAgLy8gRG9uJ3QgbW92ZSBzdGF0aWMgZWxlbWVudHNcbiAgICBpZiAoIWwuc3RhdGljKSB7XG4gICAgICBsID0gY29tcGFjdEl0ZW0oY29tcGFyZVdpdGgsIGwsIHZlcnRpY2FsQ29tcGFjdCk7XG5cbiAgICAgIC8vIEFkZCB0byBjb21wYXJpc29uIGFycmF5LiBXZSBvbmx5IGNvbGxpZGUgd2l0aCBpdGVtcyBiZWZvcmUgdGhpcyBvbmUuXG4gICAgICAvLyBTdGF0aWNzIGFyZSBhbHJlYWR5IGluIHRoaXMgYXJyYXkuXG4gICAgICBjb21wYXJlV2l0aC5wdXNoKGwpO1xuICAgIH1cblxuICAgIC8vIEFkZCB0byBvdXRwdXQgYXJyYXkgdG8gbWFrZSBzdXJlIHRoZXkgc3RpbGwgY29tZSBvdXQgaW4gdGhlIHJpZ2h0IG9yZGVyLlxuICAgIG91dFtsYXlvdXQuaW5kZXhPZihsKV0gPSBsO1xuXG4gICAgLy8gQ2xlYXIgbW92ZWQgZmxhZywgaWYgaXQgZXhpc3RzLlxuICAgIGwubW92ZWQgPSBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogQ29tcGFjdCBhbiBpdGVtIGluIHRoZSBsYXlvdXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wYWN0SXRlbShjb21wYXJlV2l0aDogTGF5b3V0LCBsOiBMYXlvdXRJdGVtLCB2ZXJ0aWNhbENvbXBhY3Q6IGJvb2xlYW4pOiBMYXlvdXRJdGVtIHtcbiAgaWYgKHZlcnRpY2FsQ29tcGFjdCkge1xuICAgIC8vIE1vdmUgdGhlIGVsZW1lbnQgdXAgYXMgZmFyIGFzIGl0IGNhbiBnbyB3aXRob3V0IGNvbGxpZGluZy5cbiAgICB3aGlsZSAobC55ID4gMCAmJiAhZ2V0Rmlyc3RDb2xsaXNpb24oY29tcGFyZVdpdGgsIGwpKSB7XG4gICAgICBsLnktLTtcbiAgICB9XG4gIH1cblxuICAvLyBNb3ZlIGl0IGRvd24sIGFuZCBrZWVwIG1vdmluZyBpdCBkb3duIGlmIGl0J3MgY29sbGlkaW5nLlxuICBsZXQgY29sbGlkZXM7XG4gIHdoaWxlKChjb2xsaWRlcyA9IGdldEZpcnN0Q29sbGlzaW9uKGNvbXBhcmVXaXRoLCBsKSkpIHtcbiAgICBsLnkgPSBjb2xsaWRlcy55ICsgY29sbGlkZXMuaDtcbiAgfVxuICByZXR1cm4gbDtcbn1cblxuLyoqXG4gKiBHaXZlbiBhIGxheW91dCwgbWFrZSBzdXJlIGFsbCBlbGVtZW50cyBmaXQgd2l0aGluIGl0cyBib3VuZHMuXG4gKlxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCBMYXlvdXQgYXJyYXkuXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGJvdW5kcyBOdW1iZXIgb2YgY29sdW1ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvcnJlY3RCb3VuZHMobGF5b3V0OiBMYXlvdXQsIGJvdW5kczoge2NvbHM6IG51bWJlcn0pOiBMYXlvdXQge1xuICBjb25zdCBjb2xsaWRlc1dpdGggPSBnZXRTdGF0aWNzKGxheW91dCk7XG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSBsYXlvdXQubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBjb25zdCBsID0gbGF5b3V0W2ldO1xuICAgIC8vIE92ZXJmbG93cyByaWdodFxuICAgIGlmIChsLnggKyBsLncgPiBib3VuZHMuY29scykgbC54ID0gYm91bmRzLmNvbHMgLSBsLnc7XG4gICAgLy8gT3ZlcmZsb3dzIGxlZnRcbiAgICBpZiAobC54IDwgMCkge1xuICAgICAgbC54ID0gMDtcbiAgICAgIGwudyA9IGJvdW5kcy5jb2xzO1xuICAgIH1cbiAgICBpZiAoIWwuc3RhdGljKSBjb2xsaWRlc1dpdGgucHVzaChsKTtcbiAgICBlbHNlIHtcbiAgICAgIC8vIElmIHRoaXMgaXMgc3RhdGljIGFuZCBjb2xsaWRlcyB3aXRoIG90aGVyIHN0YXRpY3MsIHdlIG11c3QgbW92ZSBpdCBkb3duLlxuICAgICAgLy8gV2UgaGF2ZSB0byBkbyBzb21ldGhpbmcgbmljZXIgdGhhbiBqdXN0IGxldHRpbmcgdGhlbSBvdmVybGFwLlxuICAgICAgd2hpbGUoZ2V0Rmlyc3RDb2xsaXNpb24oY29sbGlkZXNXaXRoLCBsKSkge1xuICAgICAgICBsLnkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGxheW91dDtcbn1cblxuLyoqXG4gKiBHZXQgYSBsYXlvdXQgaXRlbSBieSBJRC4gVXNlZCBzbyB3ZSBjYW4gb3ZlcnJpZGUgbGF0ZXIgb24gaWYgbmVjZXNzYXJ5LlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSAgbGF5b3V0IExheW91dCBhcnJheS5cbiAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgIElEXG4gKiBAcmV0dXJuIHtMYXlvdXRJdGVtfSAgICBJdGVtIGF0IElELlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGF5b3V0SXRlbShsYXlvdXQ6IExheW91dCwgaWQ6IHN0cmluZyk6ID9MYXlvdXRJdGVtIHtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChsYXlvdXRbaV0uaSA9PT0gaWQpIHJldHVybiBsYXlvdXRbaV07XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCBpdGVtIHRoaXMgbGF5b3V0IGNvbGxpZGVzIHdpdGguXG4gKiBJdCBkb2Vzbid0IGFwcGVhciB0byBtYXR0ZXIgd2hpY2ggb3JkZXIgd2UgYXBwcm9hY2ggdGhpcyBmcm9tLCBhbHRob3VnaFxuICogcGVyaGFwcyB0aGF0IGlzIHRoZSB3cm9uZyB0aGluZyB0byBkby5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGxheW91dEl0ZW0gTGF5b3V0IGl0ZW0uXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSAgQSBjb2xsaWRpbmcgbGF5b3V0IGl0ZW0sIG9yIHVuZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZpcnN0Q29sbGlzaW9uKGxheW91dDogTGF5b3V0LCBsYXlvdXRJdGVtOiBMYXlvdXRJdGVtKTogP0xheW91dEl0ZW0ge1xuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGF5b3V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKGNvbGxpZGVzKGxheW91dFtpXSwgbGF5b3V0SXRlbSkpIHJldHVybiBsYXlvdXRbaV07XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFsbENvbGxpc2lvbnMobGF5b3V0OiBMYXlvdXQsIGxheW91dEl0ZW06IExheW91dEl0ZW0pOiBBcnJheTxMYXlvdXRJdGVtPiB7XG4gIHJldHVybiBsYXlvdXQuZmlsdGVyKChsKSA9PiBjb2xsaWRlcyhsLCBsYXlvdXRJdGVtKSk7XG59XG5cbi8qKlxuICogR2V0IGFsbCBzdGF0aWMgZWxlbWVudHMuXG4gKiBAcGFyYW0gIHtBcnJheX0gbGF5b3V0IEFycmF5IG9mIGxheW91dCBvYmplY3RzLlxuICogQHJldHVybiB7QXJyYXl9ICAgICAgICBBcnJheSBvZiBzdGF0aWMgbGF5b3V0IGl0ZW1zLi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0YXRpY3MobGF5b3V0OiBMYXlvdXQpOiBBcnJheTxMYXlvdXRJdGVtPiB7XG4gICAgLy9yZXR1cm4gW107XG4gICAgcmV0dXJuIGxheW91dC5maWx0ZXIoKGwpID0+IGwuc3RhdGljKTtcbn1cblxuLyoqXG4gKiBNb3ZlIGFuIGVsZW1lbnQuIFJlc3BvbnNpYmxlIGZvciBkb2luZyBjYXNjYWRpbmcgbW92ZW1lbnRzIG9mIG90aGVyIGVsZW1lbnRzLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSAgICAgIGxheW91dCBGdWxsIGxheW91dCB0byBtb2RpZnkuXG4gKiBAcGFyYW0gIHtMYXlvdXRJdGVtfSBsICAgICAgZWxlbWVudCB0byBtb3ZlLlxuICogQHBhcmFtICB7TnVtYmVyfSAgICAgW3hdICAgIFggcG9zaXRpb24gaW4gZ3JpZCB1bml0cy5cbiAqIEBwYXJhbSAge051bWJlcn0gICAgIFt5XSAgICBZIHBvc2l0aW9uIGluIGdyaWQgdW5pdHMuXG4gKiBAcGFyYW0gIHtCb29sZWFufSAgICBbaXNVc2VyQWN0aW9uXSBJZiB0cnVlLCBkZXNpZ25hdGVzIHRoYXQgdGhlIGl0ZW0gd2UncmUgbW92aW5nIGlzXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWluZyBkcmFnZ2VkL3Jlc2l6ZWQgYnkgdGggZXVzZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlRWxlbWVudChsYXlvdXQ6IExheW91dCwgbDogTGF5b3V0SXRlbSwgeDogTnVtYmVyLCB5OiBOdW1iZXIsIGlzVXNlckFjdGlvbjogQm9vbGVhbik6IExheW91dCB7XG4gIGlmIChsLnN0YXRpYykgcmV0dXJuIGxheW91dDtcblxuICAvLyBTaG9ydC1jaXJjdWl0IGlmIG5vdGhpbmcgdG8gZG8uXG4gIC8vaWYgKGwueSA9PT0geSAmJiBsLnggPT09IHgpIHJldHVybiBsYXlvdXQ7XG5cbiAgY29uc3QgbW92aW5nVXAgPSB5ICYmIGwueSA+IHk7XG4gIC8vIFRoaXMgaXMgcXVpdGUgYSBiaXQgZmFzdGVyIHRoYW4gZXh0ZW5kaW5nIHRoZSBvYmplY3RcbiAgaWYgKHR5cGVvZiB4ID09PSAnbnVtYmVyJykgbC54ID0geDtcbiAgaWYgKHR5cGVvZiB5ID09PSAnbnVtYmVyJykgbC55ID0geTtcbiAgbC5tb3ZlZCA9IHRydWU7XG5cbiAgLy8gSWYgdGhpcyBjb2xsaWRlcyB3aXRoIGFueXRoaW5nLCBtb3ZlIGl0LlxuICAvLyBXaGVuIGRvaW5nIHRoaXMgY29tcGFyaXNvbiwgd2UgaGF2ZSB0byBzb3J0IHRoZSBpdGVtcyB3ZSBjb21wYXJlIHdpdGhcbiAgLy8gdG8gZW5zdXJlLCBpbiB0aGUgY2FzZSBvZiBtdWx0aXBsZSBjb2xsaXNpb25zLCB0aGF0IHdlJ3JlIGdldHRpbmcgdGhlXG4gIC8vIG5lYXJlc3QgY29sbGlzaW9uLlxuICBsZXQgc29ydGVkID0gc29ydExheW91dEl0ZW1zQnlSb3dDb2wobGF5b3V0KTtcbiAgaWYgKG1vdmluZ1VwKSBzb3J0ZWQgPSBzb3J0ZWQucmV2ZXJzZSgpO1xuICBjb25zdCBjb2xsaXNpb25zID0gZ2V0QWxsQ29sbGlzaW9ucyhzb3J0ZWQsIGwpO1xuXG4gIC8vIE1vdmUgZWFjaCBpdGVtIHRoYXQgY29sbGlkZXMgYXdheSBmcm9tIHRoaXMgZWxlbWVudC5cbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNvbGxpc2lvbnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBjb25zdCBjb2xsaXNpb24gPSBjb2xsaXNpb25zW2ldO1xuICAgIC8vIGNvbnNvbGUubG9nKCdyZXNvbHZpbmcgY29sbGlzaW9uIGJldHdlZW4nLCBsLmksICdhdCcsIGwueSwgJ2FuZCcsIGNvbGxpc2lvbi5pLCAnYXQnLCBjb2xsaXNpb24ueSk7XG5cbiAgICAvLyBTaG9ydCBjaXJjdWl0IHNvIHdlIGNhbid0IGluZmluaXRlIGxvb3BcbiAgICBpZiAoY29sbGlzaW9uLm1vdmVkKSBjb250aW51ZTtcblxuICAgIC8vIFRoaXMgbWFrZXMgaXQgZmVlbCBhIGJpdCBtb3JlIHByZWNpc2UgYnkgd2FpdGluZyB0byBzd2FwIGZvciBqdXN0IGEgYml0IHdoZW4gbW92aW5nIHVwLlxuICAgIGlmIChsLnkgPiBjb2xsaXNpb24ueSAmJiBsLnkgLSBjb2xsaXNpb24ueSA+IGNvbGxpc2lvbi5oIC8gNCkgY29udGludWU7XG5cbiAgICAvLyBEb24ndCBtb3ZlIHN0YXRpYyBpdGVtcyAtIHdlIGhhdmUgdG8gbW92ZSAqdGhpcyogZWxlbWVudCBhd2F5XG4gICAgaWYgKGNvbGxpc2lvbi5zdGF0aWMpIHtcbiAgICAgIGxheW91dCA9IG1vdmVFbGVtZW50QXdheUZyb21Db2xsaXNpb24obGF5b3V0LCBjb2xsaXNpb24sIGwsIGlzVXNlckFjdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxheW91dCA9IG1vdmVFbGVtZW50QXdheUZyb21Db2xsaXNpb24obGF5b3V0LCBsLCBjb2xsaXNpb24sIGlzVXNlckFjdGlvbik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGxheW91dDtcbn1cblxuLyoqXG4gKiBUaGlzIGlzIHdoZXJlIHRoZSBtYWdpYyBuZWVkcyB0byBoYXBwZW4gLSBnaXZlbiBhIGNvbGxpc2lvbiwgbW92ZSBhbiBlbGVtZW50IGF3YXkgZnJvbSB0aGUgY29sbGlzaW9uLlxuICogV2UgYXR0ZW1wdCB0byBtb3ZlIGl0IHVwIGlmIHRoZXJlJ3Mgcm9vbSwgb3RoZXJ3aXNlIGl0IGdvZXMgYmVsb3cuXG4gKlxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCAgICAgICAgICAgIEZ1bGwgbGF5b3V0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSAge0xheW91dEl0ZW19IGNvbGxpZGVzV2l0aCBMYXlvdXQgaXRlbSB3ZSdyZSBjb2xsaWRpbmcgd2l0aC5cbiAqIEBwYXJhbSAge0xheW91dEl0ZW19IGl0ZW1Ub01vdmUgICBMYXlvdXQgaXRlbSB3ZSdyZSBtb3ZpbmcuXG4gKiBAcGFyYW0gIHtCb29sZWFufSBbaXNVc2VyQWN0aW9uXSAgSWYgdHJ1ZSwgZGVzaWduYXRlcyB0aGF0IHRoZSBpdGVtIHdlJ3JlIG1vdmluZyBpcyBiZWluZyBkcmFnZ2VkL3Jlc2l6ZWRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSB0aGUgdXNlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vdmVFbGVtZW50QXdheUZyb21Db2xsaXNpb24obGF5b3V0OiBMYXlvdXQsIGNvbGxpZGVzV2l0aDogTGF5b3V0SXRlbSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1Ub01vdmU6IExheW91dEl0ZW0sIGlzVXNlckFjdGlvbjogP2Jvb2xlYW4pOiBMYXlvdXQge1xuXG4gIC8vIElmIHRoZXJlIGlzIGVub3VnaCBzcGFjZSBhYm92ZSB0aGUgY29sbGlzaW9uIHRvIHB1dCB0aGlzIGVsZW1lbnQsIG1vdmUgaXQgdGhlcmUuXG4gIC8vIFdlIG9ubHkgZG8gdGhpcyBvbiB0aGUgbWFpbiBjb2xsaXNpb24gYXMgdGhpcyBjYW4gZ2V0IGZ1bmt5IGluIGNhc2NhZGVzIGFuZCBjYXVzZVxuICAvLyB1bndhbnRlZCBzd2FwcGluZyBiZWhhdmlvci5cbiAgaWYgKGlzVXNlckFjdGlvbikge1xuICAgIC8vIE1ha2UgYSBtb2NrIGl0ZW0gc28gd2UgZG9uJ3QgbW9kaWZ5IHRoZSBpdGVtIGhlcmUsIG9ubHkgbW9kaWZ5IGluIG1vdmVFbGVtZW50LlxuICAgIGNvbnN0IGZha2VJdGVtOiBMYXlvdXRJdGVtID0ge1xuICAgICAgeDogaXRlbVRvTW92ZS54LFxuICAgICAgeTogaXRlbVRvTW92ZS55LFxuICAgICAgdzogaXRlbVRvTW92ZS53LFxuICAgICAgaDogaXRlbVRvTW92ZS5oLFxuICAgICAgaTogJy0xJ1xuICAgIH07XG4gICAgZmFrZUl0ZW0ueSA9IE1hdGgubWF4KGNvbGxpZGVzV2l0aC55IC0gaXRlbVRvTW92ZS5oLCAwKTtcbiAgICBpZiAoIWdldEZpcnN0Q29sbGlzaW9uKGxheW91dCwgZmFrZUl0ZW0pKSB7XG4gICAgICByZXR1cm4gbW92ZUVsZW1lbnQobGF5b3V0LCBpdGVtVG9Nb3ZlLCB1bmRlZmluZWQsIGZha2VJdGVtLnkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFByZXZpb3VzbHkgdGhpcyB3YXMgb3B0aW1pemVkIHRvIG1vdmUgYmVsb3cgdGhlIGNvbGxpc2lvbiBkaXJlY3RseSwgYnV0IHRoaXMgY2FuIGNhdXNlIHByb2JsZW1zXG4gIC8vIHdpdGggY2FzY2FkaW5nIG1vdmVzLCBhcyBhbiBpdGVtIG1heSBhY3R1YWxseSBsZWFwZmxvZyBhIGNvbGxpc2lvbiBhbmQgY2F1c2UgYSByZXZlcnNhbCBpbiBvcmRlci5cbiAgcmV0dXJuIG1vdmVFbGVtZW50KGxheW91dCwgaXRlbVRvTW92ZSwgdW5kZWZpbmVkLCBpdGVtVG9Nb3ZlLnkgKyAxKTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgdG8gY29udmVydCBhIG51bWJlciB0byBhIHBlcmNlbnRhZ2Ugc3RyaW5nLlxuICpcbiAqIEBwYXJhbSAge051bWJlcn0gbnVtIEFueSBudW1iZXJcbiAqIEByZXR1cm4ge1N0cmluZ30gICAgIFRoYXQgbnVtYmVyIGFzIGEgcGVyY2VudGFnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBlcmMobnVtOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gbnVtICogMTAwICsgJyUnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0VHJhbnNmb3JtKHRvcCwgbGVmdCwgd2lkdGgsIGhlaWdodCk6IE9iamVjdCB7XG4gIC8vIFJlcGxhY2UgdW5pdGxlc3MgaXRlbXMgd2l0aCBweFxuICBjb25zdCB0cmFuc2xhdGUgPSBcInRyYW5zbGF0ZTNkKFwiICsgbGVmdCArIFwicHgsXCIgKyB0b3AgKyBcInB4LCAwKVwiO1xuICByZXR1cm4ge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlLFxuICAgIFdlYmtpdFRyYW5zZm9ybTogdHJhbnNsYXRlLFxuICAgIE1velRyYW5zZm9ybTogdHJhbnNsYXRlLFxuICAgIG1zVHJhbnNmb3JtOiB0cmFuc2xhdGUsXG4gICAgT1RyYW5zZm9ybTogdHJhbnNsYXRlLFxuICAgIHdpZHRoOiB3aWR0aCArIFwicHhcIixcbiAgICBoZWlnaHQ6IGhlaWdodCArIFwicHhcIixcbiAgICBwb3NpdGlvbjogJ2Fic29sdXRlJ1xuICB9O1xufVxuLyoqXG4gKiBKdXN0IGxpa2UgdGhlIHNldFRyYW5zZm9ybSBtZXRob2QsIGJ1dCBpbnN0ZWFkIGl0IHdpbGwgcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUgb2YgcmlnaHQuXG4gKlxuICogQHBhcmFtIHRvcFxuICogQHBhcmFtIHJpZ2h0XG4gKiBAcGFyYW0gd2lkdGhcbiAqIEBwYXJhbSBoZWlnaHRcbiAqIEByZXR1cm5zIHt7dHJhbnNmb3JtOiBzdHJpbmcsIFdlYmtpdFRyYW5zZm9ybTogc3RyaW5nLCBNb3pUcmFuc2Zvcm06IHN0cmluZywgbXNUcmFuc2Zvcm06IHN0cmluZywgT1RyYW5zZm9ybTogc3RyaW5nLCB3aWR0aDogc3RyaW5nLCBoZWlnaHQ6IHN0cmluZywgcG9zaXRpb246IHN0cmluZ319XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRUcmFuc2Zvcm1SdGwodG9wLCByaWdodCwgd2lkdGgsIGhlaWdodCk6IE9iamVjdCB7XG4gICAgLy8gUmVwbGFjZSB1bml0bGVzcyBpdGVtcyB3aXRoIHB4XG4gICAgY29uc3QgdHJhbnNsYXRlID0gXCJ0cmFuc2xhdGUzZChcIiArIHJpZ2h0ICogLTEgKyBcInB4LFwiICsgdG9wICsgXCJweCwgMClcIjtcbiAgICByZXR1cm4ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSxcbiAgICAgICAgV2Via2l0VHJhbnNmb3JtOiB0cmFuc2xhdGUsXG4gICAgICAgIE1velRyYW5zZm9ybTogdHJhbnNsYXRlLFxuICAgICAgICBtc1RyYW5zZm9ybTogdHJhbnNsYXRlLFxuICAgICAgICBPVHJhbnNmb3JtOiB0cmFuc2xhdGUsXG4gICAgICAgIHdpZHRoOiB3aWR0aCArIFwicHhcIixcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHQgKyBcInB4XCIsXG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXG4gICAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFRvcExlZnQodG9wLCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KTogT2JqZWN0IHtcbiAgICByZXR1cm4ge1xuICAgICAgICB0b3A6IHRvcCArIFwicHhcIixcbiAgICAgICAgbGVmdDogbGVmdCArIFwicHhcIixcbiAgICAgICAgd2lkdGg6IHdpZHRoICsgXCJweFwiLFxuICAgICAgICBoZWlnaHQ6IGhlaWdodCArIFwicHhcIixcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcbiAgICB9O1xufVxuLyoqXG4gKiBKdXN0IGxpa2UgdGhlIHNldFRvcExlZnQgbWV0aG9kLCBidXQgaW5zdGVhZCwgaXQgd2lsbCByZXR1cm4gYSByaWdodCBwcm9wZXJ0eSBpbnN0ZWFkIG9mIGxlZnQuXG4gKlxuICogQHBhcmFtIHRvcFxuICogQHBhcmFtIHJpZ2h0XG4gKiBAcGFyYW0gd2lkdGhcbiAqIEBwYXJhbSBoZWlnaHRcbiAqIEByZXR1cm5zIHt7dG9wOiBzdHJpbmcsIHJpZ2h0OiBzdHJpbmcsIHdpZHRoOiBzdHJpbmcsIGhlaWdodDogc3RyaW5nLCBwb3NpdGlvbjogc3RyaW5nfX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFRvcFJpZ2h0KHRvcCwgcmlnaHQsIHdpZHRoLCBoZWlnaHQpOiBPYmplY3Qge1xuICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogdG9wICsgXCJweFwiLFxuICAgICAgICByaWdodDogcmlnaHQrIFwicHhcIixcbiAgICAgICAgd2lkdGg6IHdpZHRoICsgXCJweFwiLFxuICAgICAgICBoZWlnaHQ6IGhlaWdodCArIFwicHhcIixcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcbiAgICB9O1xufVxuXG5cbi8qKlxuICogR2V0IGxheW91dCBpdGVtcyBzb3J0ZWQgZnJvbSB0b3AgbGVmdCB0byByaWdodCBhbmQgZG93bi5cbiAqXG4gKiBAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgbGF5b3V0IG9iamVjdHMuXG4gKiBAcmV0dXJuIHtBcnJheX0gICAgICAgIExheW91dCwgc29ydGVkIHN0YXRpYyBpdGVtcyBmaXJzdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNvcnRMYXlvdXRJdGVtc0J5Um93Q29sKGxheW91dDogTGF5b3V0KTogTGF5b3V0IHtcbiAgcmV0dXJuIFtdLmNvbmNhdChsYXlvdXQpLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgIGlmIChhLnkgPiBiLnkgfHwgKGEueSA9PT0gYi55ICYmIGEueCA+IGIueCkpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH0pO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIGEgbGF5b3V0IHVzaW5nIHRoZSBpbml0aWFsTGF5b3V0IGFuZCBjaGlsZHJlbiBhcyBhIHRlbXBsYXRlLlxuICogTWlzc2luZyBlbnRyaWVzIHdpbGwgYmUgYWRkZWQsIGV4dHJhbmVvdXMgb25lcyB3aWxsIGJlIHRydW5jYXRlZC5cbiAqXG4gKiBAcGFyYW0gIHtBcnJheX0gIGluaXRpYWxMYXlvdXQgTGF5b3V0IHBhc3NlZCBpbiB0aHJvdWdoIHByb3BzLlxuICogQHBhcmFtICB7U3RyaW5nfSBicmVha3BvaW50ICAgIEN1cnJlbnQgcmVzcG9uc2l2ZSBicmVha3BvaW50LlxuICogQHBhcmFtICB7Qm9vbGVhbn0gdmVydGljYWxDb21wYWN0IFdoZXRoZXIgb3Igbm90IHRvIGNvbXBhY3QgdGhlIGxheW91dCB2ZXJ0aWNhbGx5LlxuICogQHJldHVybiB7QXJyYXl9ICAgICAgICAgICAgICAgIFdvcmtpbmcgbGF5b3V0LlxuICovXG4vKlxuZXhwb3J0IGZ1bmN0aW9uIHN5bmNocm9uaXplTGF5b3V0V2l0aENoaWxkcmVuKGluaXRpYWxMYXlvdXQ6IExheW91dCwgY2hpbGRyZW46IEFycmF5PFJlYWN0LkVsZW1lbnQ+fFJlYWN0LkVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sczogbnVtYmVyLCB2ZXJ0aWNhbENvbXBhY3Q6IGJvb2xlYW4pOiBMYXlvdXQge1xuICAvLyBlbnN1cmUgJ2NoaWxkcmVuJyBpcyBhbHdheXMgYW4gYXJyYXlcbiAgaWYgKCFBcnJheS5pc0FycmF5KGNoaWxkcmVuKSkge1xuICAgIGNoaWxkcmVuID0gW2NoaWxkcmVuXTtcbiAgfVxuICBpbml0aWFsTGF5b3V0ID0gaW5pdGlhbExheW91dCB8fCBbXTtcblxuICAvLyBHZW5lcmF0ZSBvbmUgbGF5b3V0IGl0ZW0gcGVyIGNoaWxkLlxuICBsZXQgbGF5b3V0OiBMYXlvdXQgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgbGV0IG5ld0l0ZW07XG4gICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbltpXTtcblxuICAgIC8vIERvbid0IG92ZXJ3cml0ZSBpZiBpdCBhbHJlYWR5IGV4aXN0cy5cbiAgICBjb25zdCBleGlzdHMgPSBnZXRMYXlvdXRJdGVtKGluaXRpYWxMYXlvdXQsIGNoaWxkLmtleSB8fCBcIjFcIiAvISogRklYTUUgc2F0aXNmaWVzIEZsb3cgKiEvKTtcbiAgICBpZiAoZXhpc3RzKSB7XG4gICAgICBuZXdJdGVtID0gZXhpc3RzO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBnID0gY2hpbGQucHJvcHMuX2dyaWQ7XG5cbiAgICAgIC8vIEhleSwgdGhpcyBpdGVtIGhhcyBhIF9ncmlkIHByb3BlcnR5LCB1c2UgaXQuXG4gICAgICBpZiAoZykge1xuICAgICAgICBpZiAoIWlzUHJvZHVjdGlvbikge1xuICAgICAgICAgIHZhbGlkYXRlTGF5b3V0KFtnXSwgJ1JlYWN0R3JpZExheW91dC5jaGlsZHJlbicpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFZhbGlkYXRlZDsgYWRkIGl0IHRvIHRoZSBsYXlvdXQuIEJvdHRvbSAneScgcG9zc2libGUgaXMgdGhlIGJvdHRvbSBvZiB0aGUgbGF5b3V0LlxuICAgICAgICAvLyBUaGlzIGFsbG93cyB5b3UgdG8gZG8gbmljZSBzdHVmZiBsaWtlIHNwZWNpZnkge3k6IEluZmluaXR5fVxuICAgICAgICBpZiAodmVydGljYWxDb21wYWN0KSB7XG4gICAgICAgICAgbmV3SXRlbSA9IGNsb25lTGF5b3V0SXRlbSh7Li4uZywgeTogTWF0aC5taW4oYm90dG9tKGxheW91dCksIGcueSksIGk6IGNoaWxkLmtleX0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld0l0ZW0gPSBjbG9uZUxheW91dEl0ZW0oey4uLmcsIHk6IGcueSwgaTogY2hpbGQua2V5fSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIE5vdGhpbmcgcHJvdmlkZWQ6IGVuc3VyZSB0aGlzIGlzIGFkZGVkIHRvIHRoZSBib3R0b21cbiAgICAgIGVsc2Uge1xuICAgICAgICBuZXdJdGVtID0gY2xvbmVMYXlvdXRJdGVtKHt3OiAxLCBoOiAxLCB4OiAwLCB5OiBib3R0b20obGF5b3V0KSwgaTogY2hpbGQua2V5IHx8IFwiMVwifSk7XG4gICAgICB9XG4gICAgfVxuICAgIGxheW91dFtpXSA9IG5ld0l0ZW07XG4gIH1cblxuICAvLyBDb3JyZWN0IHRoZSBsYXlvdXQuXG4gIGxheW91dCA9IGNvcnJlY3RCb3VuZHMobGF5b3V0LCB7Y29sczogY29sc30pO1xuICBsYXlvdXQgPSBjb21wYWN0KGxheW91dCwgdmVydGljYWxDb21wYWN0KTtcblxuICByZXR1cm4gbGF5b3V0O1xufVxuKi9cblxuLyoqXG4gKiBWYWxpZGF0ZSBhIGxheW91dC4gVGhyb3dzIGVycm9ycy5cbiAqXG4gKiBAcGFyYW0gIHtBcnJheX0gIGxheW91dCAgICAgICAgQXJyYXkgb2YgbGF5b3V0IGl0ZW1zLlxuICogQHBhcmFtICB7U3RyaW5nfSBbY29udGV4dE5hbWVdIENvbnRleHQgbmFtZSBmb3IgZXJyb3JzLlxuICogQHRocm93ICB7RXJyb3J9ICAgICAgICAgICAgICAgIFZhbGlkYXRpb24gZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUxheW91dChsYXlvdXQ6IExheW91dCwgY29udGV4dE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICBjb250ZXh0TmFtZSA9IGNvbnRleHROYW1lIHx8IFwiTGF5b3V0XCI7XG4gIGNvbnN0IHN1YlByb3BzID0gWyd4JywgJ3knLCAndycsICdoJ107XG4gIGlmICghQXJyYXkuaXNBcnJheShsYXlvdXQpKSB0aHJvdyBuZXcgRXJyb3IoY29udGV4dE5hbWUgKyBcIiBtdXN0IGJlIGFuIGFycmF5IVwiKTtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGNvbnN0IGl0ZW0gPSBsYXlvdXRbaV07XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBzdWJQcm9wcy5sZW5ndGg7IGorKykge1xuICAgICAgaWYgKHR5cGVvZiBpdGVtW3N1YlByb3BzW2pdXSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdWdWVHcmlkTGF5b3V0OiAnICsgY29udGV4dE5hbWUgKyAnWycgKyBpICsgJ10uJyArIHN1YlByb3BzW2pdICsgJyBtdXN0IGJlIGEgbnVtYmVyIScpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXRlbS5pICYmIHR5cGVvZiBpdGVtLmkgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Z1ZUdyaWRMYXlvdXQ6ICcgKyBjb250ZXh0TmFtZSArICdbJyArIGkgKyAnXS5pIG11c3QgYmUgYSBzdHJpbmchJyk7XG4gICAgfVxuICAgIGlmIChpdGVtLnN0YXRpYyAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBpdGVtLnN0YXRpYyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Z1ZUdyaWRMYXlvdXQ6ICcgKyBjb250ZXh0TmFtZSArICdbJyArIGkgKyAnXS5zdGF0aWMgbXVzdCBiZSBhIGJvb2xlYW4hJyk7XG4gICAgfVxuICB9XG59XG5cbi8vIEZsb3cgY2FuJ3QgcmVhbGx5IGZpZ3VyZSB0aGlzIG91dCwgc28gd2UganVzdCB1c2UgT2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gYXV0b0JpbmRIYW5kbGVycyhlbDogT2JqZWN0LCBmbnM6IEFycmF5PHN0cmluZz4pOiB2b2lkIHtcbiAgZm5zLmZvckVhY2goKGtleSkgPT4gZWxba2V5XSA9IGVsW2tleV0uYmluZChlbCkpO1xufVxuXG5cblxuLyoqXG4gKiBDb252ZXJ0IGEgSlMgb2JqZWN0IHRvIENTUyBzdHJpbmcuIFNpbWlsYXIgdG8gUmVhY3QncyBvdXRwdXQgb2YgQ1NTLlxuICogQHBhcmFtIG9ialxuICogQHJldHVybnMge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1hcmt1cChvYmopIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaik7XG4gICAgaWYgKCFrZXlzLmxlbmd0aCkgcmV0dXJuICcnO1xuICAgIHZhciBpLCBsZW4gPSBrZXlzLmxlbmd0aDtcbiAgICB2YXIgcmVzdWx0ID0gJyc7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgIHZhciB2YWwgPSBvYmpba2V5XTtcbiAgICAgICAgcmVzdWx0ICs9IGh5cGhlbmF0ZShrZXkpICsgJzonICsgYWRkUHgoa2V5LCB2YWwpICsgJzsnO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cblxuLyogVGhlIGZvbGxvd2luZyBsaXN0IGlzIGRlZmluZWQgaW4gUmVhY3QncyBjb3JlICovXG5leHBvcnQgdmFyIElTX1VOSVRMRVNTID0ge1xuICAgIGFuaW1hdGlvbkl0ZXJhdGlvbkNvdW50OiB0cnVlLFxuICAgIGJveEZsZXg6IHRydWUsXG4gICAgYm94RmxleEdyb3VwOiB0cnVlLFxuICAgIGJveE9yZGluYWxHcm91cDogdHJ1ZSxcbiAgICBjb2x1bW5Db3VudDogdHJ1ZSxcbiAgICBmbGV4OiB0cnVlLFxuICAgIGZsZXhHcm93OiB0cnVlLFxuICAgIGZsZXhQb3NpdGl2ZTogdHJ1ZSxcbiAgICBmbGV4U2hyaW5rOiB0cnVlLFxuICAgIGZsZXhOZWdhdGl2ZTogdHJ1ZSxcbiAgICBmbGV4T3JkZXI6IHRydWUsXG4gICAgZ3JpZFJvdzogdHJ1ZSxcbiAgICBncmlkQ29sdW1uOiB0cnVlLFxuICAgIGZvbnRXZWlnaHQ6IHRydWUsXG4gICAgbGluZUNsYW1wOiB0cnVlLFxuICAgIGxpbmVIZWlnaHQ6IHRydWUsXG4gICAgb3BhY2l0eTogdHJ1ZSxcbiAgICBvcmRlcjogdHJ1ZSxcbiAgICBvcnBoYW5zOiB0cnVlLFxuICAgIHRhYlNpemU6IHRydWUsXG4gICAgd2lkb3dzOiB0cnVlLFxuICAgIHpJbmRleDogdHJ1ZSxcbiAgICB6b29tOiB0cnVlLFxuXG4gICAgLy8gU1ZHLXJlbGF0ZWQgcHJvcGVydGllc1xuICAgIGZpbGxPcGFjaXR5OiB0cnVlLFxuICAgIHN0b3BPcGFjaXR5OiB0cnVlLFxuICAgIHN0cm9rZURhc2hvZmZzZXQ6IHRydWUsXG4gICAgc3Ryb2tlT3BhY2l0eTogdHJ1ZSxcbiAgICBzdHJva2VXaWR0aDogdHJ1ZVxufTtcblxuXG4vKipcbiAqIFdpbGwgYWRkIHB4IHRvIHRoZSBlbmQgb2Ygc3R5bGUgdmFsdWVzIHdoaWNoIGFyZSBOdW1iZXJzLlxuICogQHBhcmFtIG5hbWVcbiAqIEBwYXJhbSB2YWx1ZVxuICogQHJldHVybnMgeyp9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRQeChuYW1lLCB2YWx1ZSkge1xuICAgIGlmKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgIUlTX1VOSVRMRVNTWyBuYW1lIF0pIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlICsgJ3B4JztcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxufVxuXG5cbi8qKlxuICogSHlwaGVuYXRlIGEgY2FtZWxDYXNlIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblxuZXhwb3J0IHZhciBoeXBoZW5hdGVSRSA9IC8oW2EtelxcZF0pKFtBLVpdKS9nO1xuXG5leHBvcnQgZnVuY3Rpb24gaHlwaGVuYXRlKHN0cikge1xuICAgIHJldHVybiBzdHIucmVwbGFjZShoeXBoZW5hdGVSRSwgJyQxLSQyJykudG9Mb3dlckNhc2UoKTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZmluZEl0ZW1JbkFycmF5KGFycmF5LCBwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgICBmb3IgKHZhciBpPTA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKylcbiAgICAgICAgaWYgKGFycmF5W2ldW3Byb3BlcnR5XSA9PSB2YWx1ZSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZEFuZFJlbW92ZShhcnJheSwgcHJvcGVydHksIHZhbHVlKSB7XG4gICAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbiAocmVzdWx0LCBpbmRleCkge1xuICAgICAgICBpZiAocmVzdWx0W3Byb3BlcnR5XSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgIC8vUmVtb3ZlIGZyb20gYXJyYXlcbiAgICAgICAgICAgIGFycmF5LnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy91dGlscy5qcyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0\n"); +eval("/* WEBPACK VAR INJECTION */(function(process) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.bottom = bottom;\nexports.cloneLayout = cloneLayout;\nexports.cloneLayoutItem = cloneLayoutItem;\nexports.collides = collides;\nexports.compact = compact;\nexports.compactItem = compactItem;\nexports.correctBounds = correctBounds;\nexports.getLayoutItem = getLayoutItem;\nexports.getFirstCollision = getFirstCollision;\nexports.getAllCollisions = getAllCollisions;\nexports.getStatics = getStatics;\nexports.moveElement = moveElement;\nexports.moveElementAwayFromCollision = moveElementAwayFromCollision;\nexports.perc = perc;\nexports.setTransform = setTransform;\nexports.setTransformRtl = setTransformRtl;\nexports.setTopLeft = setTopLeft;\nexports.setTopRight = setTopRight;\nexports.sortLayoutItemsByRowCol = sortLayoutItemsByRowCol;\nexports.validateLayout = validateLayout;\nexports.autoBindHandlers = autoBindHandlers;\nexports.createMarkup = createMarkup;\nexports.addPx = addPx;\nexports.hyphenate = hyphenate;\nexports.findItemInArray = findItemInArray;\nexports.findAndRemove = findAndRemove;\n// @flow\n/*:: export type LayoutItemRequired = {w: number, h: number, x: number, y: number, i: string};*/\n/*:: export type LayoutItem = LayoutItemRequired &\r\n {minW?: number, minH?: number, maxW?: number, maxH?: number,\r\n moved?: boolean, static?: boolean,\r\n isDraggable?: ?boolean, isResizable?: ?boolean};*/\n/*:: export type Layout = Array;*/\n/*:: export type Position = {left: number, top: number, width: number, height: number};*/\n/*:: export type DragCallbackData = {\r\n node: HTMLElement,\r\n x: number, y: number,\r\n deltaX: number, deltaY: number,\r\n lastX: number, lastY: number\r\n};*/\n/*:: export type DragEvent = {e: Event} & DragCallbackData;*/\n/*:: export type Size = {width: number, height: number};*/\n/*:: export type ResizeEvent = {e: Event, node: HTMLElement, size: Size};*/\n\n\nvar isProduction = process.env.NODE_ENV === 'production';\n/**\r\n * Return the bottom coordinate of the layout.\r\n *\r\n * @param {Array} layout Layout array.\r\n * @return {Number} Bottom coordinate.\r\n */\nfunction bottom(layout /*: Layout*/) /*: number*/ {\n var max = 0,\n bottomY = void 0;\n for (var _i = 0, len = layout.length; _i < len; _i++) {\n bottomY = layout[_i].y + layout[_i].h;\n if (bottomY > max) max = bottomY;\n }\n return max;\n}\n\nfunction cloneLayout(layout /*: Layout*/) /*: Layout*/ {\n var newLayout = Array(layout.length);\n for (var _i2 = 0, len = layout.length; _i2 < len; _i2++) {\n newLayout[_i2] = cloneLayoutItem(layout[_i2]);\n }\n return newLayout;\n}\n\n// Fast path to cloning, since this is monomorphic\nfunction cloneLayoutItem(layoutItem /*: LayoutItem*/) /*: LayoutItem*/ {\n /*return {\r\n w: layoutItem.w, h: layoutItem.h, x: layoutItem.x, y: layoutItem.y, i: layoutItem.i,\r\n minW: layoutItem.minW, maxW: layoutItem.maxW, minH: layoutItem.minH, maxH: layoutItem.maxH,\r\n moved: Boolean(layoutItem.moved), static: Boolean(layoutItem.static),\r\n // These can be null\r\n isDraggable: layoutItem.isDraggable, isResizable: layoutItem.isResizable\r\n };*/\n return JSON.parse(JSON.stringify(layoutItem));\n}\n\n/**\r\n * Given two layoutitems, check if they collide.\r\n *\r\n * @return {Boolean} True if colliding.\r\n */\nfunction collides(l1 /*: LayoutItem*/, l2 /*: LayoutItem*/) /*: boolean*/ {\n if (l1 === l2) return false; // same element\n if (l1.x + l1.w <= l2.x) return false; // l1 is left of l2\n if (l1.x >= l2.x + l2.w) return false; // l1 is right of l2\n if (l1.y + l1.h <= l2.y) return false; // l1 is above l2\n if (l1.y >= l2.y + l2.h) return false; // l1 is below l2\n return true; // boxes overlap\n}\n\n/**\r\n * Given a layout, compact it. This involves going down each y coordinate and removing gaps\r\n * between items.\r\n *\r\n * @param {Array} layout Layout.\r\n * @param {Boolean} verticalCompact Whether or not to compact the layout\r\n * vertically.\r\n * @return {Array} Compacted Layout.\r\n */\nfunction compact(layout /*: Layout*/, verticalCompact /*: Boolean*/) /*: Layout*/ {\n // Statics go in the compareWith array right away so items flow around them.\n var compareWith = getStatics(layout);\n // We go through the items by row and column.\n var sorted = sortLayoutItemsByRowCol(layout);\n // Holding for new items.\n var out = Array(layout.length);\n\n for (var _i3 = 0, len = sorted.length; _i3 < len; _i3++) {\n var l = sorted[_i3];\n\n // Don't move static elements\n if (!l.static) {\n l = compactItem(compareWith, l, verticalCompact);\n\n // Add to comparison array. We only collide with items before this one.\n // Statics are already in this array.\n compareWith.push(l);\n }\n\n // Add to output array to make sure they still come out in the right order.\n out[layout.indexOf(l)] = l;\n\n // Clear moved flag, if it exists.\n l.moved = false;\n }\n\n return out;\n}\n\n/**\r\n * Compact an item in the layout.\r\n */\nfunction compactItem(compareWith /*: Layout*/, l /*: LayoutItem*/, verticalCompact /*: boolean*/) /*: LayoutItem*/ {\n if (verticalCompact) {\n // Move the element up as far as it can go without colliding.\n while (l.y > 0 && !getFirstCollision(compareWith, l)) {\n l.y--;\n }\n }\n\n // Move it down, and keep moving it down if it's colliding.\n var collides = void 0;\n while (collides = getFirstCollision(compareWith, l)) {\n l.y = collides.y + collides.h;\n }\n return l;\n}\n\n/**\r\n * Given a layout, make sure all elements fit within its bounds.\r\n *\r\n * @param {Array} layout Layout array.\r\n * @param {Number} bounds Number of columns.\r\n */\nfunction correctBounds(layout /*: Layout*/, bounds /*: {cols: number}*/) /*: Layout*/ {\n var collidesWith = getStatics(layout);\n for (var _i4 = 0, len = layout.length; _i4 < len; _i4++) {\n var l = layout[_i4];\n // Overflows right\n if (l.x + l.w > bounds.cols) l.x = bounds.cols - l.w;\n // Overflows left\n if (l.x < 0) {\n l.x = 0;\n l.w = bounds.cols;\n }\n if (!l.static) collidesWith.push(l);else {\n // If this is static and collides with other statics, we must move it down.\n // We have to do something nicer than just letting them overlap.\n while (getFirstCollision(collidesWith, l)) {\n l.y++;\n }\n }\n }\n return layout;\n}\n\n/**\r\n * Get a layout item by ID. Used so we can override later on if necessary.\r\n *\r\n * @param {Array} layout Layout array.\r\n * @param {String} id ID\r\n * @return {LayoutItem} Item at ID.\r\n */\nfunction getLayoutItem(layout /*: Layout*/, id /*: string*/) /*: ?LayoutItem*/ {\n for (var _i5 = 0, len = layout.length; _i5 < len; _i5++) {\n if (layout[_i5].i === id) return layout[_i5];\n }\n}\n\n/**\r\n * Returns the first item this layout collides with.\r\n * It doesn't appear to matter which order we approach this from, although\r\n * perhaps that is the wrong thing to do.\r\n *\r\n * @param {Object} layoutItem Layout item.\r\n * @return {Object|undefined} A colliding layout item, or undefined.\r\n */\nfunction getFirstCollision(layout /*: Layout*/, layoutItem /*: LayoutItem*/) /*: ?LayoutItem*/ {\n for (var _i6 = 0, len = layout.length; _i6 < len; _i6++) {\n if (collides(layout[_i6], layoutItem)) return layout[_i6];\n }\n}\n\nfunction getAllCollisions(layout /*: Layout*/, layoutItem /*: LayoutItem*/) /*: Array*/ {\n return layout.filter(function (l) {\n return collides(l, layoutItem);\n });\n}\n\n/**\r\n * Get all static elements.\r\n * @param {Array} layout Array of layout objects.\r\n * @return {Array} Array of static layout items..\r\n */\nfunction getStatics(layout /*: Layout*/) /*: Array*/ {\n //return [];\n return layout.filter(function (l) {\n return l.static;\n });\n}\n\n/**\r\n * Move an element. Responsible for doing cascading movements of other elements.\r\n *\r\n * @param {Array} layout Full layout to modify.\r\n * @param {LayoutItem} l element to move.\r\n * @param {Number} [x] X position in grid units.\r\n * @param {Number} [y] Y position in grid units.\r\n * @param {Boolean} [isUserAction] If true, designates that the item we're moving is\r\n * being dragged/resized by th euser.\r\n */\nfunction moveElement(layout /*: Layout*/, l /*: LayoutItem*/, x /*: Number*/, y /*: Number*/, isUserAction /*: Boolean*/) /*: Layout*/ {\n if (l.static) return layout;\n\n // Short-circuit if nothing to do.\n //if (l.y === y && l.x === x) return layout;\n\n var movingUp = y && l.y > y;\n // This is quite a bit faster than extending the object\n if (typeof x === 'number') l.x = x;\n if (typeof y === 'number') l.y = y;\n l.moved = true;\n\n // If this collides with anything, move it.\n // When doing this comparison, we have to sort the items we compare with\n // to ensure, in the case of multiple collisions, that we're getting the\n // nearest collision.\n var sorted = sortLayoutItemsByRowCol(layout);\n if (movingUp) sorted = sorted.reverse();\n var collisions = getAllCollisions(sorted, l);\n\n // Move each item that collides away from this element.\n for (var _i7 = 0, len = collisions.length; _i7 < len; _i7++) {\n var collision = collisions[_i7];\n // console.log('resolving collision between', l.i, 'at', l.y, 'and', collision.i, 'at', collision.y);\n\n // Short circuit so we can't infinite loop\n if (collision.moved) continue;\n\n // This makes it feel a bit more precise by waiting to swap for just a bit when moving up.\n if (l.y > collision.y && l.y - collision.y > collision.h / 4) continue;\n\n // Don't move static items - we have to move *this* element away\n if (collision.static) {\n layout = moveElementAwayFromCollision(layout, collision, l, isUserAction);\n } else {\n layout = moveElementAwayFromCollision(layout, l, collision, isUserAction);\n }\n }\n\n return layout;\n}\n\n/**\r\n * This is where the magic needs to happen - given a collision, move an element away from the collision.\r\n * We attempt to move it up if there's room, otherwise it goes below.\r\n *\r\n * @param {Array} layout Full layout to modify.\r\n * @param {LayoutItem} collidesWith Layout item we're colliding with.\r\n * @param {LayoutItem} itemToMove Layout item we're moving.\r\n * @param {Boolean} [isUserAction] If true, designates that the item we're moving is being dragged/resized\r\n * by the user.\r\n */\nfunction moveElementAwayFromCollision(layout /*: Layout*/, collidesWith /*: LayoutItem*/, itemToMove /*: LayoutItem*/, isUserAction /*: ?boolean*/) /*: Layout*/ {\n\n // If there is enough space above the collision to put this element, move it there.\n // We only do this on the main collision as this can get funky in cascades and cause\n // unwanted swapping behavior.\n if (isUserAction) {\n // Make a mock item so we don't modify the item here, only modify in moveElement.\n var fakeItem /*: LayoutItem*/ = {\n x: itemToMove.x,\n y: itemToMove.y,\n w: itemToMove.w,\n h: itemToMove.h,\n i: '-1'\n };\n fakeItem.y = Math.max(collidesWith.y - itemToMove.h, 0);\n if (!getFirstCollision(layout, fakeItem)) {\n return moveElement(layout, itemToMove, undefined, fakeItem.y);\n }\n }\n\n // Previously this was optimized to move below the collision directly, but this can cause problems\n // with cascading moves, as an item may actually leapflog a collision and cause a reversal in order.\n return moveElement(layout, itemToMove, undefined, itemToMove.y + 1);\n}\n\n/**\r\n * Helper to convert a number to a percentage string.\r\n *\r\n * @param {Number} num Any number\r\n * @return {String} That number as a percentage.\r\n */\nfunction perc(num /*: number*/) /*: string*/ {\n return num * 100 + '%';\n}\n\nfunction setTransform(top, left, width, height) /*: Object*/ {\n // Replace unitless items with px\n var translate = \"translate3d(\" + left + \"px,\" + top + \"px, 0)\";\n return {\n transform: translate,\n WebkitTransform: translate,\n MozTransform: translate,\n msTransform: translate,\n OTransform: translate,\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n/**\r\n * Just like the setTransform method, but instead it will return a negative value of right.\r\n *\r\n * @param top\r\n * @param right\r\n * @param width\r\n * @param height\r\n * @returns {{transform: string, WebkitTransform: string, MozTransform: string, msTransform: string, OTransform: string, width: string, height: string, position: string}}\r\n */\nfunction setTransformRtl(top, right, width, height) /*: Object*/ {\n // Replace unitless items with px\n var translate = \"translate3d(\" + right * -1 + \"px,\" + top + \"px, 0)\";\n return {\n transform: translate,\n WebkitTransform: translate,\n MozTransform: translate,\n msTransform: translate,\n OTransform: translate,\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n\nfunction setTopLeft(top, left, width, height) /*: Object*/ {\n return {\n top: top + \"px\",\n left: left + \"px\",\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n/**\r\n * Just like the setTopLeft method, but instead, it will return a right property instead of left.\r\n *\r\n * @param top\r\n * @param right\r\n * @param width\r\n * @param height\r\n * @returns {{top: string, right: string, width: string, height: string, position: string}}\r\n */\nfunction setTopRight(top, right, width, height) /*: Object*/ {\n return {\n top: top + \"px\",\n right: right + \"px\",\n width: width + \"px\",\n height: height + \"px\",\n position: 'absolute'\n };\n}\n\n/**\r\n * Get layout items sorted from top left to right and down.\r\n *\r\n * @return {Array} Array of layout objects.\r\n * @return {Array} Layout, sorted static items first.\r\n */\nfunction sortLayoutItemsByRowCol(layout /*: Layout*/) /*: Layout*/ {\n return [].concat(layout).sort(function (a, b) {\n if (a.y > b.y || a.y === b.y && a.x > b.x) {\n return 1;\n }\n return -1;\n });\n}\n\n/**\r\n * Generate a layout using the initialLayout and children as a template.\r\n * Missing entries will be added, extraneous ones will be truncated.\r\n *\r\n * @param {Array} initialLayout Layout passed in through props.\r\n * @param {String} breakpoint Current responsive breakpoint.\r\n * @param {Boolean} verticalCompact Whether or not to compact the layout vertically.\r\n * @return {Array} Working layout.\r\n */\n/*\r\nexport function synchronizeLayoutWithChildren(initialLayout: Layout, children: Array|React.Element,\r\n cols: number, verticalCompact: boolean): Layout {\r\n // ensure 'children' is always an array\r\n if (!Array.isArray(children)) {\r\n children = [children];\r\n }\r\n initialLayout = initialLayout || [];\r\n\r\n // Generate one layout item per child.\r\n let layout: Layout = [];\r\n for (let i = 0, len = children.length; i < len; i++) {\r\n let newItem;\r\n const child = children[i];\r\n\r\n // Don't overwrite if it already exists.\r\n const exists = getLayoutItem(initialLayout, child.key || \"1\" /!* FIXME satisfies Flow *!/);\r\n if (exists) {\r\n newItem = exists;\r\n } else {\r\n const g = child.props._grid;\r\n\r\n // Hey, this item has a _grid property, use it.\r\n if (g) {\r\n if (!isProduction) {\r\n validateLayout([g], 'ReactGridLayout.children');\r\n }\r\n // Validated; add it to the layout. Bottom 'y' possible is the bottom of the layout.\r\n // This allows you to do nice stuff like specify {y: Infinity}\r\n if (verticalCompact) {\r\n newItem = cloneLayoutItem({...g, y: Math.min(bottom(layout), g.y), i: child.key});\r\n } else {\r\n newItem = cloneLayoutItem({...g, y: g.y, i: child.key});\r\n }\r\n }\r\n // Nothing provided: ensure this is added to the bottom\r\n else {\r\n newItem = cloneLayoutItem({w: 1, h: 1, x: 0, y: bottom(layout), i: child.key || \"1\"});\r\n }\r\n }\r\n layout[i] = newItem;\r\n }\r\n\r\n // Correct the layout.\r\n layout = correctBounds(layout, {cols: cols});\r\n layout = compact(layout, verticalCompact);\r\n\r\n return layout;\r\n}\r\n*/\n\n/**\r\n * Validate a layout. Throws errors.\r\n *\r\n * @param {Array} layout Array of layout items.\r\n * @param {String} [contextName] Context name for errors.\r\n * @throw {Error} Validation error.\r\n */\nfunction validateLayout(layout /*: Layout*/, contextName /*: string*/) /*: void*/ {\n contextName = contextName || \"Layout\";\n var subProps = ['x', 'y', 'w', 'h'];\n if (!Array.isArray(layout)) throw new Error(contextName + \" must be an array!\");\n for (var _i8 = 0, len = layout.length; _i8 < len; _i8++) {\n var item = layout[_i8];\n for (var j = 0; j < subProps.length; j++) {\n if (typeof item[subProps[j]] !== 'number') {\n throw new Error('VueGridLayout: ' + contextName + '[' + _i8 + '].' + subProps[j] + ' must be a number!');\n }\n }\n if (item.i && typeof item.i !== 'string') {\n throw new Error('VueGridLayout: ' + contextName + '[' + _i8 + '].i must be a string!');\n }\n if (item.static !== undefined && typeof item.static !== 'boolean') {\n throw new Error('VueGridLayout: ' + contextName + '[' + _i8 + '].static must be a boolean!');\n }\n }\n}\n\n// Flow can't really figure this out, so we just use Object\nfunction autoBindHandlers(el /*: Object*/, fns /*: Array*/) /*: void*/ {\n fns.forEach(function (key) {\n return el[key] = el[key].bind(el);\n });\n}\n\n/**\r\n * Convert a JS object to CSS string. Similar to React's output of CSS.\r\n * @param obj\r\n * @returns {string}\r\n */\nfunction createMarkup(obj) {\n var keys = Object.keys(obj);\n if (!keys.length) return '';\n var i,\n len = keys.length;\n var result = '';\n\n for (i = 0; i < len; i++) {\n var key = keys[i];\n var val = obj[key];\n result += hyphenate(key) + ':' + addPx(key, val) + ';';\n }\n\n return result;\n}\n\n/* The following list is defined in React's core */\nvar IS_UNITLESS = exports.IS_UNITLESS = {\n animationIterationCount: true,\n boxFlex: true,\n boxFlexGroup: true,\n boxOrdinalGroup: true,\n columnCount: true,\n flex: true,\n flexGrow: true,\n flexPositive: true,\n flexShrink: true,\n flexNegative: true,\n flexOrder: true,\n gridRow: true,\n gridColumn: true,\n fontWeight: true,\n lineClamp: true,\n lineHeight: true,\n opacity: true,\n order: true,\n orphans: true,\n tabSize: true,\n widows: true,\n zIndex: true,\n zoom: true,\n\n // SVG-related properties\n fillOpacity: true,\n stopOpacity: true,\n strokeDashoffset: true,\n strokeOpacity: true,\n strokeWidth: true\n};\n\n/**\r\n * Will add px to the end of style values which are Numbers.\r\n * @param name\r\n * @param value\r\n * @returns {*}\r\n */\nfunction addPx(name, value) {\n if (typeof value === 'number' && !IS_UNITLESS[name]) {\n return value + 'px';\n } else {\n return value;\n }\n}\n\n/**\r\n * Hyphenate a camelCase string.\r\n *\r\n * @param {String} str\r\n * @return {String}\r\n */\n\nvar hyphenateRE = exports.hyphenateRE = /([a-z\\d])([A-Z])/g;\n\nfunction hyphenate(str) {\n return str.replace(hyphenateRE, '$1-$2').toLowerCase();\n}\n\nfunction findItemInArray(array, property, value) {\n for (var i = 0; i < array.length; i++) {\n if (array[i][property] == value) return true;\n }return false;\n}\n\nfunction findAndRemove(array, property, value) {\n array.forEach(function (result, index) {\n if (result[property] === value) {\n //Remove from array\n array.splice(index, 1);\n }\n });\n}\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5)))\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvdXRpbHMuanM/MmZmOCJdLCJuYW1lcyI6WyJib3R0b20iLCJjbG9uZUxheW91dCIsImNsb25lTGF5b3V0SXRlbSIsImNvbGxpZGVzIiwiY29tcGFjdCIsImNvbXBhY3RJdGVtIiwiY29ycmVjdEJvdW5kcyIsImdldExheW91dEl0ZW0iLCJnZXRGaXJzdENvbGxpc2lvbiIsImdldEFsbENvbGxpc2lvbnMiLCJnZXRTdGF0aWNzIiwibW92ZUVsZW1lbnQiLCJtb3ZlRWxlbWVudEF3YXlGcm9tQ29sbGlzaW9uIiwicGVyYyIsInNldFRyYW5zZm9ybSIsInNldFRyYW5zZm9ybVJ0bCIsInNldFRvcExlZnQiLCJzZXRUb3BSaWdodCIsInNvcnRMYXlvdXRJdGVtc0J5Um93Q29sIiwidmFsaWRhdGVMYXlvdXQiLCJhdXRvQmluZEhhbmRsZXJzIiwiY3JlYXRlTWFya3VwIiwiYWRkUHgiLCJoeXBoZW5hdGUiLCJmaW5kSXRlbUluQXJyYXkiLCJmaW5kQW5kUmVtb3ZlIiwiaXNQcm9kdWN0aW9uIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwibGF5b3V0IiwibWF4IiwiYm90dG9tWSIsImkiLCJsZW4iLCJsZW5ndGgiLCJ5IiwiaCIsIm5ld0xheW91dCIsIkFycmF5IiwibGF5b3V0SXRlbSIsIkpTT04iLCJwYXJzZSIsInN0cmluZ2lmeSIsImwxIiwibDIiLCJ4IiwidyIsInZlcnRpY2FsQ29tcGFjdCIsImNvbXBhcmVXaXRoIiwic29ydGVkIiwib3V0IiwibCIsInN0YXRpYyIsInB1c2giLCJpbmRleE9mIiwibW92ZWQiLCJib3VuZHMiLCJjb2xsaWRlc1dpdGgiLCJjb2xzIiwiaWQiLCJmaWx0ZXIiLCJpc1VzZXJBY3Rpb24iLCJtb3ZpbmdVcCIsInJldmVyc2UiLCJjb2xsaXNpb25zIiwiY29sbGlzaW9uIiwiaXRlbVRvTW92ZSIsImZha2VJdGVtIiwiTWF0aCIsInVuZGVmaW5lZCIsIm51bSIsInRvcCIsImxlZnQiLCJ3aWR0aCIsImhlaWdodCIsInRyYW5zbGF0ZSIsInRyYW5zZm9ybSIsIldlYmtpdFRyYW5zZm9ybSIsIk1velRyYW5zZm9ybSIsIm1zVHJhbnNmb3JtIiwiT1RyYW5zZm9ybSIsInBvc2l0aW9uIiwicmlnaHQiLCJjb25jYXQiLCJzb3J0IiwiYSIsImIiLCJjb250ZXh0TmFtZSIsInN1YlByb3BzIiwiaXNBcnJheSIsIkVycm9yIiwiaXRlbSIsImoiLCJlbCIsImZucyIsImZvckVhY2giLCJrZXkiLCJiaW5kIiwib2JqIiwia2V5cyIsIk9iamVjdCIsInJlc3VsdCIsInZhbCIsIklTX1VOSVRMRVNTIiwiYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQiLCJib3hGbGV4IiwiYm94RmxleEdyb3VwIiwiYm94T3JkaW5hbEdyb3VwIiwiY29sdW1uQ291bnQiLCJmbGV4IiwiZmxleEdyb3ciLCJmbGV4UG9zaXRpdmUiLCJmbGV4U2hyaW5rIiwiZmxleE5lZ2F0aXZlIiwiZmxleE9yZGVyIiwiZ3JpZFJvdyIsImdyaWRDb2x1bW4iLCJmb250V2VpZ2h0IiwibGluZUNsYW1wIiwibGluZUhlaWdodCIsIm9wYWNpdHkiLCJvcmRlciIsIm9ycGhhbnMiLCJ0YWJTaXplIiwid2lkb3dzIiwiekluZGV4Iiwiem9vbSIsImZpbGxPcGFjaXR5Iiwic3RvcE9wYWNpdHkiLCJzdHJva2VEYXNob2Zmc2V0Iiwic3Ryb2tlT3BhY2l0eSIsInN0cm9rZVdpZHRoIiwibmFtZSIsInZhbHVlIiwiaHlwaGVuYXRlUkUiLCJzdHIiLCJyZXBsYWNlIiwidG9Mb3dlckNhc2UiLCJhcnJheSIsInByb3BlcnR5IiwiaW5kZXgiLCJzcGxpY2UiXSwibWFwcGluZ3MiOiI7Ozs7O1FBeUJnQkEsTSxHQUFBQSxNO1FBU0FDLFcsR0FBQUEsVztRQVNBQyxlLEdBQUFBLGU7UUFnQkFDLFEsR0FBQUEsUTtRQWtCQUMsTyxHQUFBQSxPO1FBaUNBQyxXLEdBQUFBLFc7UUFzQkFDLGEsR0FBQUEsYTtRQThCQUMsYSxHQUFBQSxhO1FBY0FDLGlCLEdBQUFBLGlC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QXhDLEVBQStDO0FBQ2xESyxRQUFNM0MsT0FBTixDQUFjLFVBQVVNLE1BQVYsRUFBa0J1QyxLQUFsQixFQUF5QjtBQUNuQyxRQUFJdkMsT0FBT3NDLFFBQVAsTUFBcUJOLEtBQXpCLEVBQWdDO0FBQzVCO0FBQ0FLLFlBQU1HLE1BQU4sQ0FBYUQsS0FBYixFQUFvQixDQUFwQjtBQUNIO0FBQ0osR0FMRDtBQU1ILEMiLCJmaWxlIjoiMC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XHJcbmV4cG9ydCB0eXBlIExheW91dEl0ZW1SZXF1aXJlZCA9IHt3OiBudW1iZXIsIGg6IG51bWJlciwgeDogbnVtYmVyLCB5OiBudW1iZXIsIGk6IHN0cmluZ307XHJcbmV4cG9ydCB0eXBlIExheW91dEl0ZW0gPSBMYXlvdXRJdGVtUmVxdWlyZWQgJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAge21pblc/OiBudW1iZXIsIG1pbkg/OiBudW1iZXIsIG1heFc/OiBudW1iZXIsIG1heEg/OiBudW1iZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbW92ZWQ/OiBib29sZWFuLCBzdGF0aWM/OiBib29sZWFuLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlzRHJhZ2dhYmxlPzogP2Jvb2xlYW4sIGlzUmVzaXphYmxlPzogP2Jvb2xlYW59O1xyXG5leHBvcnQgdHlwZSBMYXlvdXQgPSBBcnJheTxMYXlvdXRJdGVtPjtcclxuZXhwb3J0IHR5cGUgUG9zaXRpb24gPSB7bGVmdDogbnVtYmVyLCB0b3A6IG51bWJlciwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXJ9O1xyXG5leHBvcnQgdHlwZSBEcmFnQ2FsbGJhY2tEYXRhID0ge1xyXG4gIG5vZGU6IEhUTUxFbGVtZW50LFxyXG4gIHg6IG51bWJlciwgeTogbnVtYmVyLFxyXG4gIGRlbHRhWDogbnVtYmVyLCBkZWx0YVk6IG51bWJlcixcclxuICBsYXN0WDogbnVtYmVyLCBsYXN0WTogbnVtYmVyXHJcbn07XHJcbmV4cG9ydCB0eXBlIERyYWdFdmVudCA9IHtlOiBFdmVudH0gJiBEcmFnQ2FsbGJhY2tEYXRhO1xyXG5leHBvcnQgdHlwZSBTaXplID0ge3dpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyfTtcclxuZXhwb3J0IHR5cGUgUmVzaXplRXZlbnQgPSB7ZTogRXZlbnQsIG5vZGU6IEhUTUxFbGVtZW50LCBzaXplOiBTaXplfTtcclxuXHJcbmNvbnN0IGlzUHJvZHVjdGlvbiA9IHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbic7XHJcbi8qKlxyXG4gKiBSZXR1cm4gdGhlIGJvdHRvbSBjb29yZGluYXRlIG9mIHRoZSBsYXlvdXQuXHJcbiAqXHJcbiAqIEBwYXJhbSAge0FycmF5fSBsYXlvdXQgTGF5b3V0IGFycmF5LlxyXG4gKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgIEJvdHRvbSBjb29yZGluYXRlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGJvdHRvbShsYXlvdXQ6IExheW91dCk6IG51bWJlciB7XHJcbiAgbGV0IG1heCA9IDAsIGJvdHRvbVk7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgYm90dG9tWSA9IGxheW91dFtpXS4geSArIGxheW91dFtpXS5oO1xyXG4gICAgaWYgKGJvdHRvbVkgPiBtYXgpIG1heCA9IGJvdHRvbVk7XHJcbiAgfVxyXG4gIHJldHVybiBtYXg7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjbG9uZUxheW91dChsYXlvdXQ6IExheW91dCk6IExheW91dCB7XHJcbiAgY29uc3QgbmV3TGF5b3V0ID0gQXJyYXkobGF5b3V0Lmxlbmd0aCk7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgbmV3TGF5b3V0W2ldID0gY2xvbmVMYXlvdXRJdGVtKGxheW91dFtpXSk7XHJcbiAgfVxyXG4gIHJldHVybiBuZXdMYXlvdXQ7XHJcbn1cclxuXHJcbi8vIEZhc3QgcGF0aCB0byBjbG9uaW5nLCBzaW5jZSB0aGlzIGlzIG1vbm9tb3JwaGljXHJcbmV4cG9ydCBmdW5jdGlvbiBjbG9uZUxheW91dEl0ZW0obGF5b3V0SXRlbTogTGF5b3V0SXRlbSk6IExheW91dEl0ZW0ge1xyXG4gIC8qcmV0dXJuIHtcclxuICAgIHc6IGxheW91dEl0ZW0udywgaDogbGF5b3V0SXRlbS5oLCB4OiBsYXlvdXRJdGVtLngsIHk6IGxheW91dEl0ZW0ueSwgaTogbGF5b3V0SXRlbS5pLFxyXG4gICAgbWluVzogbGF5b3V0SXRlbS5taW5XLCBtYXhXOiBsYXlvdXRJdGVtLm1heFcsIG1pbkg6IGxheW91dEl0ZW0ubWluSCwgbWF4SDogbGF5b3V0SXRlbS5tYXhILFxyXG4gICAgbW92ZWQ6IEJvb2xlYW4obGF5b3V0SXRlbS5tb3ZlZCksIHN0YXRpYzogQm9vbGVhbihsYXlvdXRJdGVtLnN0YXRpYyksXHJcbiAgICAvLyBUaGVzZSBjYW4gYmUgbnVsbFxyXG4gICAgaXNEcmFnZ2FibGU6IGxheW91dEl0ZW0uaXNEcmFnZ2FibGUsIGlzUmVzaXphYmxlOiBsYXlvdXRJdGVtLmlzUmVzaXphYmxlXHJcbiAgfTsqL1xyXG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobGF5b3V0SXRlbSkpO1xyXG59XHJcblxyXG4vKipcclxuICogR2l2ZW4gdHdvIGxheW91dGl0ZW1zLCBjaGVjayBpZiB0aGV5IGNvbGxpZGUuXHJcbiAqXHJcbiAqIEByZXR1cm4ge0Jvb2xlYW59ICAgVHJ1ZSBpZiBjb2xsaWRpbmcuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY29sbGlkZXMobDE6IExheW91dEl0ZW0sIGwyOiBMYXlvdXRJdGVtKTogYm9vbGVhbiB7XHJcbiAgaWYgKGwxID09PSBsMikgcmV0dXJuIGZhbHNlOyAvLyBzYW1lIGVsZW1lbnRcclxuICBpZiAobDEueCArIGwxLncgPD0gbDIueCkgcmV0dXJuIGZhbHNlOyAvLyBsMSBpcyBsZWZ0IG9mIGwyXHJcbiAgaWYgKGwxLnggPj0gbDIueCArIGwyLncpIHJldHVybiBmYWxzZTsgLy8gbDEgaXMgcmlnaHQgb2YgbDJcclxuICBpZiAobDEueSArIGwxLmggPD0gbDIueSkgcmV0dXJuIGZhbHNlOyAvLyBsMSBpcyBhYm92ZSBsMlxyXG4gIGlmIChsMS55ID49IGwyLnkgKyBsMi5oKSByZXR1cm4gZmFsc2U7IC8vIGwxIGlzIGJlbG93IGwyXHJcbiAgcmV0dXJuIHRydWU7IC8vIGJveGVzIG92ZXJsYXBcclxufVxyXG5cclxuLyoqXHJcbiAqIEdpdmVuIGEgbGF5b3V0LCBjb21wYWN0IGl0LiBUaGlzIGludm9sdmVzIGdvaW5nIGRvd24gZWFjaCB5IGNvb3JkaW5hdGUgYW5kIHJlbW92aW5nIGdhcHNcclxuICogYmV0d2VlbiBpdGVtcy5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCBMYXlvdXQuXHJcbiAqIEBwYXJhbSAge0Jvb2xlYW59IHZlcnRpY2FsQ29tcGFjdCBXaGV0aGVyIG9yIG5vdCB0byBjb21wYWN0IHRoZSBsYXlvdXRcclxuICogICB2ZXJ0aWNhbGx5LlxyXG4gKiBAcmV0dXJuIHtBcnJheX0gICAgICAgQ29tcGFjdGVkIExheW91dC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjb21wYWN0KGxheW91dDogTGF5b3V0LCB2ZXJ0aWNhbENvbXBhY3Q6IEJvb2xlYW4pOiBMYXlvdXQge1xyXG4gICAgLy8gU3RhdGljcyBnbyBpbiB0aGUgY29tcGFyZVdpdGggYXJyYXkgcmlnaHQgYXdheSBzbyBpdGVtcyBmbG93IGFyb3VuZCB0aGVtLlxyXG4gIGNvbnN0IGNvbXBhcmVXaXRoID0gZ2V0U3RhdGljcyhsYXlvdXQpO1xyXG4gIC8vIFdlIGdvIHRocm91Z2ggdGhlIGl0ZW1zIGJ5IHJvdyBhbmQgY29sdW1uLlxyXG4gIGNvbnN0IHNvcnRlZCA9IHNvcnRMYXlvdXRJdGVtc0J5Um93Q29sKGxheW91dCk7XHJcbiAgLy8gSG9sZGluZyBmb3IgbmV3IGl0ZW1zLlxyXG4gIGNvbnN0IG91dCA9IEFycmF5KGxheW91dC5sZW5ndGgpO1xyXG5cclxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gc29ydGVkLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBsZXQgbCA9IHNvcnRlZFtpXTtcclxuXHJcbiAgICAvLyBEb24ndCBtb3ZlIHN0YXRpYyBlbGVtZW50c1xyXG4gICAgaWYgKCFsLnN0YXRpYykge1xyXG4gICAgICBsID0gY29tcGFjdEl0ZW0oY29tcGFyZVdpdGgsIGwsIHZlcnRpY2FsQ29tcGFjdCk7XHJcblxyXG4gICAgICAvLyBBZGQgdG8gY29tcGFyaXNvbiBhcnJheS4gV2Ugb25seSBjb2xsaWRlIHdpdGggaXRlbXMgYmVmb3JlIHRoaXMgb25lLlxyXG4gICAgICAvLyBTdGF0aWNzIGFyZSBhbHJlYWR5IGluIHRoaXMgYXJyYXkuXHJcbiAgICAgIGNvbXBhcmVXaXRoLnB1c2gobCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWRkIHRvIG91dHB1dCBhcnJheSB0byBtYWtlIHN1cmUgdGhleSBzdGlsbCBjb21lIG91dCBpbiB0aGUgcmlnaHQgb3JkZXIuXHJcbiAgICBvdXRbbGF5b3V0LmluZGV4T2YobCldID0gbDtcclxuXHJcbiAgICAvLyBDbGVhciBtb3ZlZCBmbGFnLCBpZiBpdCBleGlzdHMuXHJcbiAgICBsLm1vdmVkID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gb3V0O1xyXG59XHJcblxyXG4vKipcclxuICogQ29tcGFjdCBhbiBpdGVtIGluIHRoZSBsYXlvdXQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY29tcGFjdEl0ZW0oY29tcGFyZVdpdGg6IExheW91dCwgbDogTGF5b3V0SXRlbSwgdmVydGljYWxDb21wYWN0OiBib29sZWFuKTogTGF5b3V0SXRlbSB7XHJcbiAgaWYgKHZlcnRpY2FsQ29tcGFjdCkge1xyXG4gICAgLy8gTW92ZSB0aGUgZWxlbWVudCB1cCBhcyBmYXIgYXMgaXQgY2FuIGdvIHdpdGhvdXQgY29sbGlkaW5nLlxyXG4gICAgd2hpbGUgKGwueSA+IDAgJiYgIWdldEZpcnN0Q29sbGlzaW9uKGNvbXBhcmVXaXRoLCBsKSkge1xyXG4gICAgICBsLnktLTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIE1vdmUgaXQgZG93biwgYW5kIGtlZXAgbW92aW5nIGl0IGRvd24gaWYgaXQncyBjb2xsaWRpbmcuXHJcbiAgbGV0IGNvbGxpZGVzO1xyXG4gIHdoaWxlKChjb2xsaWRlcyA9IGdldEZpcnN0Q29sbGlzaW9uKGNvbXBhcmVXaXRoLCBsKSkpIHtcclxuICAgIGwueSA9IGNvbGxpZGVzLnkgKyBjb2xsaWRlcy5oO1xyXG4gIH1cclxuICByZXR1cm4gbDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdpdmVuIGEgbGF5b3V0LCBtYWtlIHN1cmUgYWxsIGVsZW1lbnRzIGZpdCB3aXRoaW4gaXRzIGJvdW5kcy5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCBMYXlvdXQgYXJyYXkuXHJcbiAqIEBwYXJhbSAge051bWJlcn0gYm91bmRzIE51bWJlciBvZiBjb2x1bW5zLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNvcnJlY3RCb3VuZHMobGF5b3V0OiBMYXlvdXQsIGJvdW5kczoge2NvbHM6IG51bWJlcn0pOiBMYXlvdXQge1xyXG4gIGNvbnN0IGNvbGxpZGVzV2l0aCA9IGdldFN0YXRpY3MobGF5b3V0KTtcclxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGF5b3V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBjb25zdCBsID0gbGF5b3V0W2ldO1xyXG4gICAgLy8gT3ZlcmZsb3dzIHJpZ2h0XHJcbiAgICBpZiAobC54ICsgbC53ID4gYm91bmRzLmNvbHMpIGwueCA9IGJvdW5kcy5jb2xzIC0gbC53O1xyXG4gICAgLy8gT3ZlcmZsb3dzIGxlZnRcclxuICAgIGlmIChsLnggPCAwKSB7XHJcbiAgICAgIGwueCA9IDA7XHJcbiAgICAgIGwudyA9IGJvdW5kcy5jb2xzO1xyXG4gICAgfVxyXG4gICAgaWYgKCFsLnN0YXRpYykgY29sbGlkZXNXaXRoLnB1c2gobCk7XHJcbiAgICBlbHNlIHtcclxuICAgICAgLy8gSWYgdGhpcyBpcyBzdGF0aWMgYW5kIGNvbGxpZGVzIHdpdGggb3RoZXIgc3RhdGljcywgd2UgbXVzdCBtb3ZlIGl0IGRvd24uXHJcbiAgICAgIC8vIFdlIGhhdmUgdG8gZG8gc29tZXRoaW5nIG5pY2VyIHRoYW4ganVzdCBsZXR0aW5nIHRoZW0gb3ZlcmxhcC5cclxuICAgICAgd2hpbGUoZ2V0Rmlyc3RDb2xsaXNpb24oY29sbGlkZXNXaXRoLCBsKSkge1xyXG4gICAgICAgIGwueSsrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBsYXlvdXQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBsYXlvdXQgaXRlbSBieSBJRC4gVXNlZCBzbyB3ZSBjYW4gb3ZlcnJpZGUgbGF0ZXIgb24gaWYgbmVjZXNzYXJ5LlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtBcnJheX0gIGxheW91dCBMYXlvdXQgYXJyYXkuXHJcbiAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgIElEXHJcbiAqIEByZXR1cm4ge0xheW91dEl0ZW19ICAgIEl0ZW0gYXQgSUQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGF5b3V0SXRlbShsYXlvdXQ6IExheW91dCwgaWQ6IHN0cmluZyk6ID9MYXlvdXRJdGVtIHtcclxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGF5b3V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBpZiAobGF5b3V0W2ldLmkgPT09IGlkKSByZXR1cm4gbGF5b3V0W2ldO1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGZpcnN0IGl0ZW0gdGhpcyBsYXlvdXQgY29sbGlkZXMgd2l0aC5cclxuICogSXQgZG9lc24ndCBhcHBlYXIgdG8gbWF0dGVyIHdoaWNoIG9yZGVyIHdlIGFwcHJvYWNoIHRoaXMgZnJvbSwgYWx0aG91Z2hcclxuICogcGVyaGFwcyB0aGF0IGlzIHRoZSB3cm9uZyB0aGluZyB0byBkby5cclxuICpcclxuICogQHBhcmFtICB7T2JqZWN0fSBsYXlvdXRJdGVtIExheW91dCBpdGVtLlxyXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSAgQSBjb2xsaWRpbmcgbGF5b3V0IGl0ZW0sIG9yIHVuZGVmaW5lZC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGaXJzdENvbGxpc2lvbihsYXlvdXQ6IExheW91dCwgbGF5b3V0SXRlbTogTGF5b3V0SXRlbSk6ID9MYXlvdXRJdGVtIHtcclxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGF5b3V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBpZiAoY29sbGlkZXMobGF5b3V0W2ldLCBsYXlvdXRJdGVtKSkgcmV0dXJuIGxheW91dFtpXTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRBbGxDb2xsaXNpb25zKGxheW91dDogTGF5b3V0LCBsYXlvdXRJdGVtOiBMYXlvdXRJdGVtKTogQXJyYXk8TGF5b3V0SXRlbT4ge1xyXG4gIHJldHVybiBsYXlvdXQuZmlsdGVyKChsKSA9PiBjb2xsaWRlcyhsLCBsYXlvdXRJdGVtKSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgYWxsIHN0YXRpYyBlbGVtZW50cy5cclxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCBBcnJheSBvZiBsYXlvdXQgb2JqZWN0cy5cclxuICogQHJldHVybiB7QXJyYXl9ICAgICAgICBBcnJheSBvZiBzdGF0aWMgbGF5b3V0IGl0ZW1zLi5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRTdGF0aWNzKGxheW91dDogTGF5b3V0KTogQXJyYXk8TGF5b3V0SXRlbT4ge1xyXG4gICAgLy9yZXR1cm4gW107XHJcbiAgICByZXR1cm4gbGF5b3V0LmZpbHRlcigobCkgPT4gbC5zdGF0aWMpO1xyXG59XHJcblxyXG4vKipcclxuICogTW92ZSBhbiBlbGVtZW50LiBSZXNwb25zaWJsZSBmb3IgZG9pbmcgY2FzY2FkaW5nIG1vdmVtZW50cyBvZiBvdGhlciBlbGVtZW50cy5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9ICAgICAgbGF5b3V0IEZ1bGwgbGF5b3V0IHRvIG1vZGlmeS5cclxuICogQHBhcmFtICB7TGF5b3V0SXRlbX0gbCAgICAgIGVsZW1lbnQgdG8gbW92ZS5cclxuICogQHBhcmFtICB7TnVtYmVyfSAgICAgW3hdICAgIFggcG9zaXRpb24gaW4gZ3JpZCB1bml0cy5cclxuICogQHBhcmFtICB7TnVtYmVyfSAgICAgW3ldICAgIFkgcG9zaXRpb24gaW4gZ3JpZCB1bml0cy5cclxuICogQHBhcmFtICB7Qm9vbGVhbn0gICAgW2lzVXNlckFjdGlvbl0gSWYgdHJ1ZSwgZGVzaWduYXRlcyB0aGF0IHRoZSBpdGVtIHdlJ3JlIG1vdmluZyBpc1xyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWluZyBkcmFnZ2VkL3Jlc2l6ZWQgYnkgdGggZXVzZXIuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gbW92ZUVsZW1lbnQobGF5b3V0OiBMYXlvdXQsIGw6IExheW91dEl0ZW0sIHg6IE51bWJlciwgeTogTnVtYmVyLCBpc1VzZXJBY3Rpb246IEJvb2xlYW4pOiBMYXlvdXQge1xyXG4gIGlmIChsLnN0YXRpYykgcmV0dXJuIGxheW91dDtcclxuXHJcbiAgLy8gU2hvcnQtY2lyY3VpdCBpZiBub3RoaW5nIHRvIGRvLlxyXG4gIC8vaWYgKGwueSA9PT0geSAmJiBsLnggPT09IHgpIHJldHVybiBsYXlvdXQ7XHJcblxyXG4gIGNvbnN0IG1vdmluZ1VwID0geSAmJiBsLnkgPiB5O1xyXG4gIC8vIFRoaXMgaXMgcXVpdGUgYSBiaXQgZmFzdGVyIHRoYW4gZXh0ZW5kaW5nIHRoZSBvYmplY3RcclxuICBpZiAodHlwZW9mIHggPT09ICdudW1iZXInKSBsLnggPSB4O1xyXG4gIGlmICh0eXBlb2YgeSA9PT0gJ251bWJlcicpIGwueSA9IHk7XHJcbiAgbC5tb3ZlZCA9IHRydWU7XHJcblxyXG4gIC8vIElmIHRoaXMgY29sbGlkZXMgd2l0aCBhbnl0aGluZywgbW92ZSBpdC5cclxuICAvLyBXaGVuIGRvaW5nIHRoaXMgY29tcGFyaXNvbiwgd2UgaGF2ZSB0byBzb3J0IHRoZSBpdGVtcyB3ZSBjb21wYXJlIHdpdGhcclxuICAvLyB0byBlbnN1cmUsIGluIHRoZSBjYXNlIG9mIG11bHRpcGxlIGNvbGxpc2lvbnMsIHRoYXQgd2UncmUgZ2V0dGluZyB0aGVcclxuICAvLyBuZWFyZXN0IGNvbGxpc2lvbi5cclxuICBsZXQgc29ydGVkID0gc29ydExheW91dEl0ZW1zQnlSb3dDb2wobGF5b3V0KTtcclxuICBpZiAobW92aW5nVXApIHNvcnRlZCA9IHNvcnRlZC5yZXZlcnNlKCk7XHJcbiAgY29uc3QgY29sbGlzaW9ucyA9IGdldEFsbENvbGxpc2lvbnMoc29ydGVkLCBsKTtcclxuXHJcbiAgLy8gTW92ZSBlYWNoIGl0ZW0gdGhhdCBjb2xsaWRlcyBhd2F5IGZyb20gdGhpcyBlbGVtZW50LlxyXG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSBjb2xsaXNpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBjb25zdCBjb2xsaXNpb24gPSBjb2xsaXNpb25zW2ldO1xyXG4gICAgLy8gY29uc29sZS5sb2coJ3Jlc29sdmluZyBjb2xsaXNpb24gYmV0d2VlbicsIGwuaSwgJ2F0JywgbC55LCAnYW5kJywgY29sbGlzaW9uLmksICdhdCcsIGNvbGxpc2lvbi55KTtcclxuXHJcbiAgICAvLyBTaG9ydCBjaXJjdWl0IHNvIHdlIGNhbid0IGluZmluaXRlIGxvb3BcclxuICAgIGlmIChjb2xsaXNpb24ubW92ZWQpIGNvbnRpbnVlO1xyXG5cclxuICAgIC8vIFRoaXMgbWFrZXMgaXQgZmVlbCBhIGJpdCBtb3JlIHByZWNpc2UgYnkgd2FpdGluZyB0byBzd2FwIGZvciBqdXN0IGEgYml0IHdoZW4gbW92aW5nIHVwLlxyXG4gICAgaWYgKGwueSA+IGNvbGxpc2lvbi55ICYmIGwueSAtIGNvbGxpc2lvbi55ID4gY29sbGlzaW9uLmggLyA0KSBjb250aW51ZTtcclxuXHJcbiAgICAvLyBEb24ndCBtb3ZlIHN0YXRpYyBpdGVtcyAtIHdlIGhhdmUgdG8gbW92ZSAqdGhpcyogZWxlbWVudCBhd2F5XHJcbiAgICBpZiAoY29sbGlzaW9uLnN0YXRpYykge1xyXG4gICAgICBsYXlvdXQgPSBtb3ZlRWxlbWVudEF3YXlGcm9tQ29sbGlzaW9uKGxheW91dCwgY29sbGlzaW9uLCBsLCBpc1VzZXJBY3Rpb24pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbGF5b3V0ID0gbW92ZUVsZW1lbnRBd2F5RnJvbUNvbGxpc2lvbihsYXlvdXQsIGwsIGNvbGxpc2lvbiwgaXNVc2VyQWN0aW9uKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBsYXlvdXQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaGlzIGlzIHdoZXJlIHRoZSBtYWdpYyBuZWVkcyB0byBoYXBwZW4gLSBnaXZlbiBhIGNvbGxpc2lvbiwgbW92ZSBhbiBlbGVtZW50IGF3YXkgZnJvbSB0aGUgY29sbGlzaW9uLlxyXG4gKiBXZSBhdHRlbXB0IHRvIG1vdmUgaXQgdXAgaWYgdGhlcmUncyByb29tLCBvdGhlcndpc2UgaXQgZ29lcyBiZWxvdy5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCAgICAgICAgICAgIEZ1bGwgbGF5b3V0IHRvIG1vZGlmeS5cclxuICogQHBhcmFtICB7TGF5b3V0SXRlbX0gY29sbGlkZXNXaXRoIExheW91dCBpdGVtIHdlJ3JlIGNvbGxpZGluZyB3aXRoLlxyXG4gKiBAcGFyYW0gIHtMYXlvdXRJdGVtfSBpdGVtVG9Nb3ZlICAgTGF5b3V0IGl0ZW0gd2UncmUgbW92aW5nLlxyXG4gKiBAcGFyYW0gIHtCb29sZWFufSBbaXNVc2VyQWN0aW9uXSAgSWYgdHJ1ZSwgZGVzaWduYXRlcyB0aGF0IHRoZSBpdGVtIHdlJ3JlIG1vdmluZyBpcyBiZWluZyBkcmFnZ2VkL3Jlc2l6ZWRcclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5IHRoZSB1c2VyLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG1vdmVFbGVtZW50QXdheUZyb21Db2xsaXNpb24obGF5b3V0OiBMYXlvdXQsIGNvbGxpZGVzV2l0aDogTGF5b3V0SXRlbSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbVRvTW92ZTogTGF5b3V0SXRlbSwgaXNVc2VyQWN0aW9uOiA/Ym9vbGVhbik6IExheW91dCB7XHJcblxyXG4gIC8vIElmIHRoZXJlIGlzIGVub3VnaCBzcGFjZSBhYm92ZSB0aGUgY29sbGlzaW9uIHRvIHB1dCB0aGlzIGVsZW1lbnQsIG1vdmUgaXQgdGhlcmUuXHJcbiAgLy8gV2Ugb25seSBkbyB0aGlzIG9uIHRoZSBtYWluIGNvbGxpc2lvbiBhcyB0aGlzIGNhbiBnZXQgZnVua3kgaW4gY2FzY2FkZXMgYW5kIGNhdXNlXHJcbiAgLy8gdW53YW50ZWQgc3dhcHBpbmcgYmVoYXZpb3IuXHJcbiAgaWYgKGlzVXNlckFjdGlvbikge1xyXG4gICAgLy8gTWFrZSBhIG1vY2sgaXRlbSBzbyB3ZSBkb24ndCBtb2RpZnkgdGhlIGl0ZW0gaGVyZSwgb25seSBtb2RpZnkgaW4gbW92ZUVsZW1lbnQuXHJcbiAgICBjb25zdCBmYWtlSXRlbTogTGF5b3V0SXRlbSA9IHtcclxuICAgICAgeDogaXRlbVRvTW92ZS54LFxyXG4gICAgICB5OiBpdGVtVG9Nb3ZlLnksXHJcbiAgICAgIHc6IGl0ZW1Ub01vdmUudyxcclxuICAgICAgaDogaXRlbVRvTW92ZS5oLFxyXG4gICAgICBpOiAnLTEnXHJcbiAgICB9O1xyXG4gICAgZmFrZUl0ZW0ueSA9IE1hdGgubWF4KGNvbGxpZGVzV2l0aC55IC0gaXRlbVRvTW92ZS5oLCAwKTtcclxuICAgIGlmICghZ2V0Rmlyc3RDb2xsaXNpb24obGF5b3V0LCBmYWtlSXRlbSkpIHtcclxuICAgICAgcmV0dXJuIG1vdmVFbGVtZW50KGxheW91dCwgaXRlbVRvTW92ZSwgdW5kZWZpbmVkLCBmYWtlSXRlbS55KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIFByZXZpb3VzbHkgdGhpcyB3YXMgb3B0aW1pemVkIHRvIG1vdmUgYmVsb3cgdGhlIGNvbGxpc2lvbiBkaXJlY3RseSwgYnV0IHRoaXMgY2FuIGNhdXNlIHByb2JsZW1zXHJcbiAgLy8gd2l0aCBjYXNjYWRpbmcgbW92ZXMsIGFzIGFuIGl0ZW0gbWF5IGFjdHVhbGx5IGxlYXBmbG9nIGEgY29sbGlzaW9uIGFuZCBjYXVzZSBhIHJldmVyc2FsIGluIG9yZGVyLlxyXG4gIHJldHVybiBtb3ZlRWxlbWVudChsYXlvdXQsIGl0ZW1Ub01vdmUsIHVuZGVmaW5lZCwgaXRlbVRvTW92ZS55ICsgMSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBIZWxwZXIgdG8gY29udmVydCBhIG51bWJlciB0byBhIHBlcmNlbnRhZ2Ugc3RyaW5nLlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IG51bSBBbnkgbnVtYmVyXHJcbiAqIEByZXR1cm4ge1N0cmluZ30gICAgIFRoYXQgbnVtYmVyIGFzIGEgcGVyY2VudGFnZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBwZXJjKG51bTogbnVtYmVyKTogc3RyaW5nIHtcclxuICByZXR1cm4gbnVtICogMTAwICsgJyUnO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0VHJhbnNmb3JtKHRvcCwgbGVmdCwgd2lkdGgsIGhlaWdodCk6IE9iamVjdCB7XHJcbiAgLy8gUmVwbGFjZSB1bml0bGVzcyBpdGVtcyB3aXRoIHB4XHJcbiAgY29uc3QgdHJhbnNsYXRlID0gXCJ0cmFuc2xhdGUzZChcIiArIGxlZnQgKyBcInB4LFwiICsgdG9wICsgXCJweCwgMClcIjtcclxuICByZXR1cm4ge1xyXG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUsXHJcbiAgICBXZWJraXRUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgIE1velRyYW5zZm9ybTogdHJhbnNsYXRlLFxyXG4gICAgbXNUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgIE9UcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgIHdpZHRoOiB3aWR0aCArIFwicHhcIixcclxuICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxyXG4gICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcclxuICB9O1xyXG59XHJcbi8qKlxyXG4gKiBKdXN0IGxpa2UgdGhlIHNldFRyYW5zZm9ybSBtZXRob2QsIGJ1dCBpbnN0ZWFkIGl0IHdpbGwgcmV0dXJuIGEgbmVnYXRpdmUgdmFsdWUgb2YgcmlnaHQuXHJcbiAqXHJcbiAqIEBwYXJhbSB0b3BcclxuICogQHBhcmFtIHJpZ2h0XHJcbiAqIEBwYXJhbSB3aWR0aFxyXG4gKiBAcGFyYW0gaGVpZ2h0XHJcbiAqIEByZXR1cm5zIHt7dHJhbnNmb3JtOiBzdHJpbmcsIFdlYmtpdFRyYW5zZm9ybTogc3RyaW5nLCBNb3pUcmFuc2Zvcm06IHN0cmluZywgbXNUcmFuc2Zvcm06IHN0cmluZywgT1RyYW5zZm9ybTogc3RyaW5nLCB3aWR0aDogc3RyaW5nLCBoZWlnaHQ6IHN0cmluZywgcG9zaXRpb246IHN0cmluZ319XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gc2V0VHJhbnNmb3JtUnRsKHRvcCwgcmlnaHQsIHdpZHRoLCBoZWlnaHQpOiBPYmplY3Qge1xyXG4gICAgLy8gUmVwbGFjZSB1bml0bGVzcyBpdGVtcyB3aXRoIHB4XHJcbiAgICBjb25zdCB0cmFuc2xhdGUgPSBcInRyYW5zbGF0ZTNkKFwiICsgcmlnaHQgKiAtMSArIFwicHgsXCIgKyB0b3AgKyBcInB4LCAwKVwiO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICBXZWJraXRUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICBNb3pUcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICBtc1RyYW5zZm9ybTogdHJhbnNsYXRlLFxyXG4gICAgICAgIE9UcmFuc2Zvcm06IHRyYW5zbGF0ZSxcclxuICAgICAgICB3aWR0aDogd2lkdGggKyBcInB4XCIsXHJcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHQgKyBcInB4XCIsXHJcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcclxuICAgIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXRUb3BMZWZ0KHRvcCwgbGVmdCwgd2lkdGgsIGhlaWdodCk6IE9iamVjdCB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHRvcDogdG9wICsgXCJweFwiLFxyXG4gICAgICAgIGxlZnQ6IGxlZnQgKyBcInB4XCIsXHJcbiAgICAgICAgd2lkdGg6IHdpZHRoICsgXCJweFwiLFxyXG4gICAgICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxyXG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBKdXN0IGxpa2UgdGhlIHNldFRvcExlZnQgbWV0aG9kLCBidXQgaW5zdGVhZCwgaXQgd2lsbCByZXR1cm4gYSByaWdodCBwcm9wZXJ0eSBpbnN0ZWFkIG9mIGxlZnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB0b3BcclxuICogQHBhcmFtIHJpZ2h0XHJcbiAqIEBwYXJhbSB3aWR0aFxyXG4gKiBAcGFyYW0gaGVpZ2h0XHJcbiAqIEByZXR1cm5zIHt7dG9wOiBzdHJpbmcsIHJpZ2h0OiBzdHJpbmcsIHdpZHRoOiBzdHJpbmcsIGhlaWdodDogc3RyaW5nLCBwb3NpdGlvbjogc3RyaW5nfX1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXRUb3BSaWdodCh0b3AsIHJpZ2h0LCB3aWR0aCwgaGVpZ2h0KTogT2JqZWN0IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgdG9wOiB0b3AgKyBcInB4XCIsXHJcbiAgICAgICAgcmlnaHQ6IHJpZ2h0KyBcInB4XCIsXHJcbiAgICAgICAgd2lkdGg6IHdpZHRoICsgXCJweFwiLFxyXG4gICAgICAgIGhlaWdodDogaGVpZ2h0ICsgXCJweFwiLFxyXG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXHJcbiAgICB9O1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBsYXlvdXQgaXRlbXMgc29ydGVkIGZyb20gdG9wIGxlZnQgdG8gcmlnaHQgYW5kIGRvd24uXHJcbiAqXHJcbiAqIEByZXR1cm4ge0FycmF5fSBBcnJheSBvZiBsYXlvdXQgb2JqZWN0cy5cclxuICogQHJldHVybiB7QXJyYXl9ICAgICAgICBMYXlvdXQsIHNvcnRlZCBzdGF0aWMgaXRlbXMgZmlyc3QuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gc29ydExheW91dEl0ZW1zQnlSb3dDb2wobGF5b3V0OiBMYXlvdXQpOiBMYXlvdXQge1xyXG4gIHJldHVybiBbXS5jb25jYXQobGF5b3V0KS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcclxuICAgIGlmIChhLnkgPiBiLnkgfHwgKGEueSA9PT0gYi55ICYmIGEueCA+IGIueCkpIHtcclxuICAgICAgcmV0dXJuIDE7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gLTE7XHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZSBhIGxheW91dCB1c2luZyB0aGUgaW5pdGlhbExheW91dCBhbmQgY2hpbGRyZW4gYXMgYSB0ZW1wbGF0ZS5cclxuICogTWlzc2luZyBlbnRyaWVzIHdpbGwgYmUgYWRkZWQsIGV4dHJhbmVvdXMgb25lcyB3aWxsIGJlIHRydW5jYXRlZC5cclxuICpcclxuICogQHBhcmFtICB7QXJyYXl9ICBpbml0aWFsTGF5b3V0IExheW91dCBwYXNzZWQgaW4gdGhyb3VnaCBwcm9wcy5cclxuICogQHBhcmFtICB7U3RyaW5nfSBicmVha3BvaW50ICAgIEN1cnJlbnQgcmVzcG9uc2l2ZSBicmVha3BvaW50LlxyXG4gKiBAcGFyYW0gIHtCb29sZWFufSB2ZXJ0aWNhbENvbXBhY3QgV2hldGhlciBvciBub3QgdG8gY29tcGFjdCB0aGUgbGF5b3V0IHZlcnRpY2FsbHkuXHJcbiAqIEByZXR1cm4ge0FycmF5fSAgICAgICAgICAgICAgICBXb3JraW5nIGxheW91dC5cclxuICovXHJcbi8qXHJcbmV4cG9ydCBmdW5jdGlvbiBzeW5jaHJvbml6ZUxheW91dFdpdGhDaGlsZHJlbihpbml0aWFsTGF5b3V0OiBMYXlvdXQsIGNoaWxkcmVuOiBBcnJheTxSZWFjdC5FbGVtZW50PnxSZWFjdC5FbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sczogbnVtYmVyLCB2ZXJ0aWNhbENvbXBhY3Q6IGJvb2xlYW4pOiBMYXlvdXQge1xyXG4gIC8vIGVuc3VyZSAnY2hpbGRyZW4nIGlzIGFsd2F5cyBhbiBhcnJheVxyXG4gIGlmICghQXJyYXkuaXNBcnJheShjaGlsZHJlbikpIHtcclxuICAgIGNoaWxkcmVuID0gW2NoaWxkcmVuXTtcclxuICB9XHJcbiAgaW5pdGlhbExheW91dCA9IGluaXRpYWxMYXlvdXQgfHwgW107XHJcblxyXG4gIC8vIEdlbmVyYXRlIG9uZSBsYXlvdXQgaXRlbSBwZXIgY2hpbGQuXHJcbiAgbGV0IGxheW91dDogTGF5b3V0ID0gW107XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBsZXQgbmV3SXRlbTtcclxuICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5baV07XHJcblxyXG4gICAgLy8gRG9uJ3Qgb3ZlcndyaXRlIGlmIGl0IGFscmVhZHkgZXhpc3RzLlxyXG4gICAgY29uc3QgZXhpc3RzID0gZ2V0TGF5b3V0SXRlbShpbml0aWFsTGF5b3V0LCBjaGlsZC5rZXkgfHwgXCIxXCIgLyEqIEZJWE1FIHNhdGlzZmllcyBGbG93ICohLyk7XHJcbiAgICBpZiAoZXhpc3RzKSB7XHJcbiAgICAgIG5ld0l0ZW0gPSBleGlzdHM7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBnID0gY2hpbGQucHJvcHMuX2dyaWQ7XHJcblxyXG4gICAgICAvLyBIZXksIHRoaXMgaXRlbSBoYXMgYSBfZ3JpZCBwcm9wZXJ0eSwgdXNlIGl0LlxyXG4gICAgICBpZiAoZykge1xyXG4gICAgICAgIGlmICghaXNQcm9kdWN0aW9uKSB7XHJcbiAgICAgICAgICB2YWxpZGF0ZUxheW91dChbZ10sICdSZWFjdEdyaWRMYXlvdXQuY2hpbGRyZW4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gVmFsaWRhdGVkOyBhZGQgaXQgdG8gdGhlIGxheW91dC4gQm90dG9tICd5JyBwb3NzaWJsZSBpcyB0aGUgYm90dG9tIG9mIHRoZSBsYXlvdXQuXHJcbiAgICAgICAgLy8gVGhpcyBhbGxvd3MgeW91IHRvIGRvIG5pY2Ugc3R1ZmYgbGlrZSBzcGVjaWZ5IHt5OiBJbmZpbml0eX1cclxuICAgICAgICBpZiAodmVydGljYWxDb21wYWN0KSB7XHJcbiAgICAgICAgICBuZXdJdGVtID0gY2xvbmVMYXlvdXRJdGVtKHsuLi5nLCB5OiBNYXRoLm1pbihib3R0b20obGF5b3V0KSwgZy55KSwgaTogY2hpbGQua2V5fSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIG5ld0l0ZW0gPSBjbG9uZUxheW91dEl0ZW0oey4uLmcsIHk6IGcueSwgaTogY2hpbGQua2V5fSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIC8vIE5vdGhpbmcgcHJvdmlkZWQ6IGVuc3VyZSB0aGlzIGlzIGFkZGVkIHRvIHRoZSBib3R0b21cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgbmV3SXRlbSA9IGNsb25lTGF5b3V0SXRlbSh7dzogMSwgaDogMSwgeDogMCwgeTogYm90dG9tKGxheW91dCksIGk6IGNoaWxkLmtleSB8fCBcIjFcIn0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBsYXlvdXRbaV0gPSBuZXdJdGVtO1xyXG4gIH1cclxuXHJcbiAgLy8gQ29ycmVjdCB0aGUgbGF5b3V0LlxyXG4gIGxheW91dCA9IGNvcnJlY3RCb3VuZHMobGF5b3V0LCB7Y29sczogY29sc30pO1xyXG4gIGxheW91dCA9IGNvbXBhY3QobGF5b3V0LCB2ZXJ0aWNhbENvbXBhY3QpO1xyXG5cclxuICByZXR1cm4gbGF5b3V0O1xyXG59XHJcbiovXHJcblxyXG4vKipcclxuICogVmFsaWRhdGUgYSBsYXlvdXQuIFRocm93cyBlcnJvcnMuXHJcbiAqXHJcbiAqIEBwYXJhbSAge0FycmF5fSAgbGF5b3V0ICAgICAgICBBcnJheSBvZiBsYXlvdXQgaXRlbXMuXHJcbiAqIEBwYXJhbSAge1N0cmluZ30gW2NvbnRleHROYW1lXSBDb250ZXh0IG5hbWUgZm9yIGVycm9ycy5cclxuICogQHRocm93ICB7RXJyb3J9ICAgICAgICAgICAgICAgIFZhbGlkYXRpb24gZXJyb3IuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVMYXlvdXQobGF5b3V0OiBMYXlvdXQsIGNvbnRleHROYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICBjb250ZXh0TmFtZSA9IGNvbnRleHROYW1lIHx8IFwiTGF5b3V0XCI7XHJcbiAgY29uc3Qgc3ViUHJvcHMgPSBbJ3gnLCAneScsICd3JywgJ2gnXTtcclxuICBpZiAoIUFycmF5LmlzQXJyYXkobGF5b3V0KSkgdGhyb3cgbmV3IEVycm9yKGNvbnRleHROYW1lICsgXCIgbXVzdCBiZSBhbiBhcnJheSFcIik7XHJcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgY29uc3QgaXRlbSA9IGxheW91dFtpXTtcclxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgc3ViUHJvcHMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgaWYgKHR5cGVvZiBpdGVtW3N1YlByb3BzW2pdXSAhPT0gJ251bWJlcicpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Z1ZUdyaWRMYXlvdXQ6ICcgKyBjb250ZXh0TmFtZSArICdbJyArIGkgKyAnXS4nICsgc3ViUHJvcHNbal0gKyAnIG11c3QgYmUgYSBudW1iZXIhJyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChpdGVtLmkgJiYgdHlwZW9mIGl0ZW0uaSAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWdWVHcmlkTGF5b3V0OiAnICsgY29udGV4dE5hbWUgKyAnWycgKyBpICsgJ10uaSBtdXN0IGJlIGEgc3RyaW5nIScpO1xyXG4gICAgfVxyXG4gICAgaWYgKGl0ZW0uc3RhdGljICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGl0ZW0uc3RhdGljICE9PSAnYm9vbGVhbicpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWdWVHcmlkTGF5b3V0OiAnICsgY29udGV4dE5hbWUgKyAnWycgKyBpICsgJ10uc3RhdGljIG11c3QgYmUgYSBib29sZWFuIScpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLy8gRmxvdyBjYW4ndCByZWFsbHkgZmlndXJlIHRoaXMgb3V0LCBzbyB3ZSBqdXN0IHVzZSBPYmplY3RcclxuZXhwb3J0IGZ1bmN0aW9uIGF1dG9CaW5kSGFuZGxlcnMoZWw6IE9iamVjdCwgZm5zOiBBcnJheTxzdHJpbmc+KTogdm9pZCB7XHJcbiAgZm5zLmZvckVhY2goKGtleSkgPT4gZWxba2V5XSA9IGVsW2tleV0uYmluZChlbCkpO1xyXG59XHJcblxyXG5cclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0IGEgSlMgb2JqZWN0IHRvIENTUyBzdHJpbmcuIFNpbWlsYXIgdG8gUmVhY3QncyBvdXRwdXQgb2YgQ1NTLlxyXG4gKiBAcGFyYW0gb2JqXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWFya3VwKG9iaikge1xyXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xyXG4gICAgaWYgKCFrZXlzLmxlbmd0aCkgcmV0dXJuICcnO1xyXG4gICAgdmFyIGksIGxlbiA9IGtleXMubGVuZ3RoO1xyXG4gICAgdmFyIHJlc3VsdCA9ICcnO1xyXG5cclxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xyXG4gICAgICAgIHZhciB2YWwgPSBvYmpba2V5XTtcclxuICAgICAgICByZXN1bHQgKz0gaHlwaGVuYXRlKGtleSkgKyAnOicgKyBhZGRQeChrZXksIHZhbCkgKyAnOyc7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuXHJcbi8qIFRoZSBmb2xsb3dpbmcgbGlzdCBpcyBkZWZpbmVkIGluIFJlYWN0J3MgY29yZSAqL1xyXG5leHBvcnQgdmFyIElTX1VOSVRMRVNTID0ge1xyXG4gICAgYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6IHRydWUsXHJcbiAgICBib3hGbGV4OiB0cnVlLFxyXG4gICAgYm94RmxleEdyb3VwOiB0cnVlLFxyXG4gICAgYm94T3JkaW5hbEdyb3VwOiB0cnVlLFxyXG4gICAgY29sdW1uQ291bnQ6IHRydWUsXHJcbiAgICBmbGV4OiB0cnVlLFxyXG4gICAgZmxleEdyb3c6IHRydWUsXHJcbiAgICBmbGV4UG9zaXRpdmU6IHRydWUsXHJcbiAgICBmbGV4U2hyaW5rOiB0cnVlLFxyXG4gICAgZmxleE5lZ2F0aXZlOiB0cnVlLFxyXG4gICAgZmxleE9yZGVyOiB0cnVlLFxyXG4gICAgZ3JpZFJvdzogdHJ1ZSxcclxuICAgIGdyaWRDb2x1bW46IHRydWUsXHJcbiAgICBmb250V2VpZ2h0OiB0cnVlLFxyXG4gICAgbGluZUNsYW1wOiB0cnVlLFxyXG4gICAgbGluZUhlaWdodDogdHJ1ZSxcclxuICAgIG9wYWNpdHk6IHRydWUsXHJcbiAgICBvcmRlcjogdHJ1ZSxcclxuICAgIG9ycGhhbnM6IHRydWUsXHJcbiAgICB0YWJTaXplOiB0cnVlLFxyXG4gICAgd2lkb3dzOiB0cnVlLFxyXG4gICAgekluZGV4OiB0cnVlLFxyXG4gICAgem9vbTogdHJ1ZSxcclxuXHJcbiAgICAvLyBTVkctcmVsYXRlZCBwcm9wZXJ0aWVzXHJcbiAgICBmaWxsT3BhY2l0eTogdHJ1ZSxcclxuICAgIHN0b3BPcGFjaXR5OiB0cnVlLFxyXG4gICAgc3Ryb2tlRGFzaG9mZnNldDogdHJ1ZSxcclxuICAgIHN0cm9rZU9wYWNpdHk6IHRydWUsXHJcbiAgICBzdHJva2VXaWR0aDogdHJ1ZVxyXG59O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBXaWxsIGFkZCBweCB0byB0aGUgZW5kIG9mIHN0eWxlIHZhbHVlcyB3aGljaCBhcmUgTnVtYmVycy5cclxuICogQHBhcmFtIG5hbWVcclxuICogQHBhcmFtIHZhbHVlXHJcbiAqIEByZXR1cm5zIHsqfVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGFkZFB4KG5hbWUsIHZhbHVlKSB7XHJcbiAgICBpZih0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmICFJU19VTklUTEVTU1sgbmFtZSBdKSB7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlICsgJ3B4JztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIEh5cGhlbmF0ZSBhIGNhbWVsQ2FzZSBzdHJpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcclxuICogQHJldHVybiB7U3RyaW5nfVxyXG4gKi9cclxuXHJcbmV4cG9ydCB2YXIgaHlwaGVuYXRlUkUgPSAvKFthLXpcXGRdKShbQS1aXSkvZztcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBoeXBoZW5hdGUoc3RyKSB7XHJcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsICckMS0kMicpLnRvTG93ZXJDYXNlKCk7XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZmluZEl0ZW1JbkFycmF5KGFycmF5LCBwcm9wZXJ0eSwgdmFsdWUpIHtcclxuICAgIGZvciAodmFyIGk9MDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGlmIChhcnJheVtpXVtwcm9wZXJ0eV0gPT0gdmFsdWUpXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBbmRSZW1vdmUoYXJyYXksIHByb3BlcnR5LCB2YWx1ZSkge1xyXG4gICAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbiAocmVzdWx0LCBpbmRleCkge1xyXG4gICAgICAgIGlmIChyZXN1bHRbcHJvcGVydHldID09PSB2YWx1ZSkge1xyXG4gICAgICAgICAgICAvL1JlbW92ZSBmcm9tIGFycmF5XHJcbiAgICAgICAgICAgIGFycmF5LnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn1cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL3V0aWxzLmpzIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0\n"); /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { -eval("\n/* styles */\n__webpack_require__(11)\n\nvar Component = __webpack_require__(4)(\n /* script */\n __webpack_require__(14),\n /* template */\n __webpack_require__(17),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\nComponent.options.__file = \"/Users/sunzongzheng/work/vue-grid-layout/src/GridItem.vue\"\nif (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== \"default\" && key !== \"__esModule\"})) {console.error(\"named exports are not supported in *.vue files.\")}\nif (Component.options.functional) {console.error(\"[vue-loader] GridItem.vue: functional components are not supported with templates, they should use render functions.\")}\n\n/* hot reload */\nif (false) {(function () {\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), false)\n if (!hotAPI.compatible) return\n module.hot.accept()\n if (!module.hot.data) {\n hotAPI.createRecord(\"data-v-f2ef9cd2\", Component.options)\n } else {\n hotAPI.reload(\"data-v-f2ef9cd2\", Component.options)\n }\n})()}\n\nmodule.exports = Component.exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlP2RlNjMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUNBO0FBQ0Esc0JBQTRLOztBQUU1SztBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUFnRztBQUNoRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRUFBK0UsaURBQWlELElBQUk7QUFDcEksbUNBQW1DOztBQUVuQztBQUNBLFlBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsImZpbGUiOiIxLmpzIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4P3tcXFwiaWRcXFwiOlxcXCJkYXRhLXYtZjJlZjljZDJcXFwiLFxcXCJzY29wZWRcXFwiOmZhbHNlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOmZhbHNlfSEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0dyaWRJdGVtLnZ1ZVwiKVxuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZShcIiEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvY29tcG9uZW50LW5vcm1hbGl6ZXJcIikoXG4gIC8qIHNjcmlwdCAqL1xuICByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXIhLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c2NyaXB0JmluZGV4PTAhLi9HcmlkSXRlbS52dWVcIiksXG4gIC8qIHRlbXBsYXRlICovXG4gIHJlcXVpcmUoXCIhIS4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci9pbmRleD97XFxcImlkXFxcIjpcXFwiZGF0YS12LWYyZWY5Y2QyXFxcIn0hLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL0dyaWRJdGVtLnZ1ZVwiKSxcbiAgLyogc2NvcGVJZCAqL1xuICBudWxsLFxuICAvKiBjc3NNb2R1bGVzICovXG4gIG51bGxcbilcbkNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwiL1VzZXJzL3N1bnpvbmd6aGVuZy93b3JrL3Z1ZS1ncmlkLWxheW91dC9zcmMvR3JpZEl0ZW0udnVlXCJcbmlmIChDb21wb25lbnQuZXNNb2R1bGUgJiYgT2JqZWN0LmtleXMoQ29tcG9uZW50LmVzTW9kdWxlKS5zb21lKGZ1bmN0aW9uIChrZXkpIHtyZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwifSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5pZiAoQ29tcG9uZW50Lm9wdGlvbnMuZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gR3JpZEl0ZW0udnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgd2l0aCB0ZW1wbGF0ZXMsIHRoZXkgc2hvdWxkIHVzZSByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblxuLyogaG90IHJlbG9hZCAqL1xuaWYgKG1vZHVsZS5ob3QpIHsoZnVuY3Rpb24gKCkge1xuICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcbiAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcbiAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LWYyZWY5Y2QyXCIsIENvbXBvbmVudC5vcHRpb25zKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtZjJlZjljZDJcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH1cbn0pKCl9XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50LmV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL0dyaWRJdGVtLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1\n"); +eval("\n/* styles */\n__webpack_require__(10)\n\nvar Component = __webpack_require__(4)(\n /* script */\n __webpack_require__(13),\n /* template */\n __webpack_require__(16),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\nComponent.options.__file = \"C:\\\\projects\\\\JBAY\\\\vue-grid-layout\\\\src\\\\GridItem.vue\"\nif (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== \"default\" && key !== \"__esModule\"})) {console.error(\"named exports are not supported in *.vue files.\")}\nif (Component.options.functional) {console.error(\"[vue-loader] GridItem.vue: functional components are not supported with templates, they should use render functions.\")}\n\n/* hot reload */\nif (false) {(function () {\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), false)\n if (!hotAPI.compatible) return\n module.hot.accept()\n if (!module.hot.data) {\n hotAPI.createRecord(\"data-v-f2ef9cd2\", Component.options)\n } else {\n hotAPI.reload(\"data-v-f2ef9cd2\", Component.options)\n }\n})()}\n\nmodule.exports = Component.exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlP2RlNjMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUNBO0FBQ0Esc0JBQTRLOztBQUU1SztBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUFnRztBQUNoRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRUFBK0UsaURBQWlELElBQUk7QUFDcEksbUNBQW1DOztBQUVuQztBQUNBLFlBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsImZpbGUiOiIxLmpzIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4P3tcXFwiaWRcXFwiOlxcXCJkYXRhLXYtZjJlZjljZDJcXFwiLFxcXCJzY29wZWRcXFwiOmZhbHNlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOmZhbHNlfSEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0dyaWRJdGVtLnZ1ZVwiKVxuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZShcIiEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvY29tcG9uZW50LW5vcm1hbGl6ZXJcIikoXG4gIC8qIHNjcmlwdCAqL1xuICByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXIhLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c2NyaXB0JmluZGV4PTAhLi9HcmlkSXRlbS52dWVcIiksXG4gIC8qIHRlbXBsYXRlICovXG4gIHJlcXVpcmUoXCIhIS4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci9pbmRleD97XFxcImlkXFxcIjpcXFwiZGF0YS12LWYyZWY5Y2QyXFxcIn0hLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL0dyaWRJdGVtLnZ1ZVwiKSxcbiAgLyogc2NvcGVJZCAqL1xuICBudWxsLFxuICAvKiBjc3NNb2R1bGVzICovXG4gIG51bGxcbilcbkNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwiQzpcXFxccHJvamVjdHNcXFxcSkJBWVxcXFx2dWUtZ3JpZC1sYXlvdXRcXFxcc3JjXFxcXEdyaWRJdGVtLnZ1ZVwiXG5pZiAoQ29tcG9uZW50LmVzTW9kdWxlICYmIE9iamVjdC5rZXlzKENvbXBvbmVudC5lc01vZHVsZSkuc29tZShmdW5jdGlvbiAoa2V5KSB7cmV0dXJuIGtleSAhPT0gXCJkZWZhdWx0XCIgJiYga2V5ICE9PSBcIl9fZXNNb2R1bGVcIn0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuaWYgKENvbXBvbmVudC5vcHRpb25zLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIEdyaWRJdGVtLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIHdpdGggdGVtcGxhdGVzLCB0aGV5IHNob3VsZCB1c2UgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cbi8qIGhvdCByZWxvYWQgKi9cbmlmIChtb2R1bGUuaG90KSB7KGZ1bmN0aW9uICgpIHtcbiAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcbiAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG4gIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi1mMmVmOWNkMlwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfSBlbHNlIHtcbiAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LWYyZWY5Y2QyXCIsIENvbXBvbmVudC5vcHRpb25zKVxuICB9XG59KSgpfVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBvbmVudC5leHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1\n"); /***/ }), /* 2 */ @@ -96,7 +96,7 @@ eval("/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n /* 3 */ /***/ (function(module, exports, __webpack_require__) { -eval("/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n Modified by Evan You @yyx990803\n*/\n\nvar hasDocument = typeof document !== 'undefined'\n\nif (typeof DEBUG !== 'undefined' && DEBUG) {\n if (!hasDocument) {\n throw new Error(\n 'vue-style-loader cannot be used in a non-browser environment. ' +\n \"Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.\"\n ) }\n}\n\nvar listToStyles = __webpack_require__(13)\n\n/*\ntype StyleObject = {\n id: number;\n parts: Array\n}\n\ntype StyleObjectPart = {\n css: string;\n media: string;\n sourceMap: ?string\n}\n*/\n\nvar stylesInDom = {/*\n [id: number]: {\n id: number,\n refs: number,\n parts: Array<(obj?: StyleObjectPart) => void>\n }\n*/}\n\nvar head = hasDocument && (document.head || document.getElementsByTagName('head')[0])\nvar singletonElement = null\nvar singletonCounter = 0\nvar isProduction = false\nvar noop = function () {}\n\n// Force single-tag solution on IE6-9, which has a hard limit on the # of \\r\\n\\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlP2I3OTAiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7O0FBR0E7QUFDQSwyQ0FBNEMsaUNBQWlDLDRDQUE0QyxnQ0FBZ0MsZ0NBQWdDLHFDQUFxQyxjQUFjLGtCQUFrQixHQUFHLDJDQUEyQyxpQkFBaUIsZUFBZSxHQUFHLDJCQUEyQixtQkFBbUIsaUJBQWlCLEdBQUcseUNBQXlDLHNCQUFzQixpQkFBaUIsR0FBRyx1Q0FBdUMsc0JBQXNCLG1CQUFtQixpQ0FBaUMsaUJBQWlCLGdDQUFnQyw2QkFBNkIsNEJBQTRCLDJCQUEyQix3QkFBd0IsR0FBRywwQ0FBMEMseUJBQXlCLGtCQUFrQixtQkFBbUIsZ0JBQWdCLGVBQWUsMENBQTBDLGsxQkFBazFCLHdDQUF3QywyQkFBMkIsbUNBQW1DLHFDQUFxQyw2QkFBNkIsd0JBQXdCLEdBQUcsOENBQThDLGdCQUFnQixjQUFjLHlDQUF5Qyw2N0NBQTY3Qyx1Q0FBdUMsd0JBQXdCLG1DQUFtQyxxQ0FBcUMsd0JBQXdCLGtCQUFrQixHQUFHLFVBQVUsK0VBQStFLEtBQUssV0FBVyxXQUFXLFdBQVcsS0FBSyxLQUFLLFdBQVcsVUFBVSxVQUFVLEtBQUssS0FBSyxVQUFVLFVBQVUsS0FBSyxLQUFLLFVBQVUsVUFBVSxLQUFLLEtBQUssV0FBVyxVQUFVLEtBQUssS0FBSyxXQUFXLFVBQVUsV0FBVyxVQUFVLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxLQUFLLEtBQUssV0FBVyxVQUFVLFVBQVUsVUFBVSxVQUFVLFlBQVksV0FBVyxXQUFXLFdBQVcsV0FBVyxXQUFXLFdBQVcsS0FBSyxLQUFLLFVBQVUsVUFBVSxZQUFZLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxVQUFVLDZJQUE2SSw0SkFBNEosaVVBQWlVLHVDQUF1QyxrREFBa0QsNENBQTRDLDBDQUEwQywyQ0FBMkMsb0JBQW9CLHdCQUF3QixTQUFTLHFEQUFxRCx1QkFBdUIscUJBQXFCLFNBQVMs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QUFxRiw2QkFBNkIsOEVBQThFLHdEQUF3RCxtREFBbUQsa0NBQWtDLGtHQUFrRywyRkFBMkYsOEVBQThFLDhGQUE4Riw4RkFBOEYsNkJBQTZCLE9BQU8scUZBQXFGLDZCQUE2Qiw4RUFBOEUsOEZBQThGLHdGQUF3RixpREFBaUQsb0RBQW9ELGdEQUFnRCxrQ0FBa0MscUlBQXFJLDhGQUE4Rix5RkFBeUYsNkJBQTZCLE9BQU8seUZBQXlGLDZCQUE2QixtRkFBbUYsdUdBQXVHLCtJQUErSSw4RkFBOEYsd0RBQXdELGtDQUFrQyxxQkFBcUIsOEVBQThFLGlGQUFpRixxQkFBcUIsT0FBTyxpRkFBaUYscUJBQXFCLHVDQUF1QyxtQ0FBbUMsbUVBQW1FLG1FQUFtRSxxQkFBcUIsaUhBQWlILG9FQUFvRSxxQkFBcUIseUdBQXlHLGlCQUFpQixzREFBc0QseURBQXlELCtFQUErRSxtQ0FBbUMscVJBQXFSLGdiQUFnYixxQkFBcUIsT0FBTyxtQ0FBbUMsb1JBQW9SLGdiQUFnYixxQkFBcUIsdUNBQXVDLGlCQUFpQiwySEFBMkgsT0FBTyw4RUFBOEUsT0FBTywrRUFBK0UsT0FBTyxpS0FBaUsseURBQXlELHFhQUFxYSxtR0FBbUcsdUdBQXVHLHdFQUF3RSxnQ0FBZ0MsTUFBTSxpQkFBaUIsc0ZBQXNGLDBHQUEwRywwRkFBMEYsb0NBQW9DLGlCQUFpQixzSUFBc0ksT0FBTyxxREFBcUQsT0FBTyxvREFBb0QsT0FBTyw4RUFBOEUseURBQXlELDhQQUE4UCxzR0FBc0csdUdBQXVHLHdFQUF3RSw0QkFBNEIsTUFBTSxpQkFBaUIsd0RBQXdELGdEQUFnRCxrRUFBa0UsMkNBQTJDLHFCQUFxQixpQkFBaUIsdUNBQXVDLHVDQUF1QyxpQkFBaUIsYUFBYSxVQUFVLDhDQUE4Qzs7QUFFaHZrQyIsImZpbGUiOiIxMS5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi52dWUtZ3JpZC1pdGVtIHtcXG4gICAgdHJhbnNpdGlvbjogYWxsIDIwMG1zIGVhc2U7XFxuICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IGxlZnQsIHRvcCwgcmlnaHQ7XFxuICAgIC8qIGFkZCByaWdodCBmb3IgcnRsICovXFxufVxcbi52dWUtZ3JpZC1pdGVtLmNzc1RyYW5zZm9ybXMge1xcbiAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiB0cmFuc2Zvcm07XFxuICAgIGxlZnQ6IDA7XFxuICAgIHJpZ2h0OiBhdXRvO1xcbn1cXG4udnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zLnJlbmRlci1ydGwge1xcbiAgICBsZWZ0OiBhdXRvO1xcbiAgICByaWdodDogMDtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0ucmVzaXppbmcge1xcbiAgICBvcGFjaXR5OiAwLjY7XFxuICAgIHotaW5kZXg6IDM7XFxufVxcbi52dWUtZ3JpZC1pdGVtLnZ1ZS1kcmFnZ2FibGUtZHJhZ2dpbmcge1xcbiAgICB0cmFuc2l0aW9uOm5vbmU7XFxuICAgIHotaW5kZXg6IDM7XFxufVxcbi52dWUtZ3JpZC1pdGVtLnZ1ZS1ncmlkLXBsYWNlaG9sZGVyIHtcXG4gICAgYmFja2dyb3VuZDogcmVkO1xcbiAgICBvcGFjaXR5OiAwLjI7XFxuICAgIHRyYW5zaXRpb24tZHVyYXRpb246IDEwMG1zO1xcbiAgICB6LWluZGV4OiAyO1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAgIC1vLXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJlc2l6YWJsZS1oYW5kbGUge1xcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICAgIHdpZHRoOiAyMHB4O1xcbiAgICBoZWlnaHQ6IDIwcHg7XFxuICAgIGJvdHRvbTogMDtcXG4gICAgcmlnaHQ6IDA7XFxuICAgIGJhY2tncm91bmQ6IHVybCgnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJ6ZEdGdVpHRnNiMjVsUFNKdWJ5SS9QZzA4SVMwdElFZGxibVZ5WVhSdmNqb2dRV1J2WW1VZ1JtbHlaWGR2Y210eklFTlROaXdnUlhod2IzSjBJRk5XUnlCRmVIUmxibk5wYjI0Z1lua2dRV0Z5YjI0Z1FtVmhiR3dnS0doMGRIQTZMeTltYVhKbGQyOXlhM011WVdKbFlXeHNMbU52YlNrZ0xpQldaWEp6YVc5dU9pQXdMall1TVNBZ0xTMCtEVHdoUkU5RFZGbFFSU0J6ZG1jZ1VGVkNURWxESUNJdEx5OVhNME12TDBSVVJDQlRWa2NnTVM0eEx5OUZUaUlnSW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTDBkeVlYQm9hV056TDFOV1J5OHhMakV2UkZSRUwzTjJaekV4TG1SMFpDSStEVHh6ZG1jZ2FXUTlJbFZ1ZEdsMGJHVmtMVkJoWjJVbE1qQXhJaUIyYVdWM1FtOTRQU0l3SURBZ05pQTJJaUJ6ZEhsc1pUMGlZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqb2pabVptWm1abU1EQWlJSFpsY25OcGIyNDlJakV1TVNJTkNYaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhodGJEcHpjR0ZqWlQwaWNISmxjMlZ5ZG1VaURRbDRQU0l3Y0hnaUlIazlJakJ3ZUNJZ2QybGtkR2c5SWpad2VDSWdhR1ZwWjJoMFBTSTJjSGdpRFQ0TkNUeG5JRzl3WVdOcGRIazlJakF1TXpBeUlqNE5DUWs4Y0dGMGFDQmtQU0pOSURZZ05pQk1JREFnTmlCTUlEQWdOQzR5SUV3Z05DQTBMaklnVENBMExqSWdOQzR5SUV3Z05DNHlJREFnVENBMklEQWdUQ0EySURZZ1RDQTJJRFlnV2lJZ1ptbHNiRDBpSXpBd01EQXdNQ0l2UGcwSlBDOW5QZzA4TDNOMlp6ND0nKTtcXG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIHJpZ2h0O1xcbiAgICBwYWRkaW5nOiAwIDNweCAzcHggMDtcXG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXG4gICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICBjdXJzb3I6IHNlLXJlc2l6ZTtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJ0bC1yZXNpemFibGUtaGFuZGxlIHtcXG4gICAgYm90dG9tOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBiYWNrZ3JvdW5kOiB1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCM2FXUjBhRDBpTVRBdU1EQXdNREF3TURBd01EQXdNREF5SWlCb1pXbG5hSFE5SWpFd0xqQXdNREF3TURBd01EQXdNREF3TWlJZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWo0S0lEd2hMUzBnUTNKbFlYUmxaQ0IzYVhSb0lFMWxkR2h2WkNCRWNtRjNJQzBnYUhSMGNEb3ZMMmRwZEdoMVlpNWpiMjB2WkhWdmNHbDRaV3d2VFdWMGFHOWtMVVJ5WVhjdklDMHRQZ29nUEdjK0NpQWdQSFJwZEd4bFBtSmhZMnRuY205MWJtUThMM1JwZEd4bFBnb2dJRHh5WldOMElHWnBiR3c5SW01dmJtVWlJR2xrUFNKallXNTJZWE5mWW1GamEyZHliM1Z1WkNJZ2FHVnBaMmgwUFNJeE1pSWdkMmxrZEdnOUlqRXlJaUI1UFNJdE1TSWdlRDBpTFRFaUx6NEtJQ0E4WnlCa2FYTndiR0Y1UFNKdWIyNWxJaUJ2ZG1WeVpteHZkejBpZG1semFXSnNaU0lnZVQwaU1DSWdlRDBpTUNJZ2FHVnBaMmgwUFNJeE1EQWxJaUIzYVdSMGFEMGlNVEF3SlNJZ2FXUTlJbU5oYm5aaGMwZHlhV1FpUGdvZ0lDQThjbVZqZENCbWFXeHNQU0oxY213b0kyZHlhV1J3WVhSMFpYSnVLU0lnYzNSeWIydGxMWGRwWkhSb1BTSXdJaUI1UFNJd0lpQjRQU0l3SWlCb1pXbG5hSFE5SWpFd01DVWlJSGRwWkhSb1BTSXhNREFsSWk4K0NpQWdQQzluUGdvZ1BDOW5QZ29nUEdjK0NpQWdQSFJwZEd4bFBreGhlV1Z5SURFOEwzUnBkR3hsUGdvZ0lEeHNhVzVsSUdOaGJuWmhjejBpSTJabVptWm1aaUlnWTJGdWRtRnpMVzl3WVdOcGRIazlJakVpSUhOMGNtOXJaUzFzYVc1bFkyRndQU0oxYm1SbFptbHVaV1FpSUhOMGNtOXJaUzFzYVc1bGFtOXBiajBpZFc1a1pXWnBibVZrSWlCcFpEMGljM1puWHpFaUlIa3lQU0l0TnpBdU1UYzROREEzSWlCNE1qMGlNVEkwTGpRMk5ERTNOU0lnZVRFOUlpMHpPQzR6T1RJM016Y2lJSGd4UFNJeE5EUXVPREl4TWpnNUlpQnpkSEp2YTJVdGQybGtkR2c5SWpFdU5TSWdjM1J5YjJ0bFBTSWpNREF3SWlCbWFXeHNQU0p1YjI1bElpOCtDaUFnUEd4cGJtVWdjM1J5YjJ0bFBTSWpOalkyTmpZMklpQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODFJaUI1TWowaU9TNHhNRFk1TlRjaUlIZ3lQU0l3TGprME56STBOeUlnZVRFOUlpMHdMakF4T0RFeU9DSWdlREU5SWpBdU9UUTNNalEzSWlCemRISnZhMlV0ZDJsa2RHZzlJaklpSUdacGJHdzlJbTV2Ym1VaUx6NEtJQ0E4YkdsdVpTQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODNJaUI1TWowaU9TSWdlREk5SWpFd0xqQTNNelV5T1NJZ2VURTlJamtpSUhneFBTSXRNQzQyTlRVMk5DSWdjM1J5YjJ0bExYZHBaSFJvUFNJeUlpQnpkSEp2YTJVOUlpTTJOalkyTmpZaUlHWnBiR3c5SW01dmJtVWlMejRLSUR3dlp6NEtQQzl6ZG1jKyk7XFxuICAgIGJhY2tncm91bmQtcG9zaXRpb246IGJvdHRvbSBsZWZ0O1xcbiAgICBwYWRkaW5nLWxlZnQ6IDNweDtcXG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXG4gICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcbiAgICBjdXJzb3I6IHN3LXJlc2l6ZTtcXG4gICAgcmlnaHQ6IGF1dG87XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvR3JpZEl0ZW0udnVlP2JjM2YxMWI0XCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFZQTtJQUNBLDJCQUFBO0lBQ0Esc0NBQUE7SUFDQSx1QkFBQTtDQUNBO0FBRUE7SUFDQSwrQkFBQTtJQUNBLFFBQUE7SUFDQSxZQUFBO0NBQ0E7QUFFQTtJQUNBLFdBQUE7SUFDQSxTQUFBO0NBQ0E7QUFFQTtJQUNBLGFBQUE7SUFDQSxXQUFBO0NBQ0E7QUFFQTtJQUNBLGdCQUFBO0lBQ0EsV0FBQTtDQUNBO0FBRUE7SUFDQSxnQkFBQTtJQUNBLGFBQUE7SUFDQSwyQkFBQTtJQUNBLFdBQUE7SUFDQSwwQkFBQTtJQUNBLHVCQUFBO0lBQ0Esc0JBQUE7SUFDQSxxQkFBQTtJQUNBLGtCQUFBO0NBQ0E7QUFFQTtJQUNBLG1CQUFBO0lBQ0EsWUFBQTtJQUNBLGFBQUE7SUFDQSxVQUFBO0lBQ0EsU0FBQTtJQUNBLHMzQkFBQTtJQUNBLGtDQUFBO0lBQ0EscUJBQUE7SUFDQSw2QkFBQTtJQUNBLCtCQUFBO0lBQ0EsdUJBQUE7SUFDQSxrQkFBQTtDQUNBO0FBRUE7SUFDQSxVQUFBO0lBQ0EsUUFBQTtJQUNBLGcrQ0FBQTtJQUNBLGlDQUFBO0lBQ0Esa0JBQUE7SUFDQSw2QkFBQTtJQUNBLCtCQUFBO0lBQ0Esa0JBQUE7SUFDQSxZQUFBO0NBQ0FcIixcImZpbGVcIjpcIkdyaWRJdGVtLnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8dGVtcGxhdGU+XFxyXFxuICAgIDxkaXYgcmVmPVxcXCJpdGVtXFxcIlxcclxcbiAgICAgICAgIGNsYXNzPVxcXCJ2dWUtZ3JpZC1pdGVtXFxcIlxcclxcbiAgICAgICAgIDpjbGFzcz1cXFwieyAndnVlLXJlc2l6YWJsZScgOiByZXNpemFibGUsICdyZXNpemluZycgOiBpc1Jlc2l6aW5nLCAndnVlLWRyYWdnYWJsZS1kcmFnZ2luZycgOiBpc0RyYWdnaW5nLCAnY3NzVHJhbnNmb3JtcycgOiB1c2VDc3NUcmFuc2Zvcm1zLCAncmVuZGVyLXJ0bCcgOiByZW5kZXJSdGwgfVxcXCJcXHJcXG4gICAgICAgICA6c3R5bGU9XFxcInN0eWxlXFxcIlxcclxcbiAgICA+XFxyXFxuICAgICAgICA8c2xvdD48L3Nsb3Q+XFxyXFxuICAgICAgICA8c3BhbiB2LWlmPVxcXCJyZXNpemFibGVcXFwiIHJlZj1cXFwiaGFuZGxlXFxcIiA6Y2xhc3M9XFxcInJlc2l6YWJsZUhhbmRsZUNsYXNzXFxcIj48L3NwYW4+XFxyXFxuICAgICAgICA8IS0tPHNwYW4gdi1pZj1cXFwiZHJhZ2dhYmxlXFxcIiByZWY9XFxcImRyYWdIYW5kbGVcXFwiIGNsYXNzPVxcXCJ2dWUtZHJhZ2dhYmxlLWhhbmRsZVxcXCI+PC9zcGFuPi0tPlxcclxcbiAgICA8L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcbjxzdHlsZT5cXHJcXG4gICAgLnZ1ZS1ncmlkLWl0ZW0ge1xcclxcbiAgICAgICAgdHJhbnNpdGlvbjogYWxsIDIwMG1zIGVhc2U7XFxyXFxuICAgICAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiBsZWZ0LCB0b3AsIHJpZ2h0O1xcclxcbiAgICAgICAgLyogYWRkIHJpZ2h0IGZvciBydGwgKi9cXHJcXG4gICAgfVxcclxcblxcclxcbiAgICAudnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zIHtcXHJcXG4gICAgICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IHRyYW5zZm9ybTtcXHJcXG4gICAgICAgIGxlZnQ6IDA7XFxyXFxuICAgICAgICByaWdodDogYXV0bztcXHJcXG4gICAgfVxcclxcblxcclxcbiAgICAudnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zLnJlbmRlci1ydGwge1xcclxcbiAgICAgICAgbGVmdDogYXV0bztcXHJcXG4gICAgICAgIHJpZ2h0OiAwO1xcclxcbiAgICB9XFxyXFxuXFxyXFxuICAgIC52dWUtZ3JpZC1pdGVtLnJlc2l6aW5nIHtcXHJcXG4gICAgICAgIG9wYWNpdHk6IDAuNjtcXHJcXG4gICAgICAgIHotaW5kZXg6IDM7XFxyXFxuICAgIH1cXHJcXG5cXHJcXG4gICAgLnZ1ZS1ncmlkLWl0ZW0udnVlLWRyYWdnYWJsZS1kcmFnZ2luZyB7XFxyXFxuICAgICAgICB0cmFuc2l0aW9uOm5vbmU7XFxyXFxuICAgICAgICB6LWluZGV4OiAzO1xcclxcbiAgICB9XFxyXFxuXFxyXFxuICAgIC52dWUtZ3JpZC1pdGVtLnZ1ZS1ncmlkLXBsYWNlaG9sZGVyIHtcXHJcXG4gICAgICAgIGJhY2tncm91bmQ6IHJlZDtcXHJcXG4gICAgICAgIG9wYWNpdHk6IDAuMjtcXHJcXG4gICAgICAgIHRyYW5zaXRpb24tZHVyYXRpb246IDEwMG1zO1xcclxcbiAgICAgICAgei1pbmRleDogMjtcXHJcXG4gICAgICAgIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XFxyXFxuICAgICAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcclxcbiAgICAgICAgLW1zLXVzZXItc2VsZWN0OiBub25lO1xcclxcbiAgICAgICAgLW8tdXNlci1zZWxlY3Q6IG5vbmU7XFxyXFxuICAgICAgICB1c2VyLXNlbGVjdDogbm9uZTtcXHJcXG4gICAgfVxcclxcblxcclxcbiAgICAudnVlLWdyaWQtaXRlbSA+IC52dWUtcmVzaXphYmxlLWhhbmRsZSB7XFxyXFxuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxyXFxuICAgICAgICB3aWR0aDogMjBweDtcXHJcXG4gICAgICAgIGhlaWdodDogMjBweDtcXHJcXG4gICAgICAgIGJvdHRvbTogMDtcXHJcXG4gICAgICAgIHJpZ2h0OiAwO1xcclxcbiAgICAgICAgYmFja2dyb3VuZDogdXJsKCdkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQnpkR0Z1WkdGc2IyNWxQU0p1YnlJL1BnMDhJUzB0SUVkbGJtVnlZWFJ2Y2pvZ1FXUnZZbVVnUm1seVpYZHZjbXR6SUVOVE5pd2dSWGh3YjNKMElGTldSeUJGZUhSbGJuTnBiMjRnWW5rZ1FXRnliMjRnUW1WaGJHd2dLR2gwZEhBNkx5OW1hWEpsZDI5eWEzTXVZV0psWVd4c0xtTnZiU2tnTGlCV1pYSnphVzl1T2lBd0xqWXVNU0FnTFMwK0RUd2hSRTlEVkZsUVJTQnpkbWNnVUZWQ1RFbERJQ0l0THk5WE0wTXZMMFJVUkNCVFZrY2dNUzR4THk5RlRpSWdJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MMGR5WVhCb2FXTnpMMU5XUnk4eExqRXZSRlJFTDNOMlp6RXhMbVIwWkNJK0RUeHpkbWNnYVdROUlsVnVkR2wwYkdWa0xWQmhaMlVsTWpBeElpQjJhV1YzUW05NFBTSXdJREFnTmlBMklpQnpkSGxzWlQwaVltRmphMmR5YjNWdVpDMWpiMnh2Y2pvalptWm1abVptTURBaUlIWmxjbk5wYjI0OUlqRXVNU0lOQ1hodGJHNXpQU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh5TURBd0wzTjJaeUlnZUcxc2JuTTZlR3hwYm1zOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6RTVPVGt2ZUd4cGJtc2lJSGh0YkRwemNHRmpaVDBpY0hKbGMyVnlkbVVpRFFsNFBTSXdjSGdpSUhrOUlqQndlQ0lnZDJsa2RHZzlJalp3ZUNJZ2FHVnBaMmgwUFNJMmNIZ2lEVDROQ1R4bklHOXdZV05wZEhrOUlqQXVNekF5SWo0TkNRazhjR0YwYUNCa1BTSk5JRFlnTmlCTUlEQWdOaUJNSURBZ05DNHlJRXdnTkNBMExqSWdUQ0EwTGpJZ05DNHlJRXdnTkM0eUlEQWdUQ0EySURBZ1RDQTJJRFlnVENBMklEWWdXaUlnWm1sc2JEMGlJekF3TURBd01DSXZQZzBKUEM5blBnMDhMM04yWno0PScpO1xcclxcbiAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIHJpZ2h0O1xcclxcbiAgICAgICAgcGFkZGluZzogMCAzcHggM3B4IDA7XFxyXFxuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xcclxcbiAgICAgICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcclxcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXHJcXG4gICAgICAgIGN1cnNvcjogc2UtcmVzaXplO1xcclxcbiAgICB9XFxyXFxuXFxyXFxuICAgIC52dWUtZ3JpZC1pdGVtID4gLnZ1ZS1ydGwtcmVzaXphYmxlLWhhbmRsZSB7XFxyXFxuICAgICAgICBib3R0b206IDA7XFxyXFxuICAgICAgICBsZWZ0OiAwO1xcclxcbiAgICAgICAgYmFja2dyb3VuZDogdXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjNhV1IwYUQwaU1UQXVNREF3TURBd01EQXdNREF3TURBeUlpQm9aV2xuYUhROUlqRXdMakF3TURBd01EQXdNREF3TURBd01pSWdlRzFzYm5NOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6SXdNREF2YzNabklqNEtJRHdoTFMwZ1EzSmxZWFJsWkNCM2FYUm9JRTFsZEdodlpDQkVjbUYzSUMwZ2FIUjBjRG92TDJkcGRHaDFZaTVqYjIwdlpIVnZjR2w0Wld3dlRXVjBhRzlrTFVSeVlYY3ZJQzB0UGdvZ1BHYytDaUFnUEhScGRHeGxQbUpoWTJ0bmNtOTFibVE4TDNScGRHeGxQZ29nSUR4eVpXTjBJR1pwYkd3OUltNXZibVVpSUdsa1BTSmpZVzUyWVhOZlltRmphMmR5YjNWdVpDSWdhR1ZwWjJoMFBTSXhNaUlnZDJsa2RHZzlJakV5SWlCNVBTSXRNU0lnZUQwaUxURWlMejRLSUNBOFp5QmthWE53YkdGNVBTSnViMjVsSWlCdmRtVnlabXh2ZHowaWRtbHphV0pzWlNJZ2VUMGlNQ0lnZUQwaU1DSWdhR1ZwWjJoMFBTSXhNREFsSWlCM2FXUjBhRDBpTVRBd0pTSWdhV1E5SW1OaGJuWmhjMGR5YVdRaVBnb2dJQ0E4Y21WamRDQm1hV3hzUFNKMWNtd29JMmR5YVdSd1lYUjBaWEp1S1NJZ2MzUnliMnRsTFhkcFpIUm9QU0l3SWlCNVBTSXdJaUI0UFNJd0lpQm9aV2xuYUhROUlqRXdNQ1VpSUhkcFpIUm9QU0l4TURBbElpOCtDaUFnUEM5blBnb2dQQzluUGdvZ1BHYytDaUFnUEhScGRHeGxQa3hoZVdWeUlERThMM1JwZEd4bFBnb2dJRHhzYVc1bElHTmhiblpoY3owaUkyWm1abVptWmlJZ1kyRnVkbUZ6TFc5d1lXTnBkSGs5SWpFaUlITjBjbTlyWlMxc2FXNWxZMkZ3UFNKMWJtUmxabWx1WldRaUlITjBjbTlyWlMxc2FXNWxhbTlwYmowaWRXNWtaV1pwYm1Wa0lpQnBaRDBpYzNablh6RWlJSGt5UFNJdE56QXVNVGM0TkRBM0lpQjRNajBpTVRJMExqUTJOREUzTlNJZ2VURTlJaTB6T0M0ek9USTNNemNpSUhneFBTSXhORFF1T0RJeE1qZzVJaUJ6ZEhKdmEyVXRkMmxrZEdnOUlqRXVOU0lnYzNSeWIydGxQU0lqTURBd0lpQm1hV3hzUFNKdWIyNWxJaTgrQ2lBZ1BHeHBibVVnYzNSeWIydGxQU0lqTmpZMk5qWTJJaUJ6ZEhKdmEyVXRiR2x1WldOaGNEMGlkVzVrWldacGJtVmtJaUJ6ZEhKdmEyVXRiR2x1WldwdmFXNDlJblZ1WkdWbWFXNWxaQ0lnYVdROUluTjJaMTgxSWlCNU1qMGlPUzR4TURZNU5UY2lJSGd5UFNJd0xqazBOekkwTnlJZ2VURTlJaTB3TGpBeE9ERXlPQ0lnZURFOUlqQXVPVFEzTWpRM0lpQnpkSEp2YTJVdGQybGtkR2c5SWpJaUlHWnBiR3c5SW01dmJtVWlMejRLSUNBOGJHbHVaU0J6ZEhKdmEyVXRiR2x1WldOaGNEMGlkVzVrWldacGJtVmtJaUJ6ZEhKdmEyVXRiR2x1WldwdmFXNDlJblZ1WkdWbWFXNWxaQ0lnYVdROUluTjJaMTgzSWlCNU1qMGlPU0lnZURJOUlqRXdMakEzTXpVeU9TSWdlVEU5SWpraUlIZ3hQU0l0TUM0Mk5UVTJOQ0lnYzNSeWIydGxMWGRwWkhSb1BTSXlJaUJ6ZEhKdmEyVTlJaU0yTmpZMk5qWWlJR1pwYkd3OUltNXZibVVpTHo0S0lEd3ZaejRLUEM5emRtYyspO1xcclxcbiAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIGxlZnQ7XFxyXFxuICAgICAgICBwYWRkaW5nLWxlZnQ6IDNweDtcXHJcXG4gICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XFxyXFxuICAgICAgICBiYWNrZ3JvdW5kLW9yaWdpbjogY29udGVudC1ib3g7XFxyXFxuICAgICAgICBjdXJzb3I6IHN3LXJlc2l6ZTtcXHJcXG4gICAgICAgIHJpZ2h0OiBhdXRvO1xcclxcbiAgICB9XFxyXFxuPC9zdHlsZT5cXHJcXG48c2NyaXB0PlxcclxcbiAgICBpbXBvcnQge3NldFRvcExlZnQsIHNldFRvcFJpZ2h0LCBzZXRUcmFuc2Zvcm1SdGwsIHNldFRyYW5zZm9ybSwgY3JlYXRlTWFya3VwLCBnZXRMYXlvdXRJdGVtfSBmcm9tICcuL3V0aWxzJztcXHJcXG4gICAgaW1wb3J0IHtnZXRDb250cm9sUG9zaXRpb24sIG9mZnNldFhZRnJvbVBhcmVudE9mLCBjcmVhdGVDb3JlRGF0YX0gZnJvbSAnLi9kcmFnZ2FibGVVdGlscyc7XFxyXFxuICAgIC8vICAgIHZhciBldmVudEJ1cyA9IHJlcXVpcmUoJy4vZXZlbnRCdXMnKTtcXHJcXG5cXHJcXG4gICAgdmFyIGludGVyYWN0ID0gcmVxdWlyZShcXFwiaW50ZXJhY3Rqc1xcXCIpO1xcclxcblxcclxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxyXFxuICAgICAgICBuYW1lOiBcXFwiR3JpZEl0ZW1cXFwiLFxcclxcbiAgICAgICAgcHJvcHM6IHtcXHJcXG4gICAgICAgICAgICAvKmNvbHM6IHtcXHJcXG4gICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxcclxcbiAgICAgICAgICAgICB9LCovXFxyXFxuICAgICAgICAgICAgLypjb250YWluZXJXaWR0aDoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuXFxyXFxuICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgIHJvd0hlaWdodDoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgIG1hcmdpbjoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBBcnJheSxcXHJcXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICAgbWF4Um93czoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgIH0sKi9cXHJcXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IG51bGxcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogbnVsbFxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgLyp1c2VDc3NUcmFuc2Zvcm1zOiB7XFxyXFxuICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgIHN0YXRpYzoge1xcclxcbiAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlXFxyXFxuICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgICovXFxyXFxuICAgICAgICAgICAgbWluSDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbWluVzoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbWF4SDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIG1heFc6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IEluZmluaXR5XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB4OiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHk6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgdzoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBoOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGk6IHtcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGRyYWdJZ25vcmVGcm9tOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcXHJcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAnYSwgYnV0dG9uJ1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgZHJhZ0FsbG93RnJvbToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBTdHJpbmcsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogbnVsbFxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgcmVzaXplSWdub3JlRnJvbToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBTdHJpbmcsXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogJ2EsIGJ1dHRvbidcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIGluamVjdDogW1xcXCJldmVudEJ1c1xcXCJdLFxcclxcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgIHJldHVybiB7XFxyXFxuICAgICAgICAgICAgICAgIGNvbHM6IDEsXFxyXFxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiAxMDAsXFxyXFxuICAgICAgICAgICAgICAgIHJvd0hlaWdodDogMzAsXFxyXFxuICAgICAgICAgICAgICAgIG1hcmdpbjogWzEwLCAxMF0sXFxyXFxuICAgICAgICAgICAgICAgIG1heFJvd3M6IEluZmluaXR5LFxcclxcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGU6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIHJlc2l6YWJsZTogbnVsbCxcXHJcXG4gICAgICAgICAgICAgICAgdXNlQ3NzVHJhbnNmb3JtczogdHJ1ZSxcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogZmFsc2UsXFxyXFxuICAgICAgICAgICAgICAgIGRyYWdnaW5nOiBudWxsLFxcclxcbiAgICAgICAgICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgcmVzaXppbmc6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RYOiBOYU4sXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RZOiBOYU4sXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RXOiBOYU4sXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RIOiBOYU4sXFxyXFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7fSxcXHJcXG4gICAgICAgICAgICAgICAgcnRsOiBmYWxzZSxcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgZHJhZ0V2ZW50U2V0OiBmYWxzZSxcXHJcXG4gICAgICAgICAgICAgICAgcmVzaXplRXZlbnRTZXQ6IGZhbHNlLFxcclxcblxcclxcbiAgICAgICAgICAgICAgICBwcmV2aW91c1c6IG51bGwsXFxyXFxuICAgICAgICAgICAgICAgIHByZXZpb3VzSDogbnVsbCxcXHJcXG4gICAgICAgICAgICAgICAgcHJldmlvdXNYOiBudWxsLFxcclxcbiAgICAgICAgICAgICAgICBwcmV2aW91c1k6IG51bGwsXFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIGNyZWF0ZWQgKCkge1xcclxcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcXHJcXG5cXHJcXG4gICAgICAgICAgICAvLyBBY2Nlc3NpYmxlIHJlZmVybmNlcyBvZiBmdW5jdGlvbnMgZm9yIHJlbW92aW5nIGluIGJlZm9yZURlc3Ryb3lcXHJcXG4gICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlciA9IGZ1bmN0aW9uICh3aWR0aCkge1xcclxcbiAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoKHdpZHRoKTtcXHJcXG4gICAgICAgICAgICB9O1xcclxcblxcclxcbiAgICAgICAgICAgIHNlbGYuY29tcGFjdEhhbmRsZXIgPSBmdW5jdGlvbiAobGF5b3V0KSB7XFxyXFxuICAgICAgICAgICAgICAgIHNlbGYuY29tcGFjdChsYXlvdXQpO1xcclxcbiAgICAgICAgICAgIH07XFxyXFxuXFxyXFxuICAgICAgICAgICAgc2VsZi5zZXREcmFnZ2FibGVIYW5kbGVyID0gZnVuY3Rpb24gKGlzRHJhZ2dhYmxlKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmIChzZWxmLmlzRHJhZ2dhYmxlID09PSBudWxsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBzZWxmLmRyYWdnYWJsZSA9IGlzRHJhZ2dhYmxlO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIgPSBmdW5jdGlvbiAoaXNSZXNpemFibGUpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuaXNSZXNpemFibGUgPT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHNlbGYucmVzaXphYmxlID0gaXNSZXNpemFibGU7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICB9O1xcclxcblxcclxcbiAgICAgICAgICAgIHNlbGYuc2V0Um93SGVpZ2h0SGFuZGxlciA9IGZ1bmN0aW9uIChyb3dIZWlnaHQpIHtcXHJcXG4gICAgICAgICAgICAgICAgc2VsZi5yb3dIZWlnaHQgPSByb3dIZWlnaHQ7XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIgPSAoZGlyZWN0aW9uKSA9PiB7XFxyXFxuICAgICAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSAoZG9jdW1lbnQuZGlyICE9PSB1bmRlZmluZWQpID9cXHJcXG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmRpciA6XFxyXFxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcXFwiaHRtbFxcXCIpWzBdLmdldEF0dHJpYnV0ZShcXFwiZGlyXFxcIik7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMucnRsID0gKGRpcmVjdGlvbiA9PT0gXFxcInJ0bFxcXCIpO1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNvbXBhY3QoKTtcXHJcXG4gICAgICAgICAgICB9O1xcclxcblxcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCd1cGRhdGVXaWR0aCcsIHNlbGYudXBkYXRlV2lkdGhIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbignY29tcGFjdCcsIHNlbGYuY29tcGFjdEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXREcmFnZ2FibGUnLCBzZWxmLnNldERyYWdnYWJsZUhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXRSZXNpemFibGUnLCBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXRSb3dIZWlnaHQnLCBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdkaXJlY3Rpb25jaGFuZ2UnLCBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIpO1xcclxcblxcclxcbiAgICAgICAgICAgIC8qdGhpcy5ldmVudEJ1cy4kb24oJ3NldENvbE51bScsIGZ1bmN0aW9uKGNvbE51bSkge1xcclxcbiAgICAgICAgICAgICBzZWxmLmNvbHMgPSBjb2xOdW07XFxyXFxuICAgICAgICAgICAgIH0pOyovXFxyXFxuICAgICAgICAgICAgdmFyIGRpcmVjdGlvbiA9IChkb2N1bWVudC5kaXIgIT09IHVuZGVmaW5lZCkgP1xcclxcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5kaXIgOlxcclxcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcXFwiaHRtbFxcXCIpWzBdLmdldEF0dHJpYnV0ZShcXFwiZGlyXFxcIik7XFxyXFxuICAgICAgICAgICAgdGhpcy5ydGwgPSAoZGlyZWN0aW9uID09PSBcXFwicnRsXFxcIik7XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgYmVmb3JlRGVzdHJveTogZnVuY3Rpb24oKXtcXHJcXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgLy9SZW1vdmUgbGlzdGVuZXJzXFxyXFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCd1cGRhdGVXaWR0aCcsIHNlbGYudXBkYXRlV2lkdGhIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2NvbXBhY3QnLCBzZWxmLmNvbXBhY3RIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ3NldERyYWdnYWJsZScsIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlcik7XFxyXFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCdzZXRSZXNpemFibGUnLCBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignc2V0Um93SGVpZ2h0Jywgc2VsZi5zZXRSb3dIZWlnaHRIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2RpcmVjdGlvbmNoYW5nZScsIHNlbGYuZGlyZWN0aW9uY2hhbmdlSGFuZGxlcik7XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgbW91bnRlZDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgIHRoaXMuY29scyA9IHRoaXMuJHBhcmVudC5jb2xOdW07XFxyXFxuICAgICAgICAgICAgdGhpcy5yb3dIZWlnaHQgPSB0aGlzLiRwYXJlbnQucm93SGVpZ2h0O1xcclxcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSB0aGlzLiRwYXJlbnQud2lkdGggIT09IG51bGwgPyB0aGlzLiRwYXJlbnQud2lkdGggOiAxMDA7XFxyXFxuICAgICAgICAgICAgdGhpcy5tYXJnaW4gPSB0aGlzLiRwYXJlbnQubWFyZ2luICE9PSB1bmRlZmluZWQgPyB0aGlzLiRwYXJlbnQubWFyZ2luIDogWzEwLCAxMF07XFxyXFxuICAgICAgICAgICAgdGhpcy5tYXhSb3dzID0gdGhpcy4kcGFyZW50Lm1heFJvd3M7XFxyXFxuICAgICAgICAgICAgaWYgKHRoaXMuaXNEcmFnZ2FibGUgPT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLiRwYXJlbnQuaXNEcmFnZ2FibGU7XFxyXFxuICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLmlzRHJhZ2dhYmxlO1xcclxcbiAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICBpZiAodGhpcy5pc1Jlc2l6YWJsZSA9PT0gbnVsbCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHRoaXMuJHBhcmVudC5pc1Jlc2l6YWJsZTtcXHJcXG4gICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHRoaXMuaXNSZXNpemFibGU7XFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgIHRoaXMudXNlQ3NzVHJhbnNmb3JtcyA9IHRoaXMuJHBhcmVudC51c2VDc3NUcmFuc2Zvcm1zO1xcclxcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICB3YXRjaDoge1xcclxcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dhYmxlID0gdGhpcy5pc0RyYWdnYWJsZTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGRyYWdnYWJsZTogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmludGVyYWN0T2JqID09PSBudWxsIHx8IHRoaXMuaW50ZXJhY3RPYmogPT09IHVuZGVmaW5lZCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iaiA9IGludGVyYWN0KHRoaXMuJHJlZnMuaXRlbSk7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ2dhYmxlKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB2YXIgb3B0cyA9IHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVGcm9tOiB0aGlzLmRyYWdJZ25vcmVGcm9tLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93RnJvbTogdGhpcy5kcmFnQWxsb3dGcm9tXFxyXFxuICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLmRyYWdnYWJsZShvcHRzKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIC8qdGhpcy5pbnRlcmFjdE9iai5kcmFnZ2FibGUoe2FsbG93RnJvbTogJy52dWUtZHJhZ2dhYmxlLWhhbmRsZSd9KTsqL1xcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRyYWdFdmVudFNldCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0V2ZW50U2V0ID0gdHJ1ZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLm9uKCdkcmFnc3RhcnQgZHJhZ21vdmUgZHJhZ2VuZCcsIGZ1bmN0aW9uIChldmVudCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmhhbmRsZURyYWcoZXZlbnQpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5kcmFnZ2FibGUoe1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXFxyXFxuICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemFibGUgPSB0aGlzLmlzUmVzaXphYmxlO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgcmVzaXphYmxlOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJhY3RPYmogPT09IG51bGwgfHwgdGhpcy5pbnRlcmFjdE9iaiA9PT0gdW5kZWZpbmVkKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqID0gaW50ZXJhY3QodGhpcy4kcmVmcy5pdGVtKTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZXNpemFibGUpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHZhciBvcHRzID0ge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VzOiB7bGVmdDogZmFsc2UsIHJpZ2h0OiB0cnVlLCBib3R0b206IHRydWUsIHRvcDogZmFsc2V9LFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUZyb206IHRoaXMucmVzaXplSWdub3JlRnJvbVxcclxcbiAgICAgICAgICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIFxcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5yZXNpemFibGUob3B0cyk7XFxyXFxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMucmVzaXplRXZlbnRTZXQpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZUV2ZW50U2V0ID0gdHJ1ZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbigncmVzaXplc3RhcnQgcmVzaXplbW92ZSByZXNpemVlbmQnLCBmdW5jdGlvbiAoZXZlbnQpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaGFuZGxlUmVzaXplKGV2ZW50KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLnJlc2l6YWJsZSh7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcXHJcXG4gICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgY29sczogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBjb250YWluZXJXaWR0aDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB4OiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHk6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgaDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB3OiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHJlbmRlclJ0bDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIGNvbXB1dGVkOiB7XFxyXFxuICAgICAgICAgICAgcmVuZGVyUnRsKCkge1xcclxcbiAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuJHBhcmVudC5pc01pcnJvcmVkKSA/ICF0aGlzLnJ0bCA6IHRoaXMucnRsO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgcmVzaXphYmxlSGFuZGxlQ2xhc3MoKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd2dWUtcmVzaXphYmxlLWhhbmRsZSB2dWUtcnRsLXJlc2l6YWJsZS1oYW5kbGUnO1xcclxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd2dWUtcmVzaXphYmxlLWhhbmRsZSc7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICB9XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgbWV0aG9kczoge1xcclxcbiAgICAgICAgICAgIGNyZWF0ZVN0eWxlOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggKyB0aGlzLncgPiB0aGlzLmNvbHMpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueCA9IDA7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLncgPSB0aGlzLmNvbHM7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRHJhZ2dpbmcpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy50b3AgPSB0aGlzLmRyYWdnaW5nLnRvcDtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XFxyXFxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3MucmlnaHQgPSB0aGlzLmRyYWdnaW5nLmxlZnQ7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcy5sZWZ0ID0gdGhpcy5kcmFnZ2luZy5sZWZ0O1xcclxcbiAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUmVzaXppbmcpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICBwb3MuaGVpZ2h0ID0gdGhpcy5yZXNpemluZy5oZWlnaHQ7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgbGV0IHN0eWxlO1xcclxcbiAgICAgICAgICAgICAgICAvLyBDU1MgVHJhbnNmb3JtcyBzdXBwb3J0IChkZWZhdWx0KVxcclxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51c2VDc3NUcmFuc2Zvcm1zKSB7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUcmFuc2Zvcm1SdGwocG9zLnRvcCwgcG9zLnJpZ2h0LCBwb3Mud2lkdGgsIHBvcy5oZWlnaHQpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IHNldFRyYW5zZm9ybShwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gdG9wLGxlZnQgKHNsb3cpXFxyXFxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUb3BSaWdodChwb3MudG9wLCBwb3MucmlnaHQsIHBvcy53aWR0aCwgcG9zLmhlaWdodCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gc2V0VG9wTGVmdChwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlID0gc3R5bGU7XFxyXFxuXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBoYW5kbGVSZXNpemU6IGZ1bmN0aW9uIChldmVudCkge1xcclxcbiAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldENvbnRyb2xQb3NpdGlvbihldmVudCk7XFxyXFxuICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBkcmFnIHBvaW50IGZyb20gdGhlIGV2ZW50LiBUaGlzIGlzIHVzZWQgYXMgdGhlIG9mZnNldC5cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IG51bGwpIHJldHVybjsgLy8gbm90IHBvc3NpYmxlIGJ1dCBzYXRpc2ZpZXMgZmxvd1xcclxcbiAgICAgICAgICAgICAgICBjb25zdCB7eCwgeX0gPSBwb3NpdGlvbjtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U2l6ZSA9IHt3aWR0aDogMCwgaGVpZ2h0OiAwfTtcXHJcXG4gICAgICAgICAgICAgICAgc3dpdGNoIChldmVudC50eXBlKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJyZXNpemVzdGFydFxcXCI6XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c1cgPSB0aGlzLnc7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c0ggPSB0aGlzLmg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHBvcy53aWR0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemluZyA9IG5ld1NpemU7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1Jlc2l6aW5nID0gdHJ1ZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXHJcXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXFxcInJlc2l6ZW1vdmVcXFwiOlxcclxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIiMjIyByZXNpemUgPT4gXFxcIiArIGV2ZW50LnR5cGUgKyBcXFwiLCBsYXN0Vz1cXFwiICsgdGhpcy5sYXN0VyArIFxcXCIsIGxhc3RIPVxcXCIgKyB0aGlzLmxhc3RIKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3JlRXZlbnQgPSBjcmVhdGVDb3JlRGF0YSh0aGlzLmxhc3RXLCB0aGlzLmxhc3RILCB4LCB5KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGggLSBjb3JlRXZlbnQuZGVsdGFYO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUud2lkdGggPSB0aGlzLnJlc2l6aW5nLndpZHRoICsgY29yZUV2ZW50LmRlbHRhWDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS5oZWlnaHQgPSB0aGlzLnJlc2l6aW5nLmhlaWdodCArIGNvcmVFdmVudC5kZWx0YVk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8vY29uc29sZS5sb2coXFxcIiMjIyByZXNpemUgPT4gXFxcIiArIGV2ZW50LnR5cGUgKyBcXFwiLCBkZWx0YVg9XFxcIiArIGNvcmVFdmVudC5kZWx0YVggKyBcXFwiLCBkZWx0YVk9XFxcIiArIGNvcmVFdmVudC5kZWx0YVkpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzaXppbmcgPSBuZXdTaXplO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xcclxcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcXFwicmVzaXplZW5kXFxcIjpcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKFxcXCIjIyMgcmVzaXplIGVuZCA9PiB4PVxcXCIgK3RoaXMueCArIFxcXCIgeT1cXFwiICsgdGhpcy55ICsgXFxcIiB3PVxcXCIgKyB0aGlzLncgKyBcXFwiIGg9XFxcIiArIHRoaXMuaCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHBvcy53aWR0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIHJlc2l6ZSBlbmQgPT4gXFxcIiArIEpTT04uc3RyaW5naWZ5KG5ld1NpemUpKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6aW5nID0gbnVsbDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUmVzaXppbmcgPSBmYWxzZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcbiAgICAgICAgICAgICAgICAvLyBHZXQgbmV3IFdIXFxyXFxuICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNXSChuZXdTaXplLmhlaWdodCwgbmV3U2l6ZS53aWR0aCk7XFxyXFxuICAgICAgICAgICAgICAgIGlmIChwb3MudyA8IHRoaXMubWluVykge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcG9zLncgPSB0aGlzLm1pblc7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvcy53ID4gdGhpcy5tYXhXKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBwb3MudyA9IHRoaXMubWF4VztcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBpZiAocG9zLmggPCB0aGlzLm1pbkgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy5oID0gdGhpcy5taW5IO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmIChwb3MuaCA+IHRoaXMubWF4SCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSB0aGlzLm1heEg7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvcy5oIDwgMSkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSAxO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIGlmIChwb3MudyA8IDEpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHBvcy53ID0gMTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RXID0geDtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0SCA9IHk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLncgIT09IHBvcy53IHx8IHRoaXMuaCAhPT0gcG9zLmgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcInJlc2l6ZVxcXCIsIHRoaXMuaSwgcG9zLmgsIHBvcy53KTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXFxcInJlc2l6ZWVuZFxcXCIgJiYgKHRoaXMucHJldmlvdXNXICE9PSB0aGlzLncgfHwgdGhpcy5wcmV2aW91c0ggIT09IHRoaXMuaCkpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcInJlc2l6ZWRcXFwiLCB0aGlzLmksIHBvcy5oLCBwb3MudywgbmV3U2l6ZS5oZWlnaHQsIG5ld1NpemUud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInJlc2l6ZUV2ZW50XFxcIiwgZXZlbnQudHlwZSwgdGhpcy5pLCB0aGlzLngsIHRoaXMueSwgcG9zLmgsIHBvcy53KTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGhhbmRsZURyYWcoZXZlbnQpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXNpemluZykgcmV0dXJuO1xcclxcblxcclxcbiAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldENvbnRyb2xQb3NpdGlvbihldmVudCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBkcmFnIHBvaW50IGZyb20gdGhlIGV2ZW50LiBUaGlzIGlzIHVzZWQgYXMgdGhlIG9mZnNldC5cXHJcXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSBudWxsKSByZXR1cm47IC8vIG5vdCBwb3NzaWJsZSBidXQgc2F0aXNmaWVzIGZsb3dcXHJcXG4gICAgICAgICAgICAgICAgY29uc3Qge3gsIHl9ID0gcG9zaXRpb247XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIHZhciBzaG91bGRVcGRhdGUgPSBmYWxzZTtcXHJcXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3UG9zaXRpb24gPSB7dG9wOiAwLCBsZWZ0OiAwfTtcXHJcXG4gICAgICAgICAgICAgICAgc3dpdGNoIChldmVudC50eXBlKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJkcmFnc3RhcnRcXFwiOlxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNYID0gdGhpcy54O1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNZID0gdGhpcy55O1xcclxcblxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRSZWN0ID0gZXZlbnQudGFyZ2V0Lm9mZnNldFBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xpZW50UmVjdCA9IGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IChjbGllbnRSZWN0LnJpZ2h0IC0gcGFyZW50UmVjdC5yaWdodCkgKiAtMTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gY2xpZW50UmVjdC5sZWZ0IC0gcGFyZW50UmVjdC5sZWZ0O1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi50b3AgPSBjbGllbnRSZWN0LnRvcCAtIHBhcmVudFJlY3QudG9wO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBuZXdQb3NpdGlvbjtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xcclxcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcXFwiZHJhZ2VuZFxcXCI6XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmcpIHJldHVybjtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRSZWN0ID0gZXZlbnQudGFyZ2V0Lm9mZnNldFBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRSZWN0ID0gZXZlbnQudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xcclxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSAoY2xpZW50UmVjdC5yaWdodCAtIHBhcmVudFJlY3QucmlnaHQpICogLTE7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IGNsaWVudFJlY3QubGVmdCAtIHBhcmVudFJlY3QubGVmdDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24udG9wID0gY2xpZW50UmVjdC50b3AgLSBwYXJlbnRSZWN0LnRvcDtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgZHJhZyBlbmQgPT4gXFxcIiArIEpTT04uc3RyaW5naWZ5KG5ld1Bvc2l0aW9uKSk7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIERST1A6IFxcXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBudWxsO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZFVwZGF0ZSA9IHRydWU7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XFxyXFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJkcmFnbW92ZVxcXCI6XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29yZUV2ZW50ID0gY3JlYXRlQ29yZURhdGEodGhpcy5sYXN0WCwgdGhpcy5sYXN0WSwgeCwgeSk7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBBZGQgcnRsIHN1cHBvcnRcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdCAtIGNvcmVFdmVudC5kZWx0YVg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdCArIGNvcmVFdmVudC5kZWx0YVg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLnRvcCA9IHRoaXMuZHJhZ2dpbmcudG9wICsgY29yZUV2ZW50LmRlbHRhWTtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgZHJhZyA9PiBcXFwiICsgZXZlbnQudHlwZSArIFxcXCIsIHg9XFxcIiArIHggKyBcXFwiLCB5PVxcXCIgKyB5KTtcXHJcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgZHJhZyA9PiBcXFwiICsgZXZlbnQudHlwZSArIFxcXCIsIGRlbHRhWD1cXFwiICsgY29yZUV2ZW50LmRlbHRhWCArIFxcXCIsIGRlbHRhWT1cXFwiICsgY29yZUV2ZW50LmRlbHRhWSk7XFxyXFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIGRyYWcgZW5kID0+IFxcXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBuZXdQb3NpdGlvbjtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcbiAgICAgICAgICAgICAgICAvLyBHZXQgbmV3IFhZXFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1hZKG5ld1Bvc2l0aW9uLnRvcCwgbmV3UG9zaXRpb24ubGVmdCk7XFxyXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjWFkobmV3UG9zaXRpb24udG9wLCBuZXdQb3NpdGlvbi5sZWZ0KTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RYID0geDtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0WSA9IHk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggIT09IHBvcy54IHx8IHRoaXMueSAhPT0gcG9zLnkpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcIm1vdmVcXFwiLCB0aGlzLmksIHBvcy54LCBwb3MueSk7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFxcXCJkcmFnZW5kXFxcIiAmJiAodGhpcy5wcmV2aW91c1ggIT09IHRoaXMueCB8fCB0aGlzLnByZXZpb3VzWSAhPT0gdGhpcy55KSkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZW1pdChcXFwibW92ZWRcXFwiLCB0aGlzLmksIHBvcy54LCBwb3MueSk7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcXFwiZHJhZ0V2ZW50XFxcIiwgZXZlbnQudHlwZSwgdGhpcy5pLCBwb3MueCwgcG9zLnksIHRoaXMuaCwgdGhpcy53KTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIGNhbGNQb3NpdGlvbjogZnVuY3Rpb24gKHgsIHksIHcsIGgpIHtcXHJcXG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2lkdGggPSB0aGlzLmNhbGNDb2xXaWR0aCgpO1xcclxcbiAgICAgICAgICAgICAgICAvLyBhZGQgcnRsIHN1cHBvcnRcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB2YXIgb3V0ID0ge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0OiBNYXRoLnJvdW5kKGNvbFdpZHRoICogeCArICh4ICsgMSkgKiB0aGlzLm1hcmdpblswXSksXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBNYXRoLnJvdW5kKHRoaXMucm93SGVpZ2h0ICogeSArICh5ICsgMSkgKiB0aGlzLm1hcmdpblsxXSksXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gMCAqIEluZmluaXR5ID09PSBOYU4sIHdoaWNoIGNhdXNlcyBwcm9ibGVtcyB3aXRoIHJlc2l6ZSBjb25zdHJpYW50cztcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggdGhpcyBpZiBpdCBvY2N1cnMuXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB3ZSBkbyBpdCBoZXJlIHJhdGhlciB0aGFuIGxhdGVyIGJlY2F1c2UgTWF0aC5yb3VuZChJbmZpbml0eSkgY2F1c2VzIGRlb3B0XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHcgPT09IEluZmluaXR5ID8gdyA6IE1hdGgucm91bmQoY29sV2lkdGggKiB3ICsgTWF0aC5tYXgoMCwgdyAtIDEpICogdGhpcy5tYXJnaW5bMF0pLFxcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaCA9PT0gSW5maW5pdHkgPyBoIDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIGggKyBNYXRoLm1heCgwLCBoIC0gMSkgKiB0aGlzLm1hcmdpblsxXSlcXHJcXG4gICAgICAgICAgICAgICAgICAgIH07XFxyXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB2YXIgb3V0ID0ge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IE1hdGgucm91bmQoY29sV2lkdGggKiB4ICsgKHggKyAxKSAqIHRoaXMubWFyZ2luWzBdKSxcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IE1hdGgucm91bmQodGhpcy5yb3dIZWlnaHQgKiB5ICsgKHkgKyAxKSAqIHRoaXMubWFyZ2luWzFdKSxcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAwICogSW5maW5pdHkgPT09IE5hTiwgd2hpY2ggY2F1c2VzIHByb2JsZW1zIHdpdGggcmVzaXplIGNvbnN0cmlhbnRzO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpeCB0aGlzIGlmIGl0IG9jY3Vycy5cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlIHdlIGRvIGl0IGhlcmUgcmF0aGVyIHRoYW4gbGF0ZXIgYmVjYXVzZSBNYXRoLnJvdW5kKEluZmluaXR5KSBjYXVzZXMgZGVvcHRcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdyA9PT0gSW5maW5pdHkgPyB3IDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHcgKyBNYXRoLm1heCgwLCB3IC0gMSkgKiB0aGlzLm1hcmdpblswXSksXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBoID09PSBJbmZpbml0eSA/IGggOiBNYXRoLnJvdW5kKHRoaXMucm93SGVpZ2h0ICogaCArIE1hdGgubWF4KDAsIGggLSAxKSAqIHRoaXMubWFyZ2luWzFdKVxcclxcbiAgICAgICAgICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcblxcclxcblxcclxcbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0O1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgLyoqXFxyXFxuICAgICAgICAgICAgICogVHJhbnNsYXRlIHggYW5kIHkgY29vcmRpbmF0ZXMgZnJvbSBwaXhlbHMgdG8gZ3JpZCB1bml0cy5cXHJcXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IHRvcCAgVG9wIHBvc2l0aW9uIChyZWxhdGl2ZSB0byBwYXJlbnQpIGluIHBpeGVscy5cXHJcXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IGxlZnQgTGVmdCBwb3NpdGlvbiAocmVsYXRpdmUgdG8gcGFyZW50KSBpbiBwaXhlbHMuXFxyXFxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB4IGFuZCB5IGluIGdyaWQgdW5pdHMuXFxyXFxuICAgICAgICAgICAgICovXFxyXFxuICAgICAgICAgICAgLy8gVE9ETyBjaGVjayBpZiB0aGlzIGZ1bmN0aW9uIG5lZWRzIGNoYW5nZSBpbiBvcmRlciB0byBzdXBwb3J0IHJ0bC5cXHJcXG4gICAgICAgICAgICBjYWxjWFkodG9wLCBsZWZ0KSB7XFxyXFxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbFdpZHRoID0gdGhpcy5jYWxjQ29sV2lkdGgoKTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgLy8gbGVmdCA9IGNvbFdpZHRoICogeCArIG1hcmdpbiAqICh4ICsgMSlcXHJcXG4gICAgICAgICAgICAgICAgLy8gbCA9IGN4ICsgbSh4KzEpXFxyXFxuICAgICAgICAgICAgICAgIC8vIGwgPSBjeCArIG14ICsgbVxcclxcbiAgICAgICAgICAgICAgICAvLyBsIC0gbSA9IGN4ICsgbXhcXHJcXG4gICAgICAgICAgICAgICAgLy8gbCAtIG0gPSB4KGMgKyBtKVxcclxcbiAgICAgICAgICAgICAgICAvLyAobCAtIG0pIC8gKGMgKyBtKSA9IHhcXHJcXG4gICAgICAgICAgICAgICAgLy8geCA9IChsZWZ0IC0gbWFyZ2luKSAvIChjb2xkV2lkdGggKyBtYXJnaW4pXFxyXFxuICAgICAgICAgICAgICAgIGxldCB4ID0gTWF0aC5yb3VuZCgobGVmdCAtIHRoaXMubWFyZ2luWzBdKSAvIChjb2xXaWR0aCArIHRoaXMubWFyZ2luWzBdKSk7XFxyXFxuICAgICAgICAgICAgICAgIGxldCB5ID0gTWF0aC5yb3VuZCgodG9wIC0gdGhpcy5tYXJnaW5bMV0pIC8gKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pKTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgLy8gQ2FwcGluZ1xcclxcbiAgICAgICAgICAgICAgICB4ID0gTWF0aC5tYXgoTWF0aC5taW4oeCwgdGhpcy5jb2xzIC0gdGhpcy53KSwgMCk7XFxyXFxuICAgICAgICAgICAgICAgIHkgPSBNYXRoLm1heChNYXRoLm1pbih5LCB0aGlzLm1heFJvd3MgLSB0aGlzLmgpLCAwKTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgcmV0dXJuIHt4LCB5fTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIC8vIEhlbHBlciBmb3IgZ2VuZXJhdGluZyBjb2x1bW4gd2lkdGhcXHJcXG4gICAgICAgICAgICBjYWxjQ29sV2lkdGgoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHZhciBjb2xXaWR0aCA9ICh0aGlzLmNvbnRhaW5lcldpZHRoIC0gKHRoaXMubWFyZ2luWzBdICogKHRoaXMuY29scyArIDEpKSkgLyB0aGlzLmNvbHM7XFxyXFxuLy8gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIiMjIyBDT0xTPVxcXCIgKyB0aGlzLmNvbHMgKyBcXFwiIENPTCBXSURUSD1cXFwiICsgY29sV2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sV2lkdGg7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG5cXHJcXG4gICAgICAgICAgICAvKipcXHJcXG4gICAgICAgICAgICAgKiBHaXZlbiBhIGhlaWdodCBhbmQgd2lkdGggaW4gcGl4ZWwgdmFsdWVzLCBjYWxjdWxhdGUgZ3JpZCB1bml0cy5cXHJcXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IGhlaWdodCBIZWlnaHQgaW4gcGl4ZWxzLlxcclxcbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gd2lkdGggIFdpZHRoIGluIHBpeGVscy5cXHJcXG4gICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IHcsIGggYXMgZ3JpZCB1bml0cy5cXHJcXG4gICAgICAgICAgICAgKi9cXHJcXG4gICAgICAgICAgICBjYWxjV0goaGVpZ2h0LCB3aWR0aCkge1xcclxcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xXaWR0aCA9IHRoaXMuY2FsY0NvbFdpZHRoKCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIC8vIHdpZHRoID0gY29sV2lkdGggKiB3IC0gKG1hcmdpbiAqICh3IC0gMSkpXFxyXFxuICAgICAgICAgICAgICAgIC8vIC4uLlxcclxcbiAgICAgICAgICAgICAgICAvLyB3ID0gKHdpZHRoICsgbWFyZ2luKSAvIChjb2xXaWR0aCArIG1hcmdpbilcXHJcXG4gICAgICAgICAgICAgICAgbGV0IHcgPSBNYXRoLnJvdW5kKCh3aWR0aCArIHRoaXMubWFyZ2luWzBdKSAvIChjb2xXaWR0aCArIHRoaXMubWFyZ2luWzBdKSk7XFxyXFxuICAgICAgICAgICAgICAgIGxldCBoID0gTWF0aC5yb3VuZCgoaGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pIC8gKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pKTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgLy8gQ2FwcGluZ1xcclxcbiAgICAgICAgICAgICAgICB3ID0gTWF0aC5tYXgoTWF0aC5taW4odywgdGhpcy5jb2xzIC0gdGhpcy54KSwgMCk7XFxyXFxuICAgICAgICAgICAgICAgIGggPSBNYXRoLm1heChNYXRoLm1pbihoLCB0aGlzLm1heFJvd3MgLSB0aGlzLnkpLCAwKTtcXHJcXG4gICAgICAgICAgICAgICAgcmV0dXJuIHt3LCBofTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHVwZGF0ZVdpZHRoOiBmdW5jdGlvbiAod2lkdGgsIGNvbE51bSkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gd2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgIGlmIChjb2xOdW0gIT09IHVuZGVmaW5lZCAmJiBjb2xOdW0gIT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29scyA9IGNvbE51bTtcXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgY29tcGFjdDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxyXFxuICAgICAgICAgICAgfVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgfVxcclxcbjwvc2NyaXB0PlxcclxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi1mMmVmOWNkMlwiLFwic2NvcGVkXCI6ZmFsc2UsXCJoYXNJbmxpbmVDb25maWdcIjpmYWxzZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDExXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///11\n"); /***/ }), /* 12 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, exports) { -eval("exports = module.exports = __webpack_require__(2)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.vue-grid-item {\\n transition: all 200ms ease;\\n transition-property: left, top, right;\\n /* add right for rtl */\\n}\\n.vue-grid-item.cssTransforms {\\n transition-property: transform;\\n left: 0;\\n right: auto;\\n}\\n.vue-grid-item.cssTransforms.render-rtl {\\n left: auto;\\n right: 0;\\n}\\n.vue-grid-item.resizing {\\n opacity: 0.6;\\n z-index: 3;\\n}\\n.vue-grid-item.vue-draggable-dragging {\\n transition:none;\\n z-index: 3;\\n}\\n.vue-grid-item.vue-grid-placeholder {\\n background: red;\\n opacity: 0.2;\\n transition-duration: 100ms;\\n z-index: 2;\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n -ms-user-select: none;\\n -o-user-select: none;\\n user-select: none;\\n}\\n.vue-grid-item > .vue-resizable-handle {\\n position: absolute;\\n width: 20px;\\n height: 20px;\\n bottom: 0;\\n right: 0;\\n background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pg08IS0tIEdlbmVyYXRvcjogQWRvYmUgRmlyZXdvcmtzIENTNiwgRXhwb3J0IFNWRyBFeHRlbnNpb24gYnkgQWFyb24gQmVhbGwgKGh0dHA6Ly9maXJld29ya3MuYWJlYWxsLmNvbSkgLiBWZXJzaW9uOiAwLjYuMSAgLS0+DTwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DTxzdmcgaWQ9IlVudGl0bGVkLVBhZ2UlMjAxIiB2aWV3Qm94PSIwIDAgNiA2IiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZmMDAiIHZlcnNpb249IjEuMSINCXhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQl4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjZweCIgaGVpZ2h0PSI2cHgiDT4NCTxnIG9wYWNpdHk9IjAuMzAyIj4NCQk8cGF0aCBkPSJNIDYgNiBMIDAgNiBMIDAgNC4yIEwgNCA0LjIgTCA0LjIgNC4yIEwgNC4yIDAgTCA2IDAgTCA2IDYgTCA2IDYgWiIgZmlsbD0iIzAwMDAwMCIvPg0JPC9nPg08L3N2Zz4=');\\n background-position: bottom right;\\n padding: 0 3px 3px 0;\\n background-repeat: no-repeat;\\n background-origin: content-box;\\n box-sizing: border-box;\\n cursor: se-resize;\\n}\\n.vue-grid-item > .vue-rtl-resizable-handle {\\n bottom: 0;\\n left: 0;\\n background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAuMDAwMDAwMDAwMDAwMDAyIiBoZWlnaHQ9IjEwLjAwMDAwMDAwMDAwMDAwMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDwhLS0gQ3JlYXRlZCB3aXRoIE1ldGhvZCBEcmF3IC0gaHR0cDovL2dpdGh1Yi5jb20vZHVvcGl4ZWwvTWV0aG9kLURyYXcvIC0tPgogPGc+CiAgPHRpdGxlPmJhY2tncm91bmQ8L3RpdGxlPgogIDxyZWN0IGZpbGw9Im5vbmUiIGlkPSJjYW52YXNfYmFja2dyb3VuZCIgaGVpZ2h0PSIxMiIgd2lkdGg9IjEyIiB5PSItMSIgeD0iLTEiLz4KICA8ZyBkaXNwbGF5PSJub25lIiBvdmVyZmxvdz0idmlzaWJsZSIgeT0iMCIgeD0iMCIgaGVpZ2h0PSIxMDAlIiB3aWR0aD0iMTAwJSIgaWQ9ImNhbnZhc0dyaWQiPgogICA8cmVjdCBmaWxsPSJ1cmwoI2dyaWRwYXR0ZXJuKSIgc3Ryb2tlLXdpZHRoPSIwIiB5PSIwIiB4PSIwIiBoZWlnaHQ9IjEwMCUiIHdpZHRoPSIxMDAlIi8+CiAgPC9nPgogPC9nPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxsaW5lIGNhbnZhcz0iI2ZmZmZmZiIgY2FudmFzLW9wYWNpdHk9IjEiIHN0cm9rZS1saW5lY2FwPSJ1bmRlZmluZWQiIHN0cm9rZS1saW5lam9pbj0idW5kZWZpbmVkIiBpZD0ic3ZnXzEiIHkyPSItNzAuMTc4NDA3IiB4Mj0iMTI0LjQ2NDE3NSIgeTE9Ii0zOC4zOTI3MzciIHgxPSIxNDQuODIxMjg5IiBzdHJva2Utd2lkdGg9IjEuNSIgc3Ryb2tlPSIjMDAwIiBmaWxsPSJub25lIi8+CiAgPGxpbmUgc3Ryb2tlPSIjNjY2NjY2IiBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z181IiB5Mj0iOS4xMDY5NTciIHgyPSIwLjk0NzI0NyIgeTE9Ii0wLjAxODEyOCIgeDE9IjAuOTQ3MjQ3IiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz4KICA8bGluZSBzdHJva2UtbGluZWNhcD0idW5kZWZpbmVkIiBzdHJva2UtbGluZWpvaW49InVuZGVmaW5lZCIgaWQ9InN2Z183IiB5Mj0iOSIgeDI9IjEwLjA3MzUyOSIgeTE9IjkiIHgxPSItMC42NTU2NCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM2NjY2NjYiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+);\\n background-position: bottom left;\\n padding-left: 3px;\\n background-repeat: no-repeat;\\n background-origin: content-box;\\n cursor: sw-resize;\\n right: auto;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/./src/GridItem.vue?37fa2adb\"],\"names\":[],\"mappings\":\";AAYA;IACA,2BAAA;IACA,sCAAA;IACA,uBAAA;CACA;AAEA;IACA,+BAAA;IACA,QAAA;IACA,YAAA;CACA;AAEA;IACA,WAAA;IACA,SAAA;CACA;AAEA;IACA,aAAA;IACA,WAAA;CACA;AAEA;IACA,gBAAA;IACA,WAAA;CACA;AAEA;IACA,gBAAA;IACA,aAAA;IACA,2BAAA;IACA,WAAA;IACA,0BAAA;IACA,uBAAA;IACA,sBAAA;IACA,qBAAA;IACA,kBAAA;CACA;AAEA;IACA,mBAAA;IACA,YAAA;IACA,aAAA;IACA,UAAA;IACA,SAAA;IACA,s3BAAA;IACA,kCAAA;IACA,qBAAA;IACA,6BAAA;IACA,+BAAA;IACA,uBAAA;IACA,kBAAA;CACA;AAEA;IACA,UAAA;IACA,QAAA;IACA,g+CAAA;IACA,iCAAA;IACA,kBAAA;IACA,6BAAA;IACA,+BAAA;IACA,kBAAA;IACA,YAAA;CACA\",\"file\":\"GridItem.vue\",\"sourcesContent\":[\"\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlP2I3OTAiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7O0FBR0E7QUFDQSwyQ0FBNEMsaUNBQWlDLDRDQUE0QyxnQ0FBZ0MsZ0NBQWdDLHFDQUFxQyxjQUFjLGtCQUFrQixHQUFHLDJDQUEyQyxpQkFBaUIsZUFBZSxHQUFHLDJCQUEyQixtQkFBbUIsaUJBQWlCLEdBQUcseUNBQXlDLHNCQUFzQixpQkFBaUIsR0FBRyx1Q0FBdUMsc0JBQXNCLG1CQUFtQixpQ0FBaUMsaUJBQWlCLGdDQUFnQyw2QkFBNkIsNEJBQTRCLDJCQUEyQix3QkFBd0IsR0FBRywwQ0FBMEMseUJBQXlCLGtCQUFrQixtQkFBbUIsZ0JBQWdCLGVBQWUsMENBQTBDLGsxQkFBazFCLHdDQUF3QywyQkFBMkIsbUNBQW1DLHFDQUFxQyw2QkFBNkIsd0JBQXdCLEdBQUcsOENBQThDLGdCQUFnQixjQUFjLHlDQUF5Qyw2N0NBQTY3Qyx1Q0FBdUMsd0JBQXdCLG1DQUFtQyxxQ0FBcUMsd0JBQXdCLGtCQUFrQixHQUFHLFVBQVUsK0VBQStFLEtBQUssV0FBVyxXQUFXLFdBQVcsS0FBSyxLQUFLLFdBQVcsVUFBVSxVQUFVLEtBQUssS0FBSyxVQUFVLFVBQVUsS0FBSyxLQUFLLFVBQVUsVUFBVSxLQUFLLEtBQUssV0FBVyxVQUFVLEtBQUssS0FBSyxXQUFXLFVBQVUsV0FBVyxVQUFVLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxLQUFLLEtBQUssV0FBVyxVQUFVLFVBQVUsVUFBVSxVQUFVLFlBQVksV0FBVyxXQUFXLFdBQVcsV0FBVyxXQUFXLFdBQVcsS0FBSyxLQUFLLFVBQVUsVUFBVSxZQUFZLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxVQUFVLHVJQUF1SSw0SkFBNEosK1NBQStTLHFDQUFxQyxnREFBZ0Qsd0NBQXdDLHNDQUFzQyx5Q0FBeUMsa0JBQWtCLHNCQUFzQixPQUFPLGlEQUFpRCxxQkFBcUIsbUJBQW1CLE9BQU8s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OEZBQThGLHlGQUF5Riw0RUFBNEUsMEZBQTBGLDRGQUE0RiwyQkFBMkIsT0FBTyxtRkFBbUYsMkJBQTJCLDRFQUE0RSw0RkFBNEYsc0ZBQXNGLCtDQUErQyxrREFBa0QsOENBQThDLGdDQUFnQyxpSUFBaUksMEZBQTBGLHVGQUF1RiwyQkFBMkIsT0FBTyx1RkFBdUYsMkJBQTJCLGlGQUFpRixxR0FBcUcsNklBQTZJLDRGQUE0RixzREFBc0QsZ0NBQWdDLG1CQUFtQix3RUFBd0UsK0VBQStFLG1CQUFtQixPQUFPLCtFQUErRSxtQkFBbUIsbUNBQW1DLGlDQUFpQywrREFBK0QsaUVBQWlFLG1CQUFtQiwrR0FBK0csa0VBQWtFLG1CQUFtQix1R0FBdUcsZUFBZSxvREFBb0QsdURBQXVELDJFQUEyRSxpQ0FBaUMsK1FBQStRLHNhQUFzYSxtQkFBbUIsT0FBTyxpQ0FBaUMsOFFBQThRLHNhQUFzYSxtQkFBbUIsaUNBQWlDLGVBQWUscUhBQXFILE9BQU8sNEVBQTRFLE9BQU8sNkVBQTZFLE9BQU8sMkpBQTJKLHVEQUF1RCxtWkFBbVosaUdBQWlHLGlHQUFpRyxzRUFBc0UsNEJBQTRCLE1BQU0sZUFBZSxrRkFBa0Ysd0dBQXdHLHdGQUF3RixrQ0FBa0MsZUFBZSw4SEFBOEgsT0FBTyxtREFBbUQsT0FBTyxrREFBa0QsT0FBTywwRUFBMEUsdURBQXVELG9QQUFvUCxvR0FBb0csaUdBQWlHLHNFQUFzRSwwQkFBMEIsTUFBTSxlQUFlLHNEQUFzRCw4Q0FBOEMsZ0VBQWdFLHlDQUF5QyxtQkFBbUIsZUFBZSxxQ0FBcUMscUNBQXFDLGVBQWUsV0FBVyxRQUFRLDBDQUEwQzs7QUFFbDZoQyIsImZpbGUiOiIxMi5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi52dWUtZ3JpZC1pdGVtIHtcXG4gICAgdHJhbnNpdGlvbjogYWxsIDIwMG1zIGVhc2U7XFxuICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IGxlZnQsIHRvcCwgcmlnaHQ7XFxuICAgIC8qIGFkZCByaWdodCBmb3IgcnRsICovXFxufVxcbi52dWUtZ3JpZC1pdGVtLmNzc1RyYW5zZm9ybXMge1xcbiAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiB0cmFuc2Zvcm07XFxuICAgIGxlZnQ6IDA7XFxuICAgIHJpZ2h0OiBhdXRvO1xcbn1cXG4udnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zLnJlbmRlci1ydGwge1xcbiAgICBsZWZ0OiBhdXRvO1xcbiAgICByaWdodDogMDtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0ucmVzaXppbmcge1xcbiAgICBvcGFjaXR5OiAwLjY7XFxuICAgIHotaW5kZXg6IDM7XFxufVxcbi52dWUtZ3JpZC1pdGVtLnZ1ZS1kcmFnZ2FibGUtZHJhZ2dpbmcge1xcbiAgICB0cmFuc2l0aW9uOm5vbmU7XFxuICAgIHotaW5kZXg6IDM7XFxufVxcbi52dWUtZ3JpZC1pdGVtLnZ1ZS1ncmlkLXBsYWNlaG9sZGVyIHtcXG4gICAgYmFja2dyb3VuZDogcmVkO1xcbiAgICBvcGFjaXR5OiAwLjI7XFxuICAgIHRyYW5zaXRpb24tZHVyYXRpb246IDEwMG1zO1xcbiAgICB6LWluZGV4OiAyO1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAgIC1vLXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJlc2l6YWJsZS1oYW5kbGUge1xcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICAgIHdpZHRoOiAyMHB4O1xcbiAgICBoZWlnaHQ6IDIwcHg7XFxuICAgIGJvdHRvbTogMDtcXG4gICAgcmlnaHQ6IDA7XFxuICAgIGJhY2tncm91bmQ6IHVybCgnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJ6ZEdGdVpHRnNiMjVsUFNKdWJ5SS9QZzA4SVMwdElFZGxibVZ5WVhSdmNqb2dRV1J2WW1VZ1JtbHlaWGR2Y210eklFTlROaXdnUlhod2IzSjBJRk5XUnlCRmVIUmxibk5wYjI0Z1lua2dRV0Z5YjI0Z1FtVmhiR3dnS0doMGRIQTZMeTltYVhKbGQyOXlhM011WVdKbFlXeHNMbU52YlNrZ0xpQldaWEp6YVc5dU9pQXdMall1TVNBZ0xTMCtEVHdoUkU5RFZGbFFSU0J6ZG1jZ1VGVkNURWxESUNJdEx5OVhNME12TDBSVVJDQlRWa2NnTVM0eEx5OUZUaUlnSW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTDBkeVlYQm9hV056TDFOV1J5OHhMakV2UkZSRUwzTjJaekV4TG1SMFpDSStEVHh6ZG1jZ2FXUTlJbFZ1ZEdsMGJHVmtMVkJoWjJVbE1qQXhJaUIyYVdWM1FtOTRQU0l3SURBZ05pQTJJaUJ6ZEhsc1pUMGlZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqb2pabVptWm1abU1EQWlJSFpsY25OcGIyNDlJakV1TVNJTkNYaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhodGJEcHpjR0ZqWlQwaWNISmxjMlZ5ZG1VaURRbDRQU0l3Y0hnaUlIazlJakJ3ZUNJZ2QybGtkR2c5SWpad2VDSWdhR1ZwWjJoMFBTSTJjSGdpRFQ0TkNUeG5JRzl3WVdOcGRIazlJakF1TXpBeUlqNE5DUWs4Y0dGMGFDQmtQU0pOSURZZ05pQk1JREFnTmlCTUlEQWdOQzR5SUV3Z05DQTBMaklnVENBMExqSWdOQzR5SUV3Z05DNHlJREFnVENBMklEQWdUQ0EySURZZ1RDQTJJRFlnV2lJZ1ptbHNiRDBpSXpBd01EQXdNQ0l2UGcwSlBDOW5QZzA4TDNOMlp6ND0nKTtcXG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIHJpZ2h0O1xcbiAgICBwYWRkaW5nOiAwIDNweCAzcHggMDtcXG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXG4gICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgICBjdXJzb3I6IHNlLXJlc2l6ZTtcXG59XFxuLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJ0bC1yZXNpemFibGUtaGFuZGxlIHtcXG4gICAgYm90dG9tOiAwO1xcbiAgICBsZWZ0OiAwO1xcbiAgICBiYWNrZ3JvdW5kOiB1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCM2FXUjBhRDBpTVRBdU1EQXdNREF3TURBd01EQXdNREF5SWlCb1pXbG5hSFE5SWpFd0xqQXdNREF3TURBd01EQXdNREF3TWlJZ2VHMXNibk05SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpJd01EQXZjM1puSWo0S0lEd2hMUzBnUTNKbFlYUmxaQ0IzYVhSb0lFMWxkR2h2WkNCRWNtRjNJQzBnYUhSMGNEb3ZMMmRwZEdoMVlpNWpiMjB2WkhWdmNHbDRaV3d2VFdWMGFHOWtMVVJ5WVhjdklDMHRQZ29nUEdjK0NpQWdQSFJwZEd4bFBtSmhZMnRuY205MWJtUThMM1JwZEd4bFBnb2dJRHh5WldOMElHWnBiR3c5SW01dmJtVWlJR2xrUFNKallXNTJZWE5mWW1GamEyZHliM1Z1WkNJZ2FHVnBaMmgwUFNJeE1pSWdkMmxrZEdnOUlqRXlJaUI1UFNJdE1TSWdlRDBpTFRFaUx6NEtJQ0E4WnlCa2FYTndiR0Y1UFNKdWIyNWxJaUJ2ZG1WeVpteHZkejBpZG1semFXSnNaU0lnZVQwaU1DSWdlRDBpTUNJZ2FHVnBaMmgwUFNJeE1EQWxJaUIzYVdSMGFEMGlNVEF3SlNJZ2FXUTlJbU5oYm5aaGMwZHlhV1FpUGdvZ0lDQThjbVZqZENCbWFXeHNQU0oxY213b0kyZHlhV1J3WVhSMFpYSnVLU0lnYzNSeWIydGxMWGRwWkhSb1BTSXdJaUI1UFNJd0lpQjRQU0l3SWlCb1pXbG5hSFE5SWpFd01DVWlJSGRwWkhSb1BTSXhNREFsSWk4K0NpQWdQQzluUGdvZ1BDOW5QZ29nUEdjK0NpQWdQSFJwZEd4bFBreGhlV1Z5SURFOEwzUnBkR3hsUGdvZ0lEeHNhVzVsSUdOaGJuWmhjejBpSTJabVptWm1aaUlnWTJGdWRtRnpMVzl3WVdOcGRIazlJakVpSUhOMGNtOXJaUzFzYVc1bFkyRndQU0oxYm1SbFptbHVaV1FpSUhOMGNtOXJaUzFzYVc1bGFtOXBiajBpZFc1a1pXWnBibVZrSWlCcFpEMGljM1puWHpFaUlIa3lQU0l0TnpBdU1UYzROREEzSWlCNE1qMGlNVEkwTGpRMk5ERTNOU0lnZVRFOUlpMHpPQzR6T1RJM016Y2lJSGd4UFNJeE5EUXVPREl4TWpnNUlpQnpkSEp2YTJVdGQybGtkR2c5SWpFdU5TSWdjM1J5YjJ0bFBTSWpNREF3SWlCbWFXeHNQU0p1YjI1bElpOCtDaUFnUEd4cGJtVWdjM1J5YjJ0bFBTSWpOalkyTmpZMklpQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODFJaUI1TWowaU9TNHhNRFk1TlRjaUlIZ3lQU0l3TGprME56STBOeUlnZVRFOUlpMHdMakF4T0RFeU9DSWdlREU5SWpBdU9UUTNNalEzSWlCemRISnZhMlV0ZDJsa2RHZzlJaklpSUdacGJHdzlJbTV2Ym1VaUx6NEtJQ0E4YkdsdVpTQnpkSEp2YTJVdGJHbHVaV05oY0QwaWRXNWtaV1pwYm1Wa0lpQnpkSEp2YTJVdGJHbHVaV3B2YVc0OUluVnVaR1ZtYVc1bFpDSWdhV1E5SW5OMloxODNJaUI1TWowaU9TSWdlREk5SWpFd0xqQTNNelV5T1NJZ2VURTlJamtpSUhneFBTSXRNQzQyTlRVMk5DSWdjM1J5YjJ0bExYZHBaSFJvUFNJeUlpQnpkSEp2YTJVOUlpTTJOalkyTmpZaUlHWnBiR3c5SW01dmJtVWlMejRLSUR3dlp6NEtQQzl6ZG1jKyk7XFxuICAgIGJhY2tncm91bmQtcG9zaXRpb246IGJvdHRvbSBsZWZ0O1xcbiAgICBwYWRkaW5nLWxlZnQ6IDNweDtcXG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcXG4gICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcbiAgICBjdXJzb3I6IHN3LXJlc2l6ZTtcXG4gICAgcmlnaHQ6IGF1dG87XFxufVxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXCIvLi9zcmMvR3JpZEl0ZW0udnVlPzM3ZmEyYWRiXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFZQTtJQUNBLDJCQUFBO0lBQ0Esc0NBQUE7SUFDQSx1QkFBQTtDQUNBO0FBRUE7SUFDQSwrQkFBQTtJQUNBLFFBQUE7SUFDQSxZQUFBO0NBQ0E7QUFFQTtJQUNBLFdBQUE7SUFDQSxTQUFBO0NBQ0E7QUFFQTtJQUNBLGFBQUE7SUFDQSxXQUFBO0NBQ0E7QUFFQTtJQUNBLGdCQUFBO0lBQ0EsV0FBQTtDQUNBO0FBRUE7SUFDQSxnQkFBQTtJQUNBLGFBQUE7SUFDQSwyQkFBQTtJQUNBLFdBQUE7SUFDQSwwQkFBQTtJQUNBLHVCQUFBO0lBQ0Esc0JBQUE7SUFDQSxxQkFBQTtJQUNBLGtCQUFBO0NBQ0E7QUFFQTtJQUNBLG1CQUFBO0lBQ0EsWUFBQTtJQUNBLGFBQUE7SUFDQSxVQUFBO0lBQ0EsU0FBQTtJQUNBLHMzQkFBQTtJQUNBLGtDQUFBO0lBQ0EscUJBQUE7SUFDQSw2QkFBQTtJQUNBLCtCQUFBO0lBQ0EsdUJBQUE7SUFDQSxrQkFBQTtDQUNBO0FBRUE7SUFDQSxVQUFBO0lBQ0EsUUFBQTtJQUNBLGcrQ0FBQTtJQUNBLGlDQUFBO0lBQ0Esa0JBQUE7SUFDQSw2QkFBQTtJQUNBLCtCQUFBO0lBQ0Esa0JBQUE7SUFDQSxZQUFBO0NBQ0FcIixcImZpbGVcIjpcIkdyaWRJdGVtLnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8dGVtcGxhdGU+XFxuICAgIDxkaXYgcmVmPVxcXCJpdGVtXFxcIlxcbiAgICAgICAgIGNsYXNzPVxcXCJ2dWUtZ3JpZC1pdGVtXFxcIlxcbiAgICAgICAgIDpjbGFzcz1cXFwieyAndnVlLXJlc2l6YWJsZScgOiByZXNpemFibGUsICdyZXNpemluZycgOiBpc1Jlc2l6aW5nLCAndnVlLWRyYWdnYWJsZS1kcmFnZ2luZycgOiBpc0RyYWdnaW5nLCAnY3NzVHJhbnNmb3JtcycgOiB1c2VDc3NUcmFuc2Zvcm1zLCAncmVuZGVyLXJ0bCcgOiByZW5kZXJSdGwgfVxcXCJcXG4gICAgICAgICA6c3R5bGU9XFxcInN0eWxlXFxcIlxcbiAgICA+XFxuICAgICAgICA8c2xvdD48L3Nsb3Q+XFxuICAgICAgICA8c3BhbiB2LWlmPVxcXCJyZXNpemFibGVcXFwiIHJlZj1cXFwiaGFuZGxlXFxcIiA6Y2xhc3M9XFxcInJlc2l6YWJsZUhhbmRsZUNsYXNzXFxcIj48L3NwYW4+XFxuICAgICAgICA8IS0tPHNwYW4gdi1pZj1cXFwiZHJhZ2dhYmxlXFxcIiByZWY9XFxcImRyYWdIYW5kbGVcXFwiIGNsYXNzPVxcXCJ2dWUtZHJhZ2dhYmxlLWhhbmRsZVxcXCI+PC9zcGFuPi0tPlxcbiAgICA8L2Rpdj5cXG48L3RlbXBsYXRlPlxcbjxzdHlsZT5cXG4gICAgLnZ1ZS1ncmlkLWl0ZW0ge1xcbiAgICAgICAgdHJhbnNpdGlvbjogYWxsIDIwMG1zIGVhc2U7XFxuICAgICAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiBsZWZ0LCB0b3AsIHJpZ2h0O1xcbiAgICAgICAgLyogYWRkIHJpZ2h0IGZvciBydGwgKi9cXG4gICAgfVxcblxcbiAgICAudnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zIHtcXG4gICAgICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IHRyYW5zZm9ybTtcXG4gICAgICAgIGxlZnQ6IDA7XFxuICAgICAgICByaWdodDogYXV0bztcXG4gICAgfVxcblxcbiAgICAudnVlLWdyaWQtaXRlbS5jc3NUcmFuc2Zvcm1zLnJlbmRlci1ydGwge1xcbiAgICAgICAgbGVmdDogYXV0bztcXG4gICAgICAgIHJpZ2h0OiAwO1xcbiAgICB9XFxuXFxuICAgIC52dWUtZ3JpZC1pdGVtLnJlc2l6aW5nIHtcXG4gICAgICAgIG9wYWNpdHk6IDAuNjtcXG4gICAgICAgIHotaW5kZXg6IDM7XFxuICAgIH1cXG5cXG4gICAgLnZ1ZS1ncmlkLWl0ZW0udnVlLWRyYWdnYWJsZS1kcmFnZ2luZyB7XFxuICAgICAgICB0cmFuc2l0aW9uOm5vbmU7XFxuICAgICAgICB6LWluZGV4OiAzO1xcbiAgICB9XFxuXFxuICAgIC52dWUtZ3JpZC1pdGVtLnZ1ZS1ncmlkLXBsYWNlaG9sZGVyIHtcXG4gICAgICAgIGJhY2tncm91bmQ6IHJlZDtcXG4gICAgICAgIG9wYWNpdHk6IDAuMjtcXG4gICAgICAgIHRyYW5zaXRpb24tZHVyYXRpb246IDEwMG1zO1xcbiAgICAgICAgei1pbmRleDogMjtcXG4gICAgICAgIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAgICAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAgICAgLW1zLXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAgICAgLW8tdXNlci1zZWxlY3Q6IG5vbmU7XFxuICAgICAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG4gICAgfVxcblxcbiAgICAudnVlLWdyaWQtaXRlbSA+IC52dWUtcmVzaXphYmxlLWhhbmRsZSB7XFxuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICAgICAgICB3aWR0aDogMjBweDtcXG4gICAgICAgIGhlaWdodDogMjBweDtcXG4gICAgICAgIGJvdHRvbTogMDtcXG4gICAgICAgIHJpZ2h0OiAwO1xcbiAgICAgICAgYmFja2dyb3VuZDogdXJsKCdkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQnpkR0Z1WkdGc2IyNWxQU0p1YnlJL1BnMDhJUzB0SUVkbGJtVnlZWFJ2Y2pvZ1FXUnZZbVVnUm1seVpYZHZjbXR6SUVOVE5pd2dSWGh3YjNKMElGTldSeUJGZUhSbGJuTnBiMjRnWW5rZ1FXRnliMjRnUW1WaGJHd2dLR2gwZEhBNkx5OW1hWEpsZDI5eWEzTXVZV0psWVd4c0xtTnZiU2tnTGlCV1pYSnphVzl1T2lBd0xqWXVNU0FnTFMwK0RUd2hSRTlEVkZsUVJTQnpkbWNnVUZWQ1RFbERJQ0l0THk5WE0wTXZMMFJVUkNCVFZrY2dNUzR4THk5RlRpSWdJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MMGR5WVhCb2FXTnpMMU5XUnk4eExqRXZSRlJFTDNOMlp6RXhMbVIwWkNJK0RUeHpkbWNnYVdROUlsVnVkR2wwYkdWa0xWQmhaMlVsTWpBeElpQjJhV1YzUW05NFBTSXdJREFnTmlBMklpQnpkSGxzWlQwaVltRmphMmR5YjNWdVpDMWpiMnh2Y2pvalptWm1abVptTURBaUlIWmxjbk5wYjI0OUlqRXVNU0lOQ1hodGJHNXpQU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh5TURBd0wzTjJaeUlnZUcxc2JuTTZlR3hwYm1zOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6RTVPVGt2ZUd4cGJtc2lJSGh0YkRwemNHRmpaVDBpY0hKbGMyVnlkbVVpRFFsNFBTSXdjSGdpSUhrOUlqQndlQ0lnZDJsa2RHZzlJalp3ZUNJZ2FHVnBaMmgwUFNJMmNIZ2lEVDROQ1R4bklHOXdZV05wZEhrOUlqQXVNekF5SWo0TkNRazhjR0YwYUNCa1BTSk5JRFlnTmlCTUlEQWdOaUJNSURBZ05DNHlJRXdnTkNBMExqSWdUQ0EwTGpJZ05DNHlJRXdnTkM0eUlEQWdUQ0EySURBZ1RDQTJJRFlnVENBMklEWWdXaUlnWm1sc2JEMGlJekF3TURBd01DSXZQZzBKUEM5blBnMDhMM04yWno0PScpO1xcbiAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIHJpZ2h0O1xcbiAgICAgICAgcGFkZGluZzogMCAzcHggM3B4IDA7XFxuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xcbiAgICAgICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gICAgICAgIGN1cnNvcjogc2UtcmVzaXplO1xcbiAgICB9XFxuXFxuICAgIC52dWUtZ3JpZC1pdGVtID4gLnZ1ZS1ydGwtcmVzaXphYmxlLWhhbmRsZSB7XFxuICAgICAgICBib3R0b206IDA7XFxuICAgICAgICBsZWZ0OiAwO1xcbiAgICAgICAgYmFja2dyb3VuZDogdXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjNhV1IwYUQwaU1UQXVNREF3TURBd01EQXdNREF3TURBeUlpQm9aV2xuYUhROUlqRXdMakF3TURBd01EQXdNREF3TURBd01pSWdlRzFzYm5NOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6SXdNREF2YzNabklqNEtJRHdoTFMwZ1EzSmxZWFJsWkNCM2FYUm9JRTFsZEdodlpDQkVjbUYzSUMwZ2FIUjBjRG92TDJkcGRHaDFZaTVqYjIwdlpIVnZjR2w0Wld3dlRXVjBhRzlrTFVSeVlYY3ZJQzB0UGdvZ1BHYytDaUFnUEhScGRHeGxQbUpoWTJ0bmNtOTFibVE4TDNScGRHeGxQZ29nSUR4eVpXTjBJR1pwYkd3OUltNXZibVVpSUdsa1BTSmpZVzUyWVhOZlltRmphMmR5YjNWdVpDSWdhR1ZwWjJoMFBTSXhNaUlnZDJsa2RHZzlJakV5SWlCNVBTSXRNU0lnZUQwaUxURWlMejRLSUNBOFp5QmthWE53YkdGNVBTSnViMjVsSWlCdmRtVnlabXh2ZHowaWRtbHphV0pzWlNJZ2VUMGlNQ0lnZUQwaU1DSWdhR1ZwWjJoMFBTSXhNREFsSWlCM2FXUjBhRDBpTVRBd0pTSWdhV1E5SW1OaGJuWmhjMGR5YVdRaVBnb2dJQ0E4Y21WamRDQm1hV3hzUFNKMWNtd29JMmR5YVdSd1lYUjBaWEp1S1NJZ2MzUnliMnRsTFhkcFpIUm9QU0l3SWlCNVBTSXdJaUI0UFNJd0lpQm9aV2xuYUhROUlqRXdNQ1VpSUhkcFpIUm9QU0l4TURBbElpOCtDaUFnUEM5blBnb2dQQzluUGdvZ1BHYytDaUFnUEhScGRHeGxQa3hoZVdWeUlERThMM1JwZEd4bFBnb2dJRHhzYVc1bElHTmhiblpoY3owaUkyWm1abVptWmlJZ1kyRnVkbUZ6TFc5d1lXTnBkSGs5SWpFaUlITjBjbTlyWlMxc2FXNWxZMkZ3UFNKMWJtUmxabWx1WldRaUlITjBjbTlyWlMxc2FXNWxhbTlwYmowaWRXNWtaV1pwYm1Wa0lpQnBaRDBpYzNablh6RWlJSGt5UFNJdE56QXVNVGM0TkRBM0lpQjRNajBpTVRJMExqUTJOREUzTlNJZ2VURTlJaTB6T0M0ek9USTNNemNpSUhneFBTSXhORFF1T0RJeE1qZzVJaUJ6ZEhKdmEyVXRkMmxrZEdnOUlqRXVOU0lnYzNSeWIydGxQU0lqTURBd0lpQm1hV3hzUFNKdWIyNWxJaTgrQ2lBZ1BHeHBibVVnYzNSeWIydGxQU0lqTmpZMk5qWTJJaUJ6ZEhKdmEyVXRiR2x1WldOaGNEMGlkVzVrWldacGJtVmtJaUJ6ZEhKdmEyVXRiR2x1WldwdmFXNDlJblZ1WkdWbWFXNWxaQ0lnYVdROUluTjJaMTgxSWlCNU1qMGlPUzR4TURZNU5UY2lJSGd5UFNJd0xqazBOekkwTnlJZ2VURTlJaTB3TGpBeE9ERXlPQ0lnZURFOUlqQXVPVFEzTWpRM0lpQnpkSEp2YTJVdGQybGtkR2c5SWpJaUlHWnBiR3c5SW01dmJtVWlMejRLSUNBOGJHbHVaU0J6ZEhKdmEyVXRiR2x1WldOaGNEMGlkVzVrWldacGJtVmtJaUJ6ZEhKdmEyVXRiR2x1WldwdmFXNDlJblZ1WkdWbWFXNWxaQ0lnYVdROUluTjJaMTgzSWlCNU1qMGlPU0lnZURJOUlqRXdMakEzTXpVeU9TSWdlVEU5SWpraUlIZ3hQU0l0TUM0Mk5UVTJOQ0lnYzNSeWIydGxMWGRwWkhSb1BTSXlJaUJ6ZEhKdmEyVTlJaU0yTmpZMk5qWWlJR1pwYkd3OUltNXZibVVpTHo0S0lEd3ZaejRLUEM5emRtYyspO1xcbiAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIGxlZnQ7XFxuICAgICAgICBwYWRkaW5nLWxlZnQ6IDNweDtcXG4gICAgICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XFxuICAgICAgICBiYWNrZ3JvdW5kLW9yaWdpbjogY29udGVudC1ib3g7XFxuICAgICAgICBjdXJzb3I6IHN3LXJlc2l6ZTtcXG4gICAgICAgIHJpZ2h0OiBhdXRvO1xcbiAgICB9XFxuPC9zdHlsZT5cXG48c2NyaXB0PlxcbiAgICBpbXBvcnQge3NldFRvcExlZnQsIHNldFRvcFJpZ2h0LCBzZXRUcmFuc2Zvcm1SdGwsIHNldFRyYW5zZm9ybSwgY3JlYXRlTWFya3VwLCBnZXRMYXlvdXRJdGVtfSBmcm9tICcuL3V0aWxzJztcXG4gICAgaW1wb3J0IHtnZXRDb250cm9sUG9zaXRpb24sIG9mZnNldFhZRnJvbVBhcmVudE9mLCBjcmVhdGVDb3JlRGF0YX0gZnJvbSAnLi9kcmFnZ2FibGVVdGlscyc7XFxuICAgIC8vICAgIHZhciBldmVudEJ1cyA9IHJlcXVpcmUoJy4vZXZlbnRCdXMnKTtcXG5cXG4gICAgdmFyIGludGVyYWN0ID0gcmVxdWlyZShcXFwiaW50ZXJhY3Rqc1xcXCIpO1xcblxcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxuICAgICAgICBuYW1lOiBcXFwiR3JpZEl0ZW1cXFwiLFxcbiAgICAgICAgcHJvcHM6IHtcXG4gICAgICAgICAgICAvKmNvbHM6IHtcXG4gICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcbiAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxcbiAgICAgICAgICAgICB9LCovXFxuICAgICAgICAgICAgLypjb250YWluZXJXaWR0aDoge1xcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxuXFxuICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgIHJvd0hlaWdodDoge1xcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxuICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgIG1hcmdpbjoge1xcbiAgICAgICAgICAgICB0eXBlOiBBcnJheSxcXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXG4gICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICAgbWF4Um93czoge1xcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxuICAgICAgICAgICAgIH0sKi9cXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IG51bGxcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiB7XFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogbnVsbFxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgLyp1c2VDc3NUcmFuc2Zvcm1zOiB7XFxuICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxuICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgIHN0YXRpYzoge1xcbiAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcbiAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxuICAgICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlXFxuICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgbWluSDoge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgbWluVzoge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgbWF4SDoge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIG1heFc6IHtcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IEluZmluaXR5XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICB4OiB7XFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIHk6IHtcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgdzoge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBoOiB7XFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIGk6IHtcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIGRyYWdJZ25vcmVGcm9tOiB7XFxuICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAnYSwgYnV0dG9uJ1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgZHJhZ0FsbG93RnJvbToge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBTdHJpbmcsXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogbnVsbFxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgcmVzaXplSWdub3JlRnJvbToge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBTdHJpbmcsXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogJ2EsIGJ1dHRvbidcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgfSxcXG4gICAgICAgIGluamVjdDogW1xcXCJldmVudEJ1c1xcXCJdLFxcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgIHJldHVybiB7XFxuICAgICAgICAgICAgICAgIGNvbHM6IDEsXFxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiAxMDAsXFxuICAgICAgICAgICAgICAgIHJvd0hlaWdodDogMzAsXFxuICAgICAgICAgICAgICAgIG1hcmdpbjogWzEwLCAxMF0sXFxuICAgICAgICAgICAgICAgIG1heFJvd3M6IEluZmluaXR5LFxcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGU6IG51bGwsXFxuICAgICAgICAgICAgICAgIHJlc2l6YWJsZTogbnVsbCxcXG4gICAgICAgICAgICAgICAgdXNlQ3NzVHJhbnNmb3JtczogdHJ1ZSxcXG5cXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogZmFsc2UsXFxuICAgICAgICAgICAgICAgIGRyYWdnaW5nOiBudWxsLFxcbiAgICAgICAgICAgICAgICBpc1Jlc2l6aW5nOiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgcmVzaXppbmc6IG51bGwsXFxuICAgICAgICAgICAgICAgIGxhc3RYOiBOYU4sXFxuICAgICAgICAgICAgICAgIGxhc3RZOiBOYU4sXFxuICAgICAgICAgICAgICAgIGxhc3RXOiBOYU4sXFxuICAgICAgICAgICAgICAgIGxhc3RIOiBOYU4sXFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7fSxcXG4gICAgICAgICAgICAgICAgcnRsOiBmYWxzZSxcXG5cXG4gICAgICAgICAgICAgICAgZHJhZ0V2ZW50U2V0OiBmYWxzZSxcXG4gICAgICAgICAgICAgICAgcmVzaXplRXZlbnRTZXQ6IGZhbHNlLFxcblxcbiAgICAgICAgICAgICAgICBwcmV2aW91c1c6IG51bGwsXFxuICAgICAgICAgICAgICAgIHByZXZpb3VzSDogbnVsbCxcXG4gICAgICAgICAgICAgICAgcHJldmlvdXNYOiBudWxsLFxcbiAgICAgICAgICAgICAgICBwcmV2aW91c1k6IG51bGwsXFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfSxcXG4gICAgICAgIGNyZWF0ZWQgKCkge1xcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcXG5cXG4gICAgICAgICAgICAvLyBBY2Nlc3NpYmxlIHJlZmVybmNlcyBvZiBmdW5jdGlvbnMgZm9yIHJlbW92aW5nIGluIGJlZm9yZURlc3Ryb3lcXG4gICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlciA9IGZ1bmN0aW9uICh3aWR0aCkge1xcbiAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoKHdpZHRoKTtcXG4gICAgICAgICAgICB9O1xcblxcbiAgICAgICAgICAgIHNlbGYuY29tcGFjdEhhbmRsZXIgPSBmdW5jdGlvbiAobGF5b3V0KSB7XFxuICAgICAgICAgICAgICAgIHNlbGYuY29tcGFjdChsYXlvdXQpO1xcbiAgICAgICAgICAgIH07XFxuXFxuICAgICAgICAgICAgc2VsZi5zZXREcmFnZ2FibGVIYW5kbGVyID0gZnVuY3Rpb24gKGlzRHJhZ2dhYmxlKSB7XFxuICAgICAgICAgICAgICAgIGlmIChzZWxmLmlzRHJhZ2dhYmxlID09PSBudWxsKSB7XFxuICAgICAgICAgICAgICAgICAgICBzZWxmLmRyYWdnYWJsZSA9IGlzRHJhZ2dhYmxlO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfTtcXG5cXG4gICAgICAgICAgICBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIgPSBmdW5jdGlvbiAoaXNSZXNpemFibGUpIHtcXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuaXNSZXNpemFibGUgPT09IG51bGwpIHtcXG4gICAgICAgICAgICAgICAgICAgIHNlbGYucmVzaXphYmxlID0gaXNSZXNpemFibGU7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICB9O1xcblxcbiAgICAgICAgICAgIHNlbGYuc2V0Um93SGVpZ2h0SGFuZGxlciA9IGZ1bmN0aW9uIChyb3dIZWlnaHQpIHtcXG4gICAgICAgICAgICAgICAgc2VsZi5yb3dIZWlnaHQgPSByb3dIZWlnaHQ7XFxuICAgICAgICAgICAgfTtcXG5cXG4gICAgICAgICAgICBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIgPSAoZGlyZWN0aW9uKSA9PiB7XFxuICAgICAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSAoZG9jdW1lbnQuZGlyICE9PSB1bmRlZmluZWQpID9cXG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmRpciA6XFxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcXFwiaHRtbFxcXCIpWzBdLmdldEF0dHJpYnV0ZShcXFwiZGlyXFxcIik7XFxuICAgICAgICAgICAgICAgIHRoaXMucnRsID0gKGRpcmVjdGlvbiA9PT0gXFxcInJ0bFxcXCIpO1xcbiAgICAgICAgICAgICAgICB0aGlzLmNvbXBhY3QoKTtcXG4gICAgICAgICAgICB9O1xcblxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCd1cGRhdGVXaWR0aCcsIHNlbGYudXBkYXRlV2lkdGhIYW5kbGVyKTtcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbignY29tcGFjdCcsIHNlbGYuY29tcGFjdEhhbmRsZXIpO1xcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXREcmFnZ2FibGUnLCBzZWxmLnNldERyYWdnYWJsZUhhbmRsZXIpO1xcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXRSZXNpemFibGUnLCBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIpO1xcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXRSb3dIZWlnaHQnLCBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIpO1xcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdkaXJlY3Rpb25jaGFuZ2UnLCBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIpO1xcblxcbiAgICAgICAgICAgIC8qdGhpcy5ldmVudEJ1cy4kb24oJ3NldENvbE51bScsIGZ1bmN0aW9uKGNvbE51bSkge1xcbiAgICAgICAgICAgICBzZWxmLmNvbHMgPSBjb2xOdW07XFxuICAgICAgICAgICAgIH0pOyovXFxuICAgICAgICAgICAgdmFyIGRpcmVjdGlvbiA9IChkb2N1bWVudC5kaXIgIT09IHVuZGVmaW5lZCkgP1xcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5kaXIgOlxcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcXFwiaHRtbFxcXCIpWzBdLmdldEF0dHJpYnV0ZShcXFwiZGlyXFxcIik7XFxuICAgICAgICAgICAgdGhpcy5ydGwgPSAoZGlyZWN0aW9uID09PSBcXFwicnRsXFxcIik7XFxuICAgICAgICB9LFxcbiAgICAgICAgYmVmb3JlRGVzdHJveTogZnVuY3Rpb24oKXtcXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxuICAgICAgICAgICAgLy9SZW1vdmUgbGlzdGVuZXJzXFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCd1cGRhdGVXaWR0aCcsIHNlbGYudXBkYXRlV2lkdGhIYW5kbGVyKTtcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2NvbXBhY3QnLCBzZWxmLmNvbXBhY3RIYW5kbGVyKTtcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ3NldERyYWdnYWJsZScsIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlcik7XFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCdzZXRSZXNpemFibGUnLCBzZWxmLnNldFJlc2l6YWJsZUhhbmRsZXIpO1xcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignc2V0Um93SGVpZ2h0Jywgc2VsZi5zZXRSb3dIZWlnaHRIYW5kbGVyKTtcXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2RpcmVjdGlvbmNoYW5nZScsIHNlbGYuZGlyZWN0aW9uY2hhbmdlSGFuZGxlcik7XFxuICAgICAgICB9LFxcbiAgICAgICAgbW91bnRlZDogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgIHRoaXMuY29scyA9IHRoaXMuJHBhcmVudC5jb2xOdW07XFxuICAgICAgICAgICAgdGhpcy5yb3dIZWlnaHQgPSB0aGlzLiRwYXJlbnQucm93SGVpZ2h0O1xcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSB0aGlzLiRwYXJlbnQud2lkdGggIT09IG51bGwgPyB0aGlzLiRwYXJlbnQud2lkdGggOiAxMDA7XFxuICAgICAgICAgICAgdGhpcy5tYXJnaW4gPSB0aGlzLiRwYXJlbnQubWFyZ2luICE9PSB1bmRlZmluZWQgPyB0aGlzLiRwYXJlbnQubWFyZ2luIDogWzEwLCAxMF07XFxuICAgICAgICAgICAgdGhpcy5tYXhSb3dzID0gdGhpcy4kcGFyZW50Lm1heFJvd3M7XFxuICAgICAgICAgICAgaWYgKHRoaXMuaXNEcmFnZ2FibGUgPT09IG51bGwpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLiRwYXJlbnQuaXNEcmFnZ2FibGU7XFxuICAgICAgICAgICAgfSBlbHNlIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLmlzRHJhZ2dhYmxlO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBpZiAodGhpcy5pc1Jlc2l6YWJsZSA9PT0gbnVsbCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHRoaXMuJHBhcmVudC5pc1Jlc2l6YWJsZTtcXG4gICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHRoaXMuaXNSZXNpemFibGU7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIHRoaXMudXNlQ3NzVHJhbnNmb3JtcyA9IHRoaXMuJHBhcmVudC51c2VDc3NUcmFuc2Zvcm1zO1xcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXG4gICAgICAgIH0sXFxuICAgICAgICB3YXRjaDoge1xcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dhYmxlID0gdGhpcy5pc0RyYWdnYWJsZTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIGRyYWdnYWJsZTogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmludGVyYWN0T2JqID09PSBudWxsIHx8IHRoaXMuaW50ZXJhY3RPYmogPT09IHVuZGVmaW5lZCkge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iaiA9IGludGVyYWN0KHRoaXMuJHJlZnMuaXRlbSk7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ2dhYmxlKSB7XFxuICAgICAgICAgICAgICAgICAgICB2YXIgb3B0cyA9IHtcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVGcm9tOiB0aGlzLmRyYWdJZ25vcmVGcm9tLFxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93RnJvbTogdGhpcy5kcmFnQWxsb3dGcm9tXFxuICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLmRyYWdnYWJsZShvcHRzKTtcXG4gICAgICAgICAgICAgICAgICAgIC8qdGhpcy5pbnRlcmFjdE9iai5kcmFnZ2FibGUoe2FsbG93RnJvbTogJy52dWUtZHJhZ2dhYmxlLWhhbmRsZSd9KTsqL1xcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRyYWdFdmVudFNldCkge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0V2ZW50U2V0ID0gdHJ1ZTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLm9uKCdkcmFnc3RhcnQgZHJhZ21vdmUgZHJhZ2VuZCcsIGZ1bmN0aW9uIChldmVudCkge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmhhbmRsZURyYWcoZXZlbnQpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5kcmFnZ2FibGUoe1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXFxuICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IGZ1bmN0aW9uICgpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemFibGUgPSB0aGlzLmlzUmVzaXphYmxlO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgcmVzaXphYmxlOiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJhY3RPYmogPT09IG51bGwgfHwgdGhpcy5pbnRlcmFjdE9iaiA9PT0gdW5kZWZpbmVkKSB7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqID0gaW50ZXJhY3QodGhpcy4kcmVmcy5pdGVtKTtcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZXNpemFibGUpIHtcXG4gICAgICAgICAgICAgICAgICAgIHZhciBvcHRzID0ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IGZhbHNlLFxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VzOiB7bGVmdDogZmFsc2UsIHJpZ2h0OiB0cnVlLCBib3R0b206IHRydWUsIHRvcDogZmFsc2V9LFxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUZyb206IHRoaXMucmVzaXplSWdub3JlRnJvbVxcbiAgICAgICAgICAgICAgICAgICAgfTtcXG4gICAgICAgICAgICAgICAgICAgIFxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5yZXNpemFibGUob3B0cyk7XFxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMucmVzaXplRXZlbnRTZXQpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZUV2ZW50U2V0ID0gdHJ1ZTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbigncmVzaXplc3RhcnQgcmVzaXplbW92ZSByZXNpemVlbmQnLCBmdW5jdGlvbiAoZXZlbnQpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaGFuZGxlUmVzaXplKGV2ZW50KTtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLnJlc2l6YWJsZSh7XFxuICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcXG4gICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgY29sczogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBjb250YWluZXJXaWR0aDogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICB4OiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIHk6IGZ1bmN0aW9uICgpIHtcXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgaDogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICB3OiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIHJlbmRlclJ0bDogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfSxcXG4gICAgICAgIGNvbXB1dGVkOiB7XFxuICAgICAgICAgICAgcmVuZGVyUnRsKCkge1xcbiAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuJHBhcmVudC5pc01pcnJvcmVkKSA/ICF0aGlzLnJ0bCA6IHRoaXMucnRsO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgcmVzaXphYmxlSGFuZGxlQ2xhc3MoKSB7XFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd2dWUtcmVzaXphYmxlLWhhbmRsZSB2dWUtcnRsLXJlc2l6YWJsZS1oYW5kbGUnO1xcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd2dWUtcmVzaXphYmxlLWhhbmRsZSc7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICB9XFxuICAgICAgICB9LFxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIGNyZWF0ZVN0eWxlOiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggKyB0aGlzLncgPiB0aGlzLmNvbHMpIHtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMueCA9IDA7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLncgPSB0aGlzLmNvbHM7XFxuICAgICAgICAgICAgICAgIH1cXG5cXG4gICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxuXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRHJhZ2dpbmcpIHtcXG4gICAgICAgICAgICAgICAgICAgIHBvcy50b3AgPSB0aGlzLmRyYWdnaW5nLnRvcDtcXG4vLyAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XFxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3MucmlnaHQgPSB0aGlzLmRyYWdnaW5nLmxlZnQ7XFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcy5sZWZ0ID0gdGhpcy5kcmFnZ2luZy5sZWZ0O1xcbiAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUmVzaXppbmcpIHtcXG4gICAgICAgICAgICAgICAgICAgIHBvcy53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGg7XFxuICAgICAgICAgICAgICAgICAgICBwb3MuaGVpZ2h0ID0gdGhpcy5yZXNpemluZy5oZWlnaHQ7XFxuICAgICAgICAgICAgICAgIH1cXG5cXG4gICAgICAgICAgICAgICAgbGV0IHN0eWxlO1xcbiAgICAgICAgICAgICAgICAvLyBDU1MgVHJhbnNmb3JtcyBzdXBwb3J0IChkZWZhdWx0KVxcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51c2VDc3NUcmFuc2Zvcm1zKSB7XFxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUcmFuc2Zvcm1SdGwocG9zLnRvcCwgcG9zLnJpZ2h0LCBwb3Mud2lkdGgsIHBvcy5oZWlnaHQpO1xcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IHNldFRyYW5zZm9ybShwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcXG4gICAgICAgICAgICAgICAgICAgIH1cXG5cXG4gICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gdG9wLGxlZnQgKHNsb3cpXFxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUb3BSaWdodChwb3MudG9wLCBwb3MucmlnaHQsIHBvcy53aWR0aCwgcG9zLmhlaWdodCk7XFxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gc2V0VG9wTGVmdChwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcXG4gICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlID0gc3R5bGU7XFxuXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBoYW5kbGVSZXNpemU6IGZ1bmN0aW9uIChldmVudCkge1xcbiAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldENvbnRyb2xQb3NpdGlvbihldmVudCk7XFxuICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBkcmFnIHBvaW50IGZyb20gdGhlIGV2ZW50LiBUaGlzIGlzIHVzZWQgYXMgdGhlIG9mZnNldC5cXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IG51bGwpIHJldHVybjsgLy8gbm90IHBvc3NpYmxlIGJ1dCBzYXRpc2ZpZXMgZmxvd1xcbiAgICAgICAgICAgICAgICBjb25zdCB7eCwgeX0gPSBwb3NpdGlvbjtcXG5cXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U2l6ZSA9IHt3aWR0aDogMCwgaGVpZ2h0OiAwfTtcXG4gICAgICAgICAgICAgICAgc3dpdGNoIChldmVudC50eXBlKSB7XFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJyZXNpemVzdGFydFxcXCI6XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c1cgPSB0aGlzLnc7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c0ggPSB0aGlzLmg7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHBvcy53aWR0aDtcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemluZyA9IG5ld1NpemU7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1Jlc2l6aW5nID0gdHJ1ZTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXFxcInJlc2l6ZW1vdmVcXFwiOlxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIiMjIyByZXNpemUgPT4gXFxcIiArIGV2ZW50LnR5cGUgKyBcXFwiLCBsYXN0Vz1cXFwiICsgdGhpcy5sYXN0VyArIFxcXCIsIGxhc3RIPVxcXCIgKyB0aGlzLmxhc3RIKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3JlRXZlbnQgPSBjcmVhdGVDb3JlRGF0YSh0aGlzLmxhc3RXLCB0aGlzLmxhc3RILCB4LCB5KTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGggLSBjb3JlRXZlbnQuZGVsdGFYO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUud2lkdGggPSB0aGlzLnJlc2l6aW5nLndpZHRoICsgY29yZUV2ZW50LmRlbHRhWDtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS5oZWlnaHQgPSB0aGlzLnJlc2l6aW5nLmhlaWdodCArIGNvcmVFdmVudC5kZWx0YVk7XFxuXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8vY29uc29sZS5sb2coXFxcIiMjIyByZXNpemUgPT4gXFxcIiArIGV2ZW50LnR5cGUgKyBcXFwiLCBkZWx0YVg9XFxcIiArIGNvcmVFdmVudC5kZWx0YVggKyBcXFwiLCBkZWx0YVk9XFxcIiArIGNvcmVFdmVudC5kZWx0YVkpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzaXppbmcgPSBuZXdTaXplO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcXFwicmVzaXplZW5kXFxcIjpcXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKFxcXCIjIyMgcmVzaXplIGVuZCA9PiB4PVxcXCIgK3RoaXMueCArIFxcXCIgeT1cXFwiICsgdGhpcy55ICsgXFxcIiB3PVxcXCIgKyB0aGlzLncgKyBcXFwiIGg9XFxcIiArIHRoaXMuaCk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHBvcy53aWR0aDtcXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIHJlc2l6ZSBlbmQgPT4gXFxcIiArIEpTT04uc3RyaW5naWZ5KG5ld1NpemUpKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6aW5nID0gbnVsbDtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUmVzaXppbmcgPSBmYWxzZTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXG4gICAgICAgICAgICAgICAgfVxcblxcbiAgICAgICAgICAgICAgICAvLyBHZXQgbmV3IFdIXFxuICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNXSChuZXdTaXplLmhlaWdodCwgbmV3U2l6ZS53aWR0aCk7XFxuICAgICAgICAgICAgICAgIGlmIChwb3MudyA8IHRoaXMubWluVykge1xcbiAgICAgICAgICAgICAgICAgICAgcG9zLncgPSB0aGlzLm1pblc7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgaWYgKHBvcy53ID4gdGhpcy5tYXhXKSB7XFxuICAgICAgICAgICAgICAgICAgICBwb3MudyA9IHRoaXMubWF4VztcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICBpZiAocG9zLmggPCB0aGlzLm1pbkgpIHtcXG4gICAgICAgICAgICAgICAgICAgIHBvcy5oID0gdGhpcy5taW5IO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIGlmIChwb3MuaCA+IHRoaXMubWF4SCkge1xcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSB0aGlzLm1heEg7XFxuICAgICAgICAgICAgICAgIH1cXG5cXG4gICAgICAgICAgICAgICAgaWYgKHBvcy5oIDwgMSkge1xcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSAxO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIGlmIChwb3MudyA8IDEpIHtcXG4gICAgICAgICAgICAgICAgICAgIHBvcy53ID0gMTtcXG4gICAgICAgICAgICAgICAgfVxcblxcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RXID0geDtcXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0SCA9IHk7XFxuXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLncgIT09IHBvcy53IHx8IHRoaXMuaCAhPT0gcG9zLmgpIHtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcInJlc2l6ZVxcXCIsIHRoaXMuaSwgcG9zLmgsIHBvcy53KTtcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXFxcInJlc2l6ZWVuZFxcXCIgJiYgKHRoaXMucHJldmlvdXNXICE9PSB0aGlzLncgfHwgdGhpcy5wcmV2aW91c0ggIT09IHRoaXMuaCkpIHtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcInJlc2l6ZWRcXFwiLCB0aGlzLmksIHBvcy5oLCBwb3MudywgbmV3U2l6ZS5oZWlnaHQsIG5ld1NpemUud2lkdGgpO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInJlc2l6ZUV2ZW50XFxcIiwgZXZlbnQudHlwZSwgdGhpcy5pLCB0aGlzLngsIHRoaXMueSwgcG9zLmgsIHBvcy53KTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIGhhbmRsZURyYWcoZXZlbnQpIHtcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXNpemluZykgcmV0dXJuO1xcblxcbiAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldENvbnRyb2xQb3NpdGlvbihldmVudCk7XFxuXFxuICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBkcmFnIHBvaW50IGZyb20gdGhlIGV2ZW50LiBUaGlzIGlzIHVzZWQgYXMgdGhlIG9mZnNldC5cXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSBudWxsKSByZXR1cm47IC8vIG5vdCBwb3NzaWJsZSBidXQgc2F0aXNmaWVzIGZsb3dcXG4gICAgICAgICAgICAgICAgY29uc3Qge3gsIHl9ID0gcG9zaXRpb247XFxuXFxuICAgICAgICAgICAgICAgIHZhciBzaG91bGRVcGRhdGUgPSBmYWxzZTtcXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3UG9zaXRpb24gPSB7dG9wOiAwLCBsZWZ0OiAwfTtcXG4gICAgICAgICAgICAgICAgc3dpdGNoIChldmVudC50eXBlKSB7XFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJkcmFnc3RhcnRcXFwiOlxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNYID0gdGhpcy54O1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNZID0gdGhpcy55O1xcblxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRSZWN0ID0gZXZlbnQudGFyZ2V0Lm9mZnNldFBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xpZW50UmVjdCA9IGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IChjbGllbnRSZWN0LnJpZ2h0IC0gcGFyZW50UmVjdC5yaWdodCkgKiAtMTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gY2xpZW50UmVjdC5sZWZ0IC0gcGFyZW50UmVjdC5sZWZ0O1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi50b3AgPSBjbGllbnRSZWN0LnRvcCAtIHBhcmVudFJlY3QudG9wO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBuZXdQb3NpdGlvbjtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcXFwiZHJhZ2VuZFxcXCI6XFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmcpIHJldHVybjtcXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRSZWN0ID0gZXZlbnQudGFyZ2V0Lm9mZnNldFBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRSZWN0ID0gZXZlbnQudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xcbi8vICAgICAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSAoY2xpZW50UmVjdC5yaWdodCAtIHBhcmVudFJlY3QucmlnaHQpICogLTE7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IGNsaWVudFJlY3QubGVmdCAtIHBhcmVudFJlY3QubGVmdDtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24udG9wID0gY2xpZW50UmVjdC50b3AgLSBwYXJlbnRSZWN0LnRvcDtcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgZHJhZyBlbmQgPT4gXFxcIiArIEpTT04uc3RyaW5naWZ5KG5ld1Bvc2l0aW9uKSk7XFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIERST1A6IFxcXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBudWxsO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZFVwZGF0ZSA9IHRydWU7XFxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XFxuICAgICAgICAgICAgICAgICAgICBjYXNlIFxcXCJkcmFnbW92ZVxcXCI6XFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29yZUV2ZW50ID0gY3JlYXRlQ29yZURhdGEodGhpcy5sYXN0WCwgdGhpcy5sYXN0WSwgeCwgeSk7XFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBBZGQgcnRsIHN1cHBvcnRcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdCAtIGNvcmVFdmVudC5kZWx0YVg7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdCArIGNvcmVFdmVudC5kZWx0YVg7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLnRvcCA9IHRoaXMuZHJhZ2dpbmcudG9wICsgY29yZUV2ZW50LmRlbHRhWTtcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgZHJhZyA9PiBcXFwiICsgZXZlbnQudHlwZSArIFxcXCIsIHg9XFxcIiArIHggKyBcXFwiLCB5PVxcXCIgKyB5KTtcXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxcXCIjIyMgZHJhZyA9PiBcXFwiICsgZXZlbnQudHlwZSArIFxcXCIsIGRlbHRhWD1cXFwiICsgY29yZUV2ZW50LmRlbHRhWCArIFxcXCIsIGRlbHRhWT1cXFwiICsgY29yZUV2ZW50LmRlbHRhWSk7XFxuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcXFwiIyMjIGRyYWcgZW5kID0+IFxcXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBuZXdQb3NpdGlvbjtcXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcXG4gICAgICAgICAgICAgICAgfVxcblxcbiAgICAgICAgICAgICAgICAvLyBHZXQgbmV3IFhZXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1hZKG5ld1Bvc2l0aW9uLnRvcCwgbmV3UG9zaXRpb24ubGVmdCk7XFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjWFkobmV3UG9zaXRpb24udG9wLCBuZXdQb3NpdGlvbi5sZWZ0KTtcXG4gICAgICAgICAgICAgICAgfVxcblxcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RYID0geDtcXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0WSA9IHk7XFxuXFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggIT09IHBvcy54IHx8IHRoaXMueSAhPT0gcG9zLnkpIHtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXFxcIm1vdmVcXFwiLCB0aGlzLmksIHBvcy54LCBwb3MueSk7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFxcXCJkcmFnZW5kXFxcIiAmJiAodGhpcy5wcmV2aW91c1ggIT09IHRoaXMueCB8fCB0aGlzLnByZXZpb3VzWSAhPT0gdGhpcy55KSkge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZW1pdChcXFwibW92ZWRcXFwiLCB0aGlzLmksIHBvcy54LCBwb3MueSk7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcXFwiZHJhZ0V2ZW50XFxcIiwgZXZlbnQudHlwZSwgdGhpcy5pLCBwb3MueCwgcG9zLnksIHRoaXMuaCwgdGhpcy53KTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIGNhbGNQb3NpdGlvbjogZnVuY3Rpb24gKHgsIHksIHcsIGgpIHtcXG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2lkdGggPSB0aGlzLmNhbGNDb2xXaWR0aCgpO1xcbiAgICAgICAgICAgICAgICAvLyBhZGQgcnRsIHN1cHBvcnRcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XFxuICAgICAgICAgICAgICAgICAgICB2YXIgb3V0ID0ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0OiBNYXRoLnJvdW5kKGNvbFdpZHRoICogeCArICh4ICsgMSkgKiB0aGlzLm1hcmdpblswXSksXFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBNYXRoLnJvdW5kKHRoaXMucm93SGVpZ2h0ICogeSArICh5ICsgMSkgKiB0aGlzLm1hcmdpblsxXSksXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gMCAqIEluZmluaXR5ID09PSBOYU4sIHdoaWNoIGNhdXNlcyBwcm9ibGVtcyB3aXRoIHJlc2l6ZSBjb25zdHJpYW50cztcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggdGhpcyBpZiBpdCBvY2N1cnMuXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB3ZSBkbyBpdCBoZXJlIHJhdGhlciB0aGFuIGxhdGVyIGJlY2F1c2UgTWF0aC5yb3VuZChJbmZpbml0eSkgY2F1c2VzIGRlb3B0XFxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHcgPT09IEluZmluaXR5ID8gdyA6IE1hdGgucm91bmQoY29sV2lkdGggKiB3ICsgTWF0aC5tYXgoMCwgdyAtIDEpICogdGhpcy5tYXJnaW5bMF0pLFxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaCA9PT0gSW5maW5pdHkgPyBoIDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIGggKyBNYXRoLm1heCgwLCBoIC0gMSkgKiB0aGlzLm1hcmdpblsxXSlcXG4gICAgICAgICAgICAgICAgICAgIH07XFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICB2YXIgb3V0ID0ge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IE1hdGgucm91bmQoY29sV2lkdGggKiB4ICsgKHggKyAxKSAqIHRoaXMubWFyZ2luWzBdKSxcXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IE1hdGgucm91bmQodGhpcy5yb3dIZWlnaHQgKiB5ICsgKHkgKyAxKSAqIHRoaXMubWFyZ2luWzFdKSxcXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAwICogSW5maW5pdHkgPT09IE5hTiwgd2hpY2ggY2F1c2VzIHByb2JsZW1zIHdpdGggcmVzaXplIGNvbnN0cmlhbnRzO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpeCB0aGlzIGlmIGl0IG9jY3Vycy5cXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlIHdlIGRvIGl0IGhlcmUgcmF0aGVyIHRoYW4gbGF0ZXIgYmVjYXVzZSBNYXRoLnJvdW5kKEluZmluaXR5KSBjYXVzZXMgZGVvcHRcXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdyA9PT0gSW5maW5pdHkgPyB3IDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHcgKyBNYXRoLm1heCgwLCB3IC0gMSkgKiB0aGlzLm1hcmdpblswXSksXFxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBoID09PSBJbmZpbml0eSA/IGggOiBNYXRoLnJvdW5kKHRoaXMucm93SGVpZ2h0ICogaCArIE1hdGgubWF4KDAsIGggLSAxKSAqIHRoaXMubWFyZ2luWzFdKVxcbiAgICAgICAgICAgICAgICAgICAgfTtcXG4gICAgICAgICAgICAgICAgfVxcblxcblxcbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0O1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgLyoqXFxuICAgICAgICAgICAgICogVHJhbnNsYXRlIHggYW5kIHkgY29vcmRpbmF0ZXMgZnJvbSBwaXhlbHMgdG8gZ3JpZCB1bml0cy5cXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IHRvcCAgVG9wIHBvc2l0aW9uIChyZWxhdGl2ZSB0byBwYXJlbnQpIGluIHBpeGVscy5cXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IGxlZnQgTGVmdCBwb3NpdGlvbiAocmVsYXRpdmUgdG8gcGFyZW50KSBpbiBwaXhlbHMuXFxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB4IGFuZCB5IGluIGdyaWQgdW5pdHMuXFxuICAgICAgICAgICAgICovXFxuICAgICAgICAgICAgLy8gVE9ETyBjaGVjayBpZiB0aGlzIGZ1bmN0aW9uIG5lZWRzIGNoYW5nZSBpbiBvcmRlciB0byBzdXBwb3J0IHJ0bC5cXG4gICAgICAgICAgICBjYWxjWFkodG9wLCBsZWZ0KSB7XFxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbFdpZHRoID0gdGhpcy5jYWxjQ29sV2lkdGgoKTtcXG5cXG4gICAgICAgICAgICAgICAgLy8gbGVmdCA9IGNvbFdpZHRoICogeCArIG1hcmdpbiAqICh4ICsgMSlcXG4gICAgICAgICAgICAgICAgLy8gbCA9IGN4ICsgbSh4KzEpXFxuICAgICAgICAgICAgICAgIC8vIGwgPSBjeCArIG14ICsgbVxcbiAgICAgICAgICAgICAgICAvLyBsIC0gbSA9IGN4ICsgbXhcXG4gICAgICAgICAgICAgICAgLy8gbCAtIG0gPSB4KGMgKyBtKVxcbiAgICAgICAgICAgICAgICAvLyAobCAtIG0pIC8gKGMgKyBtKSA9IHhcXG4gICAgICAgICAgICAgICAgLy8geCA9IChsZWZ0IC0gbWFyZ2luKSAvIChjb2xkV2lkdGggKyBtYXJnaW4pXFxuICAgICAgICAgICAgICAgIGxldCB4ID0gTWF0aC5yb3VuZCgobGVmdCAtIHRoaXMubWFyZ2luWzBdKSAvIChjb2xXaWR0aCArIHRoaXMubWFyZ2luWzBdKSk7XFxuICAgICAgICAgICAgICAgIGxldCB5ID0gTWF0aC5yb3VuZCgodG9wIC0gdGhpcy5tYXJnaW5bMV0pIC8gKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pKTtcXG5cXG4gICAgICAgICAgICAgICAgLy8gQ2FwcGluZ1xcbiAgICAgICAgICAgICAgICB4ID0gTWF0aC5tYXgoTWF0aC5taW4oeCwgdGhpcy5jb2xzIC0gdGhpcy53KSwgMCk7XFxuICAgICAgICAgICAgICAgIHkgPSBNYXRoLm1heChNYXRoLm1pbih5LCB0aGlzLm1heFJvd3MgLSB0aGlzLmgpLCAwKTtcXG5cXG4gICAgICAgICAgICAgICAgcmV0dXJuIHt4LCB5fTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIC8vIEhlbHBlciBmb3IgZ2VuZXJhdGluZyBjb2x1bW4gd2lkdGhcXG4gICAgICAgICAgICBjYWxjQ29sV2lkdGgoKSB7XFxuICAgICAgICAgICAgICAgIHZhciBjb2xXaWR0aCA9ICh0aGlzLmNvbnRhaW5lcldpZHRoIC0gKHRoaXMubWFyZ2luWzBdICogKHRoaXMuY29scyArIDEpKSkgLyB0aGlzLmNvbHM7XFxuLy8gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIiMjIyBDT0xTPVxcXCIgKyB0aGlzLmNvbHMgKyBcXFwiIENPTCBXSURUSD1cXFwiICsgY29sV2lkdGgpO1xcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sV2lkdGg7XFxuICAgICAgICAgICAgfSxcXG5cXG4gICAgICAgICAgICAvKipcXG4gICAgICAgICAgICAgKiBHaXZlbiBhIGhlaWdodCBhbmQgd2lkdGggaW4gcGl4ZWwgdmFsdWVzLCBjYWxjdWxhdGUgZ3JpZCB1bml0cy5cXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IGhlaWdodCBIZWlnaHQgaW4gcGl4ZWxzLlxcbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gd2lkdGggIFdpZHRoIGluIHBpeGVscy5cXG4gICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IHcsIGggYXMgZ3JpZCB1bml0cy5cXG4gICAgICAgICAgICAgKi9cXG4gICAgICAgICAgICBjYWxjV0goaGVpZ2h0LCB3aWR0aCkge1xcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xXaWR0aCA9IHRoaXMuY2FsY0NvbFdpZHRoKCk7XFxuXFxuICAgICAgICAgICAgICAgIC8vIHdpZHRoID0gY29sV2lkdGggKiB3IC0gKG1hcmdpbiAqICh3IC0gMSkpXFxuICAgICAgICAgICAgICAgIC8vIC4uLlxcbiAgICAgICAgICAgICAgICAvLyB3ID0gKHdpZHRoICsgbWFyZ2luKSAvIChjb2xXaWR0aCArIG1hcmdpbilcXG4gICAgICAgICAgICAgICAgbGV0IHcgPSBNYXRoLnJvdW5kKCh3aWR0aCArIHRoaXMubWFyZ2luWzBdKSAvIChjb2xXaWR0aCArIHRoaXMubWFyZ2luWzBdKSk7XFxuICAgICAgICAgICAgICAgIGxldCBoID0gTWF0aC5yb3VuZCgoaGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pIC8gKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pKTtcXG5cXG4gICAgICAgICAgICAgICAgLy8gQ2FwcGluZ1xcbiAgICAgICAgICAgICAgICB3ID0gTWF0aC5tYXgoTWF0aC5taW4odywgdGhpcy5jb2xzIC0gdGhpcy54KSwgMCk7XFxuICAgICAgICAgICAgICAgIGggPSBNYXRoLm1heChNYXRoLm1pbihoLCB0aGlzLm1heFJvd3MgLSB0aGlzLnkpLCAwKTtcXG4gICAgICAgICAgICAgICAgcmV0dXJuIHt3LCBofTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIHVwZGF0ZVdpZHRoOiBmdW5jdGlvbiAod2lkdGgsIGNvbE51bSkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gd2lkdGg7XFxuICAgICAgICAgICAgICAgIGlmIChjb2xOdW0gIT09IHVuZGVmaW5lZCAmJiBjb2xOdW0gIT09IG51bGwpIHtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29scyA9IGNvbE51bTtcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgY29tcGFjdDogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfSxcXG4gICAgfVxcbjwvc2NyaXB0PlxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi1mMmVmOWNkMlwiLFwic2NvcGVkXCI6ZmFsc2UsXCJoYXNJbmxpbmVDb25maWdcIjpmYWxzZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDEyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///12\n"); +eval("/**\n * Translates the list format produced by css-loader into something\n * easier to manipulate.\n */\nmodule.exports = function listToStyles (parentId, list) {\n var styles = []\n var newStyles = {}\n for (var i = 0; i < list.length; i++) {\n var item = list[i]\n var id = item[0]\n var css = item[1]\n var media = item[2]\n var sourceMap = item[3]\n var part = {\n id: parentId + ':' + i,\n css: css,\n media: media,\n sourceMap: sourceMap\n }\n if (!newStyles[id]) {\n styles.push(newStyles[id] = { id: id, parts: [part] })\n } else {\n newStyles[id].parts.push(part)\n }\n }\n return styles\n}\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlci9saWIvbGlzdFRvU3R5bGVzLmpzP2I1MzUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsaUJBQWlCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyx3QkFBd0I7QUFDM0QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMTIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRyYW5zbGF0ZXMgdGhlIGxpc3QgZm9ybWF0IHByb2R1Y2VkIGJ5IGNzcy1sb2FkZXIgaW50byBzb21ldGhpbmdcbiAqIGVhc2llciB0byBtYW5pcHVsYXRlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGxpc3RUb1N0eWxlcyAocGFyZW50SWQsIGxpc3QpIHtcbiAgdmFyIHN0eWxlcyA9IFtdXG4gIHZhciBuZXdTdHlsZXMgPSB7fVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICB2YXIgaWQgPSBpdGVtWzBdXG4gICAgdmFyIGNzcyA9IGl0ZW1bMV1cbiAgICB2YXIgbWVkaWEgPSBpdGVtWzJdXG4gICAgdmFyIHNvdXJjZU1hcCA9IGl0ZW1bM11cbiAgICB2YXIgcGFydCA9IHtcbiAgICAgIGlkOiBwYXJlbnRJZCArICc6JyArIGksXG4gICAgICBjc3M6IGNzcyxcbiAgICAgIG1lZGlhOiBtZWRpYSxcbiAgICAgIHNvdXJjZU1hcDogc291cmNlTWFwXG4gICAgfVxuICAgIGlmICghbmV3U3R5bGVzW2lkXSkge1xuICAgICAgc3R5bGVzLnB1c2gobmV3U3R5bGVzW2lkXSA9IHsgaWQ6IGlkLCBwYXJ0czogW3BhcnRdIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld1N0eWxlc1tpZF0ucGFydHMucHVzaChwYXJ0KVxuICAgIH1cbiAgfVxuICByZXR1cm4gc3R5bGVzXG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2xpYi9saXN0VG9TdHlsZXMuanNcbi8vIG1vZHVsZSBpZCA9IDEyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///12\n"); /***/ }), /* 13 */ -/***/ (function(module, exports) { +/***/ (function(module, exports, __webpack_require__) { -eval("/**\n * Translates the list format produced by css-loader into something\n * easier to manipulate.\n */\nmodule.exports = function listToStyles (parentId, list) {\n var styles = []\n var newStyles = {}\n for (var i = 0; i < list.length; i++) {\n var item = list[i]\n var id = item[0]\n var css = item[1]\n var media = item[2]\n var sourceMap = item[3]\n var part = {\n id: parentId + ':' + i,\n css: css,\n media: media,\n sourceMap: sourceMap\n }\n if (!newStyles[id]) {\n styles.push(newStyles[id] = { id: id, parts: [part] })\n } else {\n newStyles[id].parts.push(part)\n }\n }\n return styles\n}\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlci9saWIvbGlzdFRvU3R5bGVzLmpzP2I1MzUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsaUJBQWlCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyx3QkFBd0I7QUFDM0QsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMTMuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRyYW5zbGF0ZXMgdGhlIGxpc3QgZm9ybWF0IHByb2R1Y2VkIGJ5IGNzcy1sb2FkZXIgaW50byBzb21ldGhpbmdcbiAqIGVhc2llciB0byBtYW5pcHVsYXRlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGxpc3RUb1N0eWxlcyAocGFyZW50SWQsIGxpc3QpIHtcbiAgdmFyIHN0eWxlcyA9IFtdXG4gIHZhciBuZXdTdHlsZXMgPSB7fVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICB2YXIgaWQgPSBpdGVtWzBdXG4gICAgdmFyIGNzcyA9IGl0ZW1bMV1cbiAgICB2YXIgbWVkaWEgPSBpdGVtWzJdXG4gICAgdmFyIHNvdXJjZU1hcCA9IGl0ZW1bM11cbiAgICB2YXIgcGFydCA9IHtcbiAgICAgIGlkOiBwYXJlbnRJZCArICc6JyArIGksXG4gICAgICBjc3M6IGNzcyxcbiAgICAgIG1lZGlhOiBtZWRpYSxcbiAgICAgIHNvdXJjZU1hcDogc291cmNlTWFwXG4gICAgfVxuICAgIGlmICghbmV3U3R5bGVzW2lkXSkge1xuICAgICAgc3R5bGVzLnB1c2gobmV3U3R5bGVzW2lkXSA9IHsgaWQ6IGlkLCBwYXJ0czogW3BhcnRdIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld1N0eWxlc1tpZF0ucGFydHMucHVzaChwYXJ0KVxuICAgIH1cbiAgfVxuICByZXR1cm4gc3R5bGVzXG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2xpYi9saXN0VG9TdHlsZXMuanNcbi8vIG1vZHVsZSBpZCA9IDEzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///13\n"); +"use strict"; +eval("\n\nexports.__esModule = true;\n\nvar _utils = __webpack_require__(0);\n\nvar _draggableUtils = __webpack_require__(14);\n\n// var eventBus = require('./eventBus');\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\nvar interact = __webpack_require__(15);\n\nexports.default = {\n name: \"GridItem\",\n props: {\n /*cols: {\n type: Number,\n required: true\n },*/\n /*containerWidth: {\n type: Number,\n required: true\n },\n rowHeight: {\n type: Number,\n required: true\n },\n margin: {\n type: Array,\n required: true\n },\n maxRows: {\n type: Number,\n required: true\n },*/\n isDraggable: {\n type: Boolean,\n required: false,\n default: null\n },\n isResizable: {\n type: Boolean,\n required: false,\n default: null\n },\n /*useCssTransforms: {\n type: Boolean,\n required: true\n },\n static: {\n type: Boolean,\n required: false,\n default: false\n },\n */\n minH: {\n type: Number,\n required: false,\n default: 1\n },\n minW: {\n type: Number,\n required: false,\n default: 1\n },\n maxH: {\n type: Number,\n required: false,\n default: Infinity\n },\n maxW: {\n type: Number,\n required: false,\n default: Infinity\n },\n x: {\n type: Number,\n required: true\n },\n y: {\n type: Number,\n required: true\n },\n w: {\n type: Number,\n required: true\n },\n h: {\n type: Number,\n required: true\n },\n i: {\n required: true\n },\n dragIgnoreFrom: {\n type: String,\n required: false,\n default: 'a, button'\n },\n dragAllowFrom: {\n type: String,\n required: false,\n default: null\n },\n resizeIgnoreFrom: {\n type: String,\n required: false,\n default: 'a, button'\n }\n },\n inject: [\"eventBus\"],\n data: function data() {\n return {\n cols: 1,\n containerWidth: 100,\n rowHeight: 30,\n margin: [10, 10],\n maxRows: Infinity,\n draggable: null,\n resizable: null,\n useCssTransforms: true,\n\n isDragging: false,\n dragging: null,\n isResizing: false,\n resizing: null,\n lastX: NaN,\n lastY: NaN,\n lastW: NaN,\n lastH: NaN,\n style: {},\n rtl: false,\n\n dragEventSet: false,\n resizeEventSet: false,\n\n previousW: null,\n previousH: null,\n previousX: null,\n previousY: null\n };\n },\n created: function created() {\n var _this = this;\n\n var self = this;\n\n // Accessible refernces of functions for removing in beforeDestroy\n self.updateWidthHandler = function (width) {\n self.updateWidth(width);\n };\n\n self.compactHandler = function (layout) {\n self.compact(layout);\n };\n\n self.setDraggableHandler = function (isDraggable) {\n if (self.isDraggable === null) {\n self.draggable = isDraggable;\n }\n };\n\n self.setResizableHandler = function (isResizable) {\n if (self.isResizable === null) {\n self.resizable = isResizable;\n }\n };\n\n self.setRowHeightHandler = function (rowHeight) {\n self.rowHeight = rowHeight;\n };\n\n self.directionchangeHandler = function (direction) {\n var direction = document.dir !== undefined ? document.dir : document.getElementsByTagName(\"html\")[0].getAttribute(\"dir\");\n _this.rtl = direction === \"rtl\";\n _this.compact();\n };\n\n this.eventBus.$on('updateWidth', self.updateWidthHandler);\n this.eventBus.$on('compact', self.compactHandler);\n this.eventBus.$on('setDraggable', self.setDraggableHandler);\n this.eventBus.$on('setResizable', self.setResizableHandler);\n this.eventBus.$on('setRowHeight', self.setRowHeightHandler);\n this.eventBus.$on('directionchange', self.directionchangeHandler);\n\n /*this.eventBus.$on('setColNum', function(colNum) {\n self.cols = colNum;\n });*/\n var direction = document.dir !== undefined ? document.dir : document.getElementsByTagName(\"html\")[0].getAttribute(\"dir\");\n this.rtl = direction === \"rtl\";\n },\n\n beforeDestroy: function beforeDestroy() {\n var self = this;\n //Remove listeners\n this.eventBus.$off('updateWidth', self.updateWidthHandler);\n this.eventBus.$off('compact', self.compactHandler);\n this.eventBus.$off('setDraggable', self.setDraggableHandler);\n this.eventBus.$off('setResizable', self.setResizableHandler);\n this.eventBus.$off('setRowHeight', self.setRowHeightHandler);\n this.eventBus.$off('directionchange', self.directionchangeHandler);\n },\n mounted: function mounted() {\n this.cols = this.$parent.colNum;\n this.rowHeight = this.$parent.rowHeight;\n this.containerWidth = this.$parent.width !== null ? this.$parent.width : 100;\n this.margin = this.$parent.margin !== undefined ? this.$parent.margin : [10, 10];\n this.maxRows = this.$parent.maxRows;\n if (this.isDraggable === null) {\n this.draggable = this.$parent.isDraggable;\n } else {\n this.draggable = this.isDraggable;\n }\n if (this.isResizable === null) {\n this.resizable = this.$parent.isResizable;\n } else {\n this.resizable = this.isResizable;\n }\n this.useCssTransforms = this.$parent.useCssTransforms;\n this.createStyle();\n },\n watch: {\n isDraggable: function isDraggable() {\n this.draggable = this.isDraggable;\n },\n draggable: function draggable() {\n var self = this;\n if (this.interactObj === null || this.interactObj === undefined) {\n this.interactObj = interact(this.$refs.item);\n }\n if (this.draggable) {\n var opts = {\n ignoreFrom: this.dragIgnoreFrom,\n allowFrom: this.dragAllowFrom\n };\n this.interactObj.draggable(opts);\n /*this.interactObj.draggable({allowFrom: '.vue-draggable-handle'});*/\n if (!this.dragEventSet) {\n this.dragEventSet = true;\n this.interactObj.on('dragstart dragmove dragend', function (event) {\n self.handleDrag(event);\n });\n }\n } else {\n this.interactObj.draggable({\n enabled: false\n });\n }\n },\n isResizable: function isResizable() {\n this.resizable = this.isResizable;\n },\n resizable: function resizable() {\n var self = this;\n if (this.interactObj === null || this.interactObj === undefined) {\n this.interactObj = interact(this.$refs.item);\n }\n if (this.resizable) {\n var opts = {\n preserveAspectRatio: false,\n edges: { left: false, right: true, bottom: true, top: false },\n ignoreFrom: this.resizeIgnoreFrom\n };\n\n this.interactObj.resizable(opts);\n if (!this.resizeEventSet) {\n this.resizeEventSet = true;\n this.interactObj.on('resizestart resizemove resizeend', function (event) {\n self.handleResize(event);\n });\n }\n } else {\n this.interactObj.resizable({\n enabled: false\n });\n }\n },\n rowHeight: function rowHeight() {\n this.createStyle();\n },\n cols: function cols() {\n this.createStyle();\n },\n containerWidth: function containerWidth() {\n this.createStyle();\n },\n x: function x() {\n this.createStyle();\n },\n y: function y() {\n this.createStyle();\n },\n h: function h() {\n this.createStyle();\n },\n w: function w() {\n this.createStyle();\n },\n renderRtl: function renderRtl() {\n this.createStyle();\n }\n },\n computed: {\n renderRtl: function renderRtl() {\n return this.$parent.isMirrored ? !this.rtl : this.rtl;\n },\n resizableHandleClass: function resizableHandleClass() {\n if (this.renderRtl) {\n return 'vue-resizable-handle vue-rtl-resizable-handle';\n } else {\n return 'vue-resizable-handle';\n }\n }\n },\n methods: {\n createStyle: function createStyle() {\n if (this.x + this.w > this.cols) {\n this.x = 0;\n this.w = this.cols;\n }\n\n var pos = this.calcPosition(this.x, this.y, this.w, this.h);\n\n if (this.isDragging) {\n pos.top = this.dragging.top;\n // Add rtl support\n if (this.renderRtl) {\n pos.right = this.dragging.left;\n } else {\n pos.left = this.dragging.left;\n }\n }\n if (this.isResizing) {\n pos.width = this.resizing.width;\n pos.height = this.resizing.height;\n }\n\n var style = void 0;\n // CSS Transforms support (default)\n if (this.useCssTransforms) {\n // Add rtl support\n if (this.renderRtl) {\n style = (0, _utils.setTransformRtl)(pos.top, pos.right, pos.width, pos.height);\n } else {\n style = (0, _utils.setTransform)(pos.top, pos.left, pos.width, pos.height);\n }\n } else {\n // top,left (slow)\n // Add rtl support\n if (this.renderRtl) {\n style = (0, _utils.setTopRight)(pos.top, pos.right, pos.width, pos.height);\n } else {\n style = (0, _utils.setTopLeft)(pos.top, pos.left, pos.width, pos.height);\n }\n }\n this.style = style;\n },\n handleResize: function handleResize(event) {\n var position = (0, _draggableUtils.getControlPosition)(event);\n // Get the current drag point from the event. This is used as the offset.\n if (position == null) return; // not possible but satisfies flow\n var x = position.x,\n y = position.y;\n\n\n var newSize = { width: 0, height: 0 };\n switch (event.type) {\n case \"resizestart\":\n this.previousW = this.w;\n this.previousH = this.h;\n var pos = this.calcPosition(this.x, this.y, this.w, this.h);\n newSize.width = pos.width;\n newSize.height = pos.height;\n this.resizing = newSize;\n this.isResizing = true;\n break;\n case \"resizemove\":\n // console.log(\"### resize => \" + event.type + \", lastW=\" + this.lastW + \", lastH=\" + this.lastH);\n var coreEvent = (0, _draggableUtils.createCoreData)(this.lastW, this.lastH, x, y);\n if (this.renderRtl) {\n newSize.width = this.resizing.width - coreEvent.deltaX;\n } else {\n newSize.width = this.resizing.width + coreEvent.deltaX;\n }\n newSize.height = this.resizing.height + coreEvent.deltaY;\n\n ///console.log(\"### resize => \" + event.type + \", deltaX=\" + coreEvent.deltaX + \", deltaY=\" + coreEvent.deltaY);\n this.resizing = newSize;\n break;\n case \"resizeend\":\n //console.log(\"### resize end => x=\" +this.x + \" y=\" + this.y + \" w=\" + this.w + \" h=\" + this.h);\n var pos = this.calcPosition(this.x, this.y, this.w, this.h);\n newSize.width = pos.width;\n newSize.height = pos.height;\n // console.log(\"### resize end => \" + JSON.stringify(newSize));\n this.resizing = null;\n this.isResizing = false;\n break;\n }\n\n // Get new WH\n var pos = this.calcWH(newSize.height, newSize.width);\n if (pos.w < this.minW) {\n pos.w = this.minW;\n }\n if (pos.w > this.maxW) {\n pos.w = this.maxW;\n }\n if (pos.h < this.minH) {\n pos.h = this.minH;\n }\n if (pos.h > this.maxH) {\n pos.h = this.maxH;\n }\n\n if (pos.h < 1) {\n pos.h = 1;\n }\n if (pos.w < 1) {\n pos.w = 1;\n }\n\n this.lastW = x;\n this.lastH = y;\n\n if (this.w !== pos.w || this.h !== pos.h) {\n this.$emit(\"resize\", this.i, pos.h, pos.w);\n }\n if (event.type === \"resizeend\" && (this.previousW !== this.w || this.previousH !== this.h)) {\n this.$emit(\"resized\", this.i, pos.h, pos.w, newSize.height, newSize.width);\n }\n this.eventBus.$emit(\"resizeEvent\", event.type, this.i, this.x, this.y, pos.h, pos.w);\n },\n handleDrag: function handleDrag(event) {\n if (this.isResizing) return;\n\n var position = (0, _draggableUtils.getControlPosition)(event);\n\n // Get the current drag point from the event. This is used as the offset.\n if (position === null) return; // not possible but satisfies flow\n var x = position.x,\n y = position.y;\n\n\n var shouldUpdate = false;\n var newPosition = { top: 0, left: 0 };\n switch (event.type) {\n case \"dragstart\":\n this.previousX = this.x;\n this.previousY = this.y;\n\n var parentRect = event.target.offsetParent.getBoundingClientRect();\n var clientRect = event.target.getBoundingClientRect();\n if (this.renderRtl) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n this.dragging = newPosition;\n this.isDragging = true;\n break;\n case \"dragend\":\n if (!this.isDragging) return;\n parentRect = event.target.offsetParent.getBoundingClientRect();\n clientRect = event.target.getBoundingClientRect();\n // Add rtl support\n if (this.renderRtl) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n // console.log(\"### drag end => \" + JSON.stringify(newPosition));\n // console.log(\"### DROP: \" + JSON.stringify(newPosition));\n this.dragging = null;\n this.isDragging = false;\n shouldUpdate = true;\n break;\n case \"dragmove\":\n var coreEvent = (0, _draggableUtils.createCoreData)(this.lastX, this.lastY, x, y);\n // Add rtl support\n if (this.renderRtl) {\n newPosition.left = this.dragging.left - coreEvent.deltaX;\n } else {\n newPosition.left = this.dragging.left + coreEvent.deltaX;\n }\n newPosition.top = this.dragging.top + coreEvent.deltaY;\n // console.log(\"### drag => \" + event.type + \", x=\" + x + \", y=\" + y);\n // console.log(\"### drag => \" + event.type + \", deltaX=\" + coreEvent.deltaX + \", deltaY=\" + coreEvent.deltaY);\n // console.log(\"### drag end => \" + JSON.stringify(newPosition));\n this.dragging = newPosition;\n break;\n }\n\n // Get new XY\n if (this.renderRtl) {\n var pos = this.calcXY(newPosition.top, newPosition.left);\n } else {\n var pos = this.calcXY(newPosition.top, newPosition.left);\n }\n\n this.lastX = x;\n this.lastY = y;\n\n if (this.x !== pos.x || this.y !== pos.y) {\n this.$emit(\"move\", this.i, pos.x, pos.y);\n }\n if (event.type === \"dragend\" && (this.previousX !== this.x || this.previousY !== this.y)) {\n this.$emit(\"moved\", this.i, pos.x, pos.y);\n }\n this.eventBus.$emit(\"dragEvent\", event.type, this.i, pos.x, pos.y, this.h, this.w);\n },\n\n calcPosition: function calcPosition(x, y, w, h) {\n var colWidth = this.calcColWidth();\n // add rtl support\n if (this.renderRtl) {\n var out = {\n right: Math.round(colWidth * x + (x + 1) * this.margin[0]),\n top: Math.round(this.rowHeight * y + (y + 1) * this.margin[1]),\n // 0 * Infinity === NaN, which causes problems with resize constriants;\n // Fix this if it occurs.\n // Note we do it here rather than later because Math.round(Infinity) causes deopt\n width: w === Infinity ? w : Math.round(colWidth * w + Math.max(0, w - 1) * this.margin[0]),\n height: h === Infinity ? h : Math.round(this.rowHeight * h + Math.max(0, h - 1) * this.margin[1])\n };\n } else {\n var out = {\n left: Math.round(colWidth * x + (x + 1) * this.margin[0]),\n top: Math.round(this.rowHeight * y + (y + 1) * this.margin[1]),\n // 0 * Infinity === NaN, which causes problems with resize constriants;\n // Fix this if it occurs.\n // Note we do it here rather than later because Math.round(Infinity) causes deopt\n width: w === Infinity ? w : Math.round(colWidth * w + Math.max(0, w - 1) * this.margin[0]),\n height: h === Infinity ? h : Math.round(this.rowHeight * h + Math.max(0, h - 1) * this.margin[1])\n };\n }\n\n return out;\n },\n /**\n * Translate x and y coordinates from pixels to grid units.\n * @param {Number} top Top position (relative to parent) in pixels.\n * @param {Number} left Left position (relative to parent) in pixels.\n * @return {Object} x and y in grid units.\n */\n // TODO check if this function needs change in order to support rtl.\n calcXY: function calcXY(top, left) {\n var colWidth = this.calcColWidth();\n\n // left = colWidth * x + margin * (x + 1)\n // l = cx + m(x+1)\n // l = cx + mx + m\n // l - m = cx + mx\n // l - m = x(c + m)\n // (l - m) / (c + m) = x\n // x = (left - margin) / (coldWidth + margin)\n var x = Math.round((left - this.margin[0]) / (colWidth + this.margin[0]));\n var y = Math.round((top - this.margin[1]) / (this.rowHeight + this.margin[1]));\n\n // Capping\n x = Math.max(Math.min(x, this.cols - this.w), 0);\n y = Math.max(Math.min(y, this.maxRows - this.h), 0);\n\n return { x: x, y: y };\n },\n\n // Helper for generating column width\n calcColWidth: function calcColWidth() {\n var colWidth = (this.containerWidth - this.margin[0] * (this.cols + 1)) / this.cols;\n // console.log(\"### COLS=\" + this.cols + \" COL WIDTH=\" + colWidth);\n return colWidth;\n },\n\n\n /**\n * Given a height and width in pixel values, calculate grid units.\n * @param {Number} height Height in pixels.\n * @param {Number} width Width in pixels.\n * @return {Object} w, h as grid units.\n */\n calcWH: function calcWH(height, width) {\n var colWidth = this.calcColWidth();\n\n // width = colWidth * w - (margin * (w - 1))\n // ...\n // w = (width + margin) / (colWidth + margin)\n var w = Math.round((width + this.margin[0]) / (colWidth + this.margin[0]));\n var h = Math.round((height + this.margin[1]) / (this.rowHeight + this.margin[1]));\n\n // Capping\n w = Math.max(Math.min(w, this.cols - this.x), 0);\n h = Math.max(Math.min(h, this.maxRows - this.y), 0);\n return { w: w, h: h };\n },\n\n updateWidth: function updateWidth(width, colNum) {\n this.containerWidth = width;\n if (colNum !== undefined && colNum !== null) {\n this.cols = colNum;\n }\n },\n compact: function compact() {\n this.createStyle();\n }\n }\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vR3JpZEl0ZW0udnVlPzdhMTYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQWdGQTs7QUFDQTs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUpBOzttQ0FNQTs7O1VBRUE7O0FBS0E7Ozs7QUFpQkE7Ozs7Ozs7Ozs7Ozs7Ozs7O2tCQUVBO3NCQUNBO3FCQUVBO0FBSkE7O2tCQU1BO3NCQUNBO3FCQUVBO0FBSkE7QUFjQTs7Ozs7Ozs7Ozs7a0JBRUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBRUE7QUFIQTs7a0JBS0E7c0JBRUE7QUFIQTs7a0JBS0E7c0JBRUE7QUFIQTs7a0JBS0E7c0JBRUE7QUFIQTs7c0JBTUE7QUFGQTs7a0JBSUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBR0E7QUFMQTtBQTNGQTthQWlHQTswQkFDQTs7a0JBRUE7NEJBQ0E7dUJBQ0E7eUJBQ0E7cUJBQ0E7dUJBQ0E7dUJBQ0E7OEJBRUE7O3dCQUNBO3NCQUNBO3dCQUNBO3NCQUNBO21CQUNBO21CQUNBO21CQUNBO21CQUNBO21CQUNBO2lCQUVBOzswQkFDQTs0QkFFQTs7dUJBQ0E7dUJBQ0E7dUJBQ0E7dUJBRUE7QUE1QkE7QUE2QkE7O0FBQ0E7O21CQUVBOztBQUNBO21EQUNBOzZCQUNBO0FBRUE7O2dEQUNBO3lCQUNBO0FBRUE7OzBEQUNBOzJDQUNBO2lDQUNBO0FBQ0E7QUFFQTs7MERBQ0E7MkNBQ0E7aUNBQ0E7QUFDQTtBQUVBOzt3REFDQTs2QkFDQTtBQUVBOzsyREFDQTs2Q0FDQSxxQkFDQSw0REFDQTtzQ0FDQTtrQkFDQTtBQUVBOzs4Q0FDQTsw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O0FBQ0E7QUFDQTtBQUNBOzJHQUNBO2tIQUVBO0FBUkE7QUFXQTs7bUJBQ0E7QUFDQTtBQU1BOzs7Ozs7QUFDQTsyQ0FDQTtnQ0FFQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtpRkFDQTtzRkFFQTs7QUFDQTswREFDQTs2REFFQTs7MkJBQ0E7QUFDQTs7QUFDQTs4Q0FDQTs7QUFFQTttQkFDQTtBQUVBOzs7QUFNQTs7Ozs7OytDQUNBO2dDQUVBOztBQUNBO0FBQ0E7QUFDQTtrRkFDQTt5RkFFQTs7QUFDQTswREFDQTs2REFDQTsyQkFDQTtBQUNBOzt5REFDQTtrQ0FDQTt5REFDQTs0QkFDQTtBQUNBO0FBQ0E7b0NBQ0E7aUJBQ0E7QUFFQTtBQTlSQTtBQWpUQSIsImZpbGUiOiIxMy5qcyIsInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cclxuICAgIDxkaXYgcmVmPVwiaXRlbVwiXHJcbiAgICAgICAgIGNsYXNzPVwidnVlLWdyaWQtaXRlbVwiXHJcbiAgICAgICAgIDpjbGFzcz1cInsgJ3Z1ZS1yZXNpemFibGUnIDogcmVzaXphYmxlLCAncmVzaXppbmcnIDogaXNSZXNpemluZywgJ3Z1ZS1kcmFnZ2FibGUtZHJhZ2dpbmcnIDogaXNEcmFnZ2luZywgJ2Nzc1RyYW5zZm9ybXMnIDogdXNlQ3NzVHJhbnNmb3JtcywgJ3JlbmRlci1ydGwnIDogcmVuZGVyUnRsIH1cIlxyXG4gICAgICAgICA6c3R5bGU9XCJzdHlsZVwiXHJcbiAgICA+XHJcbiAgICAgICAgPHNsb3Q+PC9zbG90PlxyXG4gICAgICAgIDxzcGFuIHYtaWY9XCJyZXNpemFibGVcIiByZWY9XCJoYW5kbGVcIiA6Y2xhc3M9XCJyZXNpemFibGVIYW5kbGVDbGFzc1wiPjwvc3Bhbj5cclxuICAgICAgICA8IS0tPHNwYW4gdi1pZj1cImRyYWdnYWJsZVwiIHJlZj1cImRyYWdIYW5kbGVcIiBjbGFzcz1cInZ1ZS1kcmFnZ2FibGUtaGFuZGxlXCI+PC9zcGFuPi0tPlxyXG4gICAgPC9kaXY+XHJcbjwvdGVtcGxhdGU+XHJcbjxzdHlsZT5cclxuICAgIC52dWUtZ3JpZC1pdGVtIHtcclxuICAgICAgICB0cmFuc2l0aW9uOiBhbGwgMjAwbXMgZWFzZTtcclxuICAgICAgICB0cmFuc2l0aW9uLXByb3BlcnR5OiBsZWZ0LCB0b3AsIHJpZ2h0O1xyXG4gICAgICAgIC8qIGFkZCByaWdodCBmb3IgcnRsICovXHJcbiAgICB9XHJcblxyXG4gICAgLnZ1ZS1ncmlkLWl0ZW0uY3NzVHJhbnNmb3JtcyB7XHJcbiAgICAgICAgdHJhbnNpdGlvbi1wcm9wZXJ0eTogdHJhbnNmb3JtO1xyXG4gICAgICAgIGxlZnQ6IDA7XHJcbiAgICAgICAgcmlnaHQ6IGF1dG87XHJcbiAgICB9XHJcblxyXG4gICAgLnZ1ZS1ncmlkLWl0ZW0uY3NzVHJhbnNmb3Jtcy5yZW5kZXItcnRsIHtcclxuICAgICAgICBsZWZ0OiBhdXRvO1xyXG4gICAgICAgIHJpZ2h0OiAwO1xyXG4gICAgfVxyXG5cclxuICAgIC52dWUtZ3JpZC1pdGVtLnJlc2l6aW5nIHtcclxuICAgICAgICBvcGFjaXR5OiAwLjY7XHJcbiAgICAgICAgei1pbmRleDogMztcclxuICAgIH1cclxuXHJcbiAgICAudnVlLWdyaWQtaXRlbS52dWUtZHJhZ2dhYmxlLWRyYWdnaW5nIHtcclxuICAgICAgICB0cmFuc2l0aW9uOm5vbmU7XHJcbiAgICAgICAgei1pbmRleDogMztcclxuICAgIH1cclxuXHJcbiAgICAudnVlLWdyaWQtaXRlbS52dWUtZ3JpZC1wbGFjZWhvbGRlciB7XHJcbiAgICAgICAgYmFja2dyb3VuZDogcmVkO1xyXG4gICAgICAgIG9wYWNpdHk6IDAuMjtcclxuICAgICAgICB0cmFuc2l0aW9uLWR1cmF0aW9uOiAxMDBtcztcclxuICAgICAgICB6LWluZGV4OiAyO1xyXG4gICAgICAgIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcclxuICAgICAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgLW8tdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICB9XHJcblxyXG4gICAgLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJlc2l6YWJsZS1oYW5kbGUge1xyXG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgICAgICB3aWR0aDogMjBweDtcclxuICAgICAgICBoZWlnaHQ6IDIwcHg7XHJcbiAgICAgICAgYm90dG9tOiAwO1xyXG4gICAgICAgIHJpZ2h0OiAwO1xyXG4gICAgICAgIGJhY2tncm91bmQ6IHVybCgnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJ6ZEdGdVpHRnNiMjVsUFNKdWJ5SS9QZzA4SVMwdElFZGxibVZ5WVhSdmNqb2dRV1J2WW1VZ1JtbHlaWGR2Y210eklFTlROaXdnUlhod2IzSjBJRk5XUnlCRmVIUmxibk5wYjI0Z1lua2dRV0Z5YjI0Z1FtVmhiR3dnS0doMGRIQTZMeTltYVhKbGQyOXlhM011WVdKbFlXeHNMbU52YlNrZ0xpQldaWEp6YVc5dU9pQXdMall1TVNBZ0xTMCtEVHdoUkU5RFZGbFFSU0J6ZG1jZ1VGVkNURWxESUNJdEx5OVhNME12TDBSVVJDQlRWa2NnTVM0eEx5OUZUaUlnSW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTDBkeVlYQm9hV056TDFOV1J5OHhMakV2UkZSRUwzTjJaekV4TG1SMFpDSStEVHh6ZG1jZ2FXUTlJbFZ1ZEdsMGJHVmtMVkJoWjJVbE1qQXhJaUIyYVdWM1FtOTRQU0l3SURBZ05pQTJJaUJ6ZEhsc1pUMGlZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqb2pabVptWm1abU1EQWlJSFpsY25OcGIyNDlJakV1TVNJTkNYaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhodGJEcHpjR0ZqWlQwaWNISmxjMlZ5ZG1VaURRbDRQU0l3Y0hnaUlIazlJakJ3ZUNJZ2QybGtkR2c5SWpad2VDSWdhR1ZwWjJoMFBTSTJjSGdpRFQ0TkNUeG5JRzl3WVdOcGRIazlJakF1TXpBeUlqNE5DUWs4Y0dGMGFDQmtQU0pOSURZZ05pQk1JREFnTmlCTUlEQWdOQzR5SUV3Z05DQTBMaklnVENBMExqSWdOQzR5SUV3Z05DNHlJREFnVENBMklEQWdUQ0EySURZZ1RDQTJJRFlnV2lJZ1ptbHNiRDBpSXpBd01EQXdNQ0l2UGcwSlBDOW5QZzA4TDNOMlp6ND0nKTtcclxuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBib3R0b20gcmlnaHQ7XHJcbiAgICAgICAgcGFkZGluZzogMCAzcHggM3B4IDA7XHJcbiAgICAgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcclxuICAgICAgICBiYWNrZ3JvdW5kLW9yaWdpbjogY29udGVudC1ib3g7XHJcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcclxuICAgICAgICBjdXJzb3I6IHNlLXJlc2l6ZTtcclxuICAgIH1cclxuXHJcbiAgICAudnVlLWdyaWQtaXRlbSA+IC52dWUtcnRsLXJlc2l6YWJsZS1oYW5kbGUge1xyXG4gICAgICAgIGJvdHRvbTogMDtcclxuICAgICAgICBsZWZ0OiAwO1xyXG4gICAgICAgIGJhY2tncm91bmQ6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUIzYVdSMGFEMGlNVEF1TURBd01EQXdNREF3TURBd01EQXlJaUJvWldsbmFIUTlJakV3TGpBd01EQXdNREF3TURBd01EQXdNaUlnZUcxc2JuTTlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5Mekl3TURBdmMzWm5JajRLSUR3aExTMGdRM0psWVhSbFpDQjNhWFJvSUUxbGRHaHZaQ0JFY21GM0lDMGdhSFIwY0RvdkwyZHBkR2gxWWk1amIyMHZaSFZ2Y0dsNFpXd3ZUV1YwYUc5a0xVUnlZWGN2SUMwdFBnb2dQR2MrQ2lBZ1BIUnBkR3hsUG1KaFkydG5jbTkxYm1ROEwzUnBkR3hsUGdvZ0lEeHlaV04wSUdacGJHdzlJbTV2Ym1VaUlHbGtQU0pqWVc1MllYTmZZbUZqYTJkeWIzVnVaQ0lnYUdWcFoyaDBQU0l4TWlJZ2QybGtkR2c5SWpFeUlpQjVQU0l0TVNJZ2VEMGlMVEVpTHo0S0lDQThaeUJrYVhOd2JHRjVQU0p1YjI1bElpQnZkbVZ5Wm14dmR6MGlkbWx6YVdKc1pTSWdlVDBpTUNJZ2VEMGlNQ0lnYUdWcFoyaDBQU0l4TURBbElpQjNhV1IwYUQwaU1UQXdKU0lnYVdROUltTmhiblpoYzBkeWFXUWlQZ29nSUNBOGNtVmpkQ0JtYVd4c1BTSjFjbXdvSTJkeWFXUndZWFIwWlhKdUtTSWdjM1J5YjJ0bExYZHBaSFJvUFNJd0lpQjVQU0l3SWlCNFBTSXdJaUJvWldsbmFIUTlJakV3TUNVaUlIZHBaSFJvUFNJeE1EQWxJaTgrQ2lBZ1BDOW5QZ29nUEM5blBnb2dQR2MrQ2lBZ1BIUnBkR3hsUGt4aGVXVnlJREU4TDNScGRHeGxQZ29nSUR4c2FXNWxJR05oYm5aaGN6MGlJMlptWm1abVppSWdZMkZ1ZG1GekxXOXdZV05wZEhrOUlqRWlJSE4wY205clpTMXNhVzVsWTJGd1BTSjFibVJsWm1sdVpXUWlJSE4wY205clpTMXNhVzVsYW05cGJqMGlkVzVrWldacGJtVmtJaUJwWkQwaWMzWm5YekVpSUhreVBTSXROekF1TVRjNE5EQTNJaUI0TWowaU1USTBMalEyTkRFM05TSWdlVEU5SWkwek9DNHpPVEkzTXpjaUlIZ3hQU0l4TkRRdU9ESXhNamc1SWlCemRISnZhMlV0ZDJsa2RHZzlJakV1TlNJZ2MzUnliMnRsUFNJak1EQXdJaUJtYVd4c1BTSnViMjVsSWk4K0NpQWdQR3hwYm1VZ2MzUnliMnRsUFNJak5qWTJOalkySWlCemRISnZhMlV0YkdsdVpXTmhjRDBpZFc1a1pXWnBibVZrSWlCemRISnZhMlV0YkdsdVpXcHZhVzQ5SW5WdVpHVm1hVzVsWkNJZ2FXUTlJbk4yWjE4MUlpQjVNajBpT1M0eE1EWTVOVGNpSUhneVBTSXdMamswTnpJME55SWdlVEU5SWkwd0xqQXhPREV5T0NJZ2VERTlJakF1T1RRM01qUTNJaUJ6ZEhKdmEyVXRkMmxrZEdnOUlqSWlJR1pwYkd3OUltNXZibVVpTHo0S0lDQThiR2x1WlNCemRISnZhMlV0YkdsdVpXTmhjRDBpZFc1a1pXWnBibVZrSWlCemRISnZhMlV0YkdsdVpXcHZhVzQ5SW5WdVpHVm1hVzVsWkNJZ2FXUTlJbk4yWjE4M0lpQjVNajBpT1NJZ2VESTlJakV3TGpBM016VXlPU0lnZVRFOUlqa2lJSGd4UFNJdE1DNDJOVFUyTkNJZ2MzUnliMnRsTFhkcFpIUm9QU0l5SWlCemRISnZhMlU5SWlNMk5qWTJOallpSUdacGJHdzlJbTV2Ym1VaUx6NEtJRHd2Wno0S1BDOXpkbWMrKTtcclxuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBib3R0b20gbGVmdDtcclxuICAgICAgICBwYWRkaW5nLWxlZnQ6IDNweDtcclxuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xyXG4gICAgICAgIGJhY2tncm91bmQtb3JpZ2luOiBjb250ZW50LWJveDtcclxuICAgICAgICBjdXJzb3I6IHN3LXJlc2l6ZTtcclxuICAgICAgICByaWdodDogYXV0bztcclxuICAgIH1cclxuPC9zdHlsZT5cclxuPHNjcmlwdD5cclxuICAgIGltcG9ydCB7c2V0VG9wTGVmdCwgc2V0VG9wUmlnaHQsIHNldFRyYW5zZm9ybVJ0bCwgc2V0VHJhbnNmb3JtLCBjcmVhdGVNYXJrdXAsIGdldExheW91dEl0ZW19IGZyb20gJy4vdXRpbHMnO1xyXG4gICAgaW1wb3J0IHtnZXRDb250cm9sUG9zaXRpb24sIG9mZnNldFhZRnJvbVBhcmVudE9mLCBjcmVhdGVDb3JlRGF0YX0gZnJvbSAnLi9kcmFnZ2FibGVVdGlscyc7XHJcbiAgICAvLyAgICB2YXIgZXZlbnRCdXMgPSByZXF1aXJlKCcuL2V2ZW50QnVzJyk7XHJcblxyXG4gICAgdmFyIGludGVyYWN0ID0gcmVxdWlyZShcImludGVyYWN0anNcIik7XHJcblxyXG4gICAgZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgICAgIG5hbWU6IFwiR3JpZEl0ZW1cIixcclxuICAgICAgICBwcm9wczoge1xyXG4gICAgICAgICAgICAvKmNvbHM6IHtcclxuICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcclxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICAgICAgICAgICB9LCovXHJcbiAgICAgICAgICAgIC8qY29udGFpbmVyV2lkdGg6IHtcclxuICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcclxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXHJcblxyXG4gICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgIHJvd0hlaWdodDoge1xyXG4gICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICBtYXJnaW46IHtcclxuICAgICAgICAgICAgIHR5cGU6IEFycmF5LFxyXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICBtYXhSb3dzOiB7XHJcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXHJcbiAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxyXG4gICAgICAgICAgICAgfSwqL1xyXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IG51bGxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaXNSZXNpemFibGU6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBudWxsXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8qdXNlQ3NzVHJhbnNmb3Jtczoge1xyXG4gICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXHJcbiAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgc3RhdGljOiB7XHJcbiAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxyXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgZGVmYXVsdDogZmFsc2VcclxuICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBtaW5IOiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXHJcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAxXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG1pblc6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IDFcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWF4SDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWF4Vzoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgeDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgeToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdzoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaToge1xyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZHJhZ0lnbm9yZUZyb206IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6ICdhLCBidXR0b24nXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGRyYWdBbGxvd0Zyb206IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IG51bGxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcmVzaXplSWdub3JlRnJvbToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogU3RyaW5nLFxyXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogJ2EsIGJ1dHRvbidcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIGluamVjdDogW1wiZXZlbnRCdXNcIl0sXHJcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgY29sczogMSxcclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiAxMDAsXHJcbiAgICAgICAgICAgICAgICByb3dIZWlnaHQ6IDMwLFxyXG4gICAgICAgICAgICAgICAgbWFyZ2luOiBbMTAsIDEwXSxcclxuICAgICAgICAgICAgICAgIG1heFJvd3M6IEluZmluaXR5LFxyXG4gICAgICAgICAgICAgICAgZHJhZ2dhYmxlOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcmVzaXphYmxlOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgdXNlQ3NzVHJhbnNmb3JtczogdHJ1ZSxcclxuXHJcbiAgICAgICAgICAgICAgICBpc0RyYWdnaW5nOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRyYWdnaW5nOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXNpemluZzogbnVsbCxcclxuICAgICAgICAgICAgICAgIGxhc3RYOiBOYU4sXHJcbiAgICAgICAgICAgICAgICBsYXN0WTogTmFOLFxyXG4gICAgICAgICAgICAgICAgbGFzdFc6IE5hTixcclxuICAgICAgICAgICAgICAgIGxhc3RIOiBOYU4sXHJcbiAgICAgICAgICAgICAgICBzdHlsZToge30sXHJcbiAgICAgICAgICAgICAgICBydGw6IGZhbHNlLFxyXG5cclxuICAgICAgICAgICAgICAgIGRyYWdFdmVudFNldDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXNpemVFdmVudFNldDogZmFsc2UsXHJcblxyXG4gICAgICAgICAgICAgICAgcHJldmlvdXNXOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcHJldmlvdXNIOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcHJldmlvdXNYOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcHJldmlvdXNZOiBudWxsLFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjcmVhdGVkICgpIHtcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICAgICAgLy8gQWNjZXNzaWJsZSByZWZlcm5jZXMgb2YgZnVuY3Rpb25zIGZvciByZW1vdmluZyBpbiBiZWZvcmVEZXN0cm95XHJcbiAgICAgICAgICAgIHNlbGYudXBkYXRlV2lkdGhIYW5kbGVyID0gZnVuY3Rpb24gKHdpZHRoKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoKHdpZHRoKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHNlbGYuY29tcGFjdEhhbmRsZXIgPSBmdW5jdGlvbiAobGF5b3V0KSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmNvbXBhY3QobGF5b3V0KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlciA9IGZ1bmN0aW9uIChpc0RyYWdnYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuaXNEcmFnZ2FibGUgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmLmRyYWdnYWJsZSA9IGlzRHJhZ2dhYmxlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyID0gZnVuY3Rpb24gKGlzUmVzaXphYmxlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5pc1Jlc2l6YWJsZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYucmVzaXphYmxlID0gaXNSZXNpemFibGU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIgPSBmdW5jdGlvbiAocm93SGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnJvd0hlaWdodCA9IHJvd0hlaWdodDtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHNlbGYuZGlyZWN0aW9uY2hhbmdlSGFuZGxlciA9IChkaXJlY3Rpb24pID0+IHtcclxuICAgICAgICAgICAgICAgIHZhciBkaXJlY3Rpb24gPSAoZG9jdW1lbnQuZGlyICE9PSB1bmRlZmluZWQpID9cclxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5kaXIgOlxyXG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaHRtbFwiKVswXS5nZXRBdHRyaWJ1dGUoXCJkaXJcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJ0bCA9IChkaXJlY3Rpb24gPT09IFwicnRsXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb21wYWN0KCk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbigndXBkYXRlV2lkdGgnLCBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdjb21wYWN0Jywgc2VsZi5jb21wYWN0SGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXREcmFnZ2FibGUnLCBzZWxmLnNldERyYWdnYWJsZUhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbignc2V0UmVzaXphYmxlJywgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyKTtcclxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb24oJ3NldFJvd0hlaWdodCcsIHNlbGYuc2V0Um93SGVpZ2h0SGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdkaXJlY3Rpb25jaGFuZ2UnLCBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIpO1xyXG5cclxuICAgICAgICAgICAgLyp0aGlzLmV2ZW50QnVzLiRvbignc2V0Q29sTnVtJywgZnVuY3Rpb24oY29sTnVtKSB7XHJcbiAgICAgICAgICAgICBzZWxmLmNvbHMgPSBjb2xOdW07XHJcbiAgICAgICAgICAgICB9KTsqL1xyXG4gICAgICAgICAgICB2YXIgZGlyZWN0aW9uID0gKGRvY3VtZW50LmRpciAhPT0gdW5kZWZpbmVkKSA/XHJcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5kaXIgOlxyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJodG1sXCIpWzBdLmdldEF0dHJpYnV0ZShcImRpclwiKTtcclxuICAgICAgICAgICAgdGhpcy5ydGwgPSAoZGlyZWN0aW9uID09PSBcInJ0bFwiKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgLy9SZW1vdmUgbGlzdGVuZXJzXHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZigndXBkYXRlV2lkdGgnLCBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignY29tcGFjdCcsIHNlbGYuY29tcGFjdEhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ3NldERyYWdnYWJsZScsIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlcik7XHJcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignc2V0UmVzaXphYmxlJywgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyKTtcclxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCdzZXRSb3dIZWlnaHQnLCBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2RpcmVjdGlvbmNoYW5nZScsIHNlbGYuZGlyZWN0aW9uY2hhbmdlSGFuZGxlcik7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBtb3VudGVkOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29scyA9IHRoaXMuJHBhcmVudC5jb2xOdW07XHJcbiAgICAgICAgICAgIHRoaXMucm93SGVpZ2h0ID0gdGhpcy4kcGFyZW50LnJvd0hlaWdodDtcclxuICAgICAgICAgICAgdGhpcy5jb250YWluZXJXaWR0aCA9IHRoaXMuJHBhcmVudC53aWR0aCAhPT0gbnVsbCA/IHRoaXMuJHBhcmVudC53aWR0aCA6IDEwMDtcclxuICAgICAgICAgICAgdGhpcy5tYXJnaW4gPSB0aGlzLiRwYXJlbnQubWFyZ2luICE9PSB1bmRlZmluZWQgPyB0aGlzLiRwYXJlbnQubWFyZ2luIDogWzEwLCAxMF07XHJcbiAgICAgICAgICAgIHRoaXMubWF4Um93cyA9IHRoaXMuJHBhcmVudC5tYXhSb3dzO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0RyYWdnYWJsZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLiRwYXJlbnQuaXNEcmFnZ2FibGU7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdnYWJsZSA9IHRoaXMuaXNEcmFnZ2FibGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXNpemFibGUgPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXphYmxlID0gdGhpcy4kcGFyZW50LmlzUmVzaXphYmxlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemFibGUgPSB0aGlzLmlzUmVzaXphYmxlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMudXNlQ3NzVHJhbnNmb3JtcyA9IHRoaXMuJHBhcmVudC51c2VDc3NUcmFuc2Zvcm1zO1xyXG4gICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICB3YXRjaDoge1xyXG4gICAgICAgICAgICBpc0RyYWdnYWJsZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLmlzRHJhZ2dhYmxlO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBkcmFnZ2FibGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmludGVyYWN0T2JqID09PSBudWxsIHx8IHRoaXMuaW50ZXJhY3RPYmogPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmogPSBpbnRlcmFjdCh0aGlzLiRyZWZzLml0ZW0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ2dhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9wdHMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUZyb206IHRoaXMuZHJhZ0lnbm9yZUZyb20sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93RnJvbTogdGhpcy5kcmFnQWxsb3dGcm9tXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmouZHJhZ2dhYmxlKG9wdHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8qdGhpcy5pbnRlcmFjdE9iai5kcmFnZ2FibGUoe2FsbG93RnJvbTogJy52dWUtZHJhZ2dhYmxlLWhhbmRsZSd9KTsqL1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5kcmFnRXZlbnRTZXQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnRXZlbnRTZXQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLm9uKCdkcmFnc3RhcnQgZHJhZ21vdmUgZHJhZ2VuZCcsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5oYW5kbGVEcmFnKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLmRyYWdnYWJsZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHRoaXMuaXNSZXNpemFibGU7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHJlc2l6YWJsZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJhY3RPYmogPT09IG51bGwgfHwgdGhpcy5pbnRlcmFjdE9iaiA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iaiA9IGludGVyYWN0KHRoaXMuJHJlZnMuaXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZXNpemFibGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3B0cyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJlc2VydmVBc3BlY3RSYXRpbzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2VzOiB7bGVmdDogZmFsc2UsIHJpZ2h0OiB0cnVlLCBib3R0b206IHRydWUsIHRvcDogZmFsc2V9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVGcm9tOiB0aGlzLnJlc2l6ZUlnbm9yZUZyb21cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmoucmVzaXphYmxlKG9wdHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5yZXNpemVFdmVudFNldCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZUV2ZW50U2V0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9ialxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uKCdyZXNpemVzdGFydCByZXNpemVtb3ZlIHJlc2l6ZWVuZCcsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaGFuZGxlUmVzaXplKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5yZXNpemFibGUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgY29sczogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjb250YWluZXJXaWR0aDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB4OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHk6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB3OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHJlbmRlclJ0bDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjb21wdXRlZDoge1xyXG4gICAgICAgICAgICByZW5kZXJSdGwoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuJHBhcmVudC5pc01pcnJvcmVkKSA/ICF0aGlzLnJ0bCA6IHRoaXMucnRsO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICByZXNpemFibGVIYW5kbGVDbGFzcygpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAndnVlLXJlc2l6YWJsZS1oYW5kbGUgdnVlLXJ0bC1yZXNpemFibGUtaGFuZGxlJztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICd2dWUtcmVzaXphYmxlLWhhbmRsZSc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIG1ldGhvZHM6IHtcclxuICAgICAgICAgICAgY3JlYXRlU3R5bGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggKyB0aGlzLncgPiB0aGlzLmNvbHMpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudyA9IHRoaXMuY29scztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjUG9zaXRpb24odGhpcy54LCB0aGlzLnksIHRoaXMudywgdGhpcy5oKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zLnRvcCA9IHRoaXMuZHJhZ2dpbmcudG9wO1xyXG4vLyAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcy5yaWdodCA9IHRoaXMuZHJhZ2dpbmcubGVmdDtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3MubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1Jlc2l6aW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zLndpZHRoID0gdGhpcy5yZXNpemluZy53aWR0aDtcclxuICAgICAgICAgICAgICAgICAgICBwb3MuaGVpZ2h0ID0gdGhpcy5yZXNpemluZy5oZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IHN0eWxlO1xyXG4gICAgICAgICAgICAgICAgLy8gQ1NTIFRyYW5zZm9ybXMgc3VwcG9ydCAoZGVmYXVsdClcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnVzZUNzc1RyYW5zZm9ybXMpIHtcclxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IHNldFRyYW5zZm9ybVJ0bChwb3MudG9wLCBwb3MucmlnaHQsIHBvcy53aWR0aCwgcG9zLmhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUcmFuc2Zvcm0ocG9zLnRvcCwgcG9zLmxlZnQsIHBvcy53aWR0aCwgcG9zLmhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIHRvcCxsZWZ0IChzbG93KVxyXG4vLyAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gc2V0VG9wUmlnaHQocG9zLnRvcCwgcG9zLnJpZ2h0LCBwb3Mud2lkdGgsIHBvcy5oZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gc2V0VG9wTGVmdChwb3MudG9wLCBwb3MubGVmdCwgcG9zLndpZHRoLCBwb3MuaGVpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlID0gc3R5bGU7XHJcblxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBoYW5kbGVSZXNpemU6IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSBnZXRDb250cm9sUG9zaXRpb24oZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IGRyYWcgcG9pbnQgZnJvbSB0aGUgZXZlbnQuIFRoaXMgaXMgdXNlZCBhcyB0aGUgb2Zmc2V0LlxyXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IG51bGwpIHJldHVybjsgLy8gbm90IHBvc3NpYmxlIGJ1dCBzYXRpc2ZpZXMgZmxvd1xyXG4gICAgICAgICAgICAgICAgY29uc3Qge3gsIHl9ID0gcG9zaXRpb247XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3U2l6ZSA9IHt3aWR0aDogMCwgaGVpZ2h0OiAwfTtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyZXNpemVzdGFydFwiOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzVyA9IHRoaXMudztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c0ggPSB0aGlzLmg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNQb3NpdGlvbih0aGlzLngsIHRoaXMueSwgdGhpcy53LCB0aGlzLmgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLndpZHRoID0gcG9zLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzaXppbmcgPSBuZXdTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUmVzaXppbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwicmVzaXplbW92ZVwiOlxyXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiIyMjIHJlc2l6ZSA9PiBcIiArIGV2ZW50LnR5cGUgKyBcIiwgbGFzdFc9XCIgKyB0aGlzLmxhc3RXICsgXCIsIGxhc3RIPVwiICsgdGhpcy5sYXN0SCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvcmVFdmVudCA9IGNyZWF0ZUNvcmVEYXRhKHRoaXMubGFzdFcsIHRoaXMubGFzdEgsIHgsIHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUud2lkdGggPSB0aGlzLnJlc2l6aW5nLndpZHRoIC0gY29yZUV2ZW50LmRlbHRhWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUud2lkdGggPSB0aGlzLnJlc2l6aW5nLndpZHRoICsgY29yZUV2ZW50LmRlbHRhWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHRoaXMucmVzaXppbmcuaGVpZ2h0ICsgY29yZUV2ZW50LmRlbHRhWTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vL2NvbnNvbGUubG9nKFwiIyMjIHJlc2l6ZSA9PiBcIiArIGV2ZW50LnR5cGUgKyBcIiwgZGVsdGFYPVwiICsgY29yZUV2ZW50LmRlbHRhWCArIFwiLCBkZWx0YVk9XCIgKyBjb3JlRXZlbnQuZGVsdGFZKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemluZyA9IG5ld1NpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJyZXNpemVlbmRcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIiMjIyByZXNpemUgZW5kID0+IHg9XCIgK3RoaXMueCArIFwiIHk9XCIgKyB0aGlzLnkgKyBcIiB3PVwiICsgdGhpcy53ICsgXCIgaD1cIiArIHRoaXMuaCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNQb3NpdGlvbih0aGlzLngsIHRoaXMueSwgdGhpcy53LCB0aGlzLmgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLndpZHRoID0gcG9zLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgcmVzaXplIGVuZCA9PiBcIiArIEpTT04uc3RyaW5naWZ5KG5ld1NpemUpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemluZyA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNSZXNpemluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgbmV3IFdIXHJcbiAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjV0gobmV3U2l6ZS5oZWlnaHQsIG5ld1NpemUud2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBvcy53IDwgdGhpcy5taW5XKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zLncgPSB0aGlzLm1pblc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocG9zLncgPiB0aGlzLm1heFcpIHtcclxuICAgICAgICAgICAgICAgICAgICBwb3MudyA9IHRoaXMubWF4VztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwb3MuaCA8IHRoaXMubWluSCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBvcy5oID0gdGhpcy5taW5IO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHBvcy5oID4gdGhpcy5tYXhIKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSB0aGlzLm1heEg7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHBvcy5oIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBvcy5oID0gMTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwb3MudyA8IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICBwb3MudyA9IDE7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5sYXN0VyA9IHg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RIID0geTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy53ICE9PSBwb3MudyB8fCB0aGlzLmggIT09IHBvcy5oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZW1pdChcInJlc2l6ZVwiLCB0aGlzLmksIHBvcy5oLCBwb3Mudyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJyZXNpemVlbmRcIiAmJiAodGhpcy5wcmV2aW91c1cgIT09IHRoaXMudyB8fCB0aGlzLnByZXZpb3VzSCAhPT0gdGhpcy5oKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXCJyZXNpemVkXCIsIHRoaXMuaSwgcG9zLmgsIHBvcy53LCBuZXdTaXplLmhlaWdodCwgbmV3U2l6ZS53aWR0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFwicmVzaXplRXZlbnRcIiwgZXZlbnQudHlwZSwgdGhpcy5pLCB0aGlzLngsIHRoaXMueSwgcG9zLmgsIHBvcy53KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaGFuZGxlRHJhZyhldmVudCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXNpemluZykgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0Q29udHJvbFBvc2l0aW9uKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgZHJhZyBwb2ludCBmcm9tIHRoZSBldmVudC4gVGhpcyBpcyB1c2VkIGFzIHRoZSBvZmZzZXQuXHJcbiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPT09IG51bGwpIHJldHVybjsgLy8gbm90IHBvc3NpYmxlIGJ1dCBzYXRpc2ZpZXMgZmxvd1xyXG4gICAgICAgICAgICAgICAgY29uc3Qge3gsIHl9ID0gcG9zaXRpb247XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIHNob3VsZFVwZGF0ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3UG9zaXRpb24gPSB7dG9wOiAwLCBsZWZ0OiAwfTtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJkcmFnc3RhcnRcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c1ggPSB0aGlzLng7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNZID0gdGhpcy55O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudFJlY3QgPSBldmVudC50YXJnZXQub2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xpZW50UmVjdCA9IGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gKGNsaWVudFJlY3QucmlnaHQgLSBwYXJlbnRSZWN0LnJpZ2h0KSAqIC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IGNsaWVudFJlY3QubGVmdCAtIHBhcmVudFJlY3QubGVmdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi50b3AgPSBjbGllbnRSZWN0LnRvcCAtIHBhcmVudFJlY3QudG9wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gbmV3UG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJkcmFnZW5kXCI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0RyYWdnaW5nKSByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudFJlY3QgPSBldmVudC50YXJnZXQub2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRSZWN0ID0gZXZlbnQudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSAoY2xpZW50UmVjdC5yaWdodCAtIHBhcmVudFJlY3QucmlnaHQpICogLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gY2xpZW50UmVjdC5sZWZ0IC0gcGFyZW50UmVjdC5sZWZ0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLnRvcCA9IGNsaWVudFJlY3QudG9wIC0gcGFyZW50UmVjdC50b3A7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgZHJhZyBlbmQgPT4gXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xyXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiIyMjIERST1A6IFwiICsgSlNPTi5zdHJpbmdpZnkobmV3UG9zaXRpb24pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2luZyA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG91bGRVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZHJhZ21vdmVcIjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29yZUV2ZW50ID0gY3JlYXRlQ29yZURhdGEodGhpcy5sYXN0WCwgdGhpcy5sYXN0WSwgeCwgeSk7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24ubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdCAtIGNvcmVFdmVudC5kZWx0YVg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gdGhpcy5kcmFnZ2luZy5sZWZ0ICsgY29yZUV2ZW50LmRlbHRhWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi50b3AgPSB0aGlzLmRyYWdnaW5nLnRvcCArIGNvcmVFdmVudC5kZWx0YVk7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgZHJhZyA9PiBcIiArIGV2ZW50LnR5cGUgKyBcIiwgeD1cIiArIHggKyBcIiwgeT1cIiArIHkpO1xyXG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiIyMjIGRyYWcgPT4gXCIgKyBldmVudC50eXBlICsgXCIsIGRlbHRhWD1cIiArIGNvcmVFdmVudC5kZWx0YVggKyBcIiwgZGVsdGFZPVwiICsgY29yZUV2ZW50LmRlbHRhWSk7XHJcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgZHJhZyBlbmQgPT4gXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gbmV3UG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIEdldCBuZXcgWFlcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNYWShuZXdQb3NpdGlvbi50b3AsIG5ld1Bvc2l0aW9uLmxlZnQpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjWFkobmV3UG9zaXRpb24udG9wLCBuZXdQb3NpdGlvbi5sZWZ0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RYID0geDtcclxuICAgICAgICAgICAgICAgIHRoaXMubGFzdFkgPSB5O1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnggIT09IHBvcy54IHx8IHRoaXMueSAhPT0gcG9zLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KFwibW92ZVwiLCB0aGlzLmksIHBvcy54LCBwb3MueSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJkcmFnZW5kXCIgJiYgKHRoaXMucHJldmlvdXNYICE9PSB0aGlzLnggfHwgdGhpcy5wcmV2aW91c1kgIT09IHRoaXMueSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KFwibW92ZWRcIiwgdGhpcy5pLCBwb3MueCwgcG9zLnkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcImRyYWdFdmVudFwiLCBldmVudC50eXBlLCB0aGlzLmksIHBvcy54LCBwb3MueSwgdGhpcy5oLCB0aGlzLncpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjYWxjUG9zaXRpb246IGZ1bmN0aW9uICh4LCB5LCB3LCBoKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xXaWR0aCA9IHRoaXMuY2FsY0NvbFdpZHRoKCk7XHJcbiAgICAgICAgICAgICAgICAvLyBhZGQgcnRsIHN1cHBvcnRcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvdXQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0OiBNYXRoLnJvdW5kKGNvbFdpZHRoICogeCArICh4ICsgMSkgKiB0aGlzLm1hcmdpblswXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIHkgKyAoeSArIDEpICogdGhpcy5tYXJnaW5bMV0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAwICogSW5maW5pdHkgPT09IE5hTiwgd2hpY2ggY2F1c2VzIHByb2JsZW1zIHdpdGggcmVzaXplIGNvbnN0cmlhbnRzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggdGhpcyBpZiBpdCBvY2N1cnMuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgd2UgZG8gaXQgaGVyZSByYXRoZXIgdGhhbiBsYXRlciBiZWNhdXNlIE1hdGgucm91bmQoSW5maW5pdHkpIGNhdXNlcyBkZW9wdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdyA9PT0gSW5maW5pdHkgPyB3IDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHcgKyBNYXRoLm1heCgwLCB3IC0gMSkgKiB0aGlzLm1hcmdpblswXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaCA9PT0gSW5maW5pdHkgPyBoIDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIGggKyBNYXRoLm1heCgwLCBoIC0gMSkgKiB0aGlzLm1hcmdpblsxXSlcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3V0ID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiBNYXRoLnJvdW5kKGNvbFdpZHRoICogeCArICh4ICsgMSkgKiB0aGlzLm1hcmdpblswXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIHkgKyAoeSArIDEpICogdGhpcy5tYXJnaW5bMV0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAwICogSW5maW5pdHkgPT09IE5hTiwgd2hpY2ggY2F1c2VzIHByb2JsZW1zIHdpdGggcmVzaXplIGNvbnN0cmlhbnRzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggdGhpcyBpZiBpdCBvY2N1cnMuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgd2UgZG8gaXQgaGVyZSByYXRoZXIgdGhhbiBsYXRlciBiZWNhdXNlIE1hdGgucm91bmQoSW5maW5pdHkpIGNhdXNlcyBkZW9wdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdyA9PT0gSW5maW5pdHkgPyB3IDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHcgKyBNYXRoLm1heCgwLCB3IC0gMSkgKiB0aGlzLm1hcmdpblswXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaCA9PT0gSW5maW5pdHkgPyBoIDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIGggKyBNYXRoLm1heCgwLCBoIC0gMSkgKiB0aGlzLm1hcmdpblsxXSlcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0O1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVHJhbnNsYXRlIHggYW5kIHkgY29vcmRpbmF0ZXMgZnJvbSBwaXhlbHMgdG8gZ3JpZCB1bml0cy5cclxuICAgICAgICAgICAgICogQHBhcmFtICB7TnVtYmVyfSB0b3AgIFRvcCBwb3NpdGlvbiAocmVsYXRpdmUgdG8gcGFyZW50KSBpbiBwaXhlbHMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gbGVmdCBMZWZ0IHBvc2l0aW9uIChyZWxhdGl2ZSB0byBwYXJlbnQpIGluIHBpeGVscy5cclxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB4IGFuZCB5IGluIGdyaWQgdW5pdHMuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAvLyBUT0RPIGNoZWNrIGlmIHRoaXMgZnVuY3Rpb24gbmVlZHMgY2hhbmdlIGluIG9yZGVyIHRvIHN1cHBvcnQgcnRsLlxyXG4gICAgICAgICAgICBjYWxjWFkodG9wLCBsZWZ0KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xXaWR0aCA9IHRoaXMuY2FsY0NvbFdpZHRoKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gbGVmdCA9IGNvbFdpZHRoICogeCArIG1hcmdpbiAqICh4ICsgMSlcclxuICAgICAgICAgICAgICAgIC8vIGwgPSBjeCArIG0oeCsxKVxyXG4gICAgICAgICAgICAgICAgLy8gbCA9IGN4ICsgbXggKyBtXHJcbiAgICAgICAgICAgICAgICAvLyBsIC0gbSA9IGN4ICsgbXhcclxuICAgICAgICAgICAgICAgIC8vIGwgLSBtID0geChjICsgbSlcclxuICAgICAgICAgICAgICAgIC8vIChsIC0gbSkgLyAoYyArIG0pID0geFxyXG4gICAgICAgICAgICAgICAgLy8geCA9IChsZWZ0IC0gbWFyZ2luKSAvIChjb2xkV2lkdGggKyBtYXJnaW4pXHJcbiAgICAgICAgICAgICAgICBsZXQgeCA9IE1hdGgucm91bmQoKGxlZnQgLSB0aGlzLm1hcmdpblswXSkgLyAoY29sV2lkdGggKyB0aGlzLm1hcmdpblswXSkpO1xyXG4gICAgICAgICAgICAgICAgbGV0IHkgPSBNYXRoLnJvdW5kKCh0b3AgLSB0aGlzLm1hcmdpblsxXSkgLyAodGhpcy5yb3dIZWlnaHQgKyB0aGlzLm1hcmdpblsxXSkpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIENhcHBpbmdcclxuICAgICAgICAgICAgICAgIHggPSBNYXRoLm1heChNYXRoLm1pbih4LCB0aGlzLmNvbHMgLSB0aGlzLncpLCAwKTtcclxuICAgICAgICAgICAgICAgIHkgPSBNYXRoLm1heChNYXRoLm1pbih5LCB0aGlzLm1heFJvd3MgLSB0aGlzLmgpLCAwKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge3gsIHl9O1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvLyBIZWxwZXIgZm9yIGdlbmVyYXRpbmcgY29sdW1uIHdpZHRoXHJcbiAgICAgICAgICAgIGNhbGNDb2xXaWR0aCgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBjb2xXaWR0aCA9ICh0aGlzLmNvbnRhaW5lcldpZHRoIC0gKHRoaXMubWFyZ2luWzBdICogKHRoaXMuY29scyArIDEpKSkgLyB0aGlzLmNvbHM7XHJcbi8vICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiIyMjIENPTFM9XCIgKyB0aGlzLmNvbHMgKyBcIiBDT0wgV0lEVEg9XCIgKyBjb2xXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sV2lkdGg7XHJcbiAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogR2l2ZW4gYSBoZWlnaHQgYW5kIHdpZHRoIGluIHBpeGVsIHZhbHVlcywgY2FsY3VsYXRlIGdyaWQgdW5pdHMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gaGVpZ2h0IEhlaWdodCBpbiBwaXhlbHMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gd2lkdGggIFdpZHRoIGluIHBpeGVscy5cclxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB3LCBoIGFzIGdyaWQgdW5pdHMuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBjYWxjV0goaGVpZ2h0LCB3aWR0aCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2lkdGggPSB0aGlzLmNhbGNDb2xXaWR0aCgpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIHdpZHRoID0gY29sV2lkdGggKiB3IC0gKG1hcmdpbiAqICh3IC0gMSkpXHJcbiAgICAgICAgICAgICAgICAvLyAuLi5cclxuICAgICAgICAgICAgICAgIC8vIHcgPSAod2lkdGggKyBtYXJnaW4pIC8gKGNvbFdpZHRoICsgbWFyZ2luKVxyXG4gICAgICAgICAgICAgICAgbGV0IHcgPSBNYXRoLnJvdW5kKCh3aWR0aCArIHRoaXMubWFyZ2luWzBdKSAvIChjb2xXaWR0aCArIHRoaXMubWFyZ2luWzBdKSk7XHJcbiAgICAgICAgICAgICAgICBsZXQgaCA9IE1hdGgucm91bmQoKGhlaWdodCArIHRoaXMubWFyZ2luWzFdKSAvICh0aGlzLnJvd0hlaWdodCArIHRoaXMubWFyZ2luWzFdKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQ2FwcGluZ1xyXG4gICAgICAgICAgICAgICAgdyA9IE1hdGgubWF4KE1hdGgubWluKHcsIHRoaXMuY29scyAtIHRoaXMueCksIDApO1xyXG4gICAgICAgICAgICAgICAgaCA9IE1hdGgubWF4KE1hdGgubWluKGgsIHRoaXMubWF4Um93cyAtIHRoaXMueSksIDApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHt3LCBofTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdXBkYXRlV2lkdGg6IGZ1bmN0aW9uICh3aWR0aCwgY29sTnVtKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gd2lkdGg7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sTnVtICE9PSB1bmRlZmluZWQgJiYgY29sTnVtICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2xzID0gY29sTnVtO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjb21wYWN0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgfVxyXG48L3NjcmlwdD5cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIEdyaWRJdGVtLnZ1ZT9iYzNmMTFiNCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///13\n"); /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nexports.__esModule = true;\n\nvar _utils = __webpack_require__(0);\n\nvar _draggableUtils = __webpack_require__(15);\n\n// var eventBus = require('./eventBus');\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\nvar interact = __webpack_require__(16);\n\nexports.default = {\n name: \"GridItem\",\n props: {\n /*cols: {\n type: Number,\n required: true\n },*/\n /*containerWidth: {\n type: Number,\n required: true\n },\n rowHeight: {\n type: Number,\n required: true\n },\n margin: {\n type: Array,\n required: true\n },\n maxRows: {\n type: Number,\n required: true\n },*/\n isDraggable: {\n type: Boolean,\n required: false,\n default: null\n },\n isResizable: {\n type: Boolean,\n required: false,\n default: null\n },\n /*useCssTransforms: {\n type: Boolean,\n required: true\n },\n static: {\n type: Boolean,\n required: false,\n default: false\n },\n */\n minH: {\n type: Number,\n required: false,\n default: 1\n },\n minW: {\n type: Number,\n required: false,\n default: 1\n },\n maxH: {\n type: Number,\n required: false,\n default: Infinity\n },\n maxW: {\n type: Number,\n required: false,\n default: Infinity\n },\n x: {\n type: Number,\n required: true\n },\n y: {\n type: Number,\n required: true\n },\n w: {\n type: Number,\n required: true\n },\n h: {\n type: Number,\n required: true\n },\n i: {\n required: true\n },\n dragIgnoreFrom: {\n type: String,\n required: false,\n default: 'a, button'\n },\n dragAllowFrom: {\n type: String,\n required: false,\n default: null\n },\n resizeIgnoreFrom: {\n type: String,\n required: false,\n default: 'a, button'\n }\n },\n inject: [\"eventBus\"],\n data: function data() {\n return {\n cols: 1,\n containerWidth: 100,\n rowHeight: 30,\n margin: [10, 10],\n maxRows: Infinity,\n draggable: null,\n resizable: null,\n useCssTransforms: true,\n\n isDragging: false,\n dragging: null,\n isResizing: false,\n resizing: null,\n lastX: NaN,\n lastY: NaN,\n lastW: NaN,\n lastH: NaN,\n style: {},\n rtl: false,\n\n dragEventSet: false,\n resizeEventSet: false,\n\n previousW: null,\n previousH: null,\n previousX: null,\n previousY: null\n };\n },\n created: function created() {\n var _this = this;\n\n var self = this;\n\n // Accessible refernces of functions for removing in beforeDestroy\n self.updateWidthHandler = function (width) {\n self.updateWidth(width);\n };\n\n self.compactHandler = function (layout) {\n self.compact(layout);\n };\n\n self.setDraggableHandler = function (isDraggable) {\n if (self.isDraggable === null) {\n self.draggable = isDraggable;\n }\n };\n\n self.setResizableHandler = function (isResizable) {\n if (self.isResizable === null) {\n self.resizable = isResizable;\n }\n };\n\n self.setRowHeightHandler = function (rowHeight) {\n self.rowHeight = rowHeight;\n };\n\n self.directionchangeHandler = function (direction) {\n var direction = document.dir !== undefined ? document.dir : document.getElementsByTagName(\"html\")[0].getAttribute(\"dir\");\n _this.rtl = direction === \"rtl\";\n _this.compact();\n };\n\n this.eventBus.$on('updateWidth', self.updateWidthHandler);\n this.eventBus.$on('compact', self.compactHandler);\n this.eventBus.$on('setDraggable', self.setDraggableHandler);\n this.eventBus.$on('setResizable', self.setResizableHandler);\n this.eventBus.$on('setRowHeight', self.setRowHeightHandler);\n this.eventBus.$on('directionchange', self.directionchangeHandler);\n\n /*this.eventBus.$on('setColNum', function(colNum) {\n self.cols = colNum;\n });*/\n var direction = document.dir !== undefined ? document.dir : document.getElementsByTagName(\"html\")[0].getAttribute(\"dir\");\n this.rtl = direction === \"rtl\";\n },\n\n beforeDestroy: function beforeDestroy() {\n var self = this;\n //Remove listeners\n this.eventBus.$off('updateWidth', self.updateWidthHandler);\n this.eventBus.$off('compact', self.compactHandler);\n this.eventBus.$off('setDraggable', self.setDraggableHandler);\n this.eventBus.$off('setResizable', self.setResizableHandler);\n this.eventBus.$off('setRowHeight', self.setRowHeightHandler);\n this.eventBus.$off('directionchange', self.directionchangeHandler);\n },\n mounted: function mounted() {\n this.cols = this.$parent.colNum;\n this.rowHeight = this.$parent.rowHeight;\n this.containerWidth = this.$parent.width !== null ? this.$parent.width : 100;\n this.margin = this.$parent.margin !== undefined ? this.$parent.margin : [10, 10];\n this.maxRows = this.$parent.maxRows;\n if (this.isDraggable === null) {\n this.draggable = this.$parent.isDraggable;\n } else {\n this.draggable = this.isDraggable;\n }\n if (this.isResizable === null) {\n this.resizable = this.$parent.isResizable;\n } else {\n this.resizable = this.isResizable;\n }\n this.useCssTransforms = this.$parent.useCssTransforms;\n this.createStyle();\n },\n watch: {\n isDraggable: function isDraggable() {\n this.draggable = this.isDraggable;\n },\n draggable: function draggable() {\n var self = this;\n if (this.interactObj === null || this.interactObj === undefined) {\n this.interactObj = interact(this.$refs.item);\n }\n if (this.draggable) {\n var opts = {\n ignoreFrom: this.dragIgnoreFrom,\n allowFrom: this.dragAllowFrom\n };\n this.interactObj.draggable(opts);\n /*this.interactObj.draggable({allowFrom: '.vue-draggable-handle'});*/\n if (!this.dragEventSet) {\n this.dragEventSet = true;\n this.interactObj.on('dragstart dragmove dragend', function (event) {\n self.handleDrag(event);\n });\n }\n } else {\n this.interactObj.draggable({\n enabled: false\n });\n }\n },\n isResizable: function isResizable() {\n this.resizable = this.isResizable;\n },\n resizable: function resizable() {\n var self = this;\n if (this.interactObj === null || this.interactObj === undefined) {\n this.interactObj = interact(this.$refs.item);\n }\n if (this.resizable) {\n var opts = {\n preserveAspectRatio: false,\n edges: { left: false, right: true, bottom: true, top: false },\n ignoreFrom: this.resizeIgnoreFrom\n };\n\n this.interactObj.resizable(opts);\n if (!this.resizeEventSet) {\n this.resizeEventSet = true;\n this.interactObj.on('resizestart resizemove resizeend', function (event) {\n self.handleResize(event);\n });\n }\n } else {\n this.interactObj.resizable({\n enabled: false\n });\n }\n },\n rowHeight: function rowHeight() {\n this.createStyle();\n },\n cols: function cols() {\n this.createStyle();\n },\n containerWidth: function containerWidth() {\n this.createStyle();\n },\n x: function x() {\n this.createStyle();\n },\n y: function y() {\n this.createStyle();\n },\n h: function h() {\n this.createStyle();\n },\n w: function w() {\n this.createStyle();\n },\n renderRtl: function renderRtl() {\n this.createStyle();\n }\n },\n computed: {\n renderRtl: function renderRtl() {\n return this.$parent.isMirrored ? !this.rtl : this.rtl;\n },\n resizableHandleClass: function resizableHandleClass() {\n if (this.renderRtl) {\n return 'vue-resizable-handle vue-rtl-resizable-handle';\n } else {\n return 'vue-resizable-handle';\n }\n }\n },\n methods: {\n createStyle: function createStyle() {\n if (this.x + this.w > this.cols) {\n this.x = 0;\n this.w = this.cols;\n }\n\n var pos = this.calcPosition(this.x, this.y, this.w, this.h);\n\n if (this.isDragging) {\n pos.top = this.dragging.top;\n // Add rtl support\n if (this.renderRtl) {\n pos.right = this.dragging.left;\n } else {\n pos.left = this.dragging.left;\n }\n }\n if (this.isResizing) {\n pos.width = this.resizing.width;\n pos.height = this.resizing.height;\n }\n\n var style = void 0;\n // CSS Transforms support (default)\n if (this.useCssTransforms) {\n // Add rtl support\n if (this.renderRtl) {\n style = (0, _utils.setTransformRtl)(pos.top, pos.right, pos.width, pos.height);\n } else {\n style = (0, _utils.setTransform)(pos.top, pos.left, pos.width, pos.height);\n }\n } else {\n // top,left (slow)\n // Add rtl support\n if (this.renderRtl) {\n style = (0, _utils.setTopRight)(pos.top, pos.right, pos.width, pos.height);\n } else {\n style = (0, _utils.setTopLeft)(pos.top, pos.left, pos.width, pos.height);\n }\n }\n this.style = style;\n },\n handleResize: function handleResize(event) {\n var position = (0, _draggableUtils.getControlPosition)(event);\n // Get the current drag point from the event. This is used as the offset.\n if (position == null) return; // not possible but satisfies flow\n var x = position.x,\n y = position.y;\n\n\n var newSize = { width: 0, height: 0 };\n switch (event.type) {\n case \"resizestart\":\n this.previousW = this.w;\n this.previousH = this.h;\n var pos = this.calcPosition(this.x, this.y, this.w, this.h);\n newSize.width = pos.width;\n newSize.height = pos.height;\n this.resizing = newSize;\n this.isResizing = true;\n break;\n case \"resizemove\":\n // console.log(\"### resize => \" + event.type + \", lastW=\" + this.lastW + \", lastH=\" + this.lastH);\n var coreEvent = (0, _draggableUtils.createCoreData)(this.lastW, this.lastH, x, y);\n if (this.renderRtl) {\n newSize.width = this.resizing.width - coreEvent.deltaX;\n } else {\n newSize.width = this.resizing.width + coreEvent.deltaX;\n }\n newSize.height = this.resizing.height + coreEvent.deltaY;\n\n ///console.log(\"### resize => \" + event.type + \", deltaX=\" + coreEvent.deltaX + \", deltaY=\" + coreEvent.deltaY);\n this.resizing = newSize;\n break;\n case \"resizeend\":\n //console.log(\"### resize end => x=\" +this.x + \" y=\" + this.y + \" w=\" + this.w + \" h=\" + this.h);\n var pos = this.calcPosition(this.x, this.y, this.w, this.h);\n newSize.width = pos.width;\n newSize.height = pos.height;\n // console.log(\"### resize end => \" + JSON.stringify(newSize));\n this.resizing = null;\n this.isResizing = false;\n break;\n }\n\n // Get new WH\n var pos = this.calcWH(newSize.height, newSize.width);\n if (pos.w < this.minW) {\n pos.w = this.minW;\n }\n if (pos.w > this.maxW) {\n pos.w = this.maxW;\n }\n if (pos.h < this.minH) {\n pos.h = this.minH;\n }\n if (pos.h > this.maxH) {\n pos.h = this.maxH;\n }\n\n if (pos.h < 1) {\n pos.h = 1;\n }\n if (pos.w < 1) {\n pos.w = 1;\n }\n\n this.lastW = x;\n this.lastH = y;\n\n if (this.w !== pos.w || this.h !== pos.h) {\n this.$emit(\"resize\", this.i, pos.h, pos.w);\n }\n if (event.type === \"resizeend\" && (this.previousW !== this.w || this.previousH !== this.h)) {\n this.$emit(\"resized\", this.i, pos.h, pos.w, newSize.height, newSize.width);\n }\n this.eventBus.$emit(\"resizeEvent\", event.type, this.i, this.x, this.y, pos.h, pos.w);\n },\n handleDrag: function handleDrag(event) {\n if (this.isResizing) return;\n\n var position = (0, _draggableUtils.getControlPosition)(event);\n\n // Get the current drag point from the event. This is used as the offset.\n if (position === null) return; // not possible but satisfies flow\n var x = position.x,\n y = position.y;\n\n\n var shouldUpdate = false;\n var newPosition = { top: 0, left: 0 };\n switch (event.type) {\n case \"dragstart\":\n this.previousX = this.x;\n this.previousY = this.y;\n\n var parentRect = event.target.offsetParent.getBoundingClientRect();\n var clientRect = event.target.getBoundingClientRect();\n if (this.renderRtl) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n this.dragging = newPosition;\n this.isDragging = true;\n break;\n case \"dragend\":\n if (!this.isDragging) return;\n parentRect = event.target.offsetParent.getBoundingClientRect();\n clientRect = event.target.getBoundingClientRect();\n // Add rtl support\n if (this.renderRtl) {\n newPosition.left = (clientRect.right - parentRect.right) * -1;\n } else {\n newPosition.left = clientRect.left - parentRect.left;\n }\n newPosition.top = clientRect.top - parentRect.top;\n // console.log(\"### drag end => \" + JSON.stringify(newPosition));\n // console.log(\"### DROP: \" + JSON.stringify(newPosition));\n this.dragging = null;\n this.isDragging = false;\n shouldUpdate = true;\n break;\n case \"dragmove\":\n var coreEvent = (0, _draggableUtils.createCoreData)(this.lastX, this.lastY, x, y);\n // Add rtl support\n if (this.renderRtl) {\n newPosition.left = this.dragging.left - coreEvent.deltaX;\n } else {\n newPosition.left = this.dragging.left + coreEvent.deltaX;\n }\n newPosition.top = this.dragging.top + coreEvent.deltaY;\n // console.log(\"### drag => \" + event.type + \", x=\" + x + \", y=\" + y);\n // console.log(\"### drag => \" + event.type + \", deltaX=\" + coreEvent.deltaX + \", deltaY=\" + coreEvent.deltaY);\n // console.log(\"### drag end => \" + JSON.stringify(newPosition));\n this.dragging = newPosition;\n break;\n }\n\n // Get new XY\n if (this.renderRtl) {\n var pos = this.calcXY(newPosition.top, newPosition.left);\n } else {\n var pos = this.calcXY(newPosition.top, newPosition.left);\n }\n\n this.lastX = x;\n this.lastY = y;\n\n if (this.x !== pos.x || this.y !== pos.y) {\n this.$emit(\"move\", this.i, pos.x, pos.y);\n }\n if (event.type === \"dragend\" && (this.previousX !== this.x || this.previousY !== this.y)) {\n this.$emit(\"moved\", this.i, pos.x, pos.y);\n }\n this.eventBus.$emit(\"dragEvent\", event.type, this.i, pos.x, pos.y, this.h, this.w);\n },\n\n calcPosition: function calcPosition(x, y, w, h) {\n var colWidth = this.calcColWidth();\n // add rtl support\n if (this.renderRtl) {\n var out = {\n right: Math.round(colWidth * x + (x + 1) * this.margin[0]),\n top: Math.round(this.rowHeight * y + (y + 1) * this.margin[1]),\n // 0 * Infinity === NaN, which causes problems with resize constriants;\n // Fix this if it occurs.\n // Note we do it here rather than later because Math.round(Infinity) causes deopt\n width: w === Infinity ? w : Math.round(colWidth * w + Math.max(0, w - 1) * this.margin[0]),\n height: h === Infinity ? h : Math.round(this.rowHeight * h + Math.max(0, h - 1) * this.margin[1])\n };\n } else {\n var out = {\n left: Math.round(colWidth * x + (x + 1) * this.margin[0]),\n top: Math.round(this.rowHeight * y + (y + 1) * this.margin[1]),\n // 0 * Infinity === NaN, which causes problems with resize constriants;\n // Fix this if it occurs.\n // Note we do it here rather than later because Math.round(Infinity) causes deopt\n width: w === Infinity ? w : Math.round(colWidth * w + Math.max(0, w - 1) * this.margin[0]),\n height: h === Infinity ? h : Math.round(this.rowHeight * h + Math.max(0, h - 1) * this.margin[1])\n };\n }\n\n return out;\n },\n /**\n * Translate x and y coordinates from pixels to grid units.\n * @param {Number} top Top position (relative to parent) in pixels.\n * @param {Number} left Left position (relative to parent) in pixels.\n * @return {Object} x and y in grid units.\n */\n // TODO check if this function needs change in order to support rtl.\n calcXY: function calcXY(top, left) {\n var colWidth = this.calcColWidth();\n\n // left = colWidth * x + margin * (x + 1)\n // l = cx + m(x+1)\n // l = cx + mx + m\n // l - m = cx + mx\n // l - m = x(c + m)\n // (l - m) / (c + m) = x\n // x = (left - margin) / (coldWidth + margin)\n var x = Math.round((left - this.margin[0]) / (colWidth + this.margin[0]));\n var y = Math.round((top - this.margin[1]) / (this.rowHeight + this.margin[1]));\n\n // Capping\n x = Math.max(Math.min(x, this.cols - this.w), 0);\n y = Math.max(Math.min(y, this.maxRows - this.h), 0);\n\n return { x: x, y: y };\n },\n\n // Helper for generating column width\n calcColWidth: function calcColWidth() {\n var colWidth = (this.containerWidth - this.margin[0] * (this.cols + 1)) / this.cols;\n // console.log(\"### COLS=\" + this.cols + \" COL WIDTH=\" + colWidth);\n return colWidth;\n },\n\n\n /**\n * Given a height and width in pixel values, calculate grid units.\n * @param {Number} height Height in pixels.\n * @param {Number} width Width in pixels.\n * @return {Object} w, h as grid units.\n */\n calcWH: function calcWH(height, width) {\n var colWidth = this.calcColWidth();\n\n // width = colWidth * w - (margin * (w - 1))\n // ...\n // w = (width + margin) / (colWidth + margin)\n var w = Math.round((width + this.margin[0]) / (colWidth + this.margin[0]));\n var h = Math.round((height + this.margin[1]) / (this.rowHeight + this.margin[1]));\n\n // Capping\n w = Math.max(Math.min(w, this.cols - this.x), 0);\n h = Math.max(Math.min(h, this.maxRows - this.y), 0);\n return { w: w, h: h };\n },\n\n updateWidth: function updateWidth(width, colNum) {\n this.containerWidth = width;\n if (colNum !== undefined && colNum !== null) {\n this.cols = colNum;\n }\n },\n compact: function compact() {\n this.createStyle();\n }\n }\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vR3JpZEl0ZW0udnVlPzNhMTEiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQWdGQTs7QUFDQTs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUpBOzttQ0FNQTs7O1VBRUE7O0FBS0E7Ozs7QUFpQkE7Ozs7Ozs7Ozs7Ozs7Ozs7O2tCQUVBO3NCQUNBO3FCQUVBO0FBSkE7O2tCQU1BO3NCQUNBO3FCQUVBO0FBSkE7QUFjQTs7Ozs7Ozs7Ozs7a0JBRUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBRUE7QUFIQTs7a0JBS0E7c0JBRUE7QUFIQTs7a0JBS0E7c0JBRUE7QUFIQTs7a0JBS0E7c0JBRUE7QUFIQTs7c0JBTUE7QUFGQTs7a0JBSUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBRUE7QUFKQTs7a0JBTUE7c0JBQ0E7cUJBR0E7QUFMQTtBQTNGQTthQWlHQTswQkFDQTs7a0JBRUE7NEJBQ0E7dUJBQ0E7eUJBQ0E7cUJBQ0E7dUJBQ0E7dUJBQ0E7OEJBRUE7O3dCQUNBO3NCQUNBO3dCQUNBO3NCQUNBO21CQUNBO21CQUNBO21CQUNBO21CQUNBO21CQUNBO2lCQUVBOzswQkFDQTs0QkFFQTs7dUJBQ0E7dUJBQ0E7dUJBQ0E7dUJBRUE7QUE1QkE7QUE2QkE7O0FBQ0E7O21CQUVBOztBQUNBO21EQUNBOzZCQUNBO0FBRUE7O2dEQUNBO3lCQUNBO0FBRUE7OzBEQUNBOzJDQUNBO2lDQUNBO0FBQ0E7QUFFQTs7MERBQ0E7MkNBQ0E7aUNBQ0E7QUFDQTtBQUVBOzt3REFDQTs2QkFDQTtBQUVBOzsyREFDQTs2Q0FDQSxxQkFDQSw0REFDQTtzQ0FDQTtrQkFDQTtBQUVBOzs4Q0FDQTsw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O0FBQ0E7QUFDQTtBQUNBOzJHQUNBO2tIQUVBO0FBUkE7QUFXQTs7bUJBQ0E7QUFDQTtBQU1BOzs7Ozs7QUFDQTsyQ0FDQTtnQ0FFQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtpRkFDQTtzRkFFQTs7QUFDQTswREFDQTs2REFFQTs7MkJBQ0E7QUFDQTs7QUFDQTs4Q0FDQTs7QUFFQTttQkFDQTtBQUVBOzs7QUFNQTs7Ozs7OytDQUNBO2dDQUVBOztBQUNBO0FBQ0E7QUFDQTtrRkFDQTt5RkFFQTs7QUFDQTswREFDQTs2REFDQTsyQkFDQTtBQUNBOzt5REFDQTtrQ0FDQTt5REFDQTs0QkFDQTtBQUNBO0FBQ0E7b0NBQ0E7aUJBQ0E7QUFFQTtBQTlSQTtBQWpUQSIsImZpbGUiOiIxNC5qcyIsInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cbiAgICA8ZGl2IHJlZj1cIml0ZW1cIlxuICAgICAgICAgY2xhc3M9XCJ2dWUtZ3JpZC1pdGVtXCJcbiAgICAgICAgIDpjbGFzcz1cInsgJ3Z1ZS1yZXNpemFibGUnIDogcmVzaXphYmxlLCAncmVzaXppbmcnIDogaXNSZXNpemluZywgJ3Z1ZS1kcmFnZ2FibGUtZHJhZ2dpbmcnIDogaXNEcmFnZ2luZywgJ2Nzc1RyYW5zZm9ybXMnIDogdXNlQ3NzVHJhbnNmb3JtcywgJ3JlbmRlci1ydGwnIDogcmVuZGVyUnRsIH1cIlxuICAgICAgICAgOnN0eWxlPVwic3R5bGVcIlxuICAgID5cbiAgICAgICAgPHNsb3Q+PC9zbG90PlxuICAgICAgICA8c3BhbiB2LWlmPVwicmVzaXphYmxlXCIgcmVmPVwiaGFuZGxlXCIgOmNsYXNzPVwicmVzaXphYmxlSGFuZGxlQ2xhc3NcIj48L3NwYW4+XG4gICAgICAgIDwhLS08c3BhbiB2LWlmPVwiZHJhZ2dhYmxlXCIgcmVmPVwiZHJhZ0hhbmRsZVwiIGNsYXNzPVwidnVlLWRyYWdnYWJsZS1oYW5kbGVcIj48L3NwYW4+LS0+XG4gICAgPC9kaXY+XG48L3RlbXBsYXRlPlxuPHN0eWxlPlxuICAgIC52dWUtZ3JpZC1pdGVtIHtcbiAgICAgICAgdHJhbnNpdGlvbjogYWxsIDIwMG1zIGVhc2U7XG4gICAgICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IGxlZnQsIHRvcCwgcmlnaHQ7XG4gICAgICAgIC8qIGFkZCByaWdodCBmb3IgcnRsICovXG4gICAgfVxuXG4gICAgLnZ1ZS1ncmlkLWl0ZW0uY3NzVHJhbnNmb3JtcyB7XG4gICAgICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IHRyYW5zZm9ybTtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgcmlnaHQ6IGF1dG87XG4gICAgfVxuXG4gICAgLnZ1ZS1ncmlkLWl0ZW0uY3NzVHJhbnNmb3Jtcy5yZW5kZXItcnRsIHtcbiAgICAgICAgbGVmdDogYXV0bztcbiAgICAgICAgcmlnaHQ6IDA7XG4gICAgfVxuXG4gICAgLnZ1ZS1ncmlkLWl0ZW0ucmVzaXppbmcge1xuICAgICAgICBvcGFjaXR5OiAwLjY7XG4gICAgICAgIHotaW5kZXg6IDM7XG4gICAgfVxuXG4gICAgLnZ1ZS1ncmlkLWl0ZW0udnVlLWRyYWdnYWJsZS1kcmFnZ2luZyB7XG4gICAgICAgIHRyYW5zaXRpb246bm9uZTtcbiAgICAgICAgei1pbmRleDogMztcbiAgICB9XG5cbiAgICAudnVlLWdyaWQtaXRlbS52dWUtZ3JpZC1wbGFjZWhvbGRlciB7XG4gICAgICAgIGJhY2tncm91bmQ6IHJlZDtcbiAgICAgICAgb3BhY2l0eTogMC4yO1xuICAgICAgICB0cmFuc2l0aW9uLWR1cmF0aW9uOiAxMDBtcztcbiAgICAgICAgei1pbmRleDogMjtcbiAgICAgICAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcbiAgICAgICAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcbiAgICAgICAgLW1zLXVzZXItc2VsZWN0OiBub25lO1xuICAgICAgICAtby11c2VyLXNlbGVjdDogbm9uZTtcbiAgICAgICAgdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgfVxuXG4gICAgLnZ1ZS1ncmlkLWl0ZW0gPiAudnVlLXJlc2l6YWJsZS1oYW5kbGUge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHdpZHRoOiAyMHB4O1xuICAgICAgICBoZWlnaHQ6IDIwcHg7XG4gICAgICAgIGJvdHRvbTogMDtcbiAgICAgICAgcmlnaHQ6IDA7XG4gICAgICAgIGJhY2tncm91bmQ6IHVybCgnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJ6ZEdGdVpHRnNiMjVsUFNKdWJ5SS9QZzA4SVMwdElFZGxibVZ5WVhSdmNqb2dRV1J2WW1VZ1JtbHlaWGR2Y210eklFTlROaXdnUlhod2IzSjBJRk5XUnlCRmVIUmxibk5wYjI0Z1lua2dRV0Z5YjI0Z1FtVmhiR3dnS0doMGRIQTZMeTltYVhKbGQyOXlhM011WVdKbFlXeHNMbU52YlNrZ0xpQldaWEp6YVc5dU9pQXdMall1TVNBZ0xTMCtEVHdoUkU5RFZGbFFSU0J6ZG1jZ1VGVkNURWxESUNJdEx5OVhNME12TDBSVVJDQlRWa2NnTVM0eEx5OUZUaUlnSW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTDBkeVlYQm9hV056TDFOV1J5OHhMakV2UkZSRUwzTjJaekV4TG1SMFpDSStEVHh6ZG1jZ2FXUTlJbFZ1ZEdsMGJHVmtMVkJoWjJVbE1qQXhJaUIyYVdWM1FtOTRQU0l3SURBZ05pQTJJaUJ6ZEhsc1pUMGlZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqb2pabVptWm1abU1EQWlJSFpsY25OcGIyNDlJakV1TVNJTkNYaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhodGJEcHpjR0ZqWlQwaWNISmxjMlZ5ZG1VaURRbDRQU0l3Y0hnaUlIazlJakJ3ZUNJZ2QybGtkR2c5SWpad2VDSWdhR1ZwWjJoMFBTSTJjSGdpRFQ0TkNUeG5JRzl3WVdOcGRIazlJakF1TXpBeUlqNE5DUWs4Y0dGMGFDQmtQU0pOSURZZ05pQk1JREFnTmlCTUlEQWdOQzR5SUV3Z05DQTBMaklnVENBMExqSWdOQzR5SUV3Z05DNHlJREFnVENBMklEQWdUQ0EySURZZ1RDQTJJRFlnV2lJZ1ptbHNiRDBpSXpBd01EQXdNQ0l2UGcwSlBDOW5QZzA4TDNOMlp6ND0nKTtcbiAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIHJpZ2h0O1xuICAgICAgICBwYWRkaW5nOiAwIDNweCAzcHggMDtcbiAgICAgICAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgICAgICAgYmFja2dyb3VuZC1vcmlnaW46IGNvbnRlbnQtYm94O1xuICAgICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgICBjdXJzb3I6IHNlLXJlc2l6ZTtcbiAgICB9XG5cbiAgICAudnVlLWdyaWQtaXRlbSA+IC52dWUtcnRsLXJlc2l6YWJsZS1oYW5kbGUge1xuICAgICAgICBib3R0b206IDA7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIGJhY2tncm91bmQ6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUIzYVdSMGFEMGlNVEF1TURBd01EQXdNREF3TURBd01EQXlJaUJvWldsbmFIUTlJakV3TGpBd01EQXdNREF3TURBd01EQXdNaUlnZUcxc2JuTTlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5Mekl3TURBdmMzWm5JajRLSUR3aExTMGdRM0psWVhSbFpDQjNhWFJvSUUxbGRHaHZaQ0JFY21GM0lDMGdhSFIwY0RvdkwyZHBkR2gxWWk1amIyMHZaSFZ2Y0dsNFpXd3ZUV1YwYUc5a0xVUnlZWGN2SUMwdFBnb2dQR2MrQ2lBZ1BIUnBkR3hsUG1KaFkydG5jbTkxYm1ROEwzUnBkR3hsUGdvZ0lEeHlaV04wSUdacGJHdzlJbTV2Ym1VaUlHbGtQU0pqWVc1MllYTmZZbUZqYTJkeWIzVnVaQ0lnYUdWcFoyaDBQU0l4TWlJZ2QybGtkR2c5SWpFeUlpQjVQU0l0TVNJZ2VEMGlMVEVpTHo0S0lDQThaeUJrYVhOd2JHRjVQU0p1YjI1bElpQnZkbVZ5Wm14dmR6MGlkbWx6YVdKc1pTSWdlVDBpTUNJZ2VEMGlNQ0lnYUdWcFoyaDBQU0l4TURBbElpQjNhV1IwYUQwaU1UQXdKU0lnYVdROUltTmhiblpoYzBkeWFXUWlQZ29nSUNBOGNtVmpkQ0JtYVd4c1BTSjFjbXdvSTJkeWFXUndZWFIwWlhKdUtTSWdjM1J5YjJ0bExYZHBaSFJvUFNJd0lpQjVQU0l3SWlCNFBTSXdJaUJvWldsbmFIUTlJakV3TUNVaUlIZHBaSFJvUFNJeE1EQWxJaTgrQ2lBZ1BDOW5QZ29nUEM5blBnb2dQR2MrQ2lBZ1BIUnBkR3hsUGt4aGVXVnlJREU4TDNScGRHeGxQZ29nSUR4c2FXNWxJR05oYm5aaGN6MGlJMlptWm1abVppSWdZMkZ1ZG1GekxXOXdZV05wZEhrOUlqRWlJSE4wY205clpTMXNhVzVsWTJGd1BTSjFibVJsWm1sdVpXUWlJSE4wY205clpTMXNhVzVsYW05cGJqMGlkVzVrWldacGJtVmtJaUJwWkQwaWMzWm5YekVpSUhreVBTSXROekF1TVRjNE5EQTNJaUI0TWowaU1USTBMalEyTkRFM05TSWdlVEU5SWkwek9DNHpPVEkzTXpjaUlIZ3hQU0l4TkRRdU9ESXhNamc1SWlCemRISnZhMlV0ZDJsa2RHZzlJakV1TlNJZ2MzUnliMnRsUFNJak1EQXdJaUJtYVd4c1BTSnViMjVsSWk4K0NpQWdQR3hwYm1VZ2MzUnliMnRsUFNJak5qWTJOalkySWlCemRISnZhMlV0YkdsdVpXTmhjRDBpZFc1a1pXWnBibVZrSWlCemRISnZhMlV0YkdsdVpXcHZhVzQ5SW5WdVpHVm1hVzVsWkNJZ2FXUTlJbk4yWjE4MUlpQjVNajBpT1M0eE1EWTVOVGNpSUhneVBTSXdMamswTnpJME55SWdlVEU5SWkwd0xqQXhPREV5T0NJZ2VERTlJakF1T1RRM01qUTNJaUJ6ZEhKdmEyVXRkMmxrZEdnOUlqSWlJR1pwYkd3OUltNXZibVVpTHo0S0lDQThiR2x1WlNCemRISnZhMlV0YkdsdVpXTmhjRDBpZFc1a1pXWnBibVZrSWlCemRISnZhMlV0YkdsdVpXcHZhVzQ5SW5WdVpHVm1hVzVsWkNJZ2FXUTlJbk4yWjE4M0lpQjVNajBpT1NJZ2VESTlJakV3TGpBM016VXlPU0lnZVRFOUlqa2lJSGd4UFNJdE1DNDJOVFUyTkNJZ2MzUnliMnRsTFhkcFpIUm9QU0l5SWlCemRISnZhMlU5SWlNMk5qWTJOallpSUdacGJHdzlJbTV2Ym1VaUx6NEtJRHd2Wno0S1BDOXpkbWMrKTtcbiAgICAgICAgYmFja2dyb3VuZC1wb3NpdGlvbjogYm90dG9tIGxlZnQ7XG4gICAgICAgIHBhZGRpbmctbGVmdDogM3B4O1xuICAgICAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICAgICAgICBiYWNrZ3JvdW5kLW9yaWdpbjogY29udGVudC1ib3g7XG4gICAgICAgIGN1cnNvcjogc3ctcmVzaXplO1xuICAgICAgICByaWdodDogYXV0bztcbiAgICB9XG48L3N0eWxlPlxuPHNjcmlwdD5cbiAgICBpbXBvcnQge3NldFRvcExlZnQsIHNldFRvcFJpZ2h0LCBzZXRUcmFuc2Zvcm1SdGwsIHNldFRyYW5zZm9ybSwgY3JlYXRlTWFya3VwLCBnZXRMYXlvdXRJdGVtfSBmcm9tICcuL3V0aWxzJztcbiAgICBpbXBvcnQge2dldENvbnRyb2xQb3NpdGlvbiwgb2Zmc2V0WFlGcm9tUGFyZW50T2YsIGNyZWF0ZUNvcmVEYXRhfSBmcm9tICcuL2RyYWdnYWJsZVV0aWxzJztcbiAgICAvLyAgICB2YXIgZXZlbnRCdXMgPSByZXF1aXJlKCcuL2V2ZW50QnVzJyk7XG5cbiAgICB2YXIgaW50ZXJhY3QgPSByZXF1aXJlKFwiaW50ZXJhY3Rqc1wiKTtcblxuICAgIGV4cG9ydCBkZWZhdWx0IHtcbiAgICAgICAgbmFtZTogXCJHcmlkSXRlbVwiLFxuICAgICAgICBwcm9wczoge1xuICAgICAgICAgICAgLypjb2xzOiB7XG4gICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXG4gICAgICAgICAgICAgfSwqL1xuICAgICAgICAgICAgLypjb250YWluZXJXaWR0aDoge1xuICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcbiAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxuXG4gICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICByb3dIZWlnaHQ6IHtcbiAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXG4gICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgIG1hcmdpbjoge1xuICAgICAgICAgICAgIHR5cGU6IEFycmF5LFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXG4gICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICBtYXhSb3dzOiB7XG4gICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxuICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXG4gICAgICAgICAgICAgfSwqL1xuICAgICAgICAgICAgaXNEcmFnZ2FibGU6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBudWxsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBudWxsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgLyp1c2VDc3NUcmFuc2Zvcm1zOiB7XG4gICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcbiAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxuICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgc3RhdGljOiB7XG4gICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcbiAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgZGVmYXVsdDogZmFsc2VcbiAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBtaW5IOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAxXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbWluVzoge1xuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG1heEg6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IEluZmluaXR5XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbWF4Vzoge1xuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB4OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeToge1xuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHc6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBoOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaToge1xuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZHJhZ0lnbm9yZUZyb206IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBTdHJpbmcsXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6ICdhLCBidXR0b24nXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZHJhZ0FsbG93RnJvbToge1xuICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogbnVsbFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlc2l6ZUlnbm9yZUZyb206IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBTdHJpbmcsXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6ICdhLCBidXR0b24nXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBpbmplY3Q6IFtcImV2ZW50QnVzXCJdLFxuICAgICAgICBkYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGNvbHM6IDEsXG4gICAgICAgICAgICAgICAgY29udGFpbmVyV2lkdGg6IDEwMCxcbiAgICAgICAgICAgICAgICByb3dIZWlnaHQ6IDMwLFxuICAgICAgICAgICAgICAgIG1hcmdpbjogWzEwLCAxMF0sXG4gICAgICAgICAgICAgICAgbWF4Um93czogSW5maW5pdHksXG4gICAgICAgICAgICAgICAgZHJhZ2dhYmxlOiBudWxsLFxuICAgICAgICAgICAgICAgIHJlc2l6YWJsZTogbnVsbCxcbiAgICAgICAgICAgICAgICB1c2VDc3NUcmFuc2Zvcm1zOiB0cnVlLFxuXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgZHJhZ2dpbmc6IG51bGwsXG4gICAgICAgICAgICAgICAgaXNSZXNpemluZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVzaXppbmc6IG51bGwsXG4gICAgICAgICAgICAgICAgbGFzdFg6IE5hTixcbiAgICAgICAgICAgICAgICBsYXN0WTogTmFOLFxuICAgICAgICAgICAgICAgIGxhc3RXOiBOYU4sXG4gICAgICAgICAgICAgICAgbGFzdEg6IE5hTixcbiAgICAgICAgICAgICAgICBzdHlsZToge30sXG4gICAgICAgICAgICAgICAgcnRsOiBmYWxzZSxcblxuICAgICAgICAgICAgICAgIGRyYWdFdmVudFNldDogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVzaXplRXZlbnRTZXQ6IGZhbHNlLFxuXG4gICAgICAgICAgICAgICAgcHJldmlvdXNXOiBudWxsLFxuICAgICAgICAgICAgICAgIHByZXZpb3VzSDogbnVsbCxcbiAgICAgICAgICAgICAgICBwcmV2aW91c1g6IG51bGwsXG4gICAgICAgICAgICAgICAgcHJldmlvdXNZOiBudWxsLFxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjcmVhdGVkICgpIHtcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICAgICAgLy8gQWNjZXNzaWJsZSByZWZlcm5jZXMgb2YgZnVuY3Rpb25zIGZvciByZW1vdmluZyBpbiBiZWZvcmVEZXN0cm95XG4gICAgICAgICAgICBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlciA9IGZ1bmN0aW9uICh3aWR0aCkge1xuICAgICAgICAgICAgICAgIHNlbGYudXBkYXRlV2lkdGgod2lkdGgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgc2VsZi5jb21wYWN0SGFuZGxlciA9IGZ1bmN0aW9uIChsYXlvdXQpIHtcbiAgICAgICAgICAgICAgICBzZWxmLmNvbXBhY3QobGF5b3V0KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlciA9IGZ1bmN0aW9uIChpc0RyYWdnYWJsZSkge1xuICAgICAgICAgICAgICAgIGlmIChzZWxmLmlzRHJhZ2dhYmxlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZHJhZ2dhYmxlID0gaXNEcmFnZ2FibGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyID0gZnVuY3Rpb24gKGlzUmVzaXphYmxlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuaXNSZXNpemFibGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5yZXNpemFibGUgPSBpc1Jlc2l6YWJsZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIgPSBmdW5jdGlvbiAocm93SGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgc2VsZi5yb3dIZWlnaHQgPSByb3dIZWlnaHQ7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBzZWxmLmRpcmVjdGlvbmNoYW5nZUhhbmRsZXIgPSAoZGlyZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgdmFyIGRpcmVjdGlvbiA9IChkb2N1bWVudC5kaXIgIT09IHVuZGVmaW5lZCkgP1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5kaXIgOlxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImh0bWxcIilbMF0uZ2V0QXR0cmlidXRlKFwiZGlyXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMucnRsID0gKGRpcmVjdGlvbiA9PT0gXCJydGxcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5jb21wYWN0KCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbigndXBkYXRlV2lkdGgnLCBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlcik7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbignY29tcGFjdCcsIHNlbGYuY29tcGFjdEhhbmRsZXIpO1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb24oJ3NldERyYWdnYWJsZScsIHNlbGYuc2V0RHJhZ2dhYmxlSGFuZGxlcik7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvbignc2V0UmVzaXphYmxlJywgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyKTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9uKCdzZXRSb3dIZWlnaHQnLCBzZWxmLnNldFJvd0hlaWdodEhhbmRsZXIpO1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb24oJ2RpcmVjdGlvbmNoYW5nZScsIHNlbGYuZGlyZWN0aW9uY2hhbmdlSGFuZGxlcik7XG5cbiAgICAgICAgICAgIC8qdGhpcy5ldmVudEJ1cy4kb24oJ3NldENvbE51bScsIGZ1bmN0aW9uKGNvbE51bSkge1xuICAgICAgICAgICAgIHNlbGYuY29scyA9IGNvbE51bTtcbiAgICAgICAgICAgICB9KTsqL1xuICAgICAgICAgICAgdmFyIGRpcmVjdGlvbiA9IChkb2N1bWVudC5kaXIgIT09IHVuZGVmaW5lZCkgP1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmRpciA6XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJodG1sXCIpWzBdLmdldEF0dHJpYnV0ZShcImRpclwiKTtcbiAgICAgICAgICAgIHRoaXMucnRsID0gKGRpcmVjdGlvbiA9PT0gXCJydGxcIik7XG4gICAgICAgIH0sXG4gICAgICAgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICAvL1JlbW92ZSBsaXN0ZW5lcnNcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZigndXBkYXRlV2lkdGgnLCBzZWxmLnVwZGF0ZVdpZHRoSGFuZGxlcik7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2NvbXBhY3QnLCBzZWxmLmNvbXBhY3RIYW5kbGVyKTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignc2V0RHJhZ2dhYmxlJywgc2VsZi5zZXREcmFnZ2FibGVIYW5kbGVyKTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignc2V0UmVzaXphYmxlJywgc2VsZi5zZXRSZXNpemFibGVIYW5kbGVyKTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignc2V0Um93SGVpZ2h0Jywgc2VsZi5zZXRSb3dIZWlnaHRIYW5kbGVyKTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZignZGlyZWN0aW9uY2hhbmdlJywgc2VsZi5kaXJlY3Rpb25jaGFuZ2VIYW5kbGVyKTtcbiAgICAgICAgfSxcbiAgICAgICAgbW91bnRlZDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5jb2xzID0gdGhpcy4kcGFyZW50LmNvbE51bTtcbiAgICAgICAgICAgIHRoaXMucm93SGVpZ2h0ID0gdGhpcy4kcGFyZW50LnJvd0hlaWdodDtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSB0aGlzLiRwYXJlbnQud2lkdGggIT09IG51bGwgPyB0aGlzLiRwYXJlbnQud2lkdGggOiAxMDA7XG4gICAgICAgICAgICB0aGlzLm1hcmdpbiA9IHRoaXMuJHBhcmVudC5tYXJnaW4gIT09IHVuZGVmaW5lZCA/IHRoaXMuJHBhcmVudC5tYXJnaW4gOiBbMTAsIDEwXTtcbiAgICAgICAgICAgIHRoaXMubWF4Um93cyA9IHRoaXMuJHBhcmVudC5tYXhSb3dzO1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNEcmFnZ2FibGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdnYWJsZSA9IHRoaXMuJHBhcmVudC5pc0RyYWdnYWJsZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2FibGUgPSB0aGlzLmlzRHJhZ2dhYmxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXNpemFibGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6YWJsZSA9IHRoaXMuJHBhcmVudC5pc1Jlc2l6YWJsZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemFibGUgPSB0aGlzLmlzUmVzaXphYmxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy51c2VDc3NUcmFuc2Zvcm1zID0gdGhpcy4kcGFyZW50LnVzZUNzc1RyYW5zZm9ybXM7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XG4gICAgICAgIH0sXG4gICAgICAgIHdhdGNoOiB7XG4gICAgICAgICAgICBpc0RyYWdnYWJsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dhYmxlID0gdGhpcy5pc0RyYWdnYWJsZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkcmFnZ2FibGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJhY3RPYmogPT09IG51bGwgfHwgdGhpcy5pbnRlcmFjdE9iaiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmogPSBpbnRlcmFjdCh0aGlzLiRyZWZzLml0ZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kcmFnZ2FibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9wdHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVGcm9tOiB0aGlzLmRyYWdJZ25vcmVGcm9tLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dGcm9tOiB0aGlzLmRyYWdBbGxvd0Zyb21cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0T2JqLmRyYWdnYWJsZShvcHRzKTtcbiAgICAgICAgICAgICAgICAgICAgLyp0aGlzLmludGVyYWN0T2JqLmRyYWdnYWJsZSh7YWxsb3dGcm9tOiAnLnZ1ZS1kcmFnZ2FibGUtaGFuZGxlJ30pOyovXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5kcmFnRXZlbnRTZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0V2ZW50U2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmoub24oJ2RyYWdzdGFydCBkcmFnbW92ZSBkcmFnZW5kJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5oYW5kbGVEcmFnKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5kcmFnZ2FibGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemFibGUgPSB0aGlzLmlzUmVzaXphYmxlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlc2l6YWJsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pbnRlcmFjdE9iaiA9PT0gbnVsbCB8fCB0aGlzLmludGVyYWN0T2JqID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iaiA9IGludGVyYWN0KHRoaXMuJHJlZnMuaXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlc2l6YWJsZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgb3B0cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZWRnZXM6IHtsZWZ0OiBmYWxzZSwgcmlnaHQ6IHRydWUsIGJvdHRvbTogdHJ1ZSwgdG9wOiBmYWxzZX0sXG4gICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVGcm9tOiB0aGlzLnJlc2l6ZUlnbm9yZUZyb21cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJhY3RPYmoucmVzaXphYmxlKG9wdHMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMucmVzaXplRXZlbnRTZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzaXplRXZlbnRTZXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9ialxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbigncmVzaXplc3RhcnQgcmVzaXplbW92ZSByZXNpemVlbmQnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5oYW5kbGVSZXNpemUoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcmFjdE9iai5yZXNpemFibGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJvd0hlaWdodDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb2xzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHg6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBoOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVN0eWxlKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVuZGVyUnRsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjb21wdXRlZDoge1xuICAgICAgICAgICAgcmVuZGVyUnRsKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy4kcGFyZW50LmlzTWlycm9yZWQpID8gIXRoaXMucnRsIDogdGhpcy5ydGw7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVzaXphYmxlSGFuZGxlQ2xhc3MoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAndnVlLXJlc2l6YWJsZS1oYW5kbGUgdnVlLXJ0bC1yZXNpemFibGUtaGFuZGxlJztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ3Z1ZS1yZXNpemFibGUtaGFuZGxlJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG1ldGhvZHM6IHtcbiAgICAgICAgICAgIGNyZWF0ZVN0eWxlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMueCArIHRoaXMudyA+IHRoaXMuY29scykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnggPSAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLncgPSB0aGlzLmNvbHM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIHBvcyA9IHRoaXMuY2FsY1Bvc2l0aW9uKHRoaXMueCwgdGhpcy55LCB0aGlzLncsIHRoaXMuaCk7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvcy50b3AgPSB0aGlzLmRyYWdnaW5nLnRvcDtcbi8vICAgICAgICAgICAgICAgICAgICBBZGQgcnRsIHN1cHBvcnRcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3MucmlnaHQgPSB0aGlzLmRyYWdnaW5nLmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3MubGVmdCA9IHRoaXMuZHJhZ2dpbmcubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1Jlc2l6aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvcy53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIHBvcy5oZWlnaHQgPSB0aGlzLnJlc2l6aW5nLmhlaWdodDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgc3R5bGU7XG4gICAgICAgICAgICAgICAgLy8gQ1NTIFRyYW5zZm9ybXMgc3VwcG9ydCAoZGVmYXVsdClcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51c2VDc3NUcmFuc2Zvcm1zKSB7XG4vLyAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUcmFuc2Zvcm1SdGwocG9zLnRvcCwgcG9zLnJpZ2h0LCBwb3Mud2lkdGgsIHBvcy5oZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUcmFuc2Zvcm0ocG9zLnRvcCwgcG9zLmxlZnQsIHBvcy53aWR0aCwgcG9zLmhlaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIHRvcCxsZWZ0IChzbG93KVxuLy8gICAgICAgICAgICAgICAgICAgIEFkZCBydGwgc3VwcG9ydFxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gc2V0VG9wUmlnaHQocG9zLnRvcCwgcG9zLnJpZ2h0LCBwb3Mud2lkdGgsIHBvcy5oZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBzZXRUb3BMZWZ0KHBvcy50b3AsIHBvcy5sZWZ0LCBwb3Mud2lkdGgsIHBvcy5oZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc3R5bGUgPSBzdHlsZTtcblxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGhhbmRsZVJlc2l6ZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSBnZXRDb250cm9sUG9zaXRpb24oZXZlbnQpO1xuICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBkcmFnIHBvaW50IGZyb20gdGhlIGV2ZW50LiBUaGlzIGlzIHVzZWQgYXMgdGhlIG9mZnNldC5cbiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPT0gbnVsbCkgcmV0dXJuOyAvLyBub3QgcG9zc2libGUgYnV0IHNhdGlzZmllcyBmbG93XG4gICAgICAgICAgICAgICAgY29uc3Qge3gsIHl9ID0gcG9zaXRpb247XG5cbiAgICAgICAgICAgICAgICBjb25zdCBuZXdTaXplID0ge3dpZHRoOiAwLCBoZWlnaHQ6IDB9O1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwicmVzaXplc3RhcnRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNXID0gdGhpcy53O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c0ggPSB0aGlzLmg7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjUG9zaXRpb24odGhpcy54LCB0aGlzLnksIHRoaXMudywgdGhpcy5oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUud2lkdGggPSBwb3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6aW5nID0gbmV3U2l6ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNSZXNpemluZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInJlc2l6ZW1vdmVcIjpcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgcmVzaXplID0+IFwiICsgZXZlbnQudHlwZSArIFwiLCBsYXN0Vz1cIiArIHRoaXMubGFzdFcgKyBcIiwgbGFzdEg9XCIgKyB0aGlzLmxhc3RIKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvcmVFdmVudCA9IGNyZWF0ZUNvcmVEYXRhKHRoaXMubGFzdFcsIHRoaXMubGFzdEgsIHgsIHkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2l6ZS53aWR0aCA9IHRoaXMucmVzaXppbmcud2lkdGggLSBjb3JlRXZlbnQuZGVsdGFYO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLndpZHRoID0gdGhpcy5yZXNpemluZy53aWR0aCArIGNvcmVFdmVudC5kZWx0YVg7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHRoaXMucmVzaXppbmcuaGVpZ2h0ICsgY29yZUV2ZW50LmRlbHRhWTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8vY29uc29sZS5sb2coXCIjIyMgcmVzaXplID0+IFwiICsgZXZlbnQudHlwZSArIFwiLCBkZWx0YVg9XCIgKyBjb3JlRXZlbnQuZGVsdGFYICsgXCIsIGRlbHRhWT1cIiArIGNvcmVFdmVudC5kZWx0YVkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNpemluZyA9IG5ld1NpemU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInJlc2l6ZWVuZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIiMjIyByZXNpemUgZW5kID0+IHg9XCIgK3RoaXMueCArIFwiIHk9XCIgKyB0aGlzLnkgKyBcIiB3PVwiICsgdGhpcy53ICsgXCIgaD1cIiArIHRoaXMuaCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5jYWxjUG9zaXRpb24odGhpcy54LCB0aGlzLnksIHRoaXMudywgdGhpcy5oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1NpemUud2lkdGggPSBwb3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTaXplLmhlaWdodCA9IHBvcy5oZWlnaHQ7XG4vLyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiIyMjIHJlc2l6ZSBlbmQgPT4gXCIgKyBKU09OLnN0cmluZ2lmeShuZXdTaXplKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2l6aW5nID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNSZXNpemluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gR2V0IG5ldyBXSFxuICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNXSChuZXdTaXplLmhlaWdodCwgbmV3U2l6ZS53aWR0aCk7XG4gICAgICAgICAgICAgICAgaWYgKHBvcy53IDwgdGhpcy5taW5XKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvcy53ID0gdGhpcy5taW5XO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocG9zLncgPiB0aGlzLm1heFcpIHtcbiAgICAgICAgICAgICAgICAgICAgcG9zLncgPSB0aGlzLm1heFc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChwb3MuaCA8IHRoaXMubWluSCkge1xuICAgICAgICAgICAgICAgICAgICBwb3MuaCA9IHRoaXMubWluSDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHBvcy5oID4gdGhpcy5tYXhIKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvcy5oID0gdGhpcy5tYXhIO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChwb3MuaCA8IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcG9zLmggPSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocG9zLncgPCAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvcy53ID0gMTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RXID0geDtcbiAgICAgICAgICAgICAgICB0aGlzLmxhc3RIID0geTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLncgIT09IHBvcy53IHx8IHRoaXMuaCAhPT0gcG9zLmgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZW1pdChcInJlc2l6ZVwiLCB0aGlzLmksIHBvcy5oLCBwb3Mudyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSBcInJlc2l6ZWVuZFwiICYmICh0aGlzLnByZXZpb3VzVyAhPT0gdGhpcy53IHx8IHRoaXMucHJldmlvdXNIICE9PSB0aGlzLmgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoXCJyZXNpemVkXCIsIHRoaXMuaSwgcG9zLmgsIHBvcy53LCBuZXdTaXplLmhlaWdodCwgbmV3U2l6ZS53aWR0aCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXCJyZXNpemVFdmVudFwiLCBldmVudC50eXBlLCB0aGlzLmksIHRoaXMueCwgdGhpcy55LCBwb3MuaCwgcG9zLncpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGhhbmRsZURyYWcoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1Jlc2l6aW5nKSByZXR1cm47XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldENvbnRyb2xQb3NpdGlvbihldmVudCk7XG5cbiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgZHJhZyBwb2ludCBmcm9tIHRoZSBldmVudC4gVGhpcyBpcyB1c2VkIGFzIHRoZSBvZmZzZXQuXG4gICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09PSBudWxsKSByZXR1cm47IC8vIG5vdCBwb3NzaWJsZSBidXQgc2F0aXNmaWVzIGZsb3dcbiAgICAgICAgICAgICAgICBjb25zdCB7eCwgeX0gPSBwb3NpdGlvbjtcblxuICAgICAgICAgICAgICAgIHZhciBzaG91bGRVcGRhdGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdQb3NpdGlvbiA9IHt0b3A6IDAsIGxlZnQ6IDB9O1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZHJhZ3N0YXJ0XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzWCA9IHRoaXMueDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNZID0gdGhpcy55O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50UmVjdCA9IGV2ZW50LnRhcmdldC5vZmZzZXRQYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xpZW50UmVjdCA9IGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSAoY2xpZW50UmVjdC5yaWdodCAtIHBhcmVudFJlY3QucmlnaHQpICogLTE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSBjbGllbnRSZWN0LmxlZnQgLSBwYXJlbnRSZWN0LmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi50b3AgPSBjbGllbnRSZWN0LnRvcCAtIHBhcmVudFJlY3QudG9wO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2luZyA9IG5ld1Bvc2l0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZHJhZ2VuZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmcpIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudFJlY3QgPSBldmVudC50YXJnZXQub2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50UmVjdCA9IGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgQWRkIHJ0bCBzdXBwb3J0XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gKGNsaWVudFJlY3QucmlnaHQgLSBwYXJlbnRSZWN0LnJpZ2h0KSAqIC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gY2xpZW50UmVjdC5sZWZ0IC0gcGFyZW50UmVjdC5sZWZ0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3UG9zaXRpb24udG9wID0gY2xpZW50UmVjdC50b3AgLSBwYXJlbnRSZWN0LnRvcDtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgZHJhZyBlbmQgPT4gXCIgKyBKU09OLnN0cmluZ2lmeShuZXdQb3NpdGlvbikpO1xuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIiMjIyBEUk9QOiBcIiArIEpTT04uc3RyaW5naWZ5KG5ld1Bvc2l0aW9uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZHJhZ21vdmVcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvcmVFdmVudCA9IGNyZWF0ZUNvcmVEYXRhKHRoaXMubGFzdFgsIHRoaXMubGFzdFksIHgsIHkpO1xuLy8gICAgICAgICAgICAgICAgICAgICAgICBBZGQgcnRsIHN1cHBvcnRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbmRlclJ0bCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLmxlZnQgPSB0aGlzLmRyYWdnaW5nLmxlZnQgLSBjb3JlRXZlbnQuZGVsdGFYO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQb3NpdGlvbi5sZWZ0ID0gdGhpcy5kcmFnZ2luZy5sZWZ0ICsgY29yZUV2ZW50LmRlbHRhWDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Bvc2l0aW9uLnRvcCA9IHRoaXMuZHJhZ2dpbmcudG9wICsgY29yZUV2ZW50LmRlbHRhWTtcbi8vICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgZHJhZyA9PiBcIiArIGV2ZW50LnR5cGUgKyBcIiwgeD1cIiArIHggKyBcIiwgeT1cIiArIHkpO1xuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIiMjIyBkcmFnID0+IFwiICsgZXZlbnQudHlwZSArIFwiLCBkZWx0YVg9XCIgKyBjb3JlRXZlbnQuZGVsdGFYICsgXCIsIGRlbHRhWT1cIiArIGNvcmVFdmVudC5kZWx0YVkpO1xuLy8gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIiMjIyBkcmFnIGVuZCA9PiBcIiArIEpTT04uc3RyaW5naWZ5KG5ld1Bvc2l0aW9uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nID0gbmV3UG9zaXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBHZXQgbmV3IFhZXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVuZGVyUnRsKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNYWShuZXdQb3NpdGlvbi50b3AsIG5ld1Bvc2l0aW9uLmxlZnQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmNhbGNYWShuZXdQb3NpdGlvbi50b3AsIG5ld1Bvc2l0aW9uLmxlZnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMubGFzdFggPSB4O1xuICAgICAgICAgICAgICAgIHRoaXMubGFzdFkgPSB5O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMueCAhPT0gcG9zLnggfHwgdGhpcy55ICE9PSBwb3MueSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KFwibW92ZVwiLCB0aGlzLmksIHBvcy54LCBwb3MueSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSBcImRyYWdlbmRcIiAmJiAodGhpcy5wcmV2aW91c1ggIT09IHRoaXMueCB8fCB0aGlzLnByZXZpb3VzWSAhPT0gdGhpcy55KSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbWl0KFwibW92ZWRcIiwgdGhpcy5pLCBwb3MueCwgcG9zLnkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFwiZHJhZ0V2ZW50XCIsIGV2ZW50LnR5cGUsIHRoaXMuaSwgcG9zLngsIHBvcy55LCB0aGlzLmgsIHRoaXMudyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2FsY1Bvc2l0aW9uOiBmdW5jdGlvbiAoeCwgeSwgdywgaCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbFdpZHRoID0gdGhpcy5jYWxjQ29sV2lkdGgoKTtcbiAgICAgICAgICAgICAgICAvLyBhZGQgcnRsIHN1cHBvcnRcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5yZW5kZXJSdGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG91dCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0OiBNYXRoLnJvdW5kKGNvbFdpZHRoICogeCArICh4ICsgMSkgKiB0aGlzLm1hcmdpblswXSksXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IE1hdGgucm91bmQodGhpcy5yb3dIZWlnaHQgKiB5ICsgKHkgKyAxKSAqIHRoaXMubWFyZ2luWzFdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDAgKiBJbmZpbml0eSA9PT0gTmFOLCB3aGljaCBjYXVzZXMgcHJvYmxlbXMgd2l0aCByZXNpemUgY29uc3RyaWFudHM7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGaXggdGhpcyBpZiBpdCBvY2N1cnMuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlIHdlIGRvIGl0IGhlcmUgcmF0aGVyIHRoYW4gbGF0ZXIgYmVjYXVzZSBNYXRoLnJvdW5kKEluZmluaXR5KSBjYXVzZXMgZGVvcHRcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiB3ID09PSBJbmZpbml0eSA/IHcgOiBNYXRoLnJvdW5kKGNvbFdpZHRoICogdyArIE1hdGgubWF4KDAsIHcgLSAxKSAqIHRoaXMubWFyZ2luWzBdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaCA9PT0gSW5maW5pdHkgPyBoIDogTWF0aC5yb3VuZCh0aGlzLnJvd0hlaWdodCAqIGggKyBNYXRoLm1heCgwLCBoIC0gMSkgKiB0aGlzLm1hcmdpblsxXSlcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgb3V0ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHggKyAoeCArIDEpICogdGhpcy5tYXJnaW5bMF0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBNYXRoLnJvdW5kKHRoaXMucm93SGVpZ2h0ICogeSArICh5ICsgMSkgKiB0aGlzLm1hcmdpblsxXSksXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAwICogSW5maW5pdHkgPT09IE5hTiwgd2hpY2ggY2F1c2VzIHByb2JsZW1zIHdpdGggcmVzaXplIGNvbnN0cmlhbnRzO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRml4IHRoaXMgaWYgaXQgb2NjdXJzLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB3ZSBkbyBpdCBoZXJlIHJhdGhlciB0aGFuIGxhdGVyIGJlY2F1c2UgTWF0aC5yb3VuZChJbmZpbml0eSkgY2F1c2VzIGRlb3B0XG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogdyA9PT0gSW5maW5pdHkgPyB3IDogTWF0aC5yb3VuZChjb2xXaWR0aCAqIHcgKyBNYXRoLm1heCgwLCB3IC0gMSkgKiB0aGlzLm1hcmdpblswXSksXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGggPT09IEluZmluaXR5ID8gaCA6IE1hdGgucm91bmQodGhpcy5yb3dIZWlnaHQgKiBoICsgTWF0aC5tYXgoMCwgaCAtIDEpICogdGhpcy5tYXJnaW5bMV0pXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVHJhbnNsYXRlIHggYW5kIHkgY29vcmRpbmF0ZXMgZnJvbSBwaXhlbHMgdG8gZ3JpZCB1bml0cy5cbiAgICAgICAgICAgICAqIEBwYXJhbSAge051bWJlcn0gdG9wICBUb3AgcG9zaXRpb24gKHJlbGF0aXZlIHRvIHBhcmVudCkgaW4gcGl4ZWxzLlxuICAgICAgICAgICAgICogQHBhcmFtICB7TnVtYmVyfSBsZWZ0IExlZnQgcG9zaXRpb24gKHJlbGF0aXZlIHRvIHBhcmVudCkgaW4gcGl4ZWxzLlxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB4IGFuZCB5IGluIGdyaWQgdW5pdHMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIC8vIFRPRE8gY2hlY2sgaWYgdGhpcyBmdW5jdGlvbiBuZWVkcyBjaGFuZ2UgaW4gb3JkZXIgdG8gc3VwcG9ydCBydGwuXG4gICAgICAgICAgICBjYWxjWFkodG9wLCBsZWZ0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2lkdGggPSB0aGlzLmNhbGNDb2xXaWR0aCgpO1xuXG4gICAgICAgICAgICAgICAgLy8gbGVmdCA9IGNvbFdpZHRoICogeCArIG1hcmdpbiAqICh4ICsgMSlcbiAgICAgICAgICAgICAgICAvLyBsID0gY3ggKyBtKHgrMSlcbiAgICAgICAgICAgICAgICAvLyBsID0gY3ggKyBteCArIG1cbiAgICAgICAgICAgICAgICAvLyBsIC0gbSA9IGN4ICsgbXhcbiAgICAgICAgICAgICAgICAvLyBsIC0gbSA9IHgoYyArIG0pXG4gICAgICAgICAgICAgICAgLy8gKGwgLSBtKSAvIChjICsgbSkgPSB4XG4gICAgICAgICAgICAgICAgLy8geCA9IChsZWZ0IC0gbWFyZ2luKSAvIChjb2xkV2lkdGggKyBtYXJnaW4pXG4gICAgICAgICAgICAgICAgbGV0IHggPSBNYXRoLnJvdW5kKChsZWZ0IC0gdGhpcy5tYXJnaW5bMF0pIC8gKGNvbFdpZHRoICsgdGhpcy5tYXJnaW5bMF0pKTtcbiAgICAgICAgICAgICAgICBsZXQgeSA9IE1hdGgucm91bmQoKHRvcCAtIHRoaXMubWFyZ2luWzFdKSAvICh0aGlzLnJvd0hlaWdodCArIHRoaXMubWFyZ2luWzFdKSk7XG5cbiAgICAgICAgICAgICAgICAvLyBDYXBwaW5nXG4gICAgICAgICAgICAgICAgeCA9IE1hdGgubWF4KE1hdGgubWluKHgsIHRoaXMuY29scyAtIHRoaXMudyksIDApO1xuICAgICAgICAgICAgICAgIHkgPSBNYXRoLm1heChNYXRoLm1pbih5LCB0aGlzLm1heFJvd3MgLSB0aGlzLmgpLCAwKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7eCwgeX07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgLy8gSGVscGVyIGZvciBnZW5lcmF0aW5nIGNvbHVtbiB3aWR0aFxuICAgICAgICAgICAgY2FsY0NvbFdpZHRoKCkge1xuICAgICAgICAgICAgICAgIHZhciBjb2xXaWR0aCA9ICh0aGlzLmNvbnRhaW5lcldpZHRoIC0gKHRoaXMubWFyZ2luWzBdICogKHRoaXMuY29scyArIDEpKSkgLyB0aGlzLmNvbHM7XG4vLyAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIiMjIyBDT0xTPVwiICsgdGhpcy5jb2xzICsgXCIgQ09MIFdJRFRIPVwiICsgY29sV2lkdGgpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb2xXaWR0aDtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogR2l2ZW4gYSBoZWlnaHQgYW5kIHdpZHRoIGluIHBpeGVsIHZhbHVlcywgY2FsY3VsYXRlIGdyaWQgdW5pdHMuXG4gICAgICAgICAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IGhlaWdodCBIZWlnaHQgaW4gcGl4ZWxzLlxuICAgICAgICAgICAgICogQHBhcmFtICB7TnVtYmVyfSB3aWR0aCAgV2lkdGggaW4gcGl4ZWxzLlxuICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB3LCBoIGFzIGdyaWQgdW5pdHMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNhbGNXSChoZWlnaHQsIHdpZHRoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sV2lkdGggPSB0aGlzLmNhbGNDb2xXaWR0aCgpO1xuXG4gICAgICAgICAgICAgICAgLy8gd2lkdGggPSBjb2xXaWR0aCAqIHcgLSAobWFyZ2luICogKHcgLSAxKSlcbiAgICAgICAgICAgICAgICAvLyAuLi5cbiAgICAgICAgICAgICAgICAvLyB3ID0gKHdpZHRoICsgbWFyZ2luKSAvIChjb2xXaWR0aCArIG1hcmdpbilcbiAgICAgICAgICAgICAgICBsZXQgdyA9IE1hdGgucm91bmQoKHdpZHRoICsgdGhpcy5tYXJnaW5bMF0pIC8gKGNvbFdpZHRoICsgdGhpcy5tYXJnaW5bMF0pKTtcbiAgICAgICAgICAgICAgICBsZXQgaCA9IE1hdGgucm91bmQoKGhlaWdodCArIHRoaXMubWFyZ2luWzFdKSAvICh0aGlzLnJvd0hlaWdodCArIHRoaXMubWFyZ2luWzFdKSk7XG5cbiAgICAgICAgICAgICAgICAvLyBDYXBwaW5nXG4gICAgICAgICAgICAgICAgdyA9IE1hdGgubWF4KE1hdGgubWluKHcsIHRoaXMuY29scyAtIHRoaXMueCksIDApO1xuICAgICAgICAgICAgICAgIGggPSBNYXRoLm1heChNYXRoLm1pbihoLCB0aGlzLm1heFJvd3MgLSB0aGlzLnkpLCAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge3csIGh9O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHVwZGF0ZVdpZHRoOiBmdW5jdGlvbiAod2lkdGgsIGNvbE51bSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSB3aWR0aDtcbiAgICAgICAgICAgICAgICBpZiAoY29sTnVtICE9PSB1bmRlZmluZWQgJiYgY29sTnVtICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29scyA9IGNvbE51bTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29tcGFjdDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlU3R5bGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICB9XG48L3NjcmlwdD5cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBHcmlkSXRlbS52dWU/MzdmYTJhZGIiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///14\n"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getControlPosition = getControlPosition;\nexports.offsetXYFromParentOf = offsetXYFromParentOf;\nexports.createCoreData = createCoreData;\n// Get {x, y} positions from event.\nfunction getControlPosition(e) {\n return offsetXYFromParentOf(e);\n}\n\n// Get from offsetParent\nfunction offsetXYFromParentOf(evt) {\n var offsetParent = evt.target.offsetParent || document.body;\n var offsetParentRect = evt.offsetParent === document.body ? { left: 0, top: 0 } : offsetParent.getBoundingClientRect();\n\n var x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;\n var y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;\n\n /*const x = Math.round(evt.clientX + offsetParent.scrollLeft - offsetParentRect.left);\r\n const y = Math.round(evt.clientY + offsetParent.scrollTop - offsetParentRect.top);*/\n\n return { x: x, y: y };\n}\n\n// Create an data object exposed by 's events\nfunction createCoreData(lastX, lastY, x, y) {\n // State changes are often (but not always!) async. We want the latest value.\n var isStart = !isNum(lastX);\n\n if (isStart) {\n // If this is our first move, use the x and y as last coords.\n return {\n deltaX: 0, deltaY: 0,\n lastX: x, lastY: y,\n x: x, y: y\n };\n } else {\n // Otherwise calculate proper values.\n return {\n deltaX: x - lastX, deltaY: y - lastY,\n lastX: lastX, lastY: lastY,\n x: x, y: y\n };\n }\n}\n\nfunction isNum(num) {\n return typeof num === 'number' && !isNaN(num);\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvZHJhZ2dhYmxlVXRpbHMuanM/YWQ2NyJdLCJuYW1lcyI6WyJnZXRDb250cm9sUG9zaXRpb24iLCJvZmZzZXRYWUZyb21QYXJlbnRPZiIsImNyZWF0ZUNvcmVEYXRhIiwiZSIsImV2dCIsIm9mZnNldFBhcmVudCIsInRhcmdldCIsImRvY3VtZW50IiwiYm9keSIsIm9mZnNldFBhcmVudFJlY3QiLCJsZWZ0IiwidG9wIiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0IiwieCIsImNsaWVudFgiLCJzY3JvbGxMZWZ0IiwieSIsImNsaWVudFkiLCJzY3JvbGxUb3AiLCJsYXN0WCIsImxhc3RZIiwiaXNTdGFydCIsImlzTnVtIiwiZGVsdGFYIiwiZGVsdGFZIiwibnVtIiwiaXNOYU4iXSwibWFwcGluZ3MiOiI7Ozs7O1FBQ2dCQSxrQixHQUFBQSxrQjtRQU1BQyxvQixHQUFBQSxvQjtRQWdCQUMsYyxHQUFBQSxjO0FBdkJoQjtBQUNPLFNBQVNGLGtCQUFULENBQTRCRyxDQUE1QixFQUErQjtBQUNsQyxXQUFPRixxQkFBcUJFLENBQXJCLENBQVA7QUFDSDs7QUFHRDtBQUNPLFNBQVNGLG9CQUFULENBQThCRyxHQUE5QixFQUFtQztBQUN0QyxRQUFNQyxlQUFlRCxJQUFJRSxNQUFKLENBQVdELFlBQVgsSUFBMkJFLFNBQVNDLElBQXpEO0FBQ0EsUUFBTUMsbUJBQW1CTCxJQUFJQyxZQUFKLEtBQXFCRSxTQUFTQyxJQUE5QixHQUFxQyxFQUFDRSxNQUFNLENBQVAsRUFBVUMsS0FBSyxDQUFmLEVBQXJDLEdBQXlETixhQUFhTyxxQkFBYixFQUFsRjs7QUFFQSxRQUFNQyxJQUFJVCxJQUFJVSxPQUFKLEdBQWNULGFBQWFVLFVBQTNCLEdBQXdDTixpQkFBaUJDLElBQW5FO0FBQ0EsUUFBTU0sSUFBSVosSUFBSWEsT0FBSixHQUFjWixhQUFhYSxTQUEzQixHQUF1Q1QsaUJBQWlCRSxHQUFsRTs7QUFFQTs7O0FBSUEsV0FBTyxFQUFDRSxJQUFELEVBQUlHLElBQUosRUFBUDtBQUNIOztBQUdEO0FBQ08sU0FBU2QsY0FBVCxDQUF3QmlCLEtBQXhCLEVBQStCQyxLQUEvQixFQUFzQ1AsQ0FBdEMsRUFBeUNHLENBQXpDLEVBQTRDO0FBQy9DO0FBQ0EsUUFBTUssVUFBVSxDQUFDQyxNQUFNSCxLQUFOLENBQWpCOztBQUVBLFFBQUlFLE9BQUosRUFBYTtBQUNUO0FBQ0EsZUFBTztBQUNIRSxvQkFBUSxDQURMLEVBQ1FDLFFBQVEsQ0FEaEI7QUFFSEwsbUJBQU9OLENBRkosRUFFT08sT0FBT0osQ0FGZDtBQUdISCxlQUFHQSxDQUhBLEVBR0dHLEdBQUdBO0FBSE4sU0FBUDtBQUtILEtBUEQsTUFPTztBQUNIO0FBQ0EsZUFBTztBQUNITyxvQkFBUVYsSUFBSU0sS0FEVCxFQUNnQkssUUFBUVIsSUFBSUksS0FENUI7QUFFSEQsbUJBQU9BLEtBRkosRUFFV0MsT0FBT0EsS0FGbEI7QUFHSFAsZUFBR0EsQ0FIQSxFQUdHRyxHQUFHQTtBQUhOLFNBQVA7QUFLSDtBQUNKOztBQUdELFNBQVNNLEtBQVQsQ0FBZUcsR0FBZixFQUFxQjtBQUNqQixXQUFPLE9BQU9BLEdBQVAsS0FBZSxRQUFmLElBQTJCLENBQUNDLE1BQU1ELEdBQU4sQ0FBbkM7QUFDSCIsImZpbGUiOiIxNC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdldCB7eCwgeX0gcG9zaXRpb25zIGZyb20gZXZlbnQuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250cm9sUG9zaXRpb24oZSkge1xyXG4gICAgcmV0dXJuIG9mZnNldFhZRnJvbVBhcmVudE9mKGUpO1xyXG59XHJcblxyXG5cclxuLy8gR2V0IGZyb20gb2Zmc2V0UGFyZW50XHJcbmV4cG9ydCBmdW5jdGlvbiBvZmZzZXRYWUZyb21QYXJlbnRPZihldnQpIHtcclxuICAgIGNvbnN0IG9mZnNldFBhcmVudCA9IGV2dC50YXJnZXQub2Zmc2V0UGFyZW50IHx8IGRvY3VtZW50LmJvZHk7XHJcbiAgICBjb25zdCBvZmZzZXRQYXJlbnRSZWN0ID0gZXZ0Lm9mZnNldFBhcmVudCA9PT0gZG9jdW1lbnQuYm9keSA/IHtsZWZ0OiAwLCB0b3A6IDB9IDogb2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cclxuICAgIGNvbnN0IHggPSBldnQuY2xpZW50WCArIG9mZnNldFBhcmVudC5zY3JvbGxMZWZ0IC0gb2Zmc2V0UGFyZW50UmVjdC5sZWZ0O1xyXG4gICAgY29uc3QgeSA9IGV2dC5jbGllbnRZICsgb2Zmc2V0UGFyZW50LnNjcm9sbFRvcCAtIG9mZnNldFBhcmVudFJlY3QudG9wO1xyXG5cclxuICAgIC8qY29uc3QgeCA9IE1hdGgucm91bmQoZXZ0LmNsaWVudFggKyBvZmZzZXRQYXJlbnQuc2Nyb2xsTGVmdCAtIG9mZnNldFBhcmVudFJlY3QubGVmdCk7XHJcbiAgICBjb25zdCB5ID0gTWF0aC5yb3VuZChldnQuY2xpZW50WSArIG9mZnNldFBhcmVudC5zY3JvbGxUb3AgLSBvZmZzZXRQYXJlbnRSZWN0LnRvcCk7Ki9cclxuXHJcblxyXG4gICAgcmV0dXJuIHt4LCB5fTtcclxufVxyXG5cclxuXHJcbi8vIENyZWF0ZSBhbiBkYXRhIG9iamVjdCBleHBvc2VkIGJ5IDxEcmFnZ2FibGVDb3JlPidzIGV2ZW50c1xyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29yZURhdGEobGFzdFgsIGxhc3RZLCB4LCB5KSB7XHJcbiAgICAvLyBTdGF0ZSBjaGFuZ2VzIGFyZSBvZnRlbiAoYnV0IG5vdCBhbHdheXMhKSBhc3luYy4gV2Ugd2FudCB0aGUgbGF0ZXN0IHZhbHVlLlxyXG4gICAgY29uc3QgaXNTdGFydCA9ICFpc051bShsYXN0WCk7XHJcblxyXG4gICAgaWYgKGlzU3RhcnQpIHtcclxuICAgICAgICAvLyBJZiB0aGlzIGlzIG91ciBmaXJzdCBtb3ZlLCB1c2UgdGhlIHggYW5kIHkgYXMgbGFzdCBjb29yZHMuXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgZGVsdGFYOiAwLCBkZWx0YVk6IDAsXHJcbiAgICAgICAgICAgIGxhc3RYOiB4LCBsYXN0WTogeSxcclxuICAgICAgICAgICAgeDogeCwgeTogeVxyXG4gICAgICAgIH07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIE90aGVyd2lzZSBjYWxjdWxhdGUgcHJvcGVyIHZhbHVlcy5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBkZWx0YVg6IHggLSBsYXN0WCwgZGVsdGFZOiB5IC0gbGFzdFksXHJcbiAgICAgICAgICAgIGxhc3RYOiBsYXN0WCwgbGFzdFk6IGxhc3RZLFxyXG4gICAgICAgICAgICB4OiB4LCB5OiB5XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIGlzTnVtKG51bSkgIHtcclxuICAgIHJldHVybiB0eXBlb2YgbnVtID09PSAnbnVtYmVyJyAmJiAhaXNOYU4obnVtKTtcclxufVxyXG5cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2RyYWdnYWJsZVV0aWxzLmpzIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///14\n"); /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getControlPosition = getControlPosition;\nexports.offsetXYFromParentOf = offsetXYFromParentOf;\nexports.createCoreData = createCoreData;\n// Get {x, y} positions from event.\nfunction getControlPosition(e) {\n return offsetXYFromParentOf(e);\n}\n\n// Get from offsetParent\nfunction offsetXYFromParentOf(evt) {\n var offsetParent = evt.target.offsetParent || document.body;\n var offsetParentRect = evt.offsetParent === document.body ? { left: 0, top: 0 } : offsetParent.getBoundingClientRect();\n\n var x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left;\n var y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top;\n\n /*const x = Math.round(evt.clientX + offsetParent.scrollLeft - offsetParentRect.left);\n const y = Math.round(evt.clientY + offsetParent.scrollTop - offsetParentRect.top);*/\n\n return { x: x, y: y };\n}\n\n// Create an data object exposed by 's events\nfunction createCoreData(lastX, lastY, x, y) {\n // State changes are often (but not always!) async. We want the latest value.\n var isStart = !isNum(lastX);\n\n if (isStart) {\n // If this is our first move, use the x and y as last coords.\n return {\n deltaX: 0, deltaY: 0,\n lastX: x, lastY: y,\n x: x, y: y\n };\n } else {\n // Otherwise calculate proper values.\n return {\n deltaX: x - lastX, deltaY: y - lastY,\n lastX: lastX, lastY: lastY,\n x: x, y: y\n };\n }\n}\n\nfunction isNum(num) {\n return typeof num === 'number' && !isNaN(num);\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvZHJhZ2dhYmxlVXRpbHMuanM/YWQ2NyJdLCJuYW1lcyI6WyJnZXRDb250cm9sUG9zaXRpb24iLCJvZmZzZXRYWUZyb21QYXJlbnRPZiIsImNyZWF0ZUNvcmVEYXRhIiwiZSIsImV2dCIsIm9mZnNldFBhcmVudCIsInRhcmdldCIsImRvY3VtZW50IiwiYm9keSIsIm9mZnNldFBhcmVudFJlY3QiLCJsZWZ0IiwidG9wIiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0IiwieCIsImNsaWVudFgiLCJzY3JvbGxMZWZ0IiwieSIsImNsaWVudFkiLCJzY3JvbGxUb3AiLCJsYXN0WCIsImxhc3RZIiwiaXNTdGFydCIsImlzTnVtIiwiZGVsdGFYIiwiZGVsdGFZIiwibnVtIiwiaXNOYU4iXSwibWFwcGluZ3MiOiI7Ozs7O1FBQ2dCQSxrQixHQUFBQSxrQjtRQU1BQyxvQixHQUFBQSxvQjtRQWdCQUMsYyxHQUFBQSxjO0FBdkJoQjtBQUNPLFNBQVNGLGtCQUFULENBQTRCRyxDQUE1QixFQUErQjtBQUNsQyxXQUFPRixxQkFBcUJFLENBQXJCLENBQVA7QUFDSDs7QUFHRDtBQUNPLFNBQVNGLG9CQUFULENBQThCRyxHQUE5QixFQUFtQztBQUN0QyxRQUFNQyxlQUFlRCxJQUFJRSxNQUFKLENBQVdELFlBQVgsSUFBMkJFLFNBQVNDLElBQXpEO0FBQ0EsUUFBTUMsbUJBQW1CTCxJQUFJQyxZQUFKLEtBQXFCRSxTQUFTQyxJQUE5QixHQUFxQyxFQUFDRSxNQUFNLENBQVAsRUFBVUMsS0FBSyxDQUFmLEVBQXJDLEdBQXlETixhQUFhTyxxQkFBYixFQUFsRjs7QUFFQSxRQUFNQyxJQUFJVCxJQUFJVSxPQUFKLEdBQWNULGFBQWFVLFVBQTNCLEdBQXdDTixpQkFBaUJDLElBQW5FO0FBQ0EsUUFBTU0sSUFBSVosSUFBSWEsT0FBSixHQUFjWixhQUFhYSxTQUEzQixHQUF1Q1QsaUJBQWlCRSxHQUFsRTs7QUFFQTs7O0FBSUEsV0FBTyxFQUFDRSxJQUFELEVBQUlHLElBQUosRUFBUDtBQUNIOztBQUdEO0FBQ08sU0FBU2QsY0FBVCxDQUF3QmlCLEtBQXhCLEVBQStCQyxLQUEvQixFQUFzQ1AsQ0FBdEMsRUFBeUNHLENBQXpDLEVBQTRDO0FBQy9DO0FBQ0EsUUFBTUssVUFBVSxDQUFDQyxNQUFNSCxLQUFOLENBQWpCOztBQUVBLFFBQUlFLE9BQUosRUFBYTtBQUNUO0FBQ0EsZUFBTztBQUNIRSxvQkFBUSxDQURMLEVBQ1FDLFFBQVEsQ0FEaEI7QUFFSEwsbUJBQU9OLENBRkosRUFFT08sT0FBT0osQ0FGZDtBQUdISCxlQUFHQSxDQUhBLEVBR0dHLEdBQUdBO0FBSE4sU0FBUDtBQUtILEtBUEQsTUFPTztBQUNIO0FBQ0EsZUFBTztBQUNITyxvQkFBUVYsSUFBSU0sS0FEVCxFQUNnQkssUUFBUVIsSUFBSUksS0FENUI7QUFFSEQsbUJBQU9BLEtBRkosRUFFV0MsT0FBT0EsS0FGbEI7QUFHSFAsZUFBR0EsQ0FIQSxFQUdHRyxHQUFHQTtBQUhOLFNBQVA7QUFLSDtBQUNKOztBQUdELFNBQVNNLEtBQVQsQ0FBZUcsR0FBZixFQUFxQjtBQUNqQixXQUFPLE9BQU9BLEdBQVAsS0FBZSxRQUFmLElBQTJCLENBQUNDLE1BQU1ELEdBQU4sQ0FBbkM7QUFDSCIsImZpbGUiOiIxNS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdldCB7eCwgeX0gcG9zaXRpb25zIGZyb20gZXZlbnQuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29udHJvbFBvc2l0aW9uKGUpIHtcbiAgICByZXR1cm4gb2Zmc2V0WFlGcm9tUGFyZW50T2YoZSk7XG59XG5cblxuLy8gR2V0IGZyb20gb2Zmc2V0UGFyZW50XG5leHBvcnQgZnVuY3Rpb24gb2Zmc2V0WFlGcm9tUGFyZW50T2YoZXZ0KSB7XG4gICAgY29uc3Qgb2Zmc2V0UGFyZW50ID0gZXZ0LnRhcmdldC5vZmZzZXRQYXJlbnQgfHwgZG9jdW1lbnQuYm9keTtcbiAgICBjb25zdCBvZmZzZXRQYXJlbnRSZWN0ID0gZXZ0Lm9mZnNldFBhcmVudCA9PT0gZG9jdW1lbnQuYm9keSA/IHtsZWZ0OiAwLCB0b3A6IDB9IDogb2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgY29uc3QgeCA9IGV2dC5jbGllbnRYICsgb2Zmc2V0UGFyZW50LnNjcm9sbExlZnQgLSBvZmZzZXRQYXJlbnRSZWN0LmxlZnQ7XG4gICAgY29uc3QgeSA9IGV2dC5jbGllbnRZICsgb2Zmc2V0UGFyZW50LnNjcm9sbFRvcCAtIG9mZnNldFBhcmVudFJlY3QudG9wO1xuXG4gICAgLypjb25zdCB4ID0gTWF0aC5yb3VuZChldnQuY2xpZW50WCArIG9mZnNldFBhcmVudC5zY3JvbGxMZWZ0IC0gb2Zmc2V0UGFyZW50UmVjdC5sZWZ0KTtcbiAgICBjb25zdCB5ID0gTWF0aC5yb3VuZChldnQuY2xpZW50WSArIG9mZnNldFBhcmVudC5zY3JvbGxUb3AgLSBvZmZzZXRQYXJlbnRSZWN0LnRvcCk7Ki9cblxuXG4gICAgcmV0dXJuIHt4LCB5fTtcbn1cblxuXG4vLyBDcmVhdGUgYW4gZGF0YSBvYmplY3QgZXhwb3NlZCBieSA8RHJhZ2dhYmxlQ29yZT4ncyBldmVudHNcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDb3JlRGF0YShsYXN0WCwgbGFzdFksIHgsIHkpIHtcbiAgICAvLyBTdGF0ZSBjaGFuZ2VzIGFyZSBvZnRlbiAoYnV0IG5vdCBhbHdheXMhKSBhc3luYy4gV2Ugd2FudCB0aGUgbGF0ZXN0IHZhbHVlLlxuICAgIGNvbnN0IGlzU3RhcnQgPSAhaXNOdW0obGFzdFgpO1xuXG4gICAgaWYgKGlzU3RhcnQpIHtcbiAgICAgICAgLy8gSWYgdGhpcyBpcyBvdXIgZmlyc3QgbW92ZSwgdXNlIHRoZSB4IGFuZCB5IGFzIGxhc3QgY29vcmRzLlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGVsdGFYOiAwLCBkZWx0YVk6IDAsXG4gICAgICAgICAgICBsYXN0WDogeCwgbGFzdFk6IHksXG4gICAgICAgICAgICB4OiB4LCB5OiB5XG4gICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gT3RoZXJ3aXNlIGNhbGN1bGF0ZSBwcm9wZXIgdmFsdWVzLlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGVsdGFYOiB4IC0gbGFzdFgsIGRlbHRhWTogeSAtIGxhc3RZLFxuICAgICAgICAgICAgbGFzdFg6IGxhc3RYLCBsYXN0WTogbGFzdFksXG4gICAgICAgICAgICB4OiB4LCB5OiB5XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIGlzTnVtKG51bSkgIHtcbiAgICByZXR1cm4gdHlwZW9mIG51bSA9PT0gJ251bWJlcicgJiYgIWlzTmFOKG51bSk7XG59XG5cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9kcmFnZ2FibGVVdGlscy5qcyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///15\n"); +eval("var require;var require;/**\r\n * interact.js v1.3.0-alpha.4+sha.7970416-dirty\r\n *\r\n * Copyright (c) 2012-2017 Taye Adeyemi \r\n * Open source under the MIT License.\r\n * https://raw.github.com/taye/interact.js/master/LICENSE\r\n */\r\n(function(f){if(true){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.interact = f()}})(function(){var define,module,exports;return (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 require(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 6 && arguments[6] !== undefined ? arguments[6] : false;\r\n\r\n _classCallCheck(this, InteractEvent);\r\n\r\n var target = interaction.target;\r\n var deltaSource = (target && target.options || defaults).deltaSource;\r\n var origin = getOriginXY(target, element, action);\r\n var starting = phase === 'start';\r\n var ending = phase === 'end';\r\n var coords = starting ? interaction.startCoords : interaction.curCoords;\r\n var prevEvent = interaction.prevEvent;\r\n\r\n element = element || interaction.element;\r\n\r\n var page = extend({}, coords.page);\r\n var client = extend({}, coords.client);\r\n\r\n page.x -= origin.x;\r\n page.y -= origin.y;\r\n\r\n client.x -= origin.x;\r\n client.y -= origin.y;\r\n\r\n this.ctrlKey = event.ctrlKey;\r\n this.altKey = event.altKey;\r\n this.shiftKey = event.shiftKey;\r\n this.metaKey = event.metaKey;\r\n this.button = event.button;\r\n this.buttons = event.buttons;\r\n this.target = element;\r\n this.currentTarget = element;\r\n this.relatedTarget = related || null;\r\n this.preEnd = preEnd;\r\n this.type = action + (phase || '');\r\n this.interaction = interaction;\r\n this.interactable = target;\r\n\r\n this.t0 = starting ? interaction.downTimes[interaction.downTimes.length - 1] : prevEvent.t0;\r\n\r\n var signalArg = {\r\n interaction: interaction,\r\n event: event,\r\n action: action,\r\n phase: phase,\r\n element: element,\r\n related: related,\r\n page: page,\r\n client: client,\r\n coords: coords,\r\n starting: starting,\r\n ending: ending,\r\n deltaSource: deltaSource,\r\n iEvent: this\r\n };\r\n\r\n signals.fire('set-xy', signalArg);\r\n\r\n if (ending) {\r\n // use previous coords when ending\r\n this.pageX = prevEvent.pageX;\r\n this.pageY = prevEvent.pageY;\r\n this.clientX = prevEvent.clientX;\r\n this.clientY = prevEvent.clientY;\r\n } else {\r\n this.pageX = page.x;\r\n this.pageY = page.y;\r\n this.clientX = client.x;\r\n this.clientY = client.y;\r\n }\r\n\r\n this.x0 = interaction.startCoords.page.x - origin.x;\r\n this.y0 = interaction.startCoords.page.y - origin.y;\r\n this.clientX0 = interaction.startCoords.client.x - origin.x;\r\n this.clientY0 = interaction.startCoords.client.y - origin.y;\r\n\r\n signals.fire('set-delta', signalArg);\r\n\r\n this.timeStamp = coords.timeStamp;\r\n this.dt = interaction.pointerDelta.timeStamp;\r\n this.duration = this.timeStamp - this.t0;\r\n\r\n // speed and velocity in pixels per second\r\n this.speed = interaction.pointerDelta[deltaSource].speed;\r\n this.velocityX = interaction.pointerDelta[deltaSource].vx;\r\n this.velocityY = interaction.pointerDelta[deltaSource].vy;\r\n\r\n this.swipe = ending || phase === 'inertiastart' ? this.getSwipe() : null;\r\n\r\n signals.fire('new', signalArg);\r\n }\r\n\r\n InteractEvent.prototype.getSwipe = function getSwipe() {\r\n var interaction = this.interaction;\r\n\r\n if (interaction.prevEvent.speed < 600 || this.timeStamp - interaction.prevEvent.timeStamp > 150) {\r\n return null;\r\n }\r\n\r\n var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI;\r\n var overlap = 22.5;\r\n\r\n if (angle < 0) {\r\n angle += 360;\r\n }\r\n\r\n var left = 135 - overlap <= angle && angle < 225 + overlap;\r\n var up = 225 - overlap <= angle && angle < 315 + overlap;\r\n\r\n var right = !left && (315 - overlap <= angle || angle < 45 + overlap);\r\n var down = !up && 45 - overlap <= angle && angle < 135 + overlap;\r\n\r\n return {\r\n up: up,\r\n down: down,\r\n left: left,\r\n right: right,\r\n angle: angle,\r\n speed: interaction.prevEvent.speed,\r\n velocity: {\r\n x: interaction.prevEvent.velocityX,\r\n y: interaction.prevEvent.velocityY\r\n }\r\n };\r\n };\r\n\r\n InteractEvent.prototype.preventDefault = function preventDefault() {};\r\n\r\n InteractEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {\r\n this.immediatePropagationStopped = this.propagationStopped = true;\r\n };\r\n\r\n InteractEvent.prototype.stopPropagation = function stopPropagation() {\r\n this.propagationStopped = true;\r\n };\r\n\r\n return InteractEvent;\r\n}();\r\n\r\nsignals.on('set-delta', function (_ref) {\r\n var iEvent = _ref.iEvent,\r\n interaction = _ref.interaction,\r\n starting = _ref.starting,\r\n deltaSource = _ref.deltaSource;\r\n\r\n var prevEvent = starting ? iEvent : interaction.prevEvent;\r\n\r\n if (deltaSource === 'client') {\r\n iEvent.dx = iEvent.clientX - prevEvent.clientX;\r\n iEvent.dy = iEvent.clientY - prevEvent.clientY;\r\n } else {\r\n iEvent.dx = iEvent.pageX - prevEvent.pageX;\r\n iEvent.dy = iEvent.pageY - prevEvent.pageY;\r\n }\r\n});\r\n\r\nInteractEvent.signals = signals;\r\n\r\nmodule.exports = InteractEvent;\r\n\r\n},{\"./defaultOptions\":18,\"./utils/Signals\":35,\"./utils/extend\":41,\"./utils/getOriginXY\":42}],4:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\r\n\r\nvar is = require('./utils/is');\r\nvar events = require('./utils/events');\r\nvar extend = require('./utils/extend');\r\nvar actions = require('./actions/base');\r\nvar scope = require('./scope');\r\nvar Eventable = require('./Eventable');\r\nvar defaults = require('./defaultOptions');\r\nvar signals = require('./utils/Signals').new();\r\n\r\nvar _require = require('./utils/domUtils'),\r\n getElementRect = _require.getElementRect,\r\n nodeContains = _require.nodeContains,\r\n trySelector = _require.trySelector;\r\n\r\nvar _require2 = require('./utils/window'),\r\n getWindow = _require2.getWindow;\r\n\r\nvar _require3 = require('./utils/arr'),\r\n indexOf = _require3.indexOf,\r\n contains = _require3.contains;\r\n\r\nvar _require4 = require('./utils/browser'),\r\n wheelEvent = _require4.wheelEvent;\r\n\r\n// all set interactables\r\n\r\n\r\nscope.interactables = [];\r\n\r\n/*\\\r\n * Interactable\r\n [ property ]\r\n **\r\n * Object type returned by @interact\r\n\\*/\r\n\r\nvar Interactable = function () {\r\n function Interactable(target, options) {\r\n _classCallCheck(this, Interactable);\r\n\r\n options = options || {};\r\n\r\n this.target = target;\r\n this.events = new Eventable();\r\n this._context = options.context || scope.document;\r\n this._win = getWindow(trySelector(target) ? this._context : target);\r\n this._doc = this._win.document;\r\n\r\n signals.fire('new', {\r\n target: target,\r\n options: options,\r\n interactable: this,\r\n win: this._win\r\n });\r\n\r\n scope.addDocument(this._doc, this._win);\r\n\r\n scope.interactables.push(this);\r\n\r\n this.set(options);\r\n }\r\n\r\n Interactable.prototype.setOnEvents = function setOnEvents(action, phases) {\r\n var onAction = 'on' + action;\r\n\r\n if (is.function(phases.onstart)) {\r\n this.events[onAction + 'start'] = phases.onstart;\r\n }\r\n if (is.function(phases.onmove)) {\r\n this.events[onAction + 'move'] = phases.onmove;\r\n }\r\n if (is.function(phases.onend)) {\r\n this.events[onAction + 'end'] = phases.onend;\r\n }\r\n if (is.function(phases.oninertiastart)) {\r\n this.events[onAction + 'inertiastart'] = phases.oninertiastart;\r\n }\r\n\r\n return this;\r\n };\r\n\r\n Interactable.prototype.setPerAction = function setPerAction(action, options) {\r\n // for all the default per-action options\r\n for (var option in options) {\r\n // if this option exists for this action\r\n if (option in defaults[action]) {\r\n // if the option in the options arg is an object value\r\n if (is.object(options[option])) {\r\n // duplicate the object\r\n this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\r\n\r\n if (is.object(defaults.perAction[option]) && 'enabled' in defaults.perAction[option]) {\r\n this.options[action][option].enabled = options[option].enabled === false ? false : true;\r\n }\r\n } else if (is.bool(options[option]) && is.object(defaults.perAction[option])) {\r\n this.options[action][option].enabled = options[option];\r\n } else if (options[option] !== undefined) {\r\n // or if it's not undefined, do a plain assignment\r\n this.options[action][option] = options[option];\r\n }\r\n }\r\n }\r\n };\r\n\r\n /*\\\r\n * Interactable.getRect\r\n [ method ]\r\n *\r\n * The default function to get an Interactables bounding rect. Can be\r\n * overridden using @Interactable.rectChecker.\r\n *\r\n - element (Element) #optional The element to measure.\r\n = (object) The object's bounding rectangle.\r\n o {\r\n o top : 0,\r\n o left : 0,\r\n o bottom: 0,\r\n o right : 0,\r\n o width : 0,\r\n o height: 0\r\n o }\r\n \\*/\r\n\r\n\r\n Interactable.prototype.getRect = function getRect(element) {\r\n element = element || this.target;\r\n\r\n if (is.string(this.target) && !is.element(element)) {\r\n element = this._context.querySelector(this.target);\r\n }\r\n\r\n return getElementRect(element);\r\n };\r\n\r\n /*\\\r\n * Interactable.rectChecker\r\n [ method ]\r\n *\r\n * Returns or sets the function used to calculate the interactable's\r\n * element's rectangle\r\n *\r\n - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\r\n = (function | object) The checker function or this Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.rectChecker = function rectChecker(checker) {\r\n if (is.function(checker)) {\r\n this.getRect = checker;\r\n\r\n return this;\r\n }\r\n\r\n if (checker === null) {\r\n delete this.options.getRect;\r\n\r\n return this;\r\n }\r\n\r\n return this.getRect;\r\n };\r\n\r\n Interactable.prototype._backCompatOption = function _backCompatOption(optionName, newValue) {\r\n if (trySelector(newValue) || is.object(newValue)) {\r\n this.options[optionName] = newValue;\r\n\r\n for (var _iterator = actions.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var action = _ref;\r\n\r\n this.options[action][optionName] = newValue;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n return this.options[optionName];\r\n };\r\n\r\n /*\\\r\n * Interactable.origin\r\n [ method ]\r\n *\r\n * Gets or sets the origin of the Interactable's element. The x and y\r\n * of the origin will be subtracted from action event coordinates.\r\n *\r\n - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\r\n * OR\r\n - origin (Element) #optional An HTML or SVG Element whose rect will be used\r\n **\r\n = (object) The current origin or this Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.origin = function origin(newValue) {\r\n return this._backCompatOption('origin', newValue);\r\n };\r\n\r\n /*\\\r\n * Interactable.deltaSource\r\n [ method ]\r\n *\r\n * Returns or sets the mouse coordinate types used to calculate the\r\n * movement of the pointer.\r\n *\r\n - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\r\n = (string | object) The current deltaSource or this Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.deltaSource = function deltaSource(newValue) {\r\n if (newValue === 'page' || newValue === 'client') {\r\n this.options.deltaSource = newValue;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.deltaSource;\r\n };\r\n\r\n /*\\\r\n * Interactable.context\r\n [ method ]\r\n *\r\n * Gets the selector context Node of the Interactable. The default is `window.document`.\r\n *\r\n = (Node) The context Node of this Interactable\r\n **\r\n \\*/\r\n\r\n\r\n Interactable.prototype.context = function context() {\r\n return this._context;\r\n };\r\n\r\n Interactable.prototype.inContext = function inContext(element) {\r\n return this._context === element.ownerDocument || nodeContains(this._context, element);\r\n };\r\n\r\n /*\\\r\n * Interactable.fire\r\n [ method ]\r\n *\r\n * Calls listeners for the given InteractEvent type bound globally\r\n * and directly to this Interactable\r\n *\r\n - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\r\n = (Interactable) this Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.fire = function fire(iEvent) {\r\n this.events.fire(iEvent);\r\n\r\n return this;\r\n };\r\n\r\n Interactable.prototype._onOffMultiple = function _onOffMultiple(method, eventType, listener, options) {\r\n if (is.string(eventType) && eventType.search(' ') !== -1) {\r\n eventType = eventType.trim().split(/ +/);\r\n }\r\n\r\n if (is.array(eventType)) {\r\n for (var i = 0; i < eventType.length; i++) {\r\n this[method](eventType[i], listener, options);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n if (is.object(eventType)) {\r\n for (var prop in eventType) {\r\n this[method](prop, eventType[prop], listener);\r\n }\r\n\r\n return true;\r\n }\r\n };\r\n\r\n /*\\\r\n * Interactable.on\r\n [ method ]\r\n *\r\n * Binds a listener for an InteractEvent, pointerEvent or DOM event.\r\n *\r\n - eventType (string | array | object) The types of events to listen for\r\n - listener (function) The function event (s)\r\n - options (object | boolean) #optional options object or useCapture flag for addEventListener\r\n = (object) This Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.on = function on(eventType, listener, options) {\r\n if (this._onOffMultiple('on', eventType, listener, options)) {\r\n return this;\r\n }\r\n\r\n if (eventType === 'wheel') {\r\n eventType = wheelEvent;\r\n }\r\n\r\n if (contains(Interactable.eventTypes, eventType)) {\r\n this.events.on(eventType, listener);\r\n }\r\n // delegated event for selector\r\n else if (is.string(this.target)) {\r\n events.addDelegate(this.target, this._context, eventType, listener, options);\r\n } else {\r\n events.add(this.target, eventType, listener, options);\r\n }\r\n\r\n return this;\r\n };\r\n\r\n /*\\\r\n * Interactable.off\r\n [ method ]\r\n *\r\n * Removes an InteractEvent, pointerEvent or DOM event listener\r\n *\r\n - eventType (string | array | object) The types of events that were listened for\r\n - listener (function) The listener function to be removed\r\n - options (object | boolean) #optional options object or useCapture flag for removeEventListener\r\n = (object) This Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.off = function off(eventType, listener, options) {\r\n if (this._onOffMultiple('off', eventType, listener, options)) {\r\n return this;\r\n }\r\n\r\n if (eventType === 'wheel') {\r\n eventType = wheelEvent;\r\n }\r\n\r\n // if it is an action event type\r\n if (contains(Interactable.eventTypes, eventType)) {\r\n this.events.off(eventType, listener);\r\n }\r\n // delegated event\r\n else if (is.string(this.target)) {\r\n events.removeDelegate(this.target, this._context, eventType, listener, options);\r\n }\r\n // remove listener from this Interatable's element\r\n else {\r\n events.remove(this.target, eventType, listener, options);\r\n }\r\n\r\n return this;\r\n };\r\n\r\n /*\\\r\n * Interactable.set\r\n [ method ]\r\n *\r\n * Reset the options of this Interactable\r\n - options (object) The new settings to apply\r\n = (object) This Interactable\r\n \\*/\r\n\r\n\r\n Interactable.prototype.set = function set(options) {\r\n if (!is.object(options)) {\r\n options = {};\r\n }\r\n\r\n this.options = extend({}, defaults.base);\r\n\r\n var perActions = extend({}, defaults.perAction);\r\n\r\n for (var actionName in actions.methodDict) {\r\n var methodName = actions.methodDict[actionName];\r\n\r\n this.options[actionName] = extend({}, defaults[actionName]);\r\n\r\n this.setPerAction(actionName, perActions);\r\n\r\n this[methodName](options[actionName]);\r\n }\r\n\r\n for (var _iterator2 = Interactable.settingsMethods, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref2 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref2 = _i2.value;\r\n }\r\n\r\n var setting = _ref2;\r\n\r\n this.options[setting] = defaults.base[setting];\r\n\r\n if (setting in options) {\r\n this[setting](options[setting]);\r\n }\r\n }\r\n\r\n signals.fire('set', {\r\n options: options,\r\n interactable: this\r\n });\r\n\r\n return this;\r\n };\r\n\r\n /*\\\r\n * Interactable.unset\r\n [ method ]\r\n *\r\n * Remove this interactable from the list of interactables and remove\r\n * it's action capabilities and event listeners\r\n *\r\n = (object) @interact\r\n \\*/\r\n\r\n\r\n Interactable.prototype.unset = function unset() {\r\n events.remove(this.target, 'all');\r\n\r\n if (is.string(this.target)) {\r\n // remove delegated events\r\n for (var type in events.delegatedEvents) {\r\n var delegated = events.delegatedEvents[type];\r\n\r\n if (delegated.selectors[0] === this.target && delegated.contexts[0] === this._context) {\r\n\r\n delegated.selectors.splice(0, 1);\r\n delegated.contexts.splice(0, 1);\r\n delegated.listeners.splice(0, 1);\r\n\r\n // remove the arrays if they are empty\r\n if (!delegated.selectors.length) {\r\n delegated[type] = null;\r\n }\r\n }\r\n\r\n events.remove(this._context, type, events.delegateListener);\r\n events.remove(this._context, type, events.delegateUseCapture, true);\r\n }\r\n } else {\r\n events.remove(this, 'all');\r\n }\r\n\r\n signals.fire('unset', { interactable: this });\r\n\r\n scope.interactables.splice(indexOf(scope.interactables, this), 1);\r\n\r\n // Stop related interactions when an Interactable is unset\r\n for (var _iterator3 = scope.interactions || [], _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {\r\n var _ref3;\r\n\r\n if (_isArray3) {\r\n if (_i3 >= _iterator3.length) break;\r\n _ref3 = _iterator3[_i3++];\r\n } else {\r\n _i3 = _iterator3.next();\r\n if (_i3.done) break;\r\n _ref3 = _i3.value;\r\n }\r\n\r\n var interaction = _ref3;\r\n\r\n if (interaction.target === this && interaction.interacting()) {\r\n interaction.stop();\r\n }\r\n }\r\n\r\n return scope.interact;\r\n };\r\n\r\n return Interactable;\r\n}();\r\n\r\nscope.interactables.indexOfElement = function indexOfElement(target, context) {\r\n context = context || scope.document;\r\n\r\n for (var i = 0; i < this.length; i++) {\r\n var interactable = this[i];\r\n\r\n if (interactable.target === target && interactable._context === context) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n};\r\n\r\nscope.interactables.get = function interactableGet(element, options, dontCheckInContext) {\r\n var ret = this[this.indexOfElement(element, options && options.context)];\r\n\r\n return ret && (is.string(element) || dontCheckInContext || ret.inContext(element)) ? ret : null;\r\n};\r\n\r\nscope.interactables.forEachSelector = function (callback, element) {\r\n for (var i = 0; i < this.length; i++) {\r\n var interactable = this[i];\r\n\r\n // skip non CSS selector targets and out of context elements\r\n if (!is.string(interactable.target) || element && !interactable.inContext(element)) {\r\n continue;\r\n }\r\n\r\n var ret = callback(interactable, interactable.target, interactable._context, i, this);\r\n\r\n if (ret !== undefined) {\r\n return ret;\r\n }\r\n }\r\n};\r\n\r\n// all interact.js eventTypes\r\nInteractable.eventTypes = scope.eventTypes = [];\r\n\r\nInteractable.signals = signals;\r\n\r\nInteractable.settingsMethods = ['deltaSource', 'origin', 'preventDefault', 'rectChecker'];\r\n\r\nmodule.exports = Interactable;\r\n\r\n},{\"./Eventable\":2,\"./actions/base\":6,\"./defaultOptions\":18,\"./scope\":34,\"./utils/Signals\":35,\"./utils/arr\":36,\"./utils/browser\":37,\"./utils/domUtils\":39,\"./utils/events\":40,\"./utils/extend\":41,\"./utils/is\":46,\"./utils/window\":52}],5:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\r\n\r\nvar scope = require('./scope');\r\nvar utils = require('./utils');\r\nvar events = require('./utils/events');\r\nvar browser = require('./utils/browser');\r\nvar domObjects = require('./utils/domObjects');\r\nvar finder = require('./utils/interactionFinder');\r\nvar signals = require('./utils/Signals').new();\r\n\r\nvar listeners = {};\r\nvar methodNames = ['pointerDown', 'pointerMove', 'pointerUp', 'updatePointer', 'removePointer'];\r\n\r\n// for ignoring browser's simulated mouse events\r\nvar prevTouchTime = 0;\r\n\r\n// all active and idle interactions\r\nscope.interactions = [];\r\n\r\nvar Interaction = function () {\r\n function Interaction(_ref) {\r\n var pointerType = _ref.pointerType;\r\n\r\n _classCallCheck(this, Interaction);\r\n\r\n this.target = null; // current interactable being interacted with\r\n this.element = null; // the target element of the interactable\r\n\r\n this.prepared = { // action that's ready to be fired on next move event\r\n name: null,\r\n axis: null,\r\n edges: null\r\n };\r\n\r\n // keep track of added pointers\r\n this.pointers = [];\r\n this.pointerIds = [];\r\n this.downTargets = [];\r\n this.downTimes = [];\r\n\r\n // Previous native pointer move event coordinates\r\n this.prevCoords = {\r\n page: { x: 0, y: 0 },\r\n client: { x: 0, y: 0 },\r\n timeStamp: 0\r\n };\r\n // current native pointer move event coordinates\r\n this.curCoords = {\r\n page: { x: 0, y: 0 },\r\n client: { x: 0, y: 0 },\r\n timeStamp: 0\r\n };\r\n\r\n // Starting InteractEvent pointer coordinates\r\n this.startCoords = {\r\n page: { x: 0, y: 0 },\r\n client: { x: 0, y: 0 },\r\n timeStamp: 0\r\n };\r\n\r\n // Change in coordinates and time of the pointer\r\n this.pointerDelta = {\r\n page: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\r\n client: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\r\n timeStamp: 0\r\n };\r\n\r\n this.downEvent = null; // pointerdown/mousedown/touchstart event\r\n this.downPointer = {};\r\n\r\n this._eventTarget = null;\r\n this._curEventTarget = null;\r\n\r\n this.prevEvent = null; // previous action event\r\n\r\n this.pointerIsDown = false;\r\n this.pointerWasMoved = false;\r\n this._interacting = false;\r\n\r\n this.pointerType = pointerType;\r\n\r\n signals.fire('new', this);\r\n\r\n scope.interactions.push(this);\r\n }\r\n\r\n Interaction.prototype.pointerDown = function pointerDown(pointer, event, eventTarget) {\r\n var pointerIndex = this.updatePointer(pointer, event, true);\r\n\r\n signals.fire('down', {\r\n pointer: pointer,\r\n event: event,\r\n eventTarget: eventTarget,\r\n pointerIndex: pointerIndex,\r\n interaction: this\r\n });\r\n };\r\n\r\n /*\\\r\n * Interaction.start\r\n [ method ]\r\n *\r\n * Start an action with the given Interactable and Element as tartgets. The\r\n * action must be enabled for the target Interactable and an appropriate number\r\n * of pointers must be held down - 1 for drag/resize, 2 for gesture.\r\n *\r\n * Use it with `interactable.able({ manualStart: false })` to always\r\n * [start actions manually](https://github.com/taye/interact.js/issues/114)\r\n *\r\n - action (object) The action to be performed - drag, resize, etc.\r\n - target (Interactable) The Interactable to target\r\n - element (Element) The DOM Element to target\r\n = (object) interact\r\n **\r\n | interact(target)\r\n | .draggable({\r\n | // disable the default drag start by down->move\r\n | manualStart: true\r\n | })\r\n | // start dragging after the user holds the pointer down\r\n | .on('hold', function (event) {\r\n | var interaction = event.interaction;\r\n |\r\n | if (!interaction.interacting()) {\r\n | interaction.start({ name: 'drag' },\r\n | event.interactable,\r\n | event.currentTarget);\r\n | }\r\n | });\r\n \\*/\r\n\r\n\r\n Interaction.prototype.start = function start(action, target, element) {\r\n if (this.interacting() || !this.pointerIsDown || this.pointerIds.length < (action.name === 'gesture' ? 2 : 1)) {\r\n return;\r\n }\r\n\r\n // if this interaction had been removed after stopping\r\n // add it back\r\n if (utils.indexOf(scope.interactions, this) === -1) {\r\n scope.interactions.push(this);\r\n }\r\n\r\n utils.copyAction(this.prepared, action);\r\n this.target = target;\r\n this.element = element;\r\n\r\n signals.fire('action-start', {\r\n interaction: this,\r\n event: this.downEvent\r\n });\r\n };\r\n\r\n Interaction.prototype.pointerMove = function pointerMove(pointer, event, eventTarget) {\r\n if (!this.simulation) {\r\n this.updatePointer(pointer);\r\n utils.setCoords(this.curCoords, this.pointers);\r\n }\r\n\r\n var duplicateMove = this.curCoords.page.x === this.prevCoords.page.x && this.curCoords.page.y === this.prevCoords.page.y && this.curCoords.client.x === this.prevCoords.client.x && this.curCoords.client.y === this.prevCoords.client.y;\r\n\r\n var dx = void 0;\r\n var dy = void 0;\r\n\r\n // register movement greater than pointerMoveTolerance\r\n if (this.pointerIsDown && !this.pointerWasMoved) {\r\n dx = this.curCoords.client.x - this.startCoords.client.x;\r\n dy = this.curCoords.client.y - this.startCoords.client.y;\r\n\r\n this.pointerWasMoved = utils.hypot(dx, dy) > Interaction.pointerMoveTolerance;\r\n }\r\n\r\n var signalArg = {\r\n pointer: pointer,\r\n pointerIndex: this.getPointerIndex(pointer),\r\n event: event,\r\n eventTarget: eventTarget,\r\n dx: dx,\r\n dy: dy,\r\n duplicate: duplicateMove,\r\n interaction: this,\r\n interactingBeforeMove: this.interacting()\r\n };\r\n\r\n if (!duplicateMove) {\r\n // set pointer coordinate, time changes and speeds\r\n utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\r\n }\r\n\r\n signals.fire('move', signalArg);\r\n\r\n if (!duplicateMove) {\r\n // if interacting, fire an 'action-move' signal etc\r\n if (this.interacting()) {\r\n this.doMove(signalArg);\r\n }\r\n\r\n if (this.pointerWasMoved) {\r\n utils.copyCoords(this.prevCoords, this.curCoords);\r\n }\r\n }\r\n };\r\n\r\n /*\\\r\n * Interaction.doMove\r\n [ method ]\r\n *\r\n * Force a move of the current action at the same coordinates. Useful if\r\n * snap/restrict has been changed and you want a movement with the new\r\n * settings.\r\n *\r\n **\r\n | interact(target)\r\n | .draggable(true)\r\n | .on('dragmove', function (event) {\r\n | if (someCondition) {\r\n | // change the snap settings\r\n | event.interactable.draggable({ snap: { targets: [] }});\r\n | // fire another move event with re-calculated snap\r\n | event.interaction.doMove();\r\n | }\r\n | });\r\n \\*/\r\n\r\n\r\n Interaction.prototype.doMove = function doMove(signalArg) {\r\n signalArg = utils.extend({\r\n pointer: this.pointers[0],\r\n event: this.prevEvent,\r\n eventTarget: this._eventTarget,\r\n interaction: this\r\n }, signalArg || {});\r\n\r\n signals.fire('before-action-move', signalArg);\r\n\r\n if (!this._dontFireMove) {\r\n signals.fire('action-move', signalArg);\r\n }\r\n\r\n this._dontFireMove = false;\r\n };\r\n\r\n // End interact move events and stop auto-scroll unless simulation is running\r\n\r\n\r\n Interaction.prototype.pointerUp = function pointerUp(pointer, event, eventTarget, curEventTarget) {\r\n var pointerIndex = this.getPointerIndex(pointer);\r\n\r\n signals.fire(/cancel$/i.test(event.type) ? 'cancel' : 'up', {\r\n pointer: pointer,\r\n pointerIndex: pointerIndex,\r\n event: event,\r\n eventTarget: eventTarget,\r\n curEventTarget: curEventTarget,\r\n interaction: this\r\n });\r\n\r\n if (!this.simulation) {\r\n this.end(event);\r\n }\r\n\r\n this.pointerIsDown = false;\r\n this.removePointer(pointer, event);\r\n };\r\n\r\n /*\\\r\n * Interaction.end\r\n [ method ]\r\n *\r\n * Stop the current action and fire an end event. Inertial movement does\r\n * not happen.\r\n *\r\n - event (PointerEvent) #optional\r\n **\r\n | interact(target)\r\n | .draggable(true)\r\n | .on('move', function (event) {\r\n | if (event.pageX > 1000) {\r\n | // end the current action\r\n | event.interaction.end();\r\n | // stop all further listeners from being called\r\n | event.stopImmediatePropagation();\r\n | }\r\n | });\r\n \\*/\r\n\r\n\r\n Interaction.prototype.end = function end(event) {\r\n event = event || this.prevEvent;\r\n\r\n if (this.interacting()) {\r\n signals.fire('action-end', {\r\n event: event,\r\n interaction: this\r\n });\r\n }\r\n\r\n this.stop();\r\n };\r\n\r\n Interaction.prototype.currentAction = function currentAction() {\r\n return this._interacting ? this.prepared.name : null;\r\n };\r\n\r\n Interaction.prototype.interacting = function interacting() {\r\n return this._interacting;\r\n };\r\n\r\n Interaction.prototype.stop = function stop() {\r\n signals.fire('stop', { interaction: this });\r\n\r\n if (this._interacting) {\r\n signals.fire('stop-active', { interaction: this });\r\n signals.fire('stop-' + this.prepared.name, { interaction: this });\r\n }\r\n\r\n this.target = this.element = null;\r\n\r\n this._interacting = false;\r\n this.prepared.name = this.prevEvent = null;\r\n };\r\n\r\n Interaction.prototype.getPointerIndex = function getPointerIndex(pointer) {\r\n // mouse and pen interactions may have only one pointer\r\n if (this.pointerType === 'mouse' || this.pointerType === 'pen') {\r\n return 0;\r\n }\r\n\r\n return utils.indexOf(this.pointerIds, utils.getPointerId(pointer));\r\n };\r\n\r\n Interaction.prototype.updatePointer = function updatePointer(pointer, event) {\r\n var down = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : event && /(down|start)$/i.test(event.type);\r\n\r\n var id = utils.getPointerId(pointer);\r\n var index = this.getPointerIndex(pointer);\r\n\r\n if (index === -1) {\r\n index = this.pointerIds.length;\r\n this.pointerIds[index] = id;\r\n }\r\n\r\n if (down) {\r\n signals.fire('update-pointer-down', {\r\n pointer: pointer,\r\n event: event,\r\n down: down,\r\n pointerId: id,\r\n pointerIndex: index,\r\n interaction: this\r\n });\r\n }\r\n\r\n this.pointers[index] = pointer;\r\n\r\n return index;\r\n };\r\n\r\n Interaction.prototype.removePointer = function removePointer(pointer, event) {\r\n var index = this.getPointerIndex(pointer);\r\n\r\n if (index === -1) {\r\n return;\r\n }\r\n\r\n signals.fire('remove-pointer', {\r\n pointer: pointer,\r\n event: event,\r\n pointerIndex: index,\r\n interaction: this\r\n });\r\n\r\n this.pointers.splice(index, 1);\r\n this.pointerIds.splice(index, 1);\r\n this.downTargets.splice(index, 1);\r\n this.downTimes.splice(index, 1);\r\n };\r\n\r\n Interaction.prototype._updateEventTargets = function _updateEventTargets(target, currentTarget) {\r\n this._eventTarget = target;\r\n this._curEventTarget = currentTarget;\r\n };\r\n\r\n return Interaction;\r\n}();\r\n\r\nfor (var i = 0, len = methodNames.length; i < len; i++) {\r\n var method = methodNames[i];\r\n\r\n listeners[method] = doOnInteractions(method);\r\n}\r\n\r\nfunction doOnInteractions(method) {\r\n return function (event) {\r\n var pointerType = utils.getPointerType(event);\r\n\r\n var _utils$getEventTarget = utils.getEventTargets(event),\r\n eventTarget = _utils$getEventTarget[0],\r\n curEventTarget = _utils$getEventTarget[1];\r\n\r\n var matches = []; // [ [pointer, interaction], ...]\r\n\r\n if (browser.supportsTouch && /touch/.test(event.type)) {\r\n prevTouchTime = new Date().getTime();\r\n\r\n for (var _i = 0; _i < event.changedTouches.length; _i++) {\r\n var pointer = event.changedTouches[_i];\r\n var interaction = finder.search(pointer, event.type, eventTarget);\r\n\r\n matches.push([pointer, interaction || new Interaction({ pointerType: pointerType })]);\r\n }\r\n } else {\r\n var invalidPointer = false;\r\n\r\n if (!browser.supportsPointerEvent && /mouse/.test(event.type)) {\r\n // ignore mouse events while touch interactions are active\r\n for (var _i2 = 0; _i2 < scope.interactions.length && !invalidPointer; _i2++) {\r\n invalidPointer = scope.interactions[_i2].pointerType !== 'mouse' && scope.interactions[_i2].pointerIsDown;\r\n }\r\n\r\n // try to ignore mouse events that are simulated by the browser\r\n // after a touch event\r\n invalidPointer = invalidPointer || new Date().getTime() - prevTouchTime < 500\r\n // on iOS and Firefox Mobile, MouseEvent.timeStamp is zero if simulated\r\n || event.timeStamp === 0;\r\n }\r\n\r\n if (!invalidPointer) {\r\n var _interaction = finder.search(event, event.type, eventTarget);\r\n\r\n if (!_interaction) {\r\n _interaction = new Interaction({ pointerType: pointerType });\r\n }\r\n\r\n matches.push([event, _interaction]);\r\n }\r\n }\r\n\r\n for (var _iterator = matches, _isArray = Array.isArray(_iterator), _i3 = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray) {\r\n if (_i3 >= _iterator.length) break;\r\n _ref2 = _iterator[_i3++];\r\n } else {\r\n _i3 = _iterator.next();\r\n if (_i3.done) break;\r\n _ref2 = _i3.value;\r\n }\r\n\r\n var _ref3 = _ref2,\r\n _pointer = _ref3[0],\r\n _interaction2 = _ref3[1];\r\n\r\n _interaction2._updateEventTargets(eventTarget, curEventTarget);\r\n _interaction2[method](_pointer, event, eventTarget, curEventTarget);\r\n }\r\n };\r\n}\r\n\r\nfunction endAll(event) {\r\n for (var _i4 = 0; _i4 < scope.interactions.length; _i4++) {\r\n var interaction = scope.interactions[_i4];\r\n\r\n interaction.end(event);\r\n signals.fire('endall', { event: event, interaction: interaction });\r\n }\r\n}\r\n\r\nvar docEvents = {/* 'eventType': listenerFunc */};\r\nvar pEventTypes = browser.pEventTypes;\r\n\r\nif (domObjects.PointerEvent) {\r\n docEvents[pEventTypes.down] = listeners.pointerDown;\r\n docEvents[pEventTypes.move] = listeners.pointerMove;\r\n docEvents[pEventTypes.up] = listeners.pointerUp;\r\n docEvents[pEventTypes.cancel] = listeners.pointerUp;\r\n} else {\r\n docEvents.mousedown = listeners.pointerDown;\r\n docEvents.mousemove = listeners.pointerMove;\r\n docEvents.mouseup = listeners.pointerUp;\r\n\r\n docEvents.touchstart = listeners.pointerDown;\r\n docEvents.touchmove = listeners.pointerMove;\r\n docEvents.touchend = listeners.pointerUp;\r\n docEvents.touchcancel = listeners.pointerUp;\r\n}\r\n\r\ndocEvents.blur = endAll;\r\n\r\nfunction onDocSignal(_ref4, signalName) {\r\n var doc = _ref4.doc;\r\n\r\n var eventMethod = signalName.indexOf('add') === 0 ? events.add : events.remove;\r\n\r\n // delegate event listener\r\n for (var eventType in scope.delegatedEvents) {\r\n eventMethod(doc, eventType, events.delegateListener);\r\n eventMethod(doc, eventType, events.delegateUseCapture, true);\r\n }\r\n\r\n for (var _eventType in docEvents) {\r\n eventMethod(doc, _eventType, docEvents[_eventType]);\r\n }\r\n}\r\n\r\nsignals.on('update-pointer-down', function (_ref5) {\r\n var interaction = _ref5.interaction,\r\n pointer = _ref5.pointer,\r\n pointerId = _ref5.pointerId,\r\n pointerIndex = _ref5.pointerIndex,\r\n event = _ref5.event,\r\n eventTarget = _ref5.eventTarget,\r\n down = _ref5.down;\r\n\r\n interaction.pointerIds[pointerIndex] = pointerId;\r\n interaction.pointers[pointerIndex] = pointer;\r\n\r\n if (down) {\r\n interaction.pointerIsDown = true;\r\n }\r\n\r\n if (!interaction.interacting()) {\r\n utils.setCoords(interaction.startCoords, interaction.pointers);\r\n\r\n utils.copyCoords(interaction.curCoords, interaction.startCoords);\r\n utils.copyCoords(interaction.prevCoords, interaction.startCoords);\r\n\r\n interaction.downEvent = event;\r\n interaction.downTimes[pointerIndex] = interaction.curCoords.timeStamp;\r\n interaction.downTargets[pointerIndex] = eventTarget || event && utils.getEventTargets(event)[0];\r\n interaction.pointerWasMoved = false;\r\n\r\n utils.pointerExtend(interaction.downPointer, pointer);\r\n }\r\n});\r\n\r\nscope.signals.on('add-document', onDocSignal);\r\nscope.signals.on('remove-document', onDocSignal);\r\n\r\nInteraction.pointerMoveTolerance = 1;\r\nInteraction.doOnInteractions = doOnInteractions;\r\nInteraction.endAll = endAll;\r\nInteraction.signals = signals;\r\nInteraction.docEvents = docEvents;\r\n\r\nscope.endAllInteractions = endAll;\r\n\r\nmodule.exports = Interaction;\r\n\r\n},{\"./scope\":34,\"./utils\":44,\"./utils/Signals\":35,\"./utils/browser\":37,\"./utils/domObjects\":38,\"./utils/events\":40,\"./utils/interactionFinder\":45}],6:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar Interaction = require('../Interaction');\r\nvar InteractEvent = require('../InteractEvent');\r\n\r\nvar actions = {\r\n firePrepared: firePrepared,\r\n names: [],\r\n methodDict: {}\r\n};\r\n\r\nInteraction.signals.on('action-start', function (_ref) {\r\n var interaction = _ref.interaction,\r\n event = _ref.event;\r\n\r\n interaction._interacting = true;\r\n firePrepared(interaction, event, 'start');\r\n});\r\n\r\nInteraction.signals.on('action-move', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n event = _ref2.event,\r\n preEnd = _ref2.preEnd;\r\n\r\n firePrepared(interaction, event, 'move', preEnd);\r\n\r\n // if the action was ended in a listener\r\n if (!interaction.interacting()) {\r\n return false;\r\n }\r\n});\r\n\r\nInteraction.signals.on('action-end', function (_ref3) {\r\n var interaction = _ref3.interaction,\r\n event = _ref3.event;\r\n\r\n firePrepared(interaction, event, 'end');\r\n});\r\n\r\nfunction firePrepared(interaction, event, phase, preEnd) {\r\n var actionName = interaction.prepared.name;\r\n\r\n var newEvent = new InteractEvent(interaction, event, actionName, phase, interaction.element, null, preEnd);\r\n\r\n interaction.target.fire(newEvent);\r\n interaction.prevEvent = newEvent;\r\n}\r\n\r\nmodule.exports = actions;\r\n\r\n},{\"../InteractEvent\":3,\"../Interaction\":5}],7:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar actions = require('./base');\r\nvar utils = require('../utils');\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar drag = {\r\n defaults: {\r\n enabled: false,\r\n mouseButtons: null,\r\n\r\n origin: null,\r\n snap: null,\r\n restrict: null,\r\n inertia: null,\r\n autoScroll: null,\r\n\r\n startAxis: 'xy',\r\n lockAxis: 'xy'\r\n },\r\n\r\n checker: function checker(pointer, event, interactable) {\r\n var dragOptions = interactable.options.drag;\r\n\r\n return dragOptions.enabled ? { name: 'drag', axis: dragOptions.lockAxis === 'start' ? dragOptions.startAxis : dragOptions.lockAxis } : null;\r\n },\r\n\r\n getCursor: function getCursor() {\r\n return 'move';\r\n }\r\n};\r\n\r\nInteraction.signals.on('before-action-move', function (_ref) {\r\n var interaction = _ref.interaction;\r\n\r\n if (interaction.prepared.name !== 'drag') {\r\n return;\r\n }\r\n\r\n var axis = interaction.prepared.axis;\r\n\r\n if (axis === 'x') {\r\n interaction.curCoords.page.y = interaction.startCoords.page.y;\r\n interaction.curCoords.client.y = interaction.startCoords.client.y;\r\n\r\n interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vx);\r\n interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vx);\r\n interaction.pointerDelta.client.vy = 0;\r\n interaction.pointerDelta.page.vy = 0;\r\n } else if (axis === 'y') {\r\n interaction.curCoords.page.x = interaction.startCoords.page.x;\r\n interaction.curCoords.client.x = interaction.startCoords.client.x;\r\n\r\n interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vy);\r\n interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vy);\r\n interaction.pointerDelta.client.vx = 0;\r\n interaction.pointerDelta.page.vx = 0;\r\n }\r\n});\r\n\r\n// dragmove\r\nInteractEvent.signals.on('new', function (_ref2) {\r\n var iEvent = _ref2.iEvent,\r\n interaction = _ref2.interaction;\r\n\r\n if (iEvent.type !== 'dragmove') {\r\n return;\r\n }\r\n\r\n var axis = interaction.prepared.axis;\r\n\r\n if (axis === 'x') {\r\n iEvent.pageY = interaction.startCoords.page.y;\r\n iEvent.clientY = interaction.startCoords.client.y;\r\n iEvent.dy = 0;\r\n } else if (axis === 'y') {\r\n iEvent.pageX = interaction.startCoords.page.x;\r\n iEvent.clientX = interaction.startCoords.client.x;\r\n iEvent.dx = 0;\r\n }\r\n});\r\n\r\n/*\\\r\n * Interactable.draggable\r\n [ method ]\r\n *\r\n * Gets or sets whether drag actions can be performed on the\r\n * Interactable\r\n *\r\n = (boolean) Indicates if this can be the target of drag events\r\n | var isDraggable = interact('ul li').draggable();\r\n * or\r\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\r\n = (object) This Interactable\r\n | interact(element).draggable({\r\n | onstart: function (event) {},\r\n | onmove : function (event) {},\r\n | onend : function (event) {},\r\n |\r\n | // the axis in which the first movement must be\r\n | // for the drag sequence to start\r\n | // 'xy' by default - any direction\r\n | startAxis: 'x' || 'y' || 'xy',\r\n |\r\n | // 'xy' by default - don't restrict to one axis (move in any direction)\r\n | // 'x' or 'y' to restrict movement to either axis\r\n | // 'start' to restrict movement to the axis the drag started in\r\n | lockAxis: 'x' || 'y' || 'xy' || 'start',\r\n |\r\n | // max number of drags that can happen concurrently\r\n | // with elements of this Interactable. Infinity by default\r\n | max: Infinity,\r\n |\r\n | // max number of drags that can target the same element+Interactable\r\n | // 1 by default\r\n | maxPerElement: 2\r\n | });\r\n\\*/\r\nInteractable.prototype.draggable = function (options) {\r\n if (utils.is.object(options)) {\r\n this.options.drag.enabled = options.enabled === false ? false : true;\r\n this.setPerAction('drag', options);\r\n this.setOnEvents('drag', options);\r\n\r\n if (/^(xy|x|y|start)$/.test(options.lockAxis)) {\r\n this.options.drag.lockAxis = options.lockAxis;\r\n }\r\n if (/^(xy|x|y)$/.test(options.startAxis)) {\r\n this.options.drag.startAxis = options.startAxis;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n if (utils.is.bool(options)) {\r\n this.options.drag.enabled = options;\r\n\r\n if (!options) {\r\n this.ondragstart = this.ondragstart = this.ondragend = null;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n return this.options.drag;\r\n};\r\n\r\nactions.drag = drag;\r\nactions.names.push('drag');\r\nutils.merge(Interactable.eventTypes, ['dragstart', 'dragmove', 'draginertiastart', 'draginertiaresume', 'dragend']);\r\nactions.methodDict.drag = 'draggable';\r\n\r\ndefaultOptions.drag = drag.defaults;\r\n\r\nmodule.exports = drag;\r\n\r\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"./base\":6}],8:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar actions = require('./base');\r\nvar utils = require('../utils');\r\nvar scope = require('../scope');\r\nvar interact = require('../interact');\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar drop = {\r\n defaults: {\r\n enabled: false,\r\n accept: null,\r\n overlap: 'pointer'\r\n }\r\n};\r\n\r\nvar dynamicDrop = false;\r\n\r\nInteraction.signals.on('action-start', function (_ref) {\r\n var interaction = _ref.interaction,\r\n event = _ref.event;\r\n\r\n if (interaction.prepared.name !== 'drag') {\r\n return;\r\n }\r\n\r\n // reset active dropzones\r\n interaction.activeDrops.dropzones = [];\r\n interaction.activeDrops.elements = [];\r\n interaction.activeDrops.rects = [];\r\n\r\n interaction.dropEvents = null;\r\n\r\n if (!interaction.dynamicDrop) {\r\n setActiveDrops(interaction, interaction.element);\r\n }\r\n\r\n var dragEvent = interaction.prevEvent;\r\n var dropEvents = getDropEvents(interaction, event, dragEvent);\r\n\r\n if (dropEvents.activate) {\r\n fireActiveDrops(interaction, dropEvents.activate);\r\n }\r\n});\r\n\r\nInteractEvent.signals.on('new', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n iEvent = _ref2.iEvent,\r\n event = _ref2.event;\r\n\r\n if (iEvent.type !== 'dragmove' && iEvent.type !== 'dragend') {\r\n return;\r\n }\r\n\r\n var draggableElement = interaction.element;\r\n var dragEvent = iEvent;\r\n var dropResult = getDrop(dragEvent, event, draggableElement);\r\n\r\n interaction.dropTarget = dropResult.dropzone;\r\n interaction.dropElement = dropResult.element;\r\n\r\n interaction.dropEvents = getDropEvents(interaction, event, dragEvent);\r\n});\r\n\r\nInteraction.signals.on('action-move', function (_ref3) {\r\n var interaction = _ref3.interaction;\r\n\r\n if (interaction.prepared.name !== 'drag') {\r\n return;\r\n }\r\n\r\n fireDropEvents(interaction, interaction.dropEvents);\r\n});\r\n\r\nInteraction.signals.on('action-end', function (_ref4) {\r\n var interaction = _ref4.interaction;\r\n\r\n if (interaction.prepared.name === 'drag') {\r\n fireDropEvents(interaction, interaction.dropEvents);\r\n }\r\n});\r\n\r\nInteraction.signals.on('stop-drag', function (_ref5) {\r\n var interaction = _ref5.interaction;\r\n\r\n interaction.activeDrops.dropzones = interaction.activeDrops.elements = interaction.activeDrops.rects = interaction.dropEvents = null;\r\n});\r\n\r\nfunction collectDrops(interaction, element) {\r\n var drops = [];\r\n var elements = [];\r\n\r\n element = element || interaction.element;\r\n\r\n // collect all dropzones and their elements which qualify for a drop\r\n for (var _iterator = scope.interactables, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref6;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref6 = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref6 = _i.value;\r\n }\r\n\r\n var current = _ref6;\r\n\r\n if (!current.options.drop.enabled) {\r\n continue;\r\n }\r\n\r\n var accept = current.options.drop.accept;\r\n\r\n // test the draggable element against the dropzone's accept setting\r\n if (utils.is.element(accept) && accept !== element || utils.is.string(accept) && !utils.matchesSelector(element, accept)) {\r\n\r\n continue;\r\n }\r\n\r\n // query for new elements if necessary\r\n var dropElements = utils.is.string(current.target) ? current._context.querySelectorAll(current.target) : [current.target];\r\n\r\n for (var i = 0; i < dropElements.length; i++) {\r\n var currentElement = dropElements[i];\r\n\r\n if (currentElement !== element) {\r\n drops.push(current);\r\n elements.push(currentElement);\r\n }\r\n }\r\n }\r\n\r\n return {\r\n elements: elements,\r\n dropzones: drops\r\n };\r\n}\r\n\r\nfunction fireActiveDrops(interaction, event) {\r\n var prevElement = void 0;\r\n\r\n // loop through all active dropzones and trigger event\r\n for (var i = 0; i < interaction.activeDrops.dropzones.length; i++) {\r\n var current = interaction.activeDrops.dropzones[i];\r\n var currentElement = interaction.activeDrops.elements[i];\r\n\r\n // prevent trigger of duplicate events on same element\r\n if (currentElement !== prevElement) {\r\n // set current element as event target\r\n event.target = currentElement;\r\n current.fire(event);\r\n }\r\n prevElement = currentElement;\r\n }\r\n}\r\n\r\n// Collect a new set of possible drops and save them in activeDrops.\r\n// setActiveDrops should always be called when a drag has just started or a\r\n// drag event happens while dynamicDrop is true\r\nfunction setActiveDrops(interaction, dragElement) {\r\n // get dropzones and their elements that could receive the draggable\r\n var possibleDrops = collectDrops(interaction, dragElement, true);\r\n\r\n interaction.activeDrops.dropzones = possibleDrops.dropzones;\r\n interaction.activeDrops.elements = possibleDrops.elements;\r\n interaction.activeDrops.rects = [];\r\n\r\n for (var i = 0; i < interaction.activeDrops.dropzones.length; i++) {\r\n interaction.activeDrops.rects[i] = interaction.activeDrops.dropzones[i].getRect(interaction.activeDrops.elements[i]);\r\n }\r\n}\r\n\r\nfunction getDrop(dragEvent, event, dragElement) {\r\n var interaction = dragEvent.interaction;\r\n var validDrops = [];\r\n\r\n if (dynamicDrop) {\r\n setActiveDrops(interaction, dragElement);\r\n }\r\n\r\n // collect all dropzones and their elements which qualify for a drop\r\n for (var j = 0; j < interaction.activeDrops.dropzones.length; j++) {\r\n var current = interaction.activeDrops.dropzones[j];\r\n var currentElement = interaction.activeDrops.elements[j];\r\n var rect = interaction.activeDrops.rects[j];\r\n\r\n validDrops.push(current.dropCheck(dragEvent, event, interaction.target, dragElement, currentElement, rect) ? currentElement : null);\r\n }\r\n\r\n // get the most appropriate dropzone based on DOM depth and order\r\n var dropIndex = utils.indexOfDeepestElement(validDrops);\r\n\r\n return {\r\n dropzone: interaction.activeDrops.dropzones[dropIndex] || null,\r\n element: interaction.activeDrops.elements[dropIndex] || null\r\n };\r\n}\r\n\r\nfunction getDropEvents(interaction, pointerEvent, dragEvent) {\r\n var dropEvents = {\r\n enter: null,\r\n leave: null,\r\n activate: null,\r\n deactivate: null,\r\n move: null,\r\n drop: null\r\n };\r\n\r\n var tmpl = {\r\n dragEvent: dragEvent,\r\n interaction: interaction,\r\n target: interaction.dropElement,\r\n dropzone: interaction.dropTarget,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n timeStamp: dragEvent.timeStamp\r\n };\r\n\r\n if (interaction.dropElement !== interaction.prevDropElement) {\r\n // if there was a prevDropTarget, create a dragleave event\r\n if (interaction.prevDropTarget) {\r\n dropEvents.leave = utils.extend({ type: 'dragleave' }, tmpl);\r\n\r\n dragEvent.dragLeave = dropEvents.leave.target = interaction.prevDropElement;\r\n dragEvent.prevDropzone = dropEvents.leave.dropzone = interaction.prevDropTarget;\r\n }\r\n // if the dropTarget is not null, create a dragenter event\r\n if (interaction.dropTarget) {\r\n dropEvents.enter = {\r\n dragEvent: dragEvent,\r\n interaction: interaction,\r\n target: interaction.dropElement,\r\n dropzone: interaction.dropTarget,\r\n relatedTarget: dragEvent.target,\r\n draggable: dragEvent.interactable,\r\n timeStamp: dragEvent.timeStamp,\r\n type: 'dragenter'\r\n };\r\n\r\n dragEvent.dragEnter = interaction.dropElement;\r\n dragEvent.dropzone = interaction.dropTarget;\r\n }\r\n }\r\n\r\n if (dragEvent.type === 'dragend' && interaction.dropTarget) {\r\n dropEvents.drop = utils.extend({ type: 'drop' }, tmpl);\r\n\r\n dragEvent.dropzone = interaction.dropTarget;\r\n dragEvent.relatedTarget = interaction.dropElement;\r\n }\r\n if (dragEvent.type === 'dragstart') {\r\n dropEvents.activate = utils.extend({ type: 'dropactivate' }, tmpl);\r\n\r\n dropEvents.activate.target = null;\r\n dropEvents.activate.dropzone = null;\r\n }\r\n if (dragEvent.type === 'dragend') {\r\n dropEvents.deactivate = utils.extend({ type: 'dropdeactivate' }, tmpl);\r\n\r\n dropEvents.deactivate.target = null;\r\n dropEvents.deactivate.dropzone = null;\r\n }\r\n if (dragEvent.type === 'dragmove' && interaction.dropTarget) {\r\n dropEvents.move = utils.extend({\r\n dragmove: dragEvent,\r\n type: 'dropmove'\r\n }, tmpl);\r\n\r\n dragEvent.dropzone = interaction.dropTarget;\r\n }\r\n\r\n return dropEvents;\r\n}\r\n\r\nfunction fireDropEvents(interaction, dropEvents) {\r\n if (dropEvents.leave) {\r\n interaction.prevDropTarget.fire(dropEvents.leave);\r\n }\r\n if (dropEvents.move) {\r\n interaction.dropTarget.fire(dropEvents.move);\r\n }\r\n if (dropEvents.enter) {\r\n interaction.dropTarget.fire(dropEvents.enter);\r\n }\r\n if (dropEvents.drop) {\r\n interaction.dropTarget.fire(dropEvents.drop);\r\n }\r\n if (dropEvents.deactivate) {\r\n fireActiveDrops(interaction, dropEvents.deactivate);\r\n }\r\n\r\n interaction.prevDropTarget = interaction.dropTarget;\r\n interaction.prevDropElement = interaction.dropElement;\r\n}\r\n\r\n/*\\\r\n * Interactable.dropzone\r\n [ method ]\r\n *\r\n * Returns or sets whether elements can be dropped onto this\r\n * Interactable to trigger drop events\r\n *\r\n * Dropzones can receive the following events:\r\n * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\r\n * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\r\n * - `dragmove` when a draggable that has entered the dropzone is moved\r\n * - `drop` when a draggable is dropped into this dropzone\r\n *\r\n * Use the `accept` option to allow only elements that match the given CSS\r\n * selector or element. The value can be:\r\n *\r\n * - **an Element** - only that element can be dropped into this dropzone.\r\n * - **a string**, - the element being dragged must match it as a CSS selector.\r\n * - **`null`** - accept options is cleared - it accepts any element.\r\n *\r\n * Use the `overlap` option to set how drops are checked for. The allowed\r\n * values are:\r\n *\r\n * - `'pointer'`, the pointer must be over the dropzone (default)\r\n * - `'center'`, the draggable element's center must be over the dropzone\r\n * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\r\n * e.g. `0.5` for drop to happen when half of the area of the draggable is\r\n * over the dropzone\r\n *\r\n * Use the `checker` option to specify a function to check if a dragged\r\n * element is over this Interactable.\r\n *\r\n | interact(target)\r\n | .dropChecker(function(dragEvent, // related dragmove or dragend event\r\n | event, // TouchEvent/PointerEvent/MouseEvent\r\n | dropped, // bool result of the default checker\r\n | dropzone, // dropzone Interactable\r\n | dropElement, // dropzone elemnt\r\n | draggable, // draggable Interactable\r\n | draggableElement) {// draggable element\r\n |\r\n | return dropped && event.target.hasAttribute('allow-drop');\r\n | }\r\n *\r\n *\r\n - options (boolean | object | null) #optional The new value to be set.\r\n | interact('.drop').dropzone({\r\n | accept: '.can-drop' || document.getElementById('single-drop'),\r\n | overlap: 'pointer' || 'center' || zeroToOne\r\n | }\r\n = (boolean | object) The current setting or this Interactable\r\n\\*/\r\nInteractable.prototype.dropzone = function (options) {\r\n if (utils.is.object(options)) {\r\n this.options.drop.enabled = options.enabled === false ? false : true;\r\n\r\n if (utils.is.function(options.ondrop)) {\r\n this.events.ondrop = options.ondrop;\r\n }\r\n if (utils.is.function(options.ondropactivate)) {\r\n this.events.ondropactivate = options.ondropactivate;\r\n }\r\n if (utils.is.function(options.ondropdeactivate)) {\r\n this.events.ondropdeactivate = options.ondropdeactivate;\r\n }\r\n if (utils.is.function(options.ondragenter)) {\r\n this.events.ondragenter = options.ondragenter;\r\n }\r\n if (utils.is.function(options.ondragleave)) {\r\n this.events.ondragleave = options.ondragleave;\r\n }\r\n if (utils.is.function(options.ondropmove)) {\r\n this.events.ondropmove = options.ondropmove;\r\n }\r\n\r\n if (/^(pointer|center)$/.test(options.overlap)) {\r\n this.options.drop.overlap = options.overlap;\r\n } else if (utils.is.number(options.overlap)) {\r\n this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\r\n }\r\n if ('accept' in options) {\r\n this.options.drop.accept = options.accept;\r\n }\r\n if ('checker' in options) {\r\n this.options.drop.checker = options.checker;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n if (utils.is.bool(options)) {\r\n this.options.drop.enabled = options;\r\n\r\n if (!options) {\r\n this.ondragenter = this.ondragleave = this.ondrop = this.ondropactivate = this.ondropdeactivate = null;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n return this.options.drop;\r\n};\r\n\r\nInteractable.prototype.dropCheck = function (dragEvent, event, draggable, draggableElement, dropElement, rect) {\r\n var dropped = false;\r\n\r\n // if the dropzone has no rect (eg. display: none)\r\n // call the custom dropChecker or just return false\r\n if (!(rect = rect || this.getRect(dropElement))) {\r\n return this.options.drop.checker ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement) : false;\r\n }\r\n\r\n var dropOverlap = this.options.drop.overlap;\r\n\r\n if (dropOverlap === 'pointer') {\r\n var origin = utils.getOriginXY(draggable, draggableElement, 'drag');\r\n var page = utils.getPageXY(dragEvent);\r\n\r\n page.x += origin.x;\r\n page.y += origin.y;\r\n\r\n var horizontal = page.x > rect.left && page.x < rect.right;\r\n var vertical = page.y > rect.top && page.y < rect.bottom;\r\n\r\n dropped = horizontal && vertical;\r\n }\r\n\r\n var dragRect = draggable.getRect(draggableElement);\r\n\r\n if (dragRect && dropOverlap === 'center') {\r\n var cx = dragRect.left + dragRect.width / 2;\r\n var cy = dragRect.top + dragRect.height / 2;\r\n\r\n dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\r\n }\r\n\r\n if (dragRect && utils.is.number(dropOverlap)) {\r\n var overlapArea = Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left)) * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top));\r\n\r\n var overlapRatio = overlapArea / (dragRect.width * dragRect.height);\r\n\r\n dropped = overlapRatio >= dropOverlap;\r\n }\r\n\r\n if (this.options.drop.checker) {\r\n dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\r\n }\r\n\r\n return dropped;\r\n};\r\n\r\nInteractable.signals.on('unset', function (_ref7) {\r\n var interactable = _ref7.interactable;\r\n\r\n interactable.dropzone(false);\r\n});\r\n\r\nInteractable.settingsMethods.push('dropChecker');\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.dropTarget = null; // the dropzone a drag target might be dropped into\r\n interaction.dropElement = null; // the element at the time of checking\r\n interaction.prevDropTarget = null; // the dropzone that was recently dragged away from\r\n interaction.prevDropElement = null; // the element at the time of checking\r\n interaction.dropEvents = null; // the dropEvents related to the current drag event\r\n\r\n interaction.activeDrops = {\r\n dropzones: [], // the dropzones that are mentioned below\r\n elements: [], // elements of dropzones that accept the target draggable\r\n rects: [] // the rects of the elements mentioned above\r\n };\r\n});\r\n\r\nInteraction.signals.on('stop', function (_ref8) {\r\n var interaction = _ref8.interaction;\r\n\r\n interaction.dropTarget = interaction.dropElement = interaction.prevDropTarget = interaction.prevDropElement = null;\r\n});\r\n\r\n/*\\\r\n * interact.dynamicDrop\r\n [ method ]\r\n *\r\n * Returns or sets whether the dimensions of dropzone elements are\r\n * calculated on every dragmove or only on dragstart for the default\r\n * dropChecker\r\n *\r\n - newValue (boolean) #optional True to check on each move. False to check only before start\r\n = (boolean | interact) The current setting or interact\r\n\\*/\r\ninteract.dynamicDrop = function (newValue) {\r\n if (utils.is.bool(newValue)) {\r\n //if (dragging && dynamicDrop !== newValue && !newValue) {\r\n //calcRects(dropzones);\r\n //}\r\n\r\n dynamicDrop = newValue;\r\n\r\n return interact;\r\n }\r\n return dynamicDrop;\r\n};\r\n\r\nutils.merge(Interactable.eventTypes, ['dragenter', 'dragleave', 'dropactivate', 'dropdeactivate', 'dropmove', 'drop']);\r\nactions.methodDict.drop = 'dropzone';\r\n\r\ndefaultOptions.drop = drop.defaults;\r\n\r\nmodule.exports = drop;\r\n\r\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../interact\":21,\"../scope\":34,\"../utils\":44,\"./base\":6}],9:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar actions = require('./base');\r\nvar utils = require('../utils');\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar gesture = {\r\n defaults: {\r\n enabled: false,\r\n origin: null,\r\n restrict: null\r\n },\r\n\r\n checker: function checker(pointer, event, interactable, element, interaction) {\r\n if (interaction.pointerIds.length >= 2) {\r\n return { name: 'gesture' };\r\n }\r\n\r\n return null;\r\n },\r\n\r\n getCursor: function getCursor() {\r\n return '';\r\n }\r\n};\r\n\r\nInteractEvent.signals.on('new', function (_ref) {\r\n var iEvent = _ref.iEvent,\r\n interaction = _ref.interaction;\r\n\r\n if (iEvent.type !== 'gesturestart') {\r\n return;\r\n }\r\n iEvent.ds = 0;\r\n\r\n interaction.gesture.startDistance = interaction.gesture.prevDistance = iEvent.distance;\r\n interaction.gesture.startAngle = interaction.gesture.prevAngle = iEvent.angle;\r\n interaction.gesture.scale = 1;\r\n});\r\n\r\nInteractEvent.signals.on('new', function (_ref2) {\r\n var iEvent = _ref2.iEvent,\r\n interaction = _ref2.interaction;\r\n\r\n if (iEvent.type !== 'gesturemove') {\r\n return;\r\n }\r\n\r\n iEvent.ds = iEvent.scale - interaction.gesture.scale;\r\n\r\n interaction.target.fire(iEvent);\r\n\r\n interaction.gesture.prevAngle = iEvent.angle;\r\n interaction.gesture.prevDistance = iEvent.distance;\r\n\r\n if (iEvent.scale !== Infinity && iEvent.scale !== null && iEvent.scale !== undefined && !isNaN(iEvent.scale)) {\r\n\r\n interaction.gesture.scale = iEvent.scale;\r\n }\r\n});\r\n\r\n/*\\\r\n * Interactable.gesturable\r\n [ method ]\r\n *\r\n * Gets or sets whether multitouch gestures can be performed on the\r\n * Interactable's element\r\n *\r\n = (boolean) Indicates if this can be the target of gesture events\r\n | var isGestureable = interact(element).gesturable();\r\n * or\r\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\r\n = (object) this Interactable\r\n | interact(element).gesturable({\r\n | onstart: function (event) {},\r\n | onmove : function (event) {},\r\n | onend : function (event) {},\r\n |\r\n | // limit multiple gestures.\r\n | // See the explanation in @Interactable.draggable example\r\n | max: Infinity,\r\n | maxPerElement: 1,\r\n | });\r\n\\*/\r\nInteractable.prototype.gesturable = function (options) {\r\n if (utils.is.object(options)) {\r\n this.options.gesture.enabled = options.enabled === false ? false : true;\r\n this.setPerAction('gesture', options);\r\n this.setOnEvents('gesture', options);\r\n\r\n return this;\r\n }\r\n\r\n if (utils.is.bool(options)) {\r\n this.options.gesture.enabled = options;\r\n\r\n if (!options) {\r\n this.ongesturestart = this.ongesturestart = this.ongestureend = null;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n return this.options.gesture;\r\n};\r\n\r\nInteractEvent.signals.on('set-delta', function (_ref3) {\r\n var interaction = _ref3.interaction,\r\n iEvent = _ref3.iEvent,\r\n action = _ref3.action,\r\n event = _ref3.event,\r\n starting = _ref3.starting,\r\n ending = _ref3.ending,\r\n deltaSource = _ref3.deltaSource;\r\n\r\n if (action !== 'gesture') {\r\n return;\r\n }\r\n\r\n var pointers = interaction.pointers;\r\n\r\n iEvent.touches = [pointers[0], pointers[1]];\r\n\r\n if (starting) {\r\n iEvent.distance = utils.touchDistance(pointers, deltaSource);\r\n iEvent.box = utils.touchBBox(pointers);\r\n iEvent.scale = 1;\r\n iEvent.ds = 0;\r\n iEvent.angle = utils.touchAngle(pointers, undefined, deltaSource);\r\n iEvent.da = 0;\r\n } else if (ending || event instanceof InteractEvent) {\r\n iEvent.distance = interaction.prevEvent.distance;\r\n iEvent.box = interaction.prevEvent.box;\r\n iEvent.scale = interaction.prevEvent.scale;\r\n iEvent.ds = iEvent.scale - 1;\r\n iEvent.angle = interaction.prevEvent.angle;\r\n iEvent.da = iEvent.angle - interaction.gesture.startAngle;\r\n } else {\r\n iEvent.distance = utils.touchDistance(pointers, deltaSource);\r\n iEvent.box = utils.touchBBox(pointers);\r\n iEvent.scale = iEvent.distance / interaction.gesture.startDistance;\r\n iEvent.angle = utils.touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\r\n\r\n iEvent.ds = iEvent.scale - interaction.gesture.prevScale;\r\n iEvent.da = iEvent.angle - interaction.gesture.prevAngle;\r\n }\r\n});\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.gesture = {\r\n start: { x: 0, y: 0 },\r\n\r\n startDistance: 0, // distance between two touches of touchStart\r\n prevDistance: 0,\r\n distance: 0,\r\n\r\n scale: 1, // gesture.distance / gesture.startDistance\r\n\r\n startAngle: 0, // angle of line joining two touches\r\n prevAngle: 0 // angle of the previous gesture event\r\n };\r\n});\r\n\r\nactions.gesture = gesture;\r\nactions.names.push('gesture');\r\nutils.merge(Interactable.eventTypes, ['gesturestart', 'gesturemove', 'gestureend']);\r\nactions.methodDict.gesture = 'gesturable';\r\n\r\ndefaultOptions.gesture = gesture.defaults;\r\n\r\nmodule.exports = gesture;\r\n\r\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"./base\":6}],10:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar actions = require('./base');\r\nvar utils = require('../utils');\r\nvar browser = require('../utils/browser');\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\n// Less Precision with touch input\r\nvar defaultMargin = browser.supportsTouch || browser.supportsPointerEvent ? 20 : 10;\r\n\r\nvar resize = {\r\n defaults: {\r\n enabled: false,\r\n mouseButtons: null,\r\n\r\n origin: null,\r\n snap: null,\r\n restrict: null,\r\n inertia: null,\r\n autoScroll: null,\r\n\r\n square: false,\r\n preserveAspectRatio: false,\r\n axis: 'xy',\r\n\r\n // use default margin\r\n margin: NaN,\r\n\r\n // object with props left, right, top, bottom which are\r\n // true/false values to resize when the pointer is over that edge,\r\n // CSS selectors to match the handles for each direction\r\n // or the Elements for each handle\r\n edges: null,\r\n\r\n // a value of 'none' will limit the resize rect to a minimum of 0x0\r\n // 'negate' will alow the rect to have negative width/height\r\n // 'reposition' will keep the width/height positive by swapping\r\n // the top and bottom edges and/or swapping the left and right edges\r\n invert: 'none'\r\n },\r\n\r\n checker: function checker(pointer, event, interactable, element, interaction, rect) {\r\n if (!rect) {\r\n return null;\r\n }\r\n\r\n var page = utils.extend({}, interaction.curCoords.page);\r\n var options = interactable.options;\r\n\r\n if (options.resize.enabled) {\r\n var resizeOptions = options.resize;\r\n var resizeEdges = { left: false, right: false, top: false, bottom: false };\r\n\r\n // if using resize.edges\r\n if (utils.is.object(resizeOptions.edges)) {\r\n for (var edge in resizeEdges) {\r\n resizeEdges[edge] = checkResizeEdge(edge, resizeOptions.edges[edge], page, interaction._eventTarget, element, rect, resizeOptions.margin || defaultMargin);\r\n }\r\n\r\n resizeEdges.left = resizeEdges.left && !resizeEdges.right;\r\n resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\r\n\r\n if (resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom) {\r\n return {\r\n name: 'resize',\r\n edges: resizeEdges\r\n };\r\n }\r\n } else {\r\n var right = options.resize.axis !== 'y' && page.x > rect.right - defaultMargin;\r\n var bottom = options.resize.axis !== 'x' && page.y > rect.bottom - defaultMargin;\r\n\r\n if (right || bottom) {\r\n return {\r\n name: 'resize',\r\n axes: (right ? 'x' : '') + (bottom ? 'y' : '')\r\n };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n\r\n cursors: browser.isIe9OrOlder ? {\r\n x: 'e-resize',\r\n y: 's-resize',\r\n xy: 'se-resize',\r\n\r\n top: 'n-resize',\r\n left: 'w-resize',\r\n bottom: 's-resize',\r\n right: 'e-resize',\r\n topleft: 'se-resize',\r\n bottomright: 'se-resize',\r\n topright: 'ne-resize',\r\n bottomleft: 'ne-resize'\r\n } : {\r\n x: 'ew-resize',\r\n y: 'ns-resize',\r\n xy: 'nwse-resize',\r\n\r\n top: 'ns-resize',\r\n left: 'ew-resize',\r\n bottom: 'ns-resize',\r\n right: 'ew-resize',\r\n topleft: 'nwse-resize',\r\n bottomright: 'nwse-resize',\r\n topright: 'nesw-resize',\r\n bottomleft: 'nesw-resize'\r\n },\r\n\r\n getCursor: function getCursor(action) {\r\n if (action.axis) {\r\n return resize.cursors[action.name + action.axis];\r\n } else if (action.edges) {\r\n var cursorKey = '';\r\n var edgeNames = ['top', 'bottom', 'left', 'right'];\r\n\r\n for (var i = 0; i < 4; i++) {\r\n if (action.edges[edgeNames[i]]) {\r\n cursorKey += edgeNames[i];\r\n }\r\n }\r\n\r\n return resize.cursors[cursorKey];\r\n }\r\n }\r\n};\r\n\r\n// resizestart\r\nInteractEvent.signals.on('new', function (_ref) {\r\n var iEvent = _ref.iEvent,\r\n interaction = _ref.interaction;\r\n\r\n if (iEvent.type !== 'resizestart' || !interaction.prepared.edges) {\r\n return;\r\n }\r\n\r\n var startRect = interaction.target.getRect(interaction.element);\r\n var resizeOptions = interaction.target.options.resize;\r\n\r\n /*\r\n * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\r\n * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\r\n * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\r\n * on the active edges and the edge being interacted with.\r\n */\r\n if (resizeOptions.square || resizeOptions.preserveAspectRatio) {\r\n var linkedEdges = utils.extend({}, interaction.prepared.edges);\r\n\r\n linkedEdges.top = linkedEdges.top || linkedEdges.left && !linkedEdges.bottom;\r\n linkedEdges.left = linkedEdges.left || linkedEdges.top && !linkedEdges.right;\r\n linkedEdges.bottom = linkedEdges.bottom || linkedEdges.right && !linkedEdges.top;\r\n linkedEdges.right = linkedEdges.right || linkedEdges.bottom && !linkedEdges.left;\r\n\r\n interaction.prepared._linkedEdges = linkedEdges;\r\n } else {\r\n interaction.prepared._linkedEdges = null;\r\n }\r\n\r\n // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\r\n if (resizeOptions.preserveAspectRatio) {\r\n interaction.resizeStartAspectRatio = startRect.width / startRect.height;\r\n }\r\n\r\n interaction.resizeRects = {\r\n start: startRect,\r\n current: utils.extend({}, startRect),\r\n inverted: utils.extend({}, startRect),\r\n previous: utils.extend({}, startRect),\r\n delta: {\r\n left: 0, right: 0, width: 0,\r\n top: 0, bottom: 0, height: 0\r\n }\r\n };\r\n\r\n iEvent.rect = interaction.resizeRects.inverted;\r\n iEvent.deltaRect = interaction.resizeRects.delta;\r\n});\r\n\r\n// resizemove\r\nInteractEvent.signals.on('new', function (_ref2) {\r\n var iEvent = _ref2.iEvent,\r\n phase = _ref2.phase,\r\n interaction = _ref2.interaction;\r\n\r\n if (phase !== 'move' || !interaction.prepared.edges) {\r\n return;\r\n }\r\n\r\n var resizeOptions = interaction.target.options.resize;\r\n var invert = resizeOptions.invert;\r\n var invertible = invert === 'reposition' || invert === 'negate';\r\n\r\n var edges = interaction.prepared.edges;\r\n\r\n var start = interaction.resizeRects.start;\r\n var current = interaction.resizeRects.current;\r\n var inverted = interaction.resizeRects.inverted;\r\n var delta = interaction.resizeRects.delta;\r\n var previous = utils.extend(interaction.resizeRects.previous, inverted);\r\n var originalEdges = edges;\r\n\r\n var dx = iEvent.dx;\r\n var dy = iEvent.dy;\r\n\r\n if (resizeOptions.preserveAspectRatio || resizeOptions.square) {\r\n // `resize.preserveAspectRatio` takes precedence over `resize.square`\r\n var startAspectRatio = resizeOptions.preserveAspectRatio ? interaction.resizeStartAspectRatio : 1;\r\n\r\n edges = interaction.prepared._linkedEdges;\r\n\r\n if (originalEdges.left && originalEdges.bottom || originalEdges.right && originalEdges.top) {\r\n dy = -dx / startAspectRatio;\r\n } else if (originalEdges.left || originalEdges.right) {\r\n dy = dx / startAspectRatio;\r\n } else if (originalEdges.top || originalEdges.bottom) {\r\n dx = dy * startAspectRatio;\r\n }\r\n }\r\n\r\n // update the 'current' rect without modifications\r\n if (edges.top) {\r\n current.top += dy;\r\n }\r\n if (edges.bottom) {\r\n current.bottom += dy;\r\n }\r\n if (edges.left) {\r\n current.left += dx;\r\n }\r\n if (edges.right) {\r\n current.right += dx;\r\n }\r\n\r\n if (invertible) {\r\n // if invertible, copy the current rect\r\n utils.extend(inverted, current);\r\n\r\n if (invert === 'reposition') {\r\n // swap edge values if necessary to keep width/height positive\r\n var swap = void 0;\r\n\r\n if (inverted.top > inverted.bottom) {\r\n swap = inverted.top;\r\n\r\n inverted.top = inverted.bottom;\r\n inverted.bottom = swap;\r\n }\r\n if (inverted.left > inverted.right) {\r\n swap = inverted.left;\r\n\r\n inverted.left = inverted.right;\r\n inverted.right = swap;\r\n }\r\n }\r\n } else {\r\n // if not invertible, restrict to minimum of 0x0 rect\r\n inverted.top = Math.min(current.top, start.bottom);\r\n inverted.bottom = Math.max(current.bottom, start.top);\r\n inverted.left = Math.min(current.left, start.right);\r\n inverted.right = Math.max(current.right, start.left);\r\n }\r\n\r\n inverted.width = inverted.right - inverted.left;\r\n inverted.height = inverted.bottom - inverted.top;\r\n\r\n for (var edge in inverted) {\r\n delta[edge] = inverted[edge] - previous[edge];\r\n }\r\n\r\n iEvent.edges = interaction.prepared.edges;\r\n iEvent.rect = inverted;\r\n iEvent.deltaRect = delta;\r\n});\r\n\r\n/*\\\r\n * Interactable.resizable\r\n [ method ]\r\n *\r\n * Gets or sets whether resize actions can be performed on the\r\n * Interactable\r\n *\r\n = (boolean) Indicates if this can be the target of resize elements\r\n | var isResizeable = interact('input[type=text]').resizable();\r\n * or\r\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\r\n = (object) This Interactable\r\n | interact(element).resizable({\r\n | onstart: function (event) {},\r\n | onmove : function (event) {},\r\n | onend : function (event) {},\r\n |\r\n | edges: {\r\n | top : true, // Use pointer coords to check for resize.\r\n | left : false, // Disable resizing from left edge.\r\n | bottom: '.resize-s',// Resize if pointer target matches selector\r\n | right : handleEl // Resize if pointer target is the given Element\r\n | },\r\n |\r\n | // Width and height can be adjusted independently. When `true`, width and\r\n | // height are adjusted at a 1:1 ratio.\r\n | square: false,\r\n |\r\n | // Width and height can be adjusted independently. When `true`, width and\r\n | // height maintain the aspect ratio they had when resizing started.\r\n | preserveAspectRatio: false,\r\n |\r\n | // a value of 'none' will limit the resize rect to a minimum of 0x0\r\n | // 'negate' will allow the rect to have negative width/height\r\n | // 'reposition' will keep the width/height positive by swapping\r\n | // the top and bottom edges and/or swapping the left and right edges\r\n | invert: 'none' || 'negate' || 'reposition'\r\n |\r\n | // limit multiple resizes.\r\n | // See the explanation in the @Interactable.draggable example\r\n | max: Infinity,\r\n | maxPerElement: 1,\r\n | });\r\n \\*/\r\nInteractable.prototype.resizable = function (options) {\r\n if (utils.is.object(options)) {\r\n this.options.resize.enabled = options.enabled === false ? false : true;\r\n this.setPerAction('resize', options);\r\n this.setOnEvents('resize', options);\r\n\r\n if (/^x$|^y$|^xy$/.test(options.axis)) {\r\n this.options.resize.axis = options.axis;\r\n } else if (options.axis === null) {\r\n this.options.resize.axis = defaultOptions.resize.axis;\r\n }\r\n\r\n if (utils.is.bool(options.preserveAspectRatio)) {\r\n this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\r\n } else if (utils.is.bool(options.square)) {\r\n this.options.resize.square = options.square;\r\n }\r\n\r\n return this;\r\n }\r\n if (utils.is.bool(options)) {\r\n this.options.resize.enabled = options;\r\n\r\n if (!options) {\r\n this.onresizestart = this.onresizestart = this.onresizeend = null;\r\n }\r\n\r\n return this;\r\n }\r\n return this.options.resize;\r\n};\r\n\r\nfunction checkResizeEdge(name, value, page, element, interactableElement, rect, margin) {\r\n // false, '', undefined, null\r\n if (!value) {\r\n return false;\r\n }\r\n\r\n // true value, use pointer coords and element rect\r\n if (value === true) {\r\n // if dimensions are negative, \"switch\" edges\r\n var width = utils.is.number(rect.width) ? rect.width : rect.right - rect.left;\r\n var height = utils.is.number(rect.height) ? rect.height : rect.bottom - rect.top;\r\n\r\n if (width < 0) {\r\n if (name === 'left') {\r\n name = 'right';\r\n } else if (name === 'right') {\r\n name = 'left';\r\n }\r\n }\r\n if (height < 0) {\r\n if (name === 'top') {\r\n name = 'bottom';\r\n } else if (name === 'bottom') {\r\n name = 'top';\r\n }\r\n }\r\n\r\n if (name === 'left') {\r\n return page.x < (width >= 0 ? rect.left : rect.right) + margin;\r\n }\r\n if (name === 'top') {\r\n return page.y < (height >= 0 ? rect.top : rect.bottom) + margin;\r\n }\r\n\r\n if (name === 'right') {\r\n return page.x > (width >= 0 ? rect.right : rect.left) - margin;\r\n }\r\n if (name === 'bottom') {\r\n return page.y > (height >= 0 ? rect.bottom : rect.top) - margin;\r\n }\r\n }\r\n\r\n // the remaining checks require an element\r\n if (!utils.is.element(element)) {\r\n return false;\r\n }\r\n\r\n return utils.is.element(value)\r\n // the value is an element to use as a resize handle\r\n ? value === element\r\n // otherwise check if element matches value as selector\r\n : utils.matchesUpTo(element, value, interactableElement);\r\n}\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.resizeAxes = 'xy';\r\n});\r\n\r\nInteractEvent.signals.on('set-delta', function (_ref3) {\r\n var interaction = _ref3.interaction,\r\n iEvent = _ref3.iEvent,\r\n action = _ref3.action;\r\n\r\n if (action !== 'resize' || !interaction.resizeAxes) {\r\n return;\r\n }\r\n\r\n var options = interaction.target.options;\r\n\r\n if (options.resize.square) {\r\n if (interaction.resizeAxes === 'y') {\r\n iEvent.dx = iEvent.dy;\r\n } else {\r\n iEvent.dy = iEvent.dx;\r\n }\r\n iEvent.axes = 'xy';\r\n } else {\r\n iEvent.axes = interaction.resizeAxes;\r\n\r\n if (interaction.resizeAxes === 'x') {\r\n iEvent.dy = 0;\r\n } else if (interaction.resizeAxes === 'y') {\r\n iEvent.dx = 0;\r\n }\r\n }\r\n});\r\n\r\nactions.resize = resize;\r\nactions.names.push('resize');\r\nutils.merge(Interactable.eventTypes, ['resizestart', 'resizemove', 'resizeinertiastart', 'resizeinertiaresume', 'resizeend']);\r\nactions.methodDict.resize = 'resizable';\r\n\r\ndefaultOptions.resize = resize.defaults;\r\n\r\nmodule.exports = resize;\r\n\r\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"../utils/browser\":37,\"./base\":6}],11:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar raf = require('./utils/raf');\r\nvar getWindow = require('./utils/window').getWindow;\r\nvar is = require('./utils/is');\r\nvar domUtils = require('./utils/domUtils');\r\nvar Interaction = require('./Interaction');\r\nvar defaultOptions = require('./defaultOptions');\r\n\r\nvar autoScroll = {\r\n defaults: {\r\n enabled: false,\r\n container: null, // the item that is scrolled (Window or HTMLElement)\r\n margin: 60,\r\n speed: 300 // the scroll speed in pixels per second\r\n },\r\n\r\n interaction: null,\r\n i: null, // the handle returned by window.setInterval\r\n x: 0, y: 0, // Direction each pulse is to scroll in\r\n\r\n isScrolling: false,\r\n prevTime: 0,\r\n\r\n start: function start(interaction) {\r\n autoScroll.isScrolling = true;\r\n raf.cancel(autoScroll.i);\r\n\r\n autoScroll.interaction = interaction;\r\n autoScroll.prevTime = new Date().getTime();\r\n autoScroll.i = raf.request(autoScroll.scroll);\r\n },\r\n\r\n stop: function stop() {\r\n autoScroll.isScrolling = false;\r\n raf.cancel(autoScroll.i);\r\n },\r\n\r\n // scroll the window by the values in scroll.x/y\r\n scroll: function scroll() {\r\n var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll;\r\n var container = options.container || getWindow(autoScroll.interaction.element);\r\n var now = new Date().getTime();\r\n // change in time in seconds\r\n var dt = (now - autoScroll.prevTime) / 1000;\r\n // displacement\r\n var s = options.speed * dt;\r\n\r\n if (s >= 1) {\r\n if (is.window(container)) {\r\n container.scrollBy(autoScroll.x * s, autoScroll.y * s);\r\n } else if (container) {\r\n container.scrollLeft += autoScroll.x * s;\r\n container.scrollTop += autoScroll.y * s;\r\n }\r\n\r\n autoScroll.prevTime = now;\r\n }\r\n\r\n if (autoScroll.isScrolling) {\r\n raf.cancel(autoScroll.i);\r\n autoScroll.i = raf.request(autoScroll.scroll);\r\n }\r\n },\r\n check: function check(interactable, actionName) {\r\n var options = interactable.options;\r\n\r\n return options[actionName].autoScroll && options[actionName].autoScroll.enabled;\r\n },\r\n onInteractionMove: function onInteractionMove(_ref) {\r\n var interaction = _ref.interaction,\r\n pointer = _ref.pointer;\r\n\r\n if (!(interaction.interacting() && autoScroll.check(interaction.target, interaction.prepared.name))) {\r\n return;\r\n }\r\n\r\n if (interaction.simulation) {\r\n autoScroll.x = autoScroll.y = 0;\r\n return;\r\n }\r\n\r\n var top = void 0;\r\n var right = void 0;\r\n var bottom = void 0;\r\n var left = void 0;\r\n\r\n var options = interaction.target.options[interaction.prepared.name].autoScroll;\r\n var container = options.container || getWindow(interaction.element);\r\n\r\n if (is.window(container)) {\r\n left = pointer.clientX < autoScroll.margin;\r\n top = pointer.clientY < autoScroll.margin;\r\n right = pointer.clientX > container.innerWidth - autoScroll.margin;\r\n bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\r\n } else {\r\n var rect = domUtils.getElementClientRect(container);\r\n\r\n left = pointer.clientX < rect.left + autoScroll.margin;\r\n top = pointer.clientY < rect.top + autoScroll.margin;\r\n right = pointer.clientX > rect.right - autoScroll.margin;\r\n bottom = pointer.clientY > rect.bottom - autoScroll.margin;\r\n }\r\n\r\n autoScroll.x = right ? 1 : left ? -1 : 0;\r\n autoScroll.y = bottom ? 1 : top ? -1 : 0;\r\n\r\n if (!autoScroll.isScrolling) {\r\n // set the autoScroll properties to those of the target\r\n autoScroll.margin = options.margin;\r\n autoScroll.speed = options.speed;\r\n\r\n autoScroll.start(interaction);\r\n }\r\n }\r\n};\r\n\r\nInteraction.signals.on('stop-active', function () {\r\n autoScroll.stop();\r\n});\r\n\r\nInteraction.signals.on('action-move', autoScroll.onInteractionMove);\r\n\r\ndefaultOptions.perAction.autoScroll = autoScroll.defaults;\r\n\r\nmodule.exports = autoScroll;\r\n\r\n},{\"./Interaction\":5,\"./defaultOptions\":18,\"./utils/domUtils\":39,\"./utils/is\":46,\"./utils/raf\":50,\"./utils/window\":52}],12:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar Interactable = require('../Interactable');\r\nvar actions = require('../actions/base');\r\nvar is = require('../utils/is');\r\nvar domUtils = require('../utils/domUtils');\r\n\r\nInteractable.prototype.getAction = function (pointer, event, interaction, element) {\r\n var action = this.defaultActionChecker(pointer, event, interaction, element);\r\n\r\n if (this.options.actionChecker) {\r\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\r\n }\r\n\r\n return action;\r\n};\r\n\r\n/*\\\r\n * Interactable.ignoreFrom\r\n [ method ]\r\n *\r\n * If the target of the `mousedown`, `pointerdown` or `touchstart`\r\n * event or any of it's parents match the given CSS selector or\r\n * Element, no drag/resize/gesture is started.\r\n *\r\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\r\n = (string | Element | object) The current ignoreFrom value or this Interactable\r\n **\r\n | interact(element, { ignoreFrom: document.getElementById('no-action') });\r\n | // or\r\n | interact(element).ignoreFrom('input, textarea, a');\r\n\\*/\r\nInteractable.prototype.ignoreFrom = function (newValue) {\r\n return this._backCompatOption('ignoreFrom', newValue);\r\n};\r\n\r\n/*\\\r\n * Interactable.allowFrom\r\n [ method ]\r\n *\r\n * A drag/resize/gesture is started only If the target of the\r\n * `mousedown`, `pointerdown` or `touchstart` event or any of it's\r\n * parents match the given CSS selector or Element.\r\n *\r\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\r\n = (string | Element | object) The current allowFrom value or this Interactable\r\n **\r\n | interact(element, { allowFrom: document.getElementById('drag-handle') });\r\n | // or\r\n | interact(element).allowFrom('.handle');\r\n\\*/\r\nInteractable.prototype.allowFrom = function (newValue) {\r\n return this._backCompatOption('allowFrom', newValue);\r\n};\r\n\r\nInteractable.prototype.testIgnore = function (ignoreFrom, interactableElement, element) {\r\n if (!ignoreFrom || !is.element(element)) {\r\n return false;\r\n }\r\n\r\n if (is.string(ignoreFrom)) {\r\n return domUtils.matchesUpTo(element, ignoreFrom, interactableElement);\r\n } else if (is.element(ignoreFrom)) {\r\n return domUtils.nodeContains(ignoreFrom, element);\r\n }\r\n\r\n return false;\r\n};\r\n\r\nInteractable.prototype.testAllow = function (allowFrom, interactableElement, element) {\r\n if (!allowFrom) {\r\n return true;\r\n }\r\n\r\n if (!is.element(element)) {\r\n return false;\r\n }\r\n\r\n if (is.string(allowFrom)) {\r\n return domUtils.matchesUpTo(element, allowFrom, interactableElement);\r\n } else if (is.element(allowFrom)) {\r\n return domUtils.nodeContains(allowFrom, element);\r\n }\r\n\r\n return false;\r\n};\r\n\r\nInteractable.prototype.testIgnoreAllow = function (options, interactableElement, eventTarget) {\r\n return !this.testIgnore(options.ignoreFrom, interactableElement, eventTarget) && this.testAllow(options.allowFrom, interactableElement, eventTarget);\r\n};\r\n\r\n/*\\\r\n * Interactable.actionChecker\r\n [ method ]\r\n *\r\n * Gets or sets the function used to check action to be performed on\r\n * pointerDown\r\n *\r\n - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\r\n = (Function | Interactable) The checker function or this Interactable\r\n *\r\n | interact('.resize-drag')\r\n | .resizable(true)\r\n | .draggable(true)\r\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\r\n |\r\n | if (interact.matchesSelector(event.target, '.drag-handle') {\r\n | // force drag with handle target\r\n | action.name = drag;\r\n | }\r\n | else {\r\n | // resize from the top and right edges\r\n | action.name = 'resize';\r\n | action.edges = { top: true, right: true };\r\n | }\r\n |\r\n | return action;\r\n | });\r\n\\*/\r\nInteractable.prototype.actionChecker = function (checker) {\r\n if (is.function(checker)) {\r\n this.options.actionChecker = checker;\r\n\r\n return this;\r\n }\r\n\r\n if (checker === null) {\r\n delete this.options.actionChecker;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.actionChecker;\r\n};\r\n\r\n/*\\\r\n * Interactable.styleCursor\r\n [ method ]\r\n *\r\n * Returns or sets whether the the cursor should be changed depending on the\r\n * action that would be performed if the mouse were pressed and dragged.\r\n *\r\n - newValue (boolean) #optional\r\n = (boolean | Interactable) The current setting or this Interactable\r\n\\*/\r\nInteractable.prototype.styleCursor = function (newValue) {\r\n if (is.bool(newValue)) {\r\n this.options.styleCursor = newValue;\r\n\r\n return this;\r\n }\r\n\r\n if (newValue === null) {\r\n delete this.options.styleCursor;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.styleCursor;\r\n};\r\n\r\nInteractable.prototype.defaultActionChecker = function (pointer, event, interaction, element) {\r\n var rect = this.getRect(element);\r\n var action = null;\r\n\r\n for (var _iterator = actions.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var actionName = _ref;\r\n\r\n // check mouseButton setting if the pointer is down\r\n if (interaction.pointerIsDown && interaction.mouse && (event.buttons & this.options[actionName].mouseButtons) === 0) {\r\n continue;\r\n }\r\n\r\n action = actions[actionName].checker(pointer, event, this, element, interaction, rect);\r\n\r\n if (action) {\r\n return action;\r\n }\r\n }\r\n};\r\n\r\n},{\"../Interactable\":4,\"../actions/base\":6,\"../utils/domUtils\":39,\"../utils/is\":46}],13:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar interact = require('../interact');\r\nvar Interactable = require('../Interactable');\r\nvar Interaction = require('../Interaction');\r\nvar actions = require('../actions/base');\r\nvar defaultOptions = require('../defaultOptions');\r\nvar browser = require('../utils/browser');\r\nvar scope = require('../scope');\r\nvar utils = require('../utils');\r\nvar signals = require('../utils/Signals').new();\r\n\r\nrequire('./InteractableMethods');\r\n\r\nvar autoStart = {\r\n signals: signals,\r\n withinInteractionLimit: withinInteractionLimit,\r\n // Allow this many interactions to happen simultaneously\r\n maxInteractions: Infinity,\r\n defaults: {\r\n perAction: {\r\n manualStart: false,\r\n max: Infinity,\r\n maxPerElement: 1,\r\n allowFrom: null,\r\n ignoreFrom: null\r\n }\r\n },\r\n setActionDefaults: function setActionDefaults(action) {\r\n utils.extend(action.defaults, autoStart.defaults.perAction);\r\n }\r\n};\r\n\r\n// set cursor style on mousedown\r\nInteraction.signals.on('down', function (_ref) {\r\n var interaction = _ref.interaction,\r\n pointer = _ref.pointer,\r\n event = _ref.event,\r\n eventTarget = _ref.eventTarget;\r\n\r\n if (interaction.interacting()) {\r\n return;\r\n }\r\n\r\n var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);\r\n prepare(interaction, actionInfo);\r\n});\r\n\r\n// set cursor style on mousemove\r\nInteraction.signals.on('move', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n pointer = _ref2.pointer,\r\n event = _ref2.event,\r\n eventTarget = _ref2.eventTarget;\r\n\r\n if (!interaction.mouse || interaction.pointerIsDown || interaction.interacting()) {\r\n return;\r\n }\r\n\r\n var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);\r\n prepare(interaction, actionInfo);\r\n});\r\n\r\nInteraction.signals.on('move', function (arg) {\r\n var interaction = arg.interaction,\r\n event = arg.event;\r\n\r\n\r\n if (!interaction.pointerIsDown || interaction.interacting() || !interaction.pointerWasMoved || !interaction.prepared.name) {\r\n return;\r\n }\r\n\r\n signals.fire('before-start', arg);\r\n\r\n var target = interaction.target;\r\n\r\n if (interaction.prepared.name && target) {\r\n // check manualStart and interaction limit\r\n if (target.options[interaction.prepared.name].manualStart || !withinInteractionLimit(target, interaction.element, interaction.prepared)) {\r\n interaction.stop(event);\r\n } else {\r\n interaction.start(interaction.prepared, target, interaction.element);\r\n }\r\n }\r\n});\r\n\r\n// Check if the current target supports the action.\r\n// If so, return the validated action. Otherwise, return null\r\nfunction validateAction(action, interactable, element, eventTarget) {\r\n if (utils.is.object(action) && interactable.testIgnoreAllow(interactable.options[action.name], element, eventTarget) && interactable.options[action.name].enabled && withinInteractionLimit(interactable, element, action)) {\r\n return action;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction validateSelector(interaction, pointer, event, matches, matchElements, eventTarget) {\r\n for (var i = 0, len = matches.length; i < len; i++) {\r\n var match = matches[i];\r\n var matchElement = matchElements[i];\r\n var action = validateAction(match.getAction(pointer, event, interaction, matchElement), match, matchElement, eventTarget);\r\n\r\n if (action) {\r\n return {\r\n action: action,\r\n target: match,\r\n element: matchElement\r\n };\r\n }\r\n }\r\n\r\n return {};\r\n}\r\n\r\nfunction getActionInfo(interaction, pointer, event, eventTarget) {\r\n var matches = [];\r\n var matchElements = [];\r\n\r\n var element = eventTarget;\r\n var action = null;\r\n\r\n function pushMatches(interactable, selector, context) {\r\n var elements = browser.useMatchesSelectorPolyfill ? context.querySelectorAll(selector) : undefined;\r\n\r\n if (utils.matchesSelector(element, selector, elements)) {\r\n\r\n matches.push(interactable);\r\n matchElements.push(element);\r\n }\r\n }\r\n\r\n while (utils.is.element(element)) {\r\n matches = [];\r\n matchElements = [];\r\n\r\n var elementInteractable = scope.interactables.get(element);\r\n\r\n if (elementInteractable && (action = validateAction(elementInteractable.getAction(pointer, event, interaction, element, eventTarget), elementInteractable, element, eventTarget)) && !elementInteractable.options[action.name].manualStart) {\r\n return {\r\n element: element,\r\n action: action,\r\n target: elementInteractable\r\n };\r\n } else {\r\n scope.interactables.forEachSelector(pushMatches, element);\r\n\r\n var actionInfo = validateSelector(interaction, pointer, event, matches, matchElements, eventTarget);\r\n\r\n if (actionInfo.action && !actionInfo.target.options[actionInfo.action.name].manualStart) {\r\n return actionInfo;\r\n }\r\n }\r\n\r\n element = utils.parentNode(element);\r\n }\r\n\r\n return {};\r\n}\r\n\r\nfunction prepare(interaction, _ref3) {\r\n var action = _ref3.action,\r\n target = _ref3.target,\r\n element = _ref3.element;\r\n\r\n action = action || {};\r\n\r\n if (interaction.target && interaction.target.options.styleCursor) {\r\n interaction.target._doc.documentElement.style.cursor = '';\r\n }\r\n\r\n interaction.target = target;\r\n interaction.element = element;\r\n utils.copyAction(interaction.prepared, action);\r\n\r\n if (target && target.options.styleCursor) {\r\n var cursor = action ? actions[action.name].getCursor(action) : '';\r\n interaction.target._doc.documentElement.style.cursor = cursor;\r\n }\r\n\r\n signals.fire('prepared', { interaction: interaction });\r\n}\r\n\r\nInteraction.signals.on('stop', function (_ref4) {\r\n var interaction = _ref4.interaction;\r\n\r\n var target = interaction.target;\r\n\r\n if (target && target.options.styleCursor) {\r\n target._doc.documentElement.style.cursor = '';\r\n }\r\n});\r\n\r\nInteractable.prototype.getAction = function (pointer, event, interaction, element) {\r\n var action = this.defaultActionChecker(pointer, event, interaction, element);\r\n\r\n if (this.options.actionChecker) {\r\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\r\n }\r\n\r\n return action;\r\n};\r\n\r\n/*\\\r\n * Interactable.actionChecker\r\n [ method ]\r\n *\r\n * Gets or sets the function used to check action to be performed on\r\n * pointerDown\r\n *\r\n - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\r\n = (Function | Interactable) The checker function or this Interactable\r\n *\r\n | interact('.resize-drag')\r\n | .resizable(true)\r\n | .draggable(true)\r\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\r\n |\r\n | if (interact.matchesSelector(event.target, '.drag-handle') {\r\n | // force drag with handle target\r\n | action.name = drag;\r\n | }\r\n | else {\r\n | // resize from the top and right edges\r\n | action.name = 'resize';\r\n | action.edges = { top: true, right: true };\r\n | }\r\n |\r\n | return action;\r\n | });\r\n\\*/\r\nInteractable.prototype.actionChecker = function (checker) {\r\n if (utils.is.function(checker)) {\r\n this.options.actionChecker = checker;\r\n\r\n return this;\r\n }\r\n\r\n if (checker === null) {\r\n delete this.options.actionChecker;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.actionChecker;\r\n};\r\n\r\n/*\\\r\n * Interactable.styleCursor\r\n [ method ]\r\n *\r\n * Returns or sets whether the the cursor should be changed depending on the\r\n * action that would be performed if the mouse were pressed and dragged.\r\n *\r\n - newValue (boolean) #optional\r\n = (boolean | Interactable) The current setting or this Interactable\r\n\\*/\r\nInteractable.prototype.styleCursor = function (newValue) {\r\n if (utils.is.bool(newValue)) {\r\n this.options.styleCursor = newValue;\r\n\r\n return this;\r\n }\r\n\r\n if (newValue === null) {\r\n delete this.options.styleCursor;\r\n\r\n return this;\r\n }\r\n\r\n return this.options.styleCursor;\r\n};\r\n\r\nInteractable.prototype.defaultActionChecker = function (pointer, event, interaction, element) {\r\n var rect = this.getRect(element);\r\n var buttons = event.buttons || {\r\n 0: 1,\r\n 1: 4,\r\n 3: 8,\r\n 4: 16\r\n }[event.button];\r\n var action = null;\r\n\r\n for (var _iterator = actions.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref5;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref5 = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref5 = _i.value;\r\n }\r\n\r\n var actionName = _ref5;\r\n\r\n // check mouseButton setting if the pointer is down\r\n if (interaction.pointerIsDown && interaction.mouse && (buttons & this.options[actionName].mouseButtons) === 0) {\r\n continue;\r\n }\r\n\r\n action = actions[actionName].checker(pointer, event, this, element, interaction, rect);\r\n\r\n if (action) {\r\n return action;\r\n }\r\n }\r\n};\r\n\r\nfunction withinInteractionLimit(interactable, element, action) {\r\n var options = interactable.options;\r\n var maxActions = options[action.name].max;\r\n var maxPerElement = options[action.name].maxPerElement;\r\n var activeInteractions = 0;\r\n var targetCount = 0;\r\n var targetElementCount = 0;\r\n\r\n // no actions if any of these values == 0\r\n if (!(maxActions && maxPerElement && autoStart.maxInteractions)) {\r\n return;\r\n }\r\n\r\n for (var i = 0, len = scope.interactions.length; i < len; i++) {\r\n var interaction = scope.interactions[i];\r\n var otherAction = interaction.prepared.name;\r\n\r\n if (!interaction.interacting()) {\r\n continue;\r\n }\r\n\r\n activeInteractions++;\r\n\r\n if (activeInteractions >= autoStart.maxInteractions) {\r\n return false;\r\n }\r\n\r\n if (interaction.target !== interactable) {\r\n continue;\r\n }\r\n\r\n targetCount += otherAction === action.name | 0;\r\n\r\n if (targetCount >= maxActions) {\r\n return false;\r\n }\r\n\r\n if (interaction.element === element) {\r\n targetElementCount++;\r\n\r\n if (otherAction !== action.name || targetElementCount >= maxPerElement) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n return autoStart.maxInteractions > 0;\r\n}\r\n\r\n/*\\\r\n * interact.maxInteractions\r\n [ method ]\r\n **\r\n * Returns or sets the maximum number of concurrent interactions allowed.\r\n * By default only 1 interaction is allowed at a time (for backwards\r\n * compatibility). To allow multiple interactions on the same Interactables\r\n * and elements, you need to enable it in the draggable, resizable and\r\n * gesturable `'max'` and `'maxPerElement'` options.\r\n **\r\n - newValue (number) #optional Any number. newValue <= 0 means no interactions.\r\n\\*/\r\ninteract.maxInteractions = function (newValue) {\r\n if (utils.is.number(newValue)) {\r\n autoStart.maxInteractions = newValue;\r\n\r\n return this;\r\n }\r\n\r\n return autoStart.maxInteractions;\r\n};\r\n\r\nInteractable.settingsMethods.push('styleCursor');\r\nInteractable.settingsMethods.push('actionChecker');\r\nInteractable.settingsMethods.push('ignoreFrom');\r\nInteractable.settingsMethods.push('allowFrom');\r\n\r\ndefaultOptions.base.actionChecker = null;\r\ndefaultOptions.base.styleCursor = true;\r\n\r\nutils.extend(defaultOptions.perAction, autoStart.defaults.perAction);\r\n\r\nmodule.exports = autoStart;\r\n\r\n},{\"../Interactable\":4,\"../Interaction\":5,\"../actions/base\":6,\"../defaultOptions\":18,\"../interact\":21,\"../scope\":34,\"../utils\":44,\"../utils/Signals\":35,\"../utils/browser\":37,\"./InteractableMethods\":12}],14:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar autoStart = require('./base');\r\nvar Interaction = require('../Interaction');\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.delayTimer = null;\r\n});\r\n\r\nautoStart.signals.on('prepared', function (_ref) {\r\n var interaction = _ref.interaction;\r\n\r\n var actionName = interaction.prepared.name;\r\n\r\n if (!actionName) {\r\n return;\r\n }\r\n\r\n var delay = interaction.target.options[actionName].delay;\r\n\r\n if (delay > 0) {\r\n interaction.delayTimer = setTimeout(function () {\r\n interaction.start(interaction.prepared, interaction.target, interaction.element);\r\n }, delay);\r\n }\r\n});\r\n\r\nInteraction.signals.on('move', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n duplicate = _ref2.duplicate;\r\n\r\n if (interaction.pointerWasMoved && !duplicate) {\r\n clearTimeout(interaction.delayTimer);\r\n }\r\n});\r\n\r\n// prevent regular down->move autoStart\r\nautoStart.signals.on('before-start', function (_ref3) {\r\n var interaction = _ref3.interaction;\r\n\r\n var actionName = interaction.prepared.name;\r\n\r\n if (!actionName) {\r\n return;\r\n }\r\n\r\n var delay = interaction.target.options[actionName].delay;\r\n\r\n if (delay > 0) {\r\n interaction.prepared.name = null;\r\n }\r\n});\r\n\r\n},{\"../Interaction\":5,\"./base\":13}],15:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar autoStart = require('./base');\r\nvar scope = require('../scope');\r\nvar browser = require('../utils/browser');\r\nvar is = require('../utils/is');\r\n\r\nvar _require = require('../utils/domUtils'),\r\n matchesSelector = _require.matchesSelector,\r\n parentNode = _require.parentNode;\r\n\r\nautoStart.setActionDefaults(require('../actions/drag'));\r\n\r\nautoStart.signals.on('before-start', function (_ref) {\r\n var interaction = _ref.interaction,\r\n eventTarget = _ref.eventTarget,\r\n dx = _ref.dx,\r\n dy = _ref.dy;\r\n\r\n if (interaction.prepared.name !== 'drag') {\r\n return;\r\n }\r\n\r\n // check if a drag is in the correct axis\r\n var absX = Math.abs(dx);\r\n var absY = Math.abs(dy);\r\n var options = interaction.target.options.drag;\r\n var startAxis = options.startAxis;\r\n var currentAxis = absX > absY ? 'x' : absX < absY ? 'y' : 'xy';\r\n\r\n interaction.prepared.axis = options.lockAxis === 'start' ? currentAxis[0] // always lock to one axis even if currentAxis === 'xy'\r\n : options.lockAxis;\r\n\r\n // if the movement isn't in the startAxis of the interactable\r\n if (currentAxis !== 'xy' && startAxis !== 'xy' && startAxis !== currentAxis) {\r\n // cancel the prepared action\r\n interaction.prepared.name = null;\r\n\r\n // then try to get a drag from another ineractable\r\n\r\n if (!interaction.prepared.name) {\r\n\r\n var element = eventTarget;\r\n\r\n var getDraggable = function getDraggable(interactable, selector, context) {\r\n var elements = browser.useMatchesSelectorPolyfill ? context.querySelectorAll(selector) : undefined;\r\n\r\n if (interactable === interaction.target) {\r\n return;\r\n }\r\n\r\n if (!options.manualStart && !interactable.testIgnoreAllow(options, element, eventTarget) && matchesSelector(element, selector, elements)) {\r\n\r\n var _action = interactable.getAction(interaction.downPointer, interaction.downEvent, interaction, element);\r\n\r\n if (_action && _action.name === 'drag' && checkStartAxis(currentAxis, interactable) && autoStart.validateAction(_action, interactable, element, eventTarget)) {\r\n\r\n return interactable;\r\n }\r\n }\r\n };\r\n\r\n var action = null;\r\n\r\n // check all interactables\r\n while (is.element(element)) {\r\n var elementInteractable = scope.interactables.get(element);\r\n\r\n if (elementInteractable && elementInteractable !== interaction.target && !elementInteractable.options.drag.manualStart) {\r\n\r\n action = elementInteractable.getAction(interaction.downPointer, interaction.downEvent, interaction, element);\r\n }\r\n if (action && action.name === 'drag' && checkStartAxis(currentAxis, elementInteractable)) {\r\n\r\n interaction.prepared.name = 'drag';\r\n interaction.target = elementInteractable;\r\n interaction.element = element;\r\n break;\r\n }\r\n\r\n var selectorInteractable = scope.interactables.forEachSelector(getDraggable, element);\r\n\r\n if (selectorInteractable) {\r\n interaction.prepared.name = 'drag';\r\n interaction.target = selectorInteractable;\r\n interaction.element = element;\r\n break;\r\n }\r\n\r\n element = parentNode(element);\r\n }\r\n }\r\n }\r\n});\r\n\r\nfunction checkStartAxis(startAxis, interactable) {\r\n if (!interactable) {\r\n return false;\r\n }\r\n\r\n var thisAxis = interactable.options.drag.startAxis;\r\n\r\n return startAxis === 'xy' || thisAxis === 'xy' || thisAxis === startAxis;\r\n}\r\n\r\n},{\"../actions/drag\":7,\"../scope\":34,\"../utils/browser\":37,\"../utils/domUtils\":39,\"../utils/is\":46,\"./base\":13}],16:[function(require,module,exports){\r\n'use strict';\r\n\r\nrequire('./base').setActionDefaults(require('../actions/gesture'));\r\n\r\n},{\"../actions/gesture\":9,\"./base\":13}],17:[function(require,module,exports){\r\n'use strict';\r\n\r\nrequire('./base').setActionDefaults(require('../actions/resize'));\r\n\r\n},{\"../actions/resize\":10,\"./base\":13}],18:[function(require,module,exports){\r\n'use strict';\r\n\r\nmodule.exports = {\r\n base: {\r\n accept: null,\r\n preventDefault: 'auto',\r\n deltaSource: 'page'\r\n },\r\n\r\n perAction: {\r\n origin: { x: 0, y: 0 },\r\n\r\n // only allow left button by default\r\n // see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#Return_value\r\n mouseButtons: 1,\r\n\r\n inertia: {\r\n enabled: false,\r\n resistance: 10, // the lambda in exponential decay\r\n minSpeed: 100, // target speed must be above this for inertia to start\r\n endSpeed: 10, // the speed at which inertia is slow enough to stop\r\n allowResume: true, // allow resuming an action in inertia phase\r\n smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\r\n }\r\n }\r\n};\r\n\r\n},{}],19:[function(require,module,exports){\r\n'use strict';\r\n\r\n/* browser entry point */\r\n\r\n// Legacy browser support\r\nrequire('./legacyBrowsers');\r\n\r\n// inertia\r\nrequire('./inertia');\r\n\r\n// modifiers\r\nrequire('./modifiers/snap');\r\nrequire('./modifiers/restrict');\r\n\r\n// pointerEvents\r\nrequire('./pointerEvents/base');\r\nrequire('./pointerEvents/holdRepeat');\r\nrequire('./pointerEvents/interactableTargets');\r\n\r\n// delay\r\nrequire('./autoStart/delay');\r\n\r\n// actions\r\nrequire('./actions/gesture');\r\nrequire('./actions/resize');\r\nrequire('./actions/drag');\r\nrequire('./actions/drop');\r\n\r\n// load these modifiers after resize is loaded\r\nrequire('./modifiers/snapSize');\r\nrequire('./modifiers/restrictEdges');\r\nrequire('./modifiers/restrictSize');\r\n\r\n// autoStart actions\r\nrequire('./autoStart/gesture');\r\nrequire('./autoStart/resize');\r\nrequire('./autoStart/drag');\r\n\r\n// Interactable preventDefault setting\r\nrequire('./interactablePreventDefault.js');\r\n\r\n// autoScroll\r\nrequire('./autoScroll');\r\n\r\n// export interact\r\nmodule.exports = require('./interact');\r\n\r\n},{\"./actions/drag\":7,\"./actions/drop\":8,\"./actions/gesture\":9,\"./actions/resize\":10,\"./autoScroll\":11,\"./autoStart/delay\":14,\"./autoStart/drag\":15,\"./autoStart/gesture\":16,\"./autoStart/resize\":17,\"./inertia\":20,\"./interact\":21,\"./interactablePreventDefault.js\":22,\"./legacyBrowsers\":23,\"./modifiers/restrict\":25,\"./modifiers/restrictEdges\":26,\"./modifiers/restrictSize\":27,\"./modifiers/snap\":28,\"./modifiers/snapSize\":29,\"./pointerEvents/base\":31,\"./pointerEvents/holdRepeat\":32,\"./pointerEvents/interactableTargets\":33}],20:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar InteractEvent = require('./InteractEvent');\r\nvar Interaction = require('./Interaction');\r\nvar modifiers = require('./modifiers');\r\nvar utils = require('./utils');\r\nvar animationFrame = require('./utils/raf');\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.inertiaStatus = {\r\n active: false,\r\n smoothEnd: false,\r\n allowResume: false,\r\n\r\n startEvent: null,\r\n upCoords: {},\r\n\r\n xe: 0, ye: 0,\r\n sx: 0, sy: 0,\r\n\r\n t0: 0,\r\n vx0: 0, vys: 0,\r\n duration: 0,\r\n\r\n lambda_v0: 0,\r\n one_ve_v0: 0,\r\n i: null\r\n };\r\n\r\n interaction.boundInertiaFrame = function () {\r\n return inertiaFrame.apply(interaction);\r\n };\r\n interaction.boundSmoothEndFrame = function () {\r\n return smoothEndFrame.apply(interaction);\r\n };\r\n});\r\n\r\nInteraction.signals.on('down', function (_ref) {\r\n var interaction = _ref.interaction,\r\n event = _ref.event,\r\n pointer = _ref.pointer,\r\n eventTarget = _ref.eventTarget;\r\n\r\n var status = interaction.inertiaStatus;\r\n\r\n // Check if the down event hits the current inertia target\r\n if (status.active) {\r\n var element = eventTarget;\r\n\r\n // climb up the DOM tree from the event target\r\n while (utils.is.element(element)) {\r\n\r\n // if interaction element is the current inertia target element\r\n if (element === interaction.element) {\r\n // stop inertia\r\n animationFrame.cancel(status.i);\r\n status.active = false;\r\n interaction.simulation = null;\r\n\r\n // update pointers to the down event's coordinates\r\n interaction.updatePointer(pointer);\r\n utils.setCoords(interaction.curCoords, interaction.pointers);\r\n\r\n // fire appropriate signals\r\n var signalArg = { interaction: interaction };\r\n Interaction.signals.fire('before-action-move', signalArg);\r\n Interaction.signals.fire('action-resume', signalArg);\r\n\r\n // fire a reume event\r\n var resumeEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiaresume', interaction.element);\r\n\r\n interaction.target.fire(resumeEvent);\r\n interaction.prevEvent = resumeEvent;\r\n modifiers.resetStatuses(interaction.modifierStatuses);\r\n\r\n utils.copyCoords(interaction.prevCoords, interaction.curCoords);\r\n break;\r\n }\r\n\r\n element = utils.parentNode(element);\r\n }\r\n }\r\n});\r\n\r\nInteraction.signals.on('up', function (_ref2) {\r\n var interaction = _ref2.interaction,\r\n event = _ref2.event;\r\n\r\n var status = interaction.inertiaStatus;\r\n\r\n if (!interaction.interacting() || status.active) {\r\n return;\r\n }\r\n\r\n var target = interaction.target;\r\n var options = target && target.options;\r\n var inertiaOptions = options && interaction.prepared.name && options[interaction.prepared.name].inertia;\r\n\r\n var now = new Date().getTime();\r\n var statuses = {};\r\n var page = utils.extend({}, interaction.curCoords.page);\r\n var pointerSpeed = interaction.pointerDelta.client.speed;\r\n\r\n var smoothEnd = false;\r\n var modifierResult = void 0;\r\n\r\n // check if inertia should be started\r\n var inertiaPossible = inertiaOptions && inertiaOptions.enabled && interaction.prepared.name !== 'gesture' && event !== status.startEvent;\r\n\r\n var inertia = inertiaPossible && now - interaction.curCoords.timeStamp < 50 && pointerSpeed > inertiaOptions.minSpeed && pointerSpeed > inertiaOptions.endSpeed;\r\n\r\n var modifierArg = {\r\n interaction: interaction,\r\n pageCoords: page,\r\n statuses: statuses,\r\n preEnd: true,\r\n requireEndOnly: true\r\n };\r\n\r\n // smoothEnd\r\n if (inertiaPossible && !inertia) {\r\n modifiers.resetStatuses(statuses);\r\n\r\n modifierResult = modifiers.setAll(modifierArg);\r\n\r\n if (modifierResult.shouldMove && modifierResult.locked) {\r\n smoothEnd = true;\r\n }\r\n }\r\n\r\n if (!(inertia || smoothEnd)) {\r\n return;\r\n }\r\n\r\n utils.copyCoords(status.upCoords, interaction.curCoords);\r\n\r\n interaction.pointers[0] = status.startEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiastart', interaction.element);\r\n\r\n status.t0 = now;\r\n\r\n status.active = true;\r\n status.allowResume = inertiaOptions.allowResume;\r\n interaction.simulation = status;\r\n\r\n target.fire(status.startEvent);\r\n\r\n if (inertia) {\r\n status.vx0 = interaction.pointerDelta.client.vx;\r\n status.vy0 = interaction.pointerDelta.client.vy;\r\n status.v0 = pointerSpeed;\r\n\r\n calcInertia(interaction, status);\r\n\r\n utils.extend(page, interaction.curCoords.page);\r\n\r\n page.x += status.xe;\r\n page.y += status.ye;\r\n\r\n modifiers.resetStatuses(statuses);\r\n\r\n modifierResult = modifiers.setAll(modifierArg);\r\n\r\n status.modifiedXe += modifierResult.dx;\r\n status.modifiedYe += modifierResult.dy;\r\n\r\n status.i = animationFrame.request(interaction.boundInertiaFrame);\r\n } else {\r\n status.smoothEnd = true;\r\n status.xe = modifierResult.dx;\r\n status.ye = modifierResult.dy;\r\n\r\n status.sx = status.sy = 0;\r\n\r\n status.i = animationFrame.request(interaction.boundSmoothEndFrame);\r\n }\r\n});\r\n\r\nInteraction.signals.on('stop-active', function (_ref3) {\r\n var interaction = _ref3.interaction;\r\n\r\n var status = interaction.inertiaStatus;\r\n\r\n if (status.active) {\r\n animationFrame.cancel(status.i);\r\n status.active = false;\r\n interaction.simulation = null;\r\n }\r\n});\r\n\r\nfunction calcInertia(interaction, status) {\r\n var inertiaOptions = interaction.target.options[interaction.prepared.name].inertia;\r\n var lambda = inertiaOptions.resistance;\r\n var inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\r\n\r\n status.x0 = interaction.prevEvent.pageX;\r\n status.y0 = interaction.prevEvent.pageY;\r\n status.t0 = status.startEvent.timeStamp / 1000;\r\n status.sx = status.sy = 0;\r\n\r\n status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\r\n status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\r\n status.te = inertiaDur;\r\n\r\n status.lambda_v0 = lambda / status.v0;\r\n status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\r\n}\r\n\r\nfunction inertiaFrame() {\r\n updateInertiaCoords(this);\r\n utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\r\n\r\n var status = this.inertiaStatus;\r\n var options = this.target.options[this.prepared.name].inertia;\r\n var lambda = options.resistance;\r\n var t = new Date().getTime() / 1000 - status.t0;\r\n\r\n if (t < status.te) {\r\n\r\n var progress = 1 - (Math.exp(-lambda * t) - status.lambda_v0) / status.one_ve_v0;\r\n\r\n if (status.modifiedXe === status.xe && status.modifiedYe === status.ye) {\r\n status.sx = status.xe * progress;\r\n status.sy = status.ye * progress;\r\n } else {\r\n var quadPoint = utils.getQuadraticCurvePoint(0, 0, status.xe, status.ye, status.modifiedXe, status.modifiedYe, progress);\r\n\r\n status.sx = quadPoint.x;\r\n status.sy = quadPoint.y;\r\n }\r\n\r\n this.doMove();\r\n\r\n status.i = animationFrame.request(this.boundInertiaFrame);\r\n } else {\r\n status.sx = status.modifiedXe;\r\n status.sy = status.modifiedYe;\r\n\r\n this.doMove();\r\n this.end(status.startEvent);\r\n status.active = false;\r\n this.simulation = null;\r\n }\r\n\r\n utils.copyCoords(this.prevCoords, this.curCoords);\r\n}\r\n\r\nfunction smoothEndFrame() {\r\n updateInertiaCoords(this);\r\n\r\n var status = this.inertiaStatus;\r\n var t = new Date().getTime() - status.t0;\r\n var duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\r\n\r\n if (t < duration) {\r\n status.sx = utils.easeOutQuad(t, 0, status.xe, duration);\r\n status.sy = utils.easeOutQuad(t, 0, status.ye, duration);\r\n\r\n this.pointerMove(status.startEvent, status.startEvent);\r\n\r\n status.i = animationFrame.request(this.boundSmoothEndFrame);\r\n } else {\r\n status.sx = status.xe;\r\n status.sy = status.ye;\r\n\r\n this.pointerMove(status.startEvent, status.startEvent);\r\n this.end(status.startEvent);\r\n\r\n status.smoothEnd = status.active = false;\r\n this.simulation = null;\r\n }\r\n}\r\n\r\nfunction updateInertiaCoords(interaction) {\r\n var status = interaction.inertiaStatus;\r\n\r\n // return if inertia isn't running\r\n if (!status.active) {\r\n return;\r\n }\r\n\r\n var pageUp = status.upCoords.page;\r\n var clientUp = status.upCoords.client;\r\n\r\n utils.setCoords(interaction.curCoords, [{\r\n pageX: pageUp.x + status.sx,\r\n pageY: pageUp.y + status.sy,\r\n clientX: clientUp.x + status.sx,\r\n clientY: clientUp.y + status.sy\r\n }]);\r\n}\r\n\r\n},{\"./InteractEvent\":3,\"./Interaction\":5,\"./modifiers\":24,\"./utils\":44,\"./utils/raf\":50}],21:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar browser = require('./utils/browser');\r\nvar events = require('./utils/events');\r\nvar utils = require('./utils');\r\nvar scope = require('./scope');\r\nvar Interactable = require('./Interactable');\r\nvar Interaction = require('./Interaction');\r\n\r\nvar globalEvents = {};\r\n\r\n/*\\\r\n * interact\r\n [ method ]\r\n *\r\n * The methods of this variable can be used to set elements as\r\n * interactables and also to change various default settings.\r\n *\r\n * Calling it as a function and passing an element or a valid CSS selector\r\n * string returns an Interactable object which has various methods to\r\n * configure it.\r\n *\r\n - element (Element | string) The HTML or SVG Element to interact with or CSS selector\r\n = (object) An @Interactable\r\n *\r\n > Usage\r\n | interact('#draggable').draggable(true);\r\n |\r\n | var rectables = interact('rect');\r\n | rectables\r\n | .gesturable(true)\r\n | .on('gesturemove', function (event) {\r\n | // ...\r\n | });\r\n\\*/\r\nfunction interact(element, options) {\r\n var interactable = scope.interactables.get(element, options);\r\n\r\n if (!interactable) {\r\n interactable = new Interactable(element, options);\r\n interactable.events.global = globalEvents;\r\n }\r\n\r\n return interactable;\r\n}\r\n\r\n/*\\\r\n * interact.isSet\r\n [ method ]\r\n *\r\n * Check if an element has been set\r\n - element (Element) The Element being searched for\r\n = (boolean) Indicates if the element or CSS selector was previously passed to interact\r\n\\*/\r\ninteract.isSet = function (element, options) {\r\n return scope.interactables.indexOfElement(element, options && options.context) !== -1;\r\n};\r\n\r\n/*\\\r\n * interact.on\r\n [ method ]\r\n *\r\n * Adds a global listener for an InteractEvent or adds a DOM event to\r\n * `document`\r\n *\r\n - type (string | array | object) The types of events to listen for\r\n - listener (function) The function event (s)\r\n - options (object | boolean) #optional options object or useCapture flag for addEventListener\r\n = (object) interact\r\n\\*/\r\ninteract.on = function (type, listener, options) {\r\n if (utils.is.string(type) && type.search(' ') !== -1) {\r\n type = type.trim().split(/ +/);\r\n }\r\n\r\n if (utils.is.array(type)) {\r\n for (var _iterator = type, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var eventType = _ref;\r\n\r\n interact.on(eventType, listener, options);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n if (utils.is.object(type)) {\r\n for (var prop in type) {\r\n interact.on(prop, type[prop], listener);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n // if it is an InteractEvent type, add listener to globalEvents\r\n if (utils.contains(Interactable.eventTypes, type)) {\r\n // if this type of event was never bound\r\n if (!globalEvents[type]) {\r\n globalEvents[type] = [listener];\r\n } else {\r\n globalEvents[type].push(listener);\r\n }\r\n }\r\n // If non InteractEvent type, addEventListener to document\r\n else {\r\n events.add(scope.document, type, listener, { options: options });\r\n }\r\n\r\n return interact;\r\n};\r\n\r\n/*\\\r\n * interact.off\r\n [ method ]\r\n *\r\n * Removes a global InteractEvent listener or DOM event from `document`\r\n *\r\n - type (string | array | object) The types of events that were listened for\r\n - listener (function) The listener function to be removed\r\n - options (object | boolean) #optional options object or useCapture flag for removeEventListener\r\n = (object) interact\r\n \\*/\r\ninteract.off = function (type, listener, options) {\r\n if (utils.is.string(type) && type.search(' ') !== -1) {\r\n type = type.trim().split(/ +/);\r\n }\r\n\r\n if (utils.is.array(type)) {\r\n for (var _iterator2 = type, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref2 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref2 = _i2.value;\r\n }\r\n\r\n var eventType = _ref2;\r\n\r\n interact.off(eventType, listener, options);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n if (utils.is.object(type)) {\r\n for (var prop in type) {\r\n interact.off(prop, type[prop], listener);\r\n }\r\n\r\n return interact;\r\n }\r\n\r\n if (!utils.contains(Interactable.eventTypes, type)) {\r\n events.remove(scope.document, type, listener, options);\r\n } else {\r\n var index = void 0;\r\n\r\n if (type in globalEvents && (index = utils.indexOf(globalEvents[type], listener)) !== -1) {\r\n globalEvents[type].splice(index, 1);\r\n }\r\n }\r\n\r\n return interact;\r\n};\r\n\r\n/*\\\r\n * interact.debug\r\n [ method ]\r\n *\r\n * Returns an object which exposes internal data\r\n = (object) An object with properties that outline the current state and expose internal functions and variables\r\n\\*/\r\ninteract.debug = function () {\r\n return scope;\r\n};\r\n\r\n// expose the functions used to calculate multi-touch properties\r\ninteract.getPointerAverage = utils.pointerAverage;\r\ninteract.getTouchBBox = utils.touchBBox;\r\ninteract.getTouchDistance = utils.touchDistance;\r\ninteract.getTouchAngle = utils.touchAngle;\r\n\r\ninteract.getElementRect = utils.getElementRect;\r\ninteract.getElementClientRect = utils.getElementClientRect;\r\ninteract.matchesSelector = utils.matchesSelector;\r\ninteract.closest = utils.closest;\r\n\r\n/*\\\r\n * interact.supportsTouch\r\n [ method ]\r\n *\r\n = (boolean) Whether or not the browser supports touch input\r\n\\*/\r\ninteract.supportsTouch = function () {\r\n return browser.supportsTouch;\r\n};\r\n\r\n/*\\\r\n * interact.supportsPointerEvent\r\n [ method ]\r\n *\r\n = (boolean) Whether or not the browser supports PointerEvents\r\n\\*/\r\ninteract.supportsPointerEvent = function () {\r\n return browser.supportsPointerEvent;\r\n};\r\n\r\n/*\\\r\n * interact.stop\r\n [ method ]\r\n *\r\n * Cancels all interactions (end events are not fired)\r\n *\r\n - event (Event) An event on which to call preventDefault()\r\n = (object) interact\r\n\\*/\r\ninteract.stop = function (event) {\r\n for (var i = scope.interactions.length - 1; i >= 0; i--) {\r\n scope.interactions[i].stop(event);\r\n }\r\n\r\n return interact;\r\n};\r\n\r\n/*\\\r\n * interact.pointerMoveTolerance\r\n [ method ]\r\n * Returns or sets the distance the pointer must be moved before an action\r\n * sequence occurs. This also affects tolerance for tap events.\r\n *\r\n - newValue (number) #optional The movement from the start position must be greater than this value\r\n = (number | Interactable) The current setting or interact\r\n\\*/\r\ninteract.pointerMoveTolerance = function (newValue) {\r\n if (utils.is.number(newValue)) {\r\n Interaction.pointerMoveTolerance = newValue;\r\n\r\n return this;\r\n }\r\n\r\n return Interaction.pointerMoveTolerance;\r\n};\r\n\r\ninteract.addDocument = scope.addDocument;\r\ninteract.removeDocument = scope.removeDocument;\r\n\r\nscope.interact = interact;\r\n\r\nmodule.exports = interact;\r\n\r\n},{\"./Interactable\":4,\"./Interaction\":5,\"./scope\":34,\"./utils\":44,\"./utils/browser\":37,\"./utils/events\":40}],22:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar Interactable = require('./Interactable');\r\nvar Interaction = require('./Interaction');\r\nvar scope = require('./scope');\r\nvar is = require('./utils/is');\r\nvar events = require('./utils/events');\r\n\r\nvar _require = require('./utils/domUtils'),\r\n nodeContains = _require.nodeContains,\r\n matchesSelector = _require.matchesSelector;\r\n\r\n/*\\\r\n * Interactable.preventDefault\r\n [ method ]\r\n *\r\n * Returns or sets whether to prevent the browser's default behaviour\r\n * in response to pointer events. Can be set to:\r\n * - `'always'` to always prevent\r\n * - `'never'` to never prevent\r\n * - `'auto'` to let interact.js try to determine what would be best\r\n *\r\n - newValue (string) #optional `true`, `false` or `'auto'`\r\n = (string | Interactable) The current setting or this Interactable\r\n\\*/\r\n\r\n\r\nInteractable.prototype.preventDefault = function (newValue) {\r\n if (/^(always|never|auto)$/.test(newValue)) {\r\n this.options.preventDefault = newValue;\r\n return this;\r\n }\r\n\r\n if (is.bool(newValue)) {\r\n this.options.preventDefault = newValue ? 'always' : 'never';\r\n return this;\r\n }\r\n\r\n return this.options.preventDefault;\r\n};\r\n\r\nInteractable.prototype.checkAndPreventDefault = function (event) {\r\n var setting = this.options.preventDefault;\r\n\r\n if (setting === 'never') {\r\n return;\r\n }\r\n\r\n if (setting === 'always') {\r\n event.preventDefault();\r\n return;\r\n }\r\n\r\n // setting === 'auto'\r\n\r\n // don't preventDefault if the browser supports passiveEvents\r\n // CSS touch-action and user-selecct should be used instead\r\n if (events.supportsOptions) {\r\n return;\r\n }\r\n\r\n // don't preventDefault of pointerdown events\r\n if (/^(mouse|pointer|touch)*(down|start)/i.test(event.type)) {\r\n return;\r\n }\r\n\r\n // don't preventDefault on editable elements\r\n if (is.element(event.target) && matchesSelector(event.target, 'input,select,textarea,[contenteditable=true],[contenteditable=true] *')) {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n};\r\n\r\nfunction onInteractionEvent(_ref) {\r\n var interaction = _ref.interaction,\r\n event = _ref.event;\r\n\r\n if (interaction.target) {\r\n interaction.target.checkAndPreventDefault(event);\r\n }\r\n}\r\n\r\nvar _arr = ['down', 'move', 'up', 'cancel'];\r\nfor (var _i = 0; _i < _arr.length; _i++) {\r\n var eventSignal = _arr[_i];\r\n Interaction.signals.on(eventSignal, onInteractionEvent);\r\n}\r\n\r\n// prevent native HTML5 drag on interact.js target elements\r\nInteraction.docEvents.dragstart = function preventNativeDrag(event) {\r\n for (var _iterator = scope.interactions, _isArray = Array.isArray(_iterator), _i2 = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray) {\r\n if (_i2 >= _iterator.length) break;\r\n _ref2 = _iterator[_i2++];\r\n } else {\r\n _i2 = _iterator.next();\r\n if (_i2.done) break;\r\n _ref2 = _i2.value;\r\n }\r\n\r\n var interaction = _ref2;\r\n\r\n\r\n if (interaction.element && (interaction.element === event.target || nodeContains(interaction.element, event.target))) {\r\n\r\n interaction.target.checkAndPreventDefault(event);\r\n return;\r\n }\r\n }\r\n};\r\n\r\n},{\"./Interactable\":4,\"./Interaction\":5,\"./scope\":34,\"./utils/domUtils\":39,\"./utils/events\":40,\"./utils/is\":46}],23:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar scope = require('./scope');\r\nvar events = require('./utils/events');\r\nvar browser = require('./utils/browser');\r\nvar iFinder = require('./utils/interactionFinder');\r\nvar pointerEvents = require('./pointerEvents/base');\r\n\r\nvar _require = require('./utils/window'),\r\n window = _require.window;\r\n\r\nvar toString = Object.prototype.toString;\r\n\r\nif (!window.Array.isArray) {\r\n window.Array.isArray = function (obj) {\r\n return toString.call(obj) === '[object Array]';\r\n };\r\n}\r\n\r\nif (!String.prototype.trim) {\r\n String.prototype.trim = function () {\r\n return this.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\r\n };\r\n}\r\n\r\n// http://www.quirksmode.org/dom/events/click.html\r\n// >Events leading to dblclick\r\n//\r\n// IE8 doesn't fire down event before dblclick.\r\n// This workaround tries to fire a tap and doubletap after dblclick\r\nfunction onIE8Dblclick(event) {\r\n var eventTarget = event.target;\r\n var interaction = iFinder.search(event, event.type, eventTarget);\r\n\r\n if (!interaction) {\r\n return;\r\n }\r\n\r\n if (interaction.prevTap && event.clientX === interaction.prevTap.clientX && event.clientY === interaction.prevTap.clientY && eventTarget === interaction.prevTap.target) {\r\n\r\n interaction.downTargets[0] = eventTarget;\r\n interaction.downTimes[0] = new Date().getTime();\r\n\r\n pointerEvents.fire({\r\n interaction: interaction,\r\n event: event,\r\n eventTarget: eventTarget,\r\n pointer: event,\r\n type: 'tap'\r\n });\r\n }\r\n}\r\n\r\nif (browser.isIE8) {\r\n var selectFix = function selectFix(event) {\r\n for (var _iterator = scope.interactions, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var interaction = _ref;\r\n\r\n if (interaction.interacting()) {\r\n interaction.target.checkAndPreventDefault(event);\r\n }\r\n }\r\n };\r\n\r\n var onDocIE8 = function onDocIE8(_ref2, signalName) {\r\n var doc = _ref2.doc,\r\n win = _ref2.win;\r\n\r\n var eventMethod = signalName.indexOf('listen') === 0 ? events.add : events.remove;\r\n\r\n // For IE's lack of Event#preventDefault\r\n eventMethod(doc, 'selectstart', selectFix);\r\n\r\n if (pointerEvents) {\r\n eventMethod(doc, 'dblclick', onIE8Dblclick);\r\n }\r\n };\r\n\r\n scope.signals.on('add-document', onDocIE8);\r\n scope.signals.on('remove-document', onDocIE8);\r\n}\r\n\r\nmodule.exports = null;\r\n\r\n},{\"./pointerEvents/base\":31,\"./scope\":34,\"./utils/browser\":37,\"./utils/events\":40,\"./utils/interactionFinder\":45,\"./utils/window\":52}],24:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar InteractEvent = require('../InteractEvent');\r\nvar Interaction = require('../Interaction');\r\nvar extend = require('../utils/extend');\r\n\r\nvar modifiers = {\r\n names: [],\r\n\r\n setOffsets: function setOffsets(arg) {\r\n var interaction = arg.interaction,\r\n page = arg.pageCoords;\r\n var target = interaction.target,\r\n element = interaction.element,\r\n startOffset = interaction.startOffset;\r\n\r\n var rect = target.getRect(element);\r\n\r\n if (rect) {\r\n startOffset.left = page.x - rect.left;\r\n startOffset.top = page.y - rect.top;\r\n\r\n startOffset.right = rect.right - page.x;\r\n startOffset.bottom = rect.bottom - page.y;\r\n\r\n if (!('width' in rect)) {\r\n rect.width = rect.right - rect.left;\r\n }\r\n if (!('height' in rect)) {\r\n rect.height = rect.bottom - rect.top;\r\n }\r\n } else {\r\n startOffset.left = startOffset.top = startOffset.right = startOffset.bottom = 0;\r\n }\r\n\r\n arg.rect = rect;\r\n arg.interactable = target;\r\n arg.element = element;\r\n\r\n for (var i = 0; i < modifiers.names.length; i++) {\r\n var modifierName = modifiers.names[i];\r\n\r\n arg.options = target.options[interaction.prepared.name][modifierName];\r\n\r\n if (!arg.options) {\r\n continue;\r\n }\r\n\r\n interaction.modifierOffsets[modifierName] = modifiers[modifierName].setOffset(arg);\r\n }\r\n },\r\n\r\n setAll: function setAll(arg) {\r\n var interaction = arg.interaction,\r\n statuses = arg.statuses,\r\n preEnd = arg.preEnd,\r\n requireEndOnly = arg.requireEndOnly;\r\n\r\n var coords = extend({}, arg.pageCoords);\r\n var result = {\r\n dx: 0,\r\n dy: 0,\r\n changed: false,\r\n locked: false,\r\n shouldMove: true\r\n };\r\n\r\n for (var _iterator = modifiers.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var modifierName = _ref;\r\n\r\n var modifier = modifiers[modifierName];\r\n var options = interaction.target.options[interaction.prepared.name][modifierName];\r\n\r\n if (!shouldDo(options, preEnd, requireEndOnly)) {\r\n continue;\r\n }\r\n\r\n arg.status = arg.status = statuses[modifierName];\r\n arg.options = options;\r\n arg.offset = arg.interaction.modifierOffsets[modifierName];\r\n\r\n modifier.set(arg);\r\n\r\n if (arg.status.locked) {\r\n coords.x += arg.status.dx;\r\n coords.y += arg.status.dy;\r\n\r\n result.dx += arg.status.dx;\r\n result.dy += arg.status.dy;\r\n\r\n result.locked = true;\r\n }\r\n }\r\n\r\n // a move should be fired if:\r\n // - there are no modifiers enabled,\r\n // - no modifiers are \"locked\" i.e. have changed the pointer's coordinates, or\r\n // - the locked coords have changed since the last pointer move\r\n result.shouldMove = !arg.status || !result.locked || arg.status.changed;\r\n\r\n return result;\r\n },\r\n\r\n resetStatuses: function resetStatuses(statuses) {\r\n for (var _iterator2 = modifiers.names, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref2 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref2 = _i2.value;\r\n }\r\n\r\n var modifierName = _ref2;\r\n\r\n var status = statuses[modifierName] || {};\r\n\r\n status.dx = status.dy = 0;\r\n status.modifiedX = status.modifiedY = NaN;\r\n status.locked = false;\r\n status.changed = true;\r\n\r\n statuses[modifierName] = status;\r\n }\r\n\r\n return statuses;\r\n },\r\n\r\n start: function start(_ref3, signalName) {\r\n var interaction = _ref3.interaction;\r\n\r\n var arg = {\r\n interaction: interaction,\r\n pageCoords: (signalName === 'action-resume' ? interaction.curCoords : interaction.startCoords).page,\r\n startOffset: interaction.startOffset,\r\n statuses: interaction.modifierStatuses,\r\n preEnd: false,\r\n requireEndOnly: false\r\n };\r\n\r\n modifiers.setOffsets(arg);\r\n modifiers.resetStatuses(arg.statuses);\r\n\r\n arg.pageCoords = extend({}, interaction.startCoords.page);\r\n interaction.modifierResult = modifiers.setAll(arg);\r\n }\r\n};\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\r\n interaction.modifierOffsets = {};\r\n interaction.modifierStatuses = modifiers.resetStatuses({});\r\n interaction.modifierResult = null;\r\n});\r\n\r\nInteraction.signals.on('action-start', modifiers.start);\r\nInteraction.signals.on('action-resume', modifiers.start);\r\n\r\nInteraction.signals.on('before-action-move', function (_ref4) {\r\n var interaction = _ref4.interaction,\r\n preEnd = _ref4.preEnd,\r\n interactingBeforeMove = _ref4.interactingBeforeMove;\r\n\r\n var modifierResult = modifiers.setAll({\r\n interaction: interaction,\r\n preEnd: preEnd,\r\n pageCoords: interaction.curCoords.page,\r\n statuses: interaction.modifierStatuses,\r\n requireEndOnly: false\r\n });\r\n\r\n // don't fire an action move if a modifier would keep the event in the same\r\n // cordinates as before\r\n if (!modifierResult.shouldMove && interactingBeforeMove) {\r\n interaction._dontFireMove = true;\r\n }\r\n\r\n interaction.modifierResult = modifierResult;\r\n});\r\n\r\nInteraction.signals.on('action-end', function (_ref5) {\r\n var interaction = _ref5.interaction,\r\n event = _ref5.event;\r\n\r\n for (var i = 0; i < modifiers.names.length; i++) {\r\n var options = interaction.target.options[interaction.prepared.name][modifiers.names[i]];\r\n\r\n // if the endOnly option is true for any modifier\r\n if (shouldDo(options, true, true)) {\r\n // fire a move event at the modified coordinates\r\n interaction.doMove({ event: event, preEnd: true });\r\n break;\r\n }\r\n }\r\n});\r\n\r\nInteractEvent.signals.on('set-xy', function (arg) {\r\n var iEvent = arg.iEvent,\r\n interaction = arg.interaction;\r\n\r\n var modifierArg = extend({}, arg);\r\n\r\n for (var i = 0; i < modifiers.names.length; i++) {\r\n var modifierName = modifiers.names[i];\r\n modifierArg.options = interaction.target.options[interaction.prepared.name][modifierName];\r\n\r\n if (!modifierArg.options) {\r\n continue;\r\n }\r\n\r\n var modifier = modifiers[modifierName];\r\n\r\n modifierArg.status = interaction.modifierStatuses[modifierName];\r\n\r\n iEvent[modifierName] = modifier.modifyCoords(modifierArg);\r\n }\r\n});\r\n\r\nfunction shouldDo(options, preEnd, requireEndOnly) {\r\n return options && options.enabled && (preEnd || !options.endOnly) && (!requireEndOnly || options.endOnly);\r\n}\r\n\r\nmodule.exports = modifiers;\r\n\r\n},{\"../InteractEvent\":3,\"../Interaction\":5,\"../utils/extend\":41}],25:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar modifiers = require('./index');\r\nvar utils = require('../utils');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar restrict = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n restriction: null,\r\n elementRect: null\r\n },\r\n\r\n setOffset: function setOffset(_ref) {\r\n var rect = _ref.rect,\r\n startOffset = _ref.startOffset,\r\n options = _ref.options;\r\n\r\n var elementRect = options && options.elementRect;\r\n var offset = {};\r\n\r\n if (rect && elementRect) {\r\n offset.left = startOffset.left - rect.width * elementRect.left;\r\n offset.top = startOffset.top - rect.height * elementRect.top;\r\n\r\n offset.right = startOffset.right - rect.width * (1 - elementRect.right);\r\n offset.bottom = startOffset.bottom - rect.height * (1 - elementRect.bottom);\r\n } else {\r\n offset.left = offset.top = offset.right = offset.bottom = 0;\r\n }\r\n\r\n return offset;\r\n },\r\n\r\n set: function set(_ref2) {\r\n var pageCoords = _ref2.pageCoords,\r\n interaction = _ref2.interaction,\r\n status = _ref2.status,\r\n options = _ref2.options;\r\n\r\n if (!options) {\r\n return status;\r\n }\r\n\r\n var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, pageCoords);\r\n\r\n var restriction = getRestrictionRect(options.restriction, interaction, page);\r\n\r\n if (!restriction) {\r\n return status;\r\n }\r\n\r\n status.dx = 0;\r\n status.dy = 0;\r\n status.locked = false;\r\n\r\n var rect = restriction;\r\n var modifiedX = page.x;\r\n var modifiedY = page.y;\r\n\r\n var offset = interaction.modifierOffsets.restrict;\r\n\r\n // object is assumed to have\r\n // x, y, width, height or\r\n // left, top, right, bottom\r\n if ('x' in restriction && 'y' in restriction) {\r\n modifiedX = Math.max(Math.min(rect.x + rect.width - offset.right, page.x), rect.x + offset.left);\r\n modifiedY = Math.max(Math.min(rect.y + rect.height - offset.bottom, page.y), rect.y + offset.top);\r\n } else {\r\n modifiedX = Math.max(Math.min(rect.right - offset.right, page.x), rect.left + offset.left);\r\n modifiedY = Math.max(Math.min(rect.bottom - offset.bottom, page.y), rect.top + offset.top);\r\n }\r\n\r\n status.dx = modifiedX - page.x;\r\n status.dy = modifiedY - page.y;\r\n\r\n status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;\r\n status.locked = !!(status.dx || status.dy);\r\n\r\n status.modifiedX = modifiedX;\r\n status.modifiedY = modifiedY;\r\n },\r\n\r\n modifyCoords: function modifyCoords(_ref3) {\r\n var page = _ref3.page,\r\n client = _ref3.client,\r\n status = _ref3.status,\r\n phase = _ref3.phase,\r\n options = _ref3.options;\r\n\r\n var elementRect = options && options.elementRect;\r\n\r\n if (options && options.enabled && !(phase === 'start' && elementRect && status.locked)) {\r\n\r\n if (status.locked) {\r\n page.x += status.dx;\r\n page.y += status.dy;\r\n client.x += status.dx;\r\n client.y += status.dy;\r\n\r\n return {\r\n dx: status.dx,\r\n dy: status.dy\r\n };\r\n }\r\n }\r\n },\r\n\r\n getRestrictionRect: getRestrictionRect\r\n};\r\n\r\nfunction getRestrictionRect(value, interaction, page) {\r\n if (utils.is.function(value)) {\r\n return utils.resolveRectLike(value, interaction.target, interaction.element, [page.x, page.y, interaction]);\r\n } else {\r\n return utils.resolveRectLike(value, interaction.target, interaction.element);\r\n }\r\n}\r\n\r\nmodifiers.restrict = restrict;\r\nmodifiers.names.push('restrict');\r\n\r\ndefaultOptions.perAction.restrict = restrict.defaults;\r\n\r\nmodule.exports = restrict;\r\n\r\n},{\"../defaultOptions\":18,\"../utils\":44,\"./index\":24}],26:[function(require,module,exports){\r\n'use strict';\r\n\r\n// This module adds the options.resize.restrictEdges setting which sets min and\r\n// max for the top, left, bottom and right edges of the target being resized.\r\n//\r\n// interact(target).resize({\r\n// edges: { top: true, left: true },\r\n// restrictEdges: {\r\n// inner: { top: 200, left: 200, right: 400, bottom: 400 },\r\n// outer: { top: 0, left: 0, right: 600, bottom: 600 },\r\n// },\r\n// });\r\n\r\nvar modifiers = require('./index');\r\nvar utils = require('../utils');\r\nvar rectUtils = require('../utils/rect');\r\nvar defaultOptions = require('../defaultOptions');\r\nvar resize = require('../actions/resize');\r\n\r\nvar _require = require('./restrict'),\r\n getRestrictionRect = _require.getRestrictionRect;\r\n\r\nvar noInner = { top: +Infinity, left: +Infinity, bottom: -Infinity, right: -Infinity };\r\nvar noOuter = { top: -Infinity, left: -Infinity, bottom: +Infinity, right: +Infinity };\r\n\r\nvar restrictEdges = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n min: null,\r\n max: null,\r\n offset: null\r\n },\r\n\r\n setOffset: function setOffset(_ref) {\r\n var interaction = _ref.interaction,\r\n startOffset = _ref.startOffset,\r\n options = _ref.options;\r\n\r\n if (!options) {\r\n return utils.extend({}, startOffset);\r\n }\r\n\r\n var offset = getRestrictionRect(options.offset, interaction, interaction.startCoords.page);\r\n\r\n if (offset) {\r\n return {\r\n top: startOffset.top + offset.y,\r\n left: startOffset.left + offset.x,\r\n bottom: startOffset.bottom + offset.y,\r\n right: startOffset.right + offset.x\r\n };\r\n }\r\n\r\n return startOffset;\r\n },\r\n\r\n set: function set(_ref2) {\r\n var pageCoords = _ref2.pageCoords,\r\n interaction = _ref2.interaction,\r\n status = _ref2.status,\r\n offset = _ref2.offset,\r\n options = _ref2.options;\r\n\r\n var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;\r\n\r\n if (!interaction.interacting() || !edges) {\r\n return;\r\n }\r\n\r\n var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, pageCoords);\r\n var inner = rectUtils.xywhToTlbr(getRestrictionRect(options.inner, interaction, page)) || noInner;\r\n var outer = rectUtils.xywhToTlbr(getRestrictionRect(options.outer, interaction, page)) || noOuter;\r\n\r\n var modifiedX = page.x;\r\n var modifiedY = page.y;\r\n\r\n status.dx = 0;\r\n status.dy = 0;\r\n status.locked = false;\r\n\r\n if (edges.top) {\r\n modifiedY = Math.min(Math.max(outer.top + offset.top, page.y), inner.top + offset.top);\r\n } else if (edges.bottom) {\r\n modifiedY = Math.max(Math.min(outer.bottom - offset.bottom, page.y), inner.bottom - offset.bottom);\r\n }\r\n if (edges.left) {\r\n modifiedX = Math.min(Math.max(outer.left + offset.left, page.x), inner.left + offset.left);\r\n } else if (edges.right) {\r\n modifiedX = Math.max(Math.min(outer.right - offset.right, page.x), inner.right - offset.right);\r\n }\r\n\r\n status.dx = modifiedX - page.x;\r\n status.dy = modifiedY - page.y;\r\n\r\n status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;\r\n status.locked = !!(status.dx || status.dy);\r\n\r\n status.modifiedX = modifiedX;\r\n status.modifiedY = modifiedY;\r\n },\r\n\r\n modifyCoords: function modifyCoords(_ref3) {\r\n var page = _ref3.page,\r\n client = _ref3.client,\r\n status = _ref3.status,\r\n phase = _ref3.phase,\r\n options = _ref3.options;\r\n\r\n if (options && options.enabled && !(phase === 'start' && status.locked)) {\r\n\r\n if (status.locked) {\r\n page.x += status.dx;\r\n page.y += status.dy;\r\n client.x += status.dx;\r\n client.y += status.dy;\r\n\r\n return {\r\n dx: status.dx,\r\n dy: status.dy\r\n };\r\n }\r\n }\r\n },\r\n\r\n noInner: noInner,\r\n noOuter: noOuter,\r\n getRestrictionRect: getRestrictionRect\r\n};\r\n\r\nmodifiers.restrictEdges = restrictEdges;\r\nmodifiers.names.push('restrictEdges');\r\n\r\ndefaultOptions.perAction.restrictEdges = restrictEdges.defaults;\r\nresize.defaults.restrictEdges = restrictEdges.defaults;\r\n\r\nmodule.exports = restrictEdges;\r\n\r\n},{\"../actions/resize\":10,\"../defaultOptions\":18,\"../utils\":44,\"../utils/rect\":51,\"./index\":24,\"./restrict\":25}],27:[function(require,module,exports){\r\n'use strict';\r\n\r\n// This module adds the options.resize.restrictSize setting which sets min and\r\n// max width and height for the target being resized.\r\n//\r\n// interact(target).resize({\r\n// edges: { top: true, left: true },\r\n// restrictSize: {\r\n// min: { width: -600, height: -600 },\r\n// max: { width: 600, height: 600 },\r\n// },\r\n// });\r\n\r\nvar modifiers = require('./index');\r\nvar restrictEdges = require('./restrictEdges');\r\nvar utils = require('../utils');\r\nvar rectUtils = require('../utils/rect');\r\nvar defaultOptions = require('../defaultOptions');\r\nvar resize = require('../actions/resize');\r\n\r\nvar noMin = { width: -Infinity, height: -Infinity };\r\nvar noMax = { width: +Infinity, height: +Infinity };\r\n\r\nvar restrictSize = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n min: null,\r\n max: null\r\n },\r\n\r\n setOffset: function setOffset(_ref) {\r\n var interaction = _ref.interaction;\r\n\r\n return interaction.startOffset;\r\n },\r\n\r\n set: function set(arg) {\r\n var interaction = arg.interaction,\r\n options = arg.options;\r\n\r\n var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;\r\n\r\n if (!interaction.interacting() || !edges) {\r\n return;\r\n }\r\n\r\n var rect = rectUtils.xywhToTlbr(interaction.resizeRects.inverted);\r\n\r\n var minSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.min, interaction)) || noMin;\r\n var maxSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.max, interaction)) || noMax;\r\n\r\n arg.options = {\r\n enabled: options.enabled,\r\n endOnly: options.endOnly,\r\n inner: utils.extend({}, restrictEdges.noInner),\r\n outer: utils.extend({}, restrictEdges.noOuter)\r\n };\r\n\r\n if (edges.top) {\r\n arg.options.inner.top = rect.bottom - minSize.height;\r\n arg.options.outer.top = rect.bottom - maxSize.height;\r\n } else if (edges.bottom) {\r\n arg.options.inner.bottom = rect.top + minSize.height;\r\n arg.options.outer.bottom = rect.top + maxSize.height;\r\n }\r\n if (edges.left) {\r\n arg.options.inner.left = rect.right - minSize.width;\r\n arg.options.outer.left = rect.right - maxSize.width;\r\n } else if (edges.right) {\r\n arg.options.inner.right = rect.left + minSize.width;\r\n arg.options.outer.right = rect.left + maxSize.width;\r\n }\r\n\r\n restrictEdges.set(arg);\r\n },\r\n\r\n modifyCoords: restrictEdges.modifyCoords\r\n};\r\n\r\nmodifiers.restrictSize = restrictSize;\r\nmodifiers.names.push('restrictSize');\r\n\r\ndefaultOptions.perAction.restrictSize = restrictSize.defaults;\r\nresize.defaults.restrictSize = restrictSize.defaults;\r\n\r\nmodule.exports = restrictSize;\r\n\r\n},{\"../actions/resize\":10,\"../defaultOptions\":18,\"../utils\":44,\"../utils/rect\":51,\"./index\":24,\"./restrictEdges\":26}],28:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar modifiers = require('./index');\r\nvar interact = require('../interact');\r\nvar utils = require('../utils');\r\nvar defaultOptions = require('../defaultOptions');\r\n\r\nvar snap = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n range: Infinity,\r\n targets: null,\r\n offsets: null,\r\n\r\n relativePoints: null\r\n },\r\n\r\n setOffset: function setOffset(_ref) {\r\n var interaction = _ref.interaction,\r\n interactable = _ref.interactable,\r\n element = _ref.element,\r\n rect = _ref.rect,\r\n startOffset = _ref.startOffset,\r\n options = _ref.options;\r\n\r\n var offsets = [];\r\n var optionsOrigin = utils.rectToXY(utils.resolveRectLike(options.origin));\r\n var origin = optionsOrigin || utils.getOriginXY(interactable, element, interaction.prepared.name);\r\n options = options || interactable.options[interaction.prepared.name].snap || {};\r\n\r\n var snapOffset = void 0;\r\n\r\n if (options.offset === 'startCoords') {\r\n snapOffset = {\r\n x: interaction.startCoords.page.x - origin.x,\r\n y: interaction.startCoords.page.y - origin.y\r\n };\r\n } else {\r\n var offsetRect = utils.resolveRectLike(options.offset, interactable, element, [interaction]);\r\n\r\n snapOffset = utils.rectToXY(offsetRect) || { x: 0, y: 0 };\r\n }\r\n\r\n if (rect && options.relativePoints && options.relativePoints.length) {\r\n for (var _iterator = options.relativePoints, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref2 = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref2 = _i.value;\r\n }\r\n\r\n var _ref3 = _ref2,\r\n relativeX = _ref3.x,\r\n relativeY = _ref3.y;\r\n\r\n offsets.push({\r\n x: startOffset.left - rect.width * relativeX + snapOffset.x,\r\n y: startOffset.top - rect.height * relativeY + snapOffset.y\r\n });\r\n }\r\n } else {\r\n offsets.push(snapOffset);\r\n }\r\n\r\n return offsets;\r\n },\r\n\r\n set: function set(_ref4) {\r\n var interaction = _ref4.interaction,\r\n pageCoords = _ref4.pageCoords,\r\n status = _ref4.status,\r\n options = _ref4.options,\r\n offsets = _ref4.offset;\r\n\r\n var targets = [];\r\n var target = void 0;\r\n var page = void 0;\r\n var i = void 0;\r\n\r\n if (status.useStatusXY) {\r\n page = { x: status.x, y: status.y };\r\n } else {\r\n var origin = utils.getOriginXY(interaction.target, interaction.element, interaction.prepared.name);\r\n\r\n page = utils.extend({}, pageCoords);\r\n\r\n page.x -= origin.x;\r\n page.y -= origin.y;\r\n }\r\n\r\n status.realX = page.x;\r\n status.realY = page.y;\r\n\r\n var len = options.targets ? options.targets.length : 0;\r\n\r\n for (var _iterator2 = offsets, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref5;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref5 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref5 = _i2.value;\r\n }\r\n\r\n var _ref6 = _ref5,\r\n offsetX = _ref6.x,\r\n offsetY = _ref6.y;\r\n\r\n var relativeX = page.x - offsetX;\r\n var relativeY = page.y - offsetY;\r\n\r\n for (var _iterator3 = options.targets, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {\r\n var _ref7;\r\n\r\n if (_isArray3) {\r\n if (_i3 >= _iterator3.length) break;\r\n _ref7 = _iterator3[_i3++];\r\n } else {\r\n _i3 = _iterator3.next();\r\n if (_i3.done) break;\r\n _ref7 = _i3.value;\r\n }\r\n\r\n var snapTarget = _ref7;\r\n\r\n if (utils.is.function(snapTarget)) {\r\n target = snapTarget(relativeX, relativeY, interaction);\r\n } else {\r\n target = snapTarget;\r\n }\r\n\r\n if (!target) {\r\n continue;\r\n }\r\n\r\n targets.push({\r\n x: utils.is.number(target.x) ? target.x + offsetX : relativeX,\r\n y: utils.is.number(target.y) ? target.y + offsetY : relativeY,\r\n\r\n range: utils.is.number(target.range) ? target.range : options.range\r\n });\r\n }\r\n }\r\n\r\n var closest = {\r\n target: null,\r\n inRange: false,\r\n distance: 0,\r\n range: 0,\r\n dx: 0,\r\n dy: 0\r\n };\r\n\r\n for (i = 0, len = targets.length; i < len; i++) {\r\n target = targets[i];\r\n\r\n var range = target.range;\r\n var dx = target.x - page.x;\r\n var dy = target.y - page.y;\r\n var distance = utils.hypot(dx, dy);\r\n var inRange = distance <= range;\r\n\r\n // Infinite targets count as being out of range\r\n // compared to non infinite ones that are in range\r\n if (range === Infinity && closest.inRange && closest.range !== Infinity) {\r\n inRange = false;\r\n }\r\n\r\n if (!closest.target || (inRange\r\n // is the closest target in range?\r\n ? closest.inRange && range !== Infinity\r\n // the pointer is relatively deeper in this target\r\n ? distance / range < closest.distance / closest.range\r\n // this target has Infinite range and the closest doesn't\r\n : range === Infinity && closest.range !== Infinity ||\r\n // OR this target is closer that the previous closest\r\n distance < closest.distance :\r\n // The other is not in range and the pointer is closer to this target\r\n !closest.inRange && distance < closest.distance)) {\r\n\r\n closest.target = target;\r\n closest.distance = distance;\r\n closest.range = range;\r\n closest.inRange = inRange;\r\n closest.dx = dx;\r\n closest.dy = dy;\r\n\r\n status.range = range;\r\n }\r\n }\r\n\r\n var snapChanged = void 0;\r\n\r\n if (closest.target) {\r\n snapChanged = status.modifiedX !== closest.target.x || status.modifiedY !== closest.target.y;\r\n\r\n status.modifiedX = closest.target.x;\r\n status.modifiedY = closest.target.y;\r\n } else {\r\n snapChanged = true;\r\n\r\n status.modifiedX = NaN;\r\n status.modifiedY = NaN;\r\n }\r\n\r\n status.dx = closest.dx;\r\n status.dy = closest.dy;\r\n\r\n status.changed = snapChanged || closest.inRange && !status.locked;\r\n status.locked = closest.inRange;\r\n },\r\n\r\n modifyCoords: function modifyCoords(_ref8) {\r\n var page = _ref8.page,\r\n client = _ref8.client,\r\n status = _ref8.status,\r\n phase = _ref8.phase,\r\n options = _ref8.options;\r\n\r\n var relativePoints = options && options.relativePoints;\r\n\r\n if (options && options.enabled && !(phase === 'start' && relativePoints && relativePoints.length)) {\r\n\r\n if (status.locked) {\r\n page.x += status.dx;\r\n page.y += status.dy;\r\n client.x += status.dx;\r\n client.y += status.dy;\r\n }\r\n\r\n return {\r\n range: status.range,\r\n locked: status.locked,\r\n x: status.modifiedX,\r\n y: status.modifiedY,\r\n realX: status.realX,\r\n realY: status.realY,\r\n dx: status.dx,\r\n dy: status.dy\r\n };\r\n }\r\n }\r\n};\r\n\r\ninteract.createSnapGrid = function (grid) {\r\n return function (x, y) {\r\n var limits = grid.limits || {\r\n left: -Infinity,\r\n right: Infinity,\r\n top: -Infinity,\r\n bottom: Infinity\r\n };\r\n var offsetX = 0;\r\n var offsetY = 0;\r\n\r\n if (utils.is.object(grid.offset)) {\r\n offsetX = grid.offset.x;\r\n offsetY = grid.offset.y;\r\n }\r\n\r\n var gridx = Math.round((x - offsetX) / grid.x);\r\n var gridy = Math.round((y - offsetY) / grid.y);\r\n\r\n var newX = Math.max(limits.left, Math.min(limits.right, gridx * grid.x + offsetX));\r\n var newY = Math.max(limits.top, Math.min(limits.bottom, gridy * grid.y + offsetY));\r\n\r\n return {\r\n x: newX,\r\n y: newY,\r\n range: grid.range\r\n };\r\n };\r\n};\r\n\r\nmodifiers.snap = snap;\r\nmodifiers.names.push('snap');\r\n\r\ndefaultOptions.perAction.snap = snap.defaults;\r\n\r\nmodule.exports = snap;\r\n\r\n},{\"../defaultOptions\":18,\"../interact\":21,\"../utils\":44,\"./index\":24}],29:[function(require,module,exports){\r\n'use strict';\r\n\r\n// This module allows snapping of the size of targets during resize\r\n// interactions.\r\n\r\nvar modifiers = require('./index');\r\nvar snap = require('./snap');\r\nvar defaultOptions = require('../defaultOptions');\r\nvar resize = require('../actions/resize');\r\nvar utils = require('../utils/');\r\n\r\nvar snapSize = {\r\n defaults: {\r\n enabled: false,\r\n endOnly: false,\r\n range: Infinity,\r\n targets: null,\r\n offsets: null\r\n },\r\n\r\n setOffset: function setOffset(arg) {\r\n var interaction = arg.interaction,\r\n options = arg.options;\r\n\r\n var edges = interaction.prepared.edges;\r\n\r\n if (!edges) {\r\n return;\r\n }\r\n\r\n arg.options = {\r\n relativePoints: [{\r\n x: edges.left ? 0 : 1,\r\n y: edges.top ? 0 : 1\r\n }],\r\n origin: { x: 0, y: 0 },\r\n offset: 'self',\r\n range: options.range\r\n };\r\n\r\n var offsets = snap.setOffset(arg);\r\n arg.options = options;\r\n\r\n return offsets;\r\n },\r\n\r\n set: function set(arg) {\r\n var interaction = arg.interaction,\r\n options = arg.options,\r\n offset = arg.offset,\r\n pageCoords = arg.pageCoords;\r\n\r\n var page = utils.extend({}, pageCoords);\r\n var relativeX = page.x - offset[0].x;\r\n var relativeY = page.y - offset[0].y;\r\n\r\n arg.options = utils.extend({}, options);\r\n arg.options.targets = [];\r\n\r\n for (var _iterator = options.targets, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var snapTarget = _ref;\r\n\r\n var target = void 0;\r\n\r\n if (utils.is.function(snapTarget)) {\r\n target = snapTarget(relativeX, relativeY, interaction);\r\n } else {\r\n target = snapTarget;\r\n }\r\n\r\n if (!target) {\r\n continue;\r\n }\r\n\r\n if ('width' in target && 'height' in target) {\r\n target.x = target.width;\r\n target.y = target.height;\r\n }\r\n\r\n arg.options.targets.push(target);\r\n }\r\n\r\n snap.set(arg);\r\n },\r\n\r\n modifyCoords: function modifyCoords(arg) {\r\n var options = arg.options;\r\n\r\n\r\n arg.options = utils.extend({}, options);\r\n arg.options.enabled = options.enabled;\r\n arg.options.relativePoints = [null];\r\n\r\n snap.modifyCoords(arg);\r\n }\r\n};\r\n\r\nmodifiers.snapSize = snapSize;\r\nmodifiers.names.push('snapSize');\r\n\r\ndefaultOptions.perAction.snapSize = snapSize.defaults;\r\nresize.defaults.snapSize = snapSize.defaults;\r\n\r\nmodule.exports = snapSize;\r\n\r\n},{\"../actions/resize\":10,\"../defaultOptions\":18,\"../utils/\":44,\"./index\":24,\"./snap\":28}],30:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\r\n\r\nvar pointerUtils = require('../utils/pointerUtils');\r\n\r\nmodule.exports = function () {\r\n function PointerEvent(type, pointer, event, eventTarget, interaction) {\r\n _classCallCheck(this, PointerEvent);\r\n\r\n pointerUtils.pointerExtend(this, event);\r\n\r\n if (event !== pointer) {\r\n pointerUtils.pointerExtend(this, pointer);\r\n }\r\n\r\n this.interaction = interaction;\r\n\r\n this.timeStamp = new Date().getTime();\r\n this.originalEvent = event;\r\n this.type = type;\r\n this.pointerId = pointerUtils.getPointerId(pointer);\r\n this.pointerType = pointerUtils.getPointerType(pointer);\r\n this.target = eventTarget;\r\n this.currentTarget = null;\r\n\r\n if (type === 'tap') {\r\n var pointerIndex = interaction.getPointerIndex(pointer);\r\n this.dt = this.timeStamp - interaction.downTimes[pointerIndex];\r\n\r\n var interval = this.timeStamp - interaction.tapTime;\r\n\r\n this.double = !!(interaction.prevTap && interaction.prevTap.type !== 'doubletap' && interaction.prevTap.target === this.target && interval < 500);\r\n } else if (type === 'doubletap') {\r\n this.dt = pointer.timeStamp - interaction.tapTime;\r\n }\r\n }\r\n\r\n PointerEvent.prototype.subtractOrigin = function subtractOrigin(_ref) {\r\n var originX = _ref.x,\r\n originY = _ref.y;\r\n\r\n this.pageX -= originX;\r\n this.pageY -= originY;\r\n this.clientX -= originX;\r\n this.clientY -= originY;\r\n\r\n return this;\r\n };\r\n\r\n PointerEvent.prototype.addOrigin = function addOrigin(_ref2) {\r\n var originX = _ref2.x,\r\n originY = _ref2.y;\r\n\r\n this.pageX += originX;\r\n this.pageY += originY;\r\n this.clientX += originX;\r\n this.clientY += originY;\r\n\r\n return this;\r\n };\r\n\r\n PointerEvent.prototype.preventDefault = function preventDefault() {\r\n this.originalEvent.preventDefault();\r\n };\r\n\r\n PointerEvent.prototype.stopPropagation = function stopPropagation() {\r\n this.propagationStopped = true;\r\n };\r\n\r\n PointerEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {\r\n this.immediatePropagationStopped = this.propagationStopped = true;\r\n };\r\n\r\n return PointerEvent;\r\n}();\r\n\r\n},{\"../utils/pointerUtils\":49}],31:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar PointerEvent = require('./PointerEvent');\r\nvar Interaction = require('../Interaction');\r\nvar utils = require('../utils');\r\nvar browser = require('../utils/browser');\r\nvar defaults = require('../defaultOptions');\r\nvar signals = require('../utils/Signals').new();\r\n\r\nvar _require = require('../utils/arr'),\r\n filter = _require.filter;\r\n\r\nvar simpleSignals = ['down', 'up', 'cancel'];\r\nvar simpleEvents = ['down', 'up', 'cancel'];\r\n\r\nvar pointerEvents = {\r\n PointerEvent: PointerEvent,\r\n fire: fire,\r\n collectEventTargets: collectEventTargets,\r\n signals: signals,\r\n defaults: {\r\n holdDuration: 600,\r\n ignoreFrom: null,\r\n allowFrom: null,\r\n origin: { x: 0, y: 0 }\r\n },\r\n types: ['down', 'move', 'up', 'cancel', 'tap', 'doubletap', 'hold']\r\n};\r\n\r\nfunction fire(arg) {\r\n var interaction = arg.interaction,\r\n pointer = arg.pointer,\r\n event = arg.event,\r\n eventTarget = arg.eventTarget,\r\n _arg$type = arg.type,\r\n type = _arg$type === undefined ? arg.pointerEvent.type : _arg$type,\r\n _arg$targets = arg.targets,\r\n targets = _arg$targets === undefined ? collectEventTargets(arg) : _arg$targets,\r\n _arg$pointerEvent = arg.pointerEvent,\r\n pointerEvent = _arg$pointerEvent === undefined ? new PointerEvent(type, pointer, event, eventTarget, interaction) : _arg$pointerEvent;\r\n\r\n\r\n var signalArg = {\r\n interaction: interaction,\r\n pointer: pointer,\r\n event: event,\r\n eventTarget: eventTarget,\r\n targets: targets,\r\n type: type,\r\n pointerEvent: pointerEvent\r\n };\r\n\r\n for (var i = 0; i < targets.length; i++) {\r\n var target = targets[i];\r\n\r\n for (var prop in target.props || {}) {\r\n pointerEvent[prop] = target.props[prop];\r\n }\r\n\r\n var origin = utils.getOriginXY(target.eventable, target.element);\r\n\r\n pointerEvent.subtractOrigin(origin);\r\n pointerEvent.eventable = target.eventable;\r\n pointerEvent.currentTarget = target.element;\r\n\r\n target.eventable.fire(pointerEvent);\r\n\r\n pointerEvent.addOrigin(origin);\r\n\r\n if (pointerEvent.immediatePropagationStopped || pointerEvent.propagationStopped && i + 1 < targets.length && targets[i + 1].element !== pointerEvent.currentTarget) {\r\n break;\r\n }\r\n }\r\n\r\n signals.fire('fired', signalArg);\r\n\r\n if (type === 'tap') {\r\n // if pointerEvent should make a double tap, create and fire a doubletap\r\n // PointerEvent and use that as the prevTap\r\n var prevTap = pointerEvent.double ? fire({\r\n interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,\r\n type: 'doubletap'\r\n }) : pointerEvent;\r\n\r\n interaction.prevTap = prevTap;\r\n interaction.tapTime = prevTap.timeStamp;\r\n }\r\n\r\n return pointerEvent;\r\n}\r\n\r\nfunction collectEventTargets(_ref) {\r\n var interaction = _ref.interaction,\r\n pointer = _ref.pointer,\r\n event = _ref.event,\r\n eventTarget = _ref.eventTarget,\r\n type = _ref.type;\r\n\r\n var pointerIndex = interaction.getPointerIndex(pointer);\r\n\r\n // do not fire a tap event if the pointer was moved before being lifted\r\n if (type === 'tap' && (interaction.pointerWasMoved\r\n // or if the pointerup target is different to the pointerdown target\r\n || !(interaction.downTargets[pointerIndex] && interaction.downTargets[pointerIndex] === eventTarget))) {\r\n return [];\r\n }\r\n\r\n var path = utils.getPath(eventTarget);\r\n var signalArg = {\r\n interaction: interaction,\r\n pointer: pointer,\r\n event: event,\r\n eventTarget: eventTarget,\r\n type: type,\r\n path: path,\r\n targets: [],\r\n element: null\r\n };\r\n\r\n for (var _iterator = path, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref2;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref2 = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref2 = _i.value;\r\n }\r\n\r\n var element = _ref2;\r\n\r\n signalArg.element = element;\r\n\r\n signals.fire('collect-targets', signalArg);\r\n }\r\n\r\n if (type === 'hold') {\r\n signalArg.targets = filter(signalArg.targets, function (target) {\r\n return target.eventable.options.holdDuration === interaction.holdTimers[pointerIndex].duration;\r\n });\r\n }\r\n\r\n return signalArg.targets;\r\n}\r\n\r\nInteraction.signals.on('update-pointer-down', function (_ref3) {\r\n var interaction = _ref3.interaction,\r\n pointerIndex = _ref3.pointerIndex;\r\n\r\n interaction.holdTimers[pointerIndex] = { duration: Infinity, timeout: null };\r\n});\r\n\r\nInteraction.signals.on('remove-pointer', function (_ref4) {\r\n var interaction = _ref4.interaction,\r\n pointerIndex = _ref4.pointerIndex;\r\n\r\n interaction.holdTimers.splice(pointerIndex, 1);\r\n});\r\n\r\nInteraction.signals.on('move', function (_ref5) {\r\n var interaction = _ref5.interaction,\r\n pointer = _ref5.pointer,\r\n event = _ref5.event,\r\n eventTarget = _ref5.eventTarget,\r\n duplicateMove = _ref5.duplicateMove;\r\n\r\n var pointerIndex = interaction.getPointerIndex(pointer);\r\n\r\n if (!duplicateMove && (!interaction.pointerIsDown || interaction.pointerWasMoved)) {\r\n if (interaction.pointerIsDown) {\r\n clearTimeout(interaction.holdTimers[pointerIndex].timeout);\r\n }\r\n\r\n fire({\r\n interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,\r\n type: 'move'\r\n });\r\n }\r\n});\r\n\r\nInteraction.signals.on('down', function (_ref6) {\r\n var interaction = _ref6.interaction,\r\n pointer = _ref6.pointer,\r\n event = _ref6.event,\r\n eventTarget = _ref6.eventTarget,\r\n pointerIndex = _ref6.pointerIndex;\r\n\r\n // copy event to be used in timeout for IE8\r\n var eventCopy = browser.isIE8 ? utils.extend({}, event) : event;\r\n\r\n var timer = interaction.holdTimers[pointerIndex];\r\n var path = utils.getPath(eventTarget);\r\n var signalArg = {\r\n interaction: interaction,\r\n pointer: pointer,\r\n event: event,\r\n eventTarget: eventTarget,\r\n type: 'hold',\r\n targets: [],\r\n path: path,\r\n element: null\r\n };\r\n\r\n for (var _iterator2 = path, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref7;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref7 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref7 = _i2.value;\r\n }\r\n\r\n var element = _ref7;\r\n\r\n signalArg.element = element;\r\n\r\n signals.fire('collect-targets', signalArg);\r\n }\r\n\r\n if (!signalArg.targets.length) {\r\n return;\r\n }\r\n\r\n var minDuration = Infinity;\r\n\r\n for (var i = 0; i < signalArg.targets.length; i++) {\r\n var target = signalArg.targets[i];\r\n var holdDuration = target.eventable.options.holdDuration;\r\n\r\n if (holdDuration < minDuration) {\r\n minDuration = holdDuration;\r\n }\r\n }\r\n\r\n timer.duration = minDuration;\r\n timer.timeout = setTimeout(function () {\r\n fire({\r\n interaction: interaction,\r\n eventTarget: eventTarget,\r\n pointer: browser.isIE8 ? eventCopy : pointer,\r\n event: eventCopy,\r\n type: 'hold'\r\n });\r\n }, minDuration);\r\n});\r\n\r\nInteraction.signals.on('up', function (_ref8) {\r\n var interaction = _ref8.interaction,\r\n pointer = _ref8.pointer,\r\n event = _ref8.event,\r\n eventTarget = _ref8.eventTarget;\r\n\r\n if (!interaction.pointerWasMoved) {\r\n fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: 'tap' });\r\n }\r\n});\r\n\r\n['up', 'cancel'].forEach(function (signalName) {\r\n Interaction.signals.on(signalName, function (_ref9) {\r\n var interaction = _ref9.interaction,\r\n pointerIndex = _ref9.pointerIndex;\r\n\r\n if (interaction.holdTimers[pointerIndex]) {\r\n clearTimeout(interaction.holdTimers[pointerIndex].timeout);\r\n }\r\n });\r\n});\r\n\r\nfunction createSignalListener(type) {\r\n return function (_ref10) {\r\n var interaction = _ref10.interaction,\r\n pointer = _ref10.pointer,\r\n event = _ref10.event,\r\n eventTarget = _ref10.eventTarget;\r\n\r\n fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: type });\r\n };\r\n}\r\n\r\nfor (var i = 0; i < simpleSignals.length; i++) {\r\n Interaction.signals.on(simpleSignals[i], createSignalListener(simpleEvents[i]));\r\n}\r\n\r\nInteraction.signals.on('new', function (interaction) {\r\n interaction.prevTap = null; // the most recent tap event on this interaction\r\n interaction.tapTime = 0; // time of the most recent tap event\r\n interaction.holdTimers = []; // [{ duration, timeout }]\r\n});\r\n\r\ndefaults.pointerEvents = pointerEvents.defaults;\r\nmodule.exports = pointerEvents;\r\n\r\n},{\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"../utils/Signals\":35,\"../utils/arr\":36,\"../utils/browser\":37,\"./PointerEvent\":30}],32:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar pointerEvents = require('./base');\r\nvar Interaction = require('../Interaction');\r\n\r\npointerEvents.signals.on('new', onNew);\r\npointerEvents.signals.on('fired', onFired);\r\n\r\nvar _arr = ['move', 'up', 'cancel', 'endall'];\r\nfor (var _i = 0; _i < _arr.length; _i++) {\r\n var signal = _arr[_i];\r\n Interaction.signals.on(signal, endHoldRepeat);\r\n}\r\n\r\nfunction onNew(_ref) {\r\n var pointerEvent = _ref.pointerEvent;\r\n\r\n if (pointerEvent.type !== 'hold') {\r\n return;\r\n }\r\n\r\n pointerEvent.count = (pointerEvent.count || 0) + 1;\r\n}\r\n\r\nfunction onFired(_ref2) {\r\n var interaction = _ref2.interaction,\r\n pointerEvent = _ref2.pointerEvent,\r\n eventTarget = _ref2.eventTarget,\r\n targets = _ref2.targets;\r\n\r\n if (pointerEvent.type !== 'hold' || !targets.length) {\r\n return;\r\n }\r\n\r\n // get the repeat interval from the first eventable\r\n var interval = targets[0].eventable.options.holdRepeatInterval;\r\n\r\n // don't repeat if the interval is 0 or less\r\n if (interval <= 0) {\r\n return;\r\n }\r\n\r\n // set a timeout to fire the holdrepeat event\r\n interaction.holdIntervalHandle = setTimeout(function () {\r\n pointerEvents.fire({\r\n interaction: interaction,\r\n eventTarget: eventTarget,\r\n type: 'hold',\r\n pointer: pointerEvent,\r\n event: pointerEvent\r\n });\r\n }, interval);\r\n}\r\n\r\nfunction endHoldRepeat(_ref3) {\r\n var interaction = _ref3.interaction;\r\n\r\n // set the interaction's holdStopTime property\r\n // to stop further holdRepeat events\r\n if (interaction.holdIntervalHandle) {\r\n clearInterval(interaction.holdIntervalHandle);\r\n interaction.holdIntervalHandle = null;\r\n }\r\n}\r\n\r\n// don't repeat by default\r\npointerEvents.defaults.holdRepeatInterval = 0;\r\npointerEvents.types.push('holdrepeat');\r\n\r\nmodule.exports = {\r\n onNew: onNew,\r\n onFired: onFired,\r\n endHoldRepeat: endHoldRepeat\r\n};\r\n\r\n},{\"../Interaction\":5,\"./base\":31}],33:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar pointerEvents = require('./base');\r\nvar Interactable = require('../Interactable');\r\nvar browser = require('../utils/browser');\r\nvar is = require('../utils/is');\r\nvar domUtils = require('../utils/domUtils');\r\nvar scope = require('../scope');\r\nvar extend = require('../utils/extend');\r\n\r\nvar _require = require('../utils/arr'),\r\n merge = _require.merge;\r\n\r\npointerEvents.signals.on('collect-targets', function (_ref) {\r\n var targets = _ref.targets,\r\n element = _ref.element,\r\n type = _ref.type,\r\n eventTarget = _ref.eventTarget;\r\n\r\n function collectSelectors(interactable, selector, context) {\r\n var els = browser.useMatchesSelectorPolyfill ? context.querySelectorAll(selector) : undefined;\r\n\r\n var eventable = interactable.events;\r\n var options = eventable.options;\r\n\r\n if (eventable[type] && is.element(element) && domUtils.matchesSelector(element, selector, els) && interactable.testIgnoreAllow(options, element, eventTarget)) {\r\n\r\n targets.push({\r\n element: element,\r\n eventable: eventable,\r\n props: { interactable: interactable }\r\n });\r\n }\r\n }\r\n\r\n var interactable = scope.interactables.get(element);\r\n\r\n if (interactable) {\r\n var eventable = interactable.events;\r\n var options = eventable.options;\r\n\r\n if (eventable[type] && interactable.testIgnoreAllow(options, element, eventTarget)) {\r\n targets.push({\r\n element: element,\r\n eventable: eventable,\r\n props: { interactable: interactable }\r\n });\r\n }\r\n }\r\n\r\n scope.interactables.forEachSelector(collectSelectors, element);\r\n});\r\n\r\nInteractable.signals.on('new', function (_ref2) {\r\n var interactable = _ref2.interactable;\r\n\r\n interactable.events.getRect = function (element) {\r\n return interactable.getRect(element);\r\n };\r\n});\r\n\r\nInteractable.signals.on('set', function (_ref3) {\r\n var interactable = _ref3.interactable,\r\n options = _ref3.options;\r\n\r\n extend(interactable.events.options, pointerEvents.defaults);\r\n extend(interactable.events.options, options);\r\n});\r\n\r\nmerge(Interactable.eventTypes, pointerEvents.types);\r\n\r\nInteractable.prototype.pointerEvents = function (options) {\r\n extend(this.events.options, options);\r\n\r\n return this;\r\n};\r\n\r\nvar __backCompatOption = Interactable.prototype._backCompatOption;\r\n\r\nInteractable.prototype._backCompatOption = function (optionName, newValue) {\r\n var ret = __backCompatOption.call(this, optionName, newValue);\r\n\r\n if (ret === this) {\r\n this.events.options[optionName] = newValue;\r\n }\r\n\r\n return ret;\r\n};\r\n\r\nInteractable.settingsMethods.push('pointerEvents');\r\n\r\n},{\"../Interactable\":4,\"../scope\":34,\"../utils/arr\":36,\"../utils/browser\":37,\"../utils/domUtils\":39,\"../utils/extend\":41,\"../utils/is\":46,\"./base\":31}],34:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar utils = require('./utils');\r\nvar events = require('./utils/events');\r\nvar signals = require('./utils/Signals').new();\r\n\r\nvar scope = {\r\n signals: signals,\r\n events: events,\r\n utils: utils,\r\n\r\n // main document\r\n document: require('./utils/domObjects').document,\r\n // all documents being listened to\r\n documents: [],\r\n\r\n addDocument: function addDocument(doc, win) {\r\n // do nothing if document is already known\r\n if (utils.contains(scope.documents, doc)) {\r\n return false;\r\n }\r\n\r\n win = win || scope.getWindow(doc);\r\n\r\n scope.documents.push(doc);\r\n events.documents.push(doc);\r\n\r\n // don't add an unload event for the main document\r\n // so that the page may be cached in browser history\r\n if (doc !== scope.document) {\r\n events.add(win, 'unload', scope.onWindowUnload);\r\n }\r\n\r\n signals.fire('add-document', { doc: doc, win: win });\r\n },\r\n\r\n removeDocument: function removeDocument(doc, win) {\r\n var index = utils.indexOf(scope.documents, doc);\r\n\r\n win = win || scope.getWindow(doc);\r\n\r\n events.remove(win, 'unload', scope.onWindowUnload);\r\n\r\n scope.documents.splice(index, 1);\r\n events.documents.splice(index, 1);\r\n\r\n signals.fire('remove-document', { win: win, doc: doc });\r\n },\r\n\r\n onWindowUnload: function onWindowUnload() {\r\n scope.removeDocument(this.document, this);\r\n }\r\n};\r\n\r\nmodule.exports = scope;\r\n\r\n},{\"./utils\":44,\"./utils/Signals\":35,\"./utils/domObjects\":38,\"./utils/events\":40}],35:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\r\n\r\nvar _require = require('./arr'),\r\n indexOf = _require.indexOf;\r\n\r\nvar Signals = function () {\r\n function Signals() {\r\n _classCallCheck(this, Signals);\r\n\r\n this.listeners = {\r\n // signalName: [listeners],\r\n };\r\n }\r\n\r\n Signals.prototype.on = function on(name, listener) {\r\n if (!this.listeners[name]) {\r\n this.listeners[name] = [listener];\r\n return;\r\n }\r\n\r\n this.listeners[name].push(listener);\r\n };\r\n\r\n Signals.prototype.off = function off(name, listener) {\r\n if (!this.listeners[name]) {\r\n return;\r\n }\r\n\r\n var index = indexOf(this.listeners[name], listener);\r\n\r\n if (index !== -1) {\r\n this.listeners[name].splice(index, 1);\r\n }\r\n };\r\n\r\n Signals.prototype.fire = function fire(name, arg) {\r\n var targetListeners = this.listeners[name];\r\n\r\n if (!targetListeners) {\r\n return;\r\n }\r\n\r\n for (var i = 0; i < targetListeners.length; i++) {\r\n if (targetListeners[i](arg, name) === false) {\r\n return;\r\n }\r\n }\r\n };\r\n\r\n return Signals;\r\n}();\r\n\r\nSignals.new = function () {\r\n return new Signals();\r\n};\r\n\r\nmodule.exports = Signals;\r\n\r\n},{\"./arr\":36}],36:[function(require,module,exports){\r\n\"use strict\";\r\n\r\nfunction indexOf(array, target) {\r\n for (var i = 0, len = array.length; i < len; i++) {\r\n if (array[i] === target) {\r\n return i;\r\n }\r\n }\r\n\r\n return -1;\r\n}\r\n\r\nfunction contains(array, target) {\r\n return indexOf(array, target) !== -1;\r\n}\r\n\r\nfunction merge(target, source) {\r\n for (var i = 0; i < source.length; i++) {\r\n target.push(source[i]);\r\n }\r\n\r\n return target;\r\n}\r\n\r\nfunction filter(array, test) {\r\n var result = [];\r\n\r\n for (var i = 0; i < array.length; i++) {\r\n if (test(array[i])) {\r\n result.push(array[i]);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nmodule.exports = {\r\n indexOf: indexOf,\r\n contains: contains,\r\n merge: merge,\r\n filter: filter\r\n};\r\n\r\n},{}],37:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar _require = require('./window'),\r\n window = _require.window;\r\n\r\nvar is = require('./is');\r\nvar domObjects = require('./domObjects');\r\n\r\nvar Element = domObjects.Element;\r\nvar navigator = window.navigator;\r\n\r\nvar browser = {\r\n // Does the browser support touch input?\r\n supportsTouch: !!('ontouchstart' in window || is.function(window.DocumentTouch) && domObjects.document instanceof window.DocumentTouch),\r\n\r\n // Does the browser support PointerEvents\r\n supportsPointerEvent: !!domObjects.PointerEvent,\r\n\r\n isIE8: 'attachEvent' in window && !('addEventListener' in window),\r\n\r\n // Opera Mobile must be handled differently\r\n isOperaMobile: navigator.appName === 'Opera' && browser.supportsTouch && navigator.userAgent.match('Presto'),\r\n\r\n // scrolling doesn't change the result of getClientRects on iOS 7\r\n isIOS7: /iP(hone|od|ad)/.test(navigator.platform) && /OS 7[^\\d]/.test(navigator.appVersion),\r\n\r\n isIe9OrOlder: /MSIE (8|9)/.test(navigator.userAgent),\r\n\r\n // prefix matchesSelector\r\n prefixedMatchesSelector: 'matches' in Element.prototype ? 'matches' : 'webkitMatchesSelector' in Element.prototype ? 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ? 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ? 'oMatchesSelector' : 'msMatchesSelector',\r\n\r\n useMatchesSelectorPolyfill: false,\r\n\r\n pEventTypes: domObjects.PointerEvent ? domObjects.PointerEvent === window.MSPointerEvent ? {\r\n up: 'MSPointerUp',\r\n down: 'MSPointerDown',\r\n over: 'mouseover',\r\n out: 'mouseout',\r\n move: 'MSPointerMove',\r\n cancel: 'MSPointerCancel'\r\n } : {\r\n up: 'pointerup',\r\n down: 'pointerdown',\r\n over: 'pointerover',\r\n out: 'pointerout',\r\n move: 'pointermove',\r\n cancel: 'pointercancel'\r\n } : null,\r\n\r\n // because Webkit and Opera still use 'mousewheel' event type\r\n wheelEvent: 'onmousewheel' in domObjects.document ? 'mousewheel' : 'wheel'\r\n\r\n};\r\n\r\nbrowser.useMatchesSelectorPolyfill = !is.function(Element.prototype[browser.prefixedMatchesSelector]);\r\n\r\nmodule.exports = browser;\r\n\r\n},{\"./domObjects\":38,\"./is\":46,\"./window\":52}],38:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar domObjects = {};\r\nvar win = require('./window').window;\r\n\r\nfunction blank() {}\r\n\r\ndomObjects.document = win.document;\r\ndomObjects.DocumentFragment = win.DocumentFragment || blank;\r\ndomObjects.SVGElement = win.SVGElement || blank;\r\ndomObjects.SVGSVGElement = win.SVGSVGElement || blank;\r\ndomObjects.SVGElementInstance = win.SVGElementInstance || blank;\r\ndomObjects.Element = win.Element || blank;\r\ndomObjects.HTMLElement = win.HTMLElement || domObjects.Element;\r\n\r\ndomObjects.Event = win.Event;\r\ndomObjects.Touch = win.Touch || blank;\r\ndomObjects.PointerEvent = win.PointerEvent || win.MSPointerEvent;\r\n\r\nmodule.exports = domObjects;\r\n\r\n},{\"./window\":52}],39:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar win = require('./window');\r\nvar browser = require('./browser');\r\nvar is = require('./is');\r\nvar domObjects = require('./domObjects');\r\n\r\nvar domUtils = {\r\n nodeContains: function nodeContains(parent, child) {\r\n while (child) {\r\n if (child === parent) {\r\n return true;\r\n }\r\n\r\n child = child.parentNode;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n closest: function closest(element, selector) {\r\n while (is.element(element)) {\r\n if (domUtils.matchesSelector(element, selector)) {\r\n return element;\r\n }\r\n\r\n element = domUtils.parentNode(element);\r\n }\r\n\r\n return null;\r\n },\r\n\r\n parentNode: function parentNode(node) {\r\n var parent = node.parentNode;\r\n\r\n if (is.docFrag(parent)) {\r\n // skip past #shado-root fragments\r\n while ((parent = parent.host) && is.docFrag(parent)) {\r\n continue;\r\n }\r\n\r\n return parent;\r\n }\r\n\r\n return parent;\r\n },\r\n\r\n // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\r\n matchesSelectorPolyfill: browser.useMatchesSelectorPolyfill ? function (element, selector, elems) {\r\n elems = elems || element.parentNode.querySelectorAll(selector);\r\n\r\n for (var i = 0, len = elems.length; i < len; i++) {\r\n if (elems[i] === element) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n } : null,\r\n\r\n matchesSelector: function matchesSelector(element, selector, nodeList) {\r\n if (browser.useMatchesSelectorPolyfill) {\r\n return domUtils.matchesSelectorPolyfill(element, selector, nodeList);\r\n }\r\n\r\n // remove /deep/ from selectors if shadowDOM polyfill is used\r\n if (win.window !== win.realWindow) {\r\n selector = selector.replace(/\\/deep\\//g, ' ');\r\n }\r\n\r\n return element[browser.prefixedMatchesSelector](selector);\r\n },\r\n\r\n // Test for the element that's \"above\" all other qualifiers\r\n indexOfDeepestElement: function indexOfDeepestElement(elements) {\r\n var deepestZoneParents = [];\r\n var dropzoneParents = [];\r\n var dropzone = void 0;\r\n var deepestZone = elements[0];\r\n var index = deepestZone ? 0 : -1;\r\n var parent = void 0;\r\n var child = void 0;\r\n var i = void 0;\r\n var n = void 0;\r\n\r\n for (i = 1; i < elements.length; i++) {\r\n dropzone = elements[i];\r\n\r\n // an element might belong to multiple selector dropzones\r\n if (!dropzone || dropzone === deepestZone) {\r\n continue;\r\n }\r\n\r\n if (!deepestZone) {\r\n deepestZone = dropzone;\r\n index = i;\r\n continue;\r\n }\r\n\r\n // check if the deepest or current are document.documentElement or document.rootElement\r\n // - if the current dropzone is, do nothing and continue\r\n if (dropzone.parentNode === dropzone.ownerDocument) {\r\n continue;\r\n }\r\n // - if deepest is, update with the current dropzone and continue to next\r\n else if (deepestZone.parentNode === dropzone.ownerDocument) {\r\n deepestZone = dropzone;\r\n index = i;\r\n continue;\r\n }\r\n\r\n if (!deepestZoneParents.length) {\r\n parent = deepestZone;\r\n while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {\r\n deepestZoneParents.unshift(parent);\r\n parent = parent.parentNode;\r\n }\r\n }\r\n\r\n // if this element is an svg element and the current deepest is\r\n // an HTMLElement\r\n if (deepestZone instanceof domObjects.HTMLElement && dropzone instanceof domObjects.SVGElement && !(dropzone instanceof domObjects.SVGSVGElement)) {\r\n\r\n if (dropzone === deepestZone.parentNode) {\r\n continue;\r\n }\r\n\r\n parent = dropzone.ownerSVGElement;\r\n } else {\r\n parent = dropzone;\r\n }\r\n\r\n dropzoneParents = [];\r\n\r\n while (parent.parentNode !== parent.ownerDocument) {\r\n dropzoneParents.unshift(parent);\r\n parent = parent.parentNode;\r\n }\r\n\r\n n = 0;\r\n\r\n // get (position of last common ancestor) + 1\r\n while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {\r\n n++;\r\n }\r\n\r\n var parents = [dropzoneParents[n - 1], dropzoneParents[n], deepestZoneParents[n]];\r\n\r\n child = parents[0].lastChild;\r\n\r\n while (child) {\r\n if (child === parents[1]) {\r\n deepestZone = dropzone;\r\n index = i;\r\n deepestZoneParents = [];\r\n\r\n break;\r\n } else if (child === parents[2]) {\r\n break;\r\n }\r\n\r\n child = child.previousSibling;\r\n }\r\n }\r\n\r\n return index;\r\n },\r\n\r\n matchesUpTo: function matchesUpTo(element, selector, limit) {\r\n while (is.element(element)) {\r\n if (domUtils.matchesSelector(element, selector)) {\r\n return true;\r\n }\r\n\r\n element = domUtils.parentNode(element);\r\n\r\n if (element === limit) {\r\n return domUtils.matchesSelector(element, selector);\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n\r\n getActualElement: function getActualElement(element) {\r\n return element instanceof domObjects.SVGElementInstance ? element.correspondingUseElement : element;\r\n },\r\n\r\n getScrollXY: function getScrollXY(relevantWindow) {\r\n relevantWindow = relevantWindow || win.window;\r\n return {\r\n x: relevantWindow.scrollX || relevantWindow.document.documentElement.scrollLeft,\r\n y: relevantWindow.scrollY || relevantWindow.document.documentElement.scrollTop\r\n };\r\n },\r\n\r\n getElementClientRect: function getElementClientRect(element) {\r\n var clientRect = element instanceof domObjects.SVGElement ? element.getBoundingClientRect() : element.getClientRects()[0];\r\n\r\n return clientRect && {\r\n left: clientRect.left,\r\n right: clientRect.right,\r\n top: clientRect.top,\r\n bottom: clientRect.bottom,\r\n width: clientRect.width || clientRect.right - clientRect.left,\r\n height: clientRect.height || clientRect.bottom - clientRect.top\r\n };\r\n },\r\n\r\n getElementRect: function getElementRect(element) {\r\n var clientRect = domUtils.getElementClientRect(element);\r\n\r\n if (!browser.isIOS7 && clientRect) {\r\n var scroll = domUtils.getScrollXY(win.getWindow(element));\r\n\r\n clientRect.left += scroll.x;\r\n clientRect.right += scroll.x;\r\n clientRect.top += scroll.y;\r\n clientRect.bottom += scroll.y;\r\n }\r\n\r\n return clientRect;\r\n },\r\n\r\n getPath: function getPath(element) {\r\n var path = [];\r\n\r\n while (element) {\r\n path.push(element);\r\n element = domUtils.parentNode(element);\r\n }\r\n\r\n return path;\r\n },\r\n\r\n trySelector: function trySelector(value) {\r\n if (!is.string(value)) {\r\n return false;\r\n }\r\n\r\n // an exception will be raised if it is invalid\r\n domObjects.document.querySelector(value);\r\n return true;\r\n }\r\n};\r\n\r\nmodule.exports = domUtils;\r\n\r\n},{\"./browser\":37,\"./domObjects\":38,\"./is\":46,\"./window\":52}],40:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar is = require('./is');\r\nvar domUtils = require('./domUtils');\r\nvar pExtend = require('./pointerExtend');\r\n\r\nvar _require = require('./window'),\r\n window = _require.window,\r\n getWindow = _require.getWindow;\r\n\r\nvar _require2 = require('./arr'),\r\n indexOf = _require2.indexOf,\r\n contains = _require2.contains;\r\n\r\nvar useAttachEvent = 'attachEvent' in window && !('addEventListener' in window);\r\nvar addEvent = useAttachEvent ? 'attachEvent' : 'addEventListener';\r\nvar removeEvent = useAttachEvent ? 'detachEvent' : 'removeEventListener';\r\nvar on = useAttachEvent ? 'on' : '';\r\n\r\nvar elements = [];\r\nvar targets = [];\r\nvar attachedListeners = [];\r\n\r\n// {\r\n// type: {\r\n// selectors: ['selector', ...],\r\n// contexts : [document, ...],\r\n// listeners: [[listener, capture, passive], ...]\r\n// }\r\n// }\r\nvar delegatedEvents = {};\r\n\r\nvar documents = [];\r\n\r\nvar supportsOptions = !useAttachEvent && function () {\r\n var supported = false;\r\n\r\n window.document.createElement('div').addEventListener('test', null, {\r\n get capture() {\r\n supported = true;\r\n }\r\n });\r\n\r\n return supported;\r\n}();\r\n\r\nfunction add(element, type, listener, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n var elementIndex = indexOf(elements, element);\r\n var target = targets[elementIndex];\r\n\r\n if (!target) {\r\n target = {\r\n events: {},\r\n typeCount: 0\r\n };\r\n\r\n elementIndex = elements.push(element) - 1;\r\n targets.push(target);\r\n\r\n attachedListeners.push(useAttachEvent ? {\r\n supplied: [],\r\n wrapped: [],\r\n useCount: []\r\n } : null);\r\n }\r\n\r\n if (!target.events[type]) {\r\n target.events[type] = [];\r\n target.typeCount++;\r\n }\r\n\r\n if (!contains(target.events[type], listener)) {\r\n var ret = void 0;\r\n\r\n if (useAttachEvent) {\r\n var _attachedListeners$el = attachedListeners[elementIndex],\r\n supplied = _attachedListeners$el.supplied,\r\n wrapped = _attachedListeners$el.wrapped,\r\n useCount = _attachedListeners$el.useCount;\r\n\r\n var listenerIndex = indexOf(supplied, listener);\r\n\r\n var wrappedListener = wrapped[listenerIndex] || function (event) {\r\n if (!event.immediatePropagationStopped) {\r\n event.target = event.srcElement;\r\n event.currentTarget = element;\r\n\r\n event.preventDefault = event.preventDefault || preventDef;\r\n event.stopPropagation = event.stopPropagation || stopProp;\r\n event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\r\n\r\n if (/mouse|click/.test(event.type)) {\r\n event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\r\n event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\r\n }\r\n\r\n listener(event);\r\n }\r\n };\r\n\r\n ret = element[addEvent](on + type, wrappedListener, !!options.capture);\r\n\r\n if (listenerIndex === -1) {\r\n supplied.push(listener);\r\n wrapped.push(wrappedListener);\r\n useCount.push(1);\r\n } else {\r\n useCount[listenerIndex]++;\r\n }\r\n } else {\r\n ret = element[addEvent](type, listener, supportsOptions ? options : !!options.capture);\r\n }\r\n target.events[type].push(listener);\r\n\r\n return ret;\r\n }\r\n}\r\n\r\nfunction remove(element, type, listener, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n var elementIndex = indexOf(elements, element);\r\n var target = targets[elementIndex];\r\n\r\n if (!target || !target.events) {\r\n return;\r\n }\r\n\r\n var wrappedListener = listener;\r\n var listeners = void 0;\r\n var listenerIndex = void 0;\r\n\r\n if (useAttachEvent) {\r\n listeners = attachedListeners[elementIndex];\r\n listenerIndex = indexOf(listeners.supplied, listener);\r\n wrappedListener = listeners.wrapped[listenerIndex];\r\n }\r\n\r\n if (type === 'all') {\r\n for (type in target.events) {\r\n if (target.events.hasOwnProperty(type)) {\r\n remove(element, type, 'all');\r\n }\r\n }\r\n return;\r\n }\r\n\r\n if (target.events[type]) {\r\n var len = target.events[type].length;\r\n\r\n if (listener === 'all') {\r\n for (var i = 0; i < len; i++) {\r\n remove(element, type, target.events[type][i], options);\r\n }\r\n return;\r\n } else {\r\n for (var _i = 0; _i < len; _i++) {\r\n if (target.events[type][_i] === listener) {\r\n element[removeEvent](on + type, wrappedListener, supportsOptions ? options : !!options.capture);\r\n target.events[type].splice(_i, 1);\r\n\r\n if (useAttachEvent && listeners) {\r\n listeners.useCount[listenerIndex]--;\r\n if (listeners.useCount[listenerIndex] === 0) {\r\n listeners.supplied.splice(listenerIndex, 1);\r\n listeners.wrapped.splice(listenerIndex, 1);\r\n listeners.useCount.splice(listenerIndex, 1);\r\n }\r\n }\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (target.events[type] && target.events[type].length === 0) {\r\n target.events[type] = null;\r\n target.typeCount--;\r\n }\r\n }\r\n\r\n if (!target.typeCount) {\r\n targets.splice(elementIndex, 1);\r\n elements.splice(elementIndex, 1);\r\n attachedListeners.splice(elementIndex, 1);\r\n }\r\n}\r\n\r\nfunction addDelegate(selector, context, type, listener, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n if (!delegatedEvents[type]) {\r\n delegatedEvents[type] = {\r\n selectors: [],\r\n contexts: [],\r\n listeners: []\r\n };\r\n\r\n // add delegate listener functions\r\n for (var i = 0; i < documents.length; i++) {\r\n add(documents[i], type, delegateListener);\r\n add(documents[i], type, delegateUseCapture, true);\r\n }\r\n }\r\n\r\n var delegated = delegatedEvents[type];\r\n var index = void 0;\r\n\r\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\r\n if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {\r\n break;\r\n }\r\n }\r\n\r\n if (index === -1) {\r\n index = delegated.selectors.length;\r\n\r\n delegated.selectors.push(selector);\r\n delegated.contexts.push(context);\r\n delegated.listeners.push([]);\r\n }\r\n\r\n // keep listener and capture and passive flags\r\n delegated.listeners[index].push([listener, !!options.capture, options.passive]);\r\n}\r\n\r\nfunction removeDelegate(selector, context, type, listener, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n var delegated = delegatedEvents[type];\r\n var matchFound = false;\r\n var index = void 0;\r\n\r\n if (!delegated) {\r\n return;\r\n }\r\n\r\n // count from last index of delegated to 0\r\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\r\n // look for matching selector and context Node\r\n if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {\r\n\r\n var listeners = delegated.listeners[index];\r\n\r\n // each item of the listeners array is an array: [function, capture, passive]\r\n for (var i = listeners.length - 1; i >= 0; i--) {\r\n var _listeners$i = listeners[i],\r\n fn = _listeners$i[0],\r\n capture = _listeners$i[1],\r\n passive = _listeners$i[2];\r\n\r\n // check if the listener functions and capture and passive flags match\r\n\r\n if (fn === listener && capture === !!options.capture && passive === options.passive) {\r\n // remove the listener from the array of listeners\r\n listeners.splice(i, 1);\r\n\r\n // if all listeners for this interactable have been removed\r\n // remove the interactable from the delegated arrays\r\n if (!listeners.length) {\r\n delegated.selectors.splice(index, 1);\r\n delegated.contexts.splice(index, 1);\r\n delegated.listeners.splice(index, 1);\r\n\r\n // remove delegate function from context\r\n remove(context, type, delegateListener);\r\n remove(context, type, delegateUseCapture, true);\r\n\r\n // remove the arrays if they are empty\r\n if (!delegated.selectors.length) {\r\n delegatedEvents[type] = null;\r\n }\r\n }\r\n\r\n // only remove one listener\r\n matchFound = true;\r\n break;\r\n }\r\n }\r\n\r\n if (matchFound) {\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n// bound to the interactable context when a DOM event\r\n// listener is added to a selector interactable\r\nfunction delegateListener(event, optionalArg) {\r\n var options = getOptions(optionalArg);\r\n var fakeEvent = {};\r\n var delegated = delegatedEvents[event.type];\r\n var eventTarget = domUtils.getActualElement(event.path ? event.path[0] : event.target);\r\n var element = eventTarget;\r\n\r\n // duplicate the event so that currentTarget can be changed\r\n pExtend(fakeEvent, event);\r\n\r\n fakeEvent.originalEvent = event;\r\n fakeEvent.preventDefault = preventOriginalDefault;\r\n\r\n // climb up document tree looking for selector matches\r\n while (is.element(element)) {\r\n for (var i = 0; i < delegated.selectors.length; i++) {\r\n var selector = delegated.selectors[i];\r\n var context = delegated.contexts[i];\r\n\r\n if (domUtils.matchesSelector(element, selector) && domUtils.nodeContains(context, eventTarget) && domUtils.nodeContains(context, element)) {\r\n\r\n var listeners = delegated.listeners[i];\r\n\r\n fakeEvent.currentTarget = element;\r\n\r\n for (var j = 0; j < listeners.length; j++) {\r\n var _listeners$j = listeners[j],\r\n fn = _listeners$j[0],\r\n capture = _listeners$j[1],\r\n passive = _listeners$j[2];\r\n\r\n\r\n if (capture === !!options.capture && passive === options.passive) {\r\n fn(fakeEvent);\r\n }\r\n }\r\n }\r\n }\r\n\r\n element = domUtils.parentNode(element);\r\n }\r\n}\r\n\r\nfunction delegateUseCapture(event) {\r\n return delegateListener.call(this, event, true);\r\n}\r\n\r\nfunction preventDef() {\r\n this.returnValue = false;\r\n}\r\n\r\nfunction preventOriginalDefault() {\r\n this.originalEvent.preventDefault();\r\n}\r\n\r\nfunction stopProp() {\r\n this.cancelBubble = true;\r\n}\r\n\r\nfunction stopImmProp() {\r\n this.cancelBubble = true;\r\n this.immediatePropagationStopped = true;\r\n}\r\n\r\nfunction getOptions(param) {\r\n return is.object(param) ? param : { capture: param };\r\n}\r\n\r\nmodule.exports = {\r\n add: add,\r\n remove: remove,\r\n\r\n addDelegate: addDelegate,\r\n removeDelegate: removeDelegate,\r\n\r\n delegateListener: delegateListener,\r\n delegateUseCapture: delegateUseCapture,\r\n delegatedEvents: delegatedEvents,\r\n documents: documents,\r\n\r\n useAttachEvent: useAttachEvent,\r\n supportsOptions: supportsOptions,\r\n\r\n _elements: elements,\r\n _targets: targets,\r\n _attachedListeners: attachedListeners\r\n};\r\n\r\n},{\"./arr\":36,\"./domUtils\":39,\"./is\":46,\"./pointerExtend\":48,\"./window\":52}],41:[function(require,module,exports){\r\n\"use strict\";\r\n\r\nmodule.exports = function extend(dest, source) {\r\n for (var prop in source) {\r\n dest[prop] = source[prop];\r\n }\r\n return dest;\r\n};\r\n\r\n},{}],42:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar _require = require('./rect'),\r\n resolveRectLike = _require.resolveRectLike,\r\n rectToXY = _require.rectToXY;\r\n\r\nmodule.exports = function (target, element, action) {\r\n var actionOptions = target.options[action];\r\n var actionOrigin = actionOptions && actionOptions.origin;\r\n var origin = actionOrigin || target.options.origin;\r\n\r\n var originRect = resolveRectLike(origin, target, element, [target && element]);\r\n\r\n return rectToXY(originRect) || { x: 0, y: 0 };\r\n};\r\n\r\n},{\"./rect\":51}],43:[function(require,module,exports){\r\n\"use strict\";\r\n\r\nmodule.exports = function (x, y) {\r\n return Math.sqrt(x * x + y * y);\r\n};\r\n\r\n},{}],44:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar extend = require('./extend');\r\nvar win = require('./window');\r\n\r\nvar utils = {\r\n warnOnce: function warnOnce(method, message) {\r\n var warned = false;\r\n\r\n return function () {\r\n if (!warned) {\r\n win.window.console.warn(message);\r\n warned = true;\r\n }\r\n\r\n return method.apply(this, arguments);\r\n };\r\n },\r\n\r\n // http://stackoverflow.com/a/5634528/2280888\r\n _getQBezierValue: function _getQBezierValue(t, p1, p2, p3) {\r\n var iT = 1 - t;\r\n return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\r\n },\r\n\r\n getQuadraticCurvePoint: function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {\r\n return {\r\n x: utils._getQBezierValue(position, startX, cpX, endX),\r\n y: utils._getQBezierValue(position, startY, cpY, endY)\r\n };\r\n },\r\n\r\n // http://gizma.com/easing/\r\n easeOutQuad: function easeOutQuad(t, b, c, d) {\r\n t /= d;\r\n return -c * t * (t - 2) + b;\r\n },\r\n\r\n copyAction: function copyAction(dest, src) {\r\n dest.name = src.name;\r\n dest.axis = src.axis;\r\n dest.edges = src.edges;\r\n\r\n return dest;\r\n },\r\n\r\n is: require('./is'),\r\n extend: extend,\r\n hypot: require('./hypot'),\r\n getOriginXY: require('./getOriginXY')\r\n};\r\n\r\nextend(utils, require('./arr'));\r\nextend(utils, require('./domUtils'));\r\nextend(utils, require('./pointerUtils'));\r\nextend(utils, require('./rect'));\r\n\r\nmodule.exports = utils;\r\n\r\n},{\"./arr\":36,\"./domUtils\":39,\"./extend\":41,\"./getOriginXY\":42,\"./hypot\":43,\"./is\":46,\"./pointerUtils\":49,\"./rect\":51,\"./window\":52}],45:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar scope = require('../scope');\r\nvar utils = require('./index');\r\n\r\nvar finder = {\r\n methodOrder: ['simulationResume', 'mouseOrPen', 'hasPointer', 'idle'],\r\n\r\n search: function search(pointer, eventType, eventTarget) {\r\n var pointerType = utils.getPointerType(pointer);\r\n var pointerId = utils.getPointerId(pointer);\r\n var details = { pointer: pointer, pointerId: pointerId, pointerType: pointerType, eventType: eventType, eventTarget: eventTarget };\r\n\r\n for (var _iterator = finder.methodOrder, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var method = _ref;\r\n\r\n var interaction = finder[method](details);\r\n\r\n if (interaction) {\r\n return interaction;\r\n }\r\n }\r\n },\r\n\r\n // try to resume simulation with a new pointer\r\n simulationResume: function simulationResume(_ref2) {\r\n var pointerType = _ref2.pointerType,\r\n eventType = _ref2.eventType,\r\n eventTarget = _ref2.eventTarget;\r\n\r\n if (!/down|start/i.test(eventType)) {\r\n return null;\r\n }\r\n\r\n for (var _iterator2 = scope.interactions, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\r\n var _ref3;\r\n\r\n if (_isArray2) {\r\n if (_i2 >= _iterator2.length) break;\r\n _ref3 = _iterator2[_i2++];\r\n } else {\r\n _i2 = _iterator2.next();\r\n if (_i2.done) break;\r\n _ref3 = _i2.value;\r\n }\r\n\r\n var interaction = _ref3;\r\n\r\n var element = eventTarget;\r\n\r\n if (interaction.simulation && interaction.simulation.allowResume && interaction.pointerType === pointerType) {\r\n while (element) {\r\n // if the element is the interaction element\r\n if (element === interaction.element) {\r\n return interaction;\r\n }\r\n element = utils.parentNode(element);\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n\r\n // if it's a mouse or pen interaction\r\n mouseOrPen: function mouseOrPen(_ref4) {\r\n var pointerId = _ref4.pointerId,\r\n pointerType = _ref4.pointerType,\r\n eventType = _ref4.eventType;\r\n\r\n if (pointerType !== 'mouse' && pointerType !== 'pen') {\r\n return null;\r\n }\r\n\r\n var firstNonActive = void 0;\r\n\r\n for (var _iterator3 = scope.interactions, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {\r\n var _ref5;\r\n\r\n if (_isArray3) {\r\n if (_i3 >= _iterator3.length) break;\r\n _ref5 = _iterator3[_i3++];\r\n } else {\r\n _i3 = _iterator3.next();\r\n if (_i3.done) break;\r\n _ref5 = _i3.value;\r\n }\r\n\r\n var interaction = _ref5;\r\n\r\n if (interaction.pointerType === pointerType) {\r\n // if it's a down event, skip interactions with running simulations\r\n if (interaction.simulation && !utils.contains(interaction.pointerIds, pointerId)) {\r\n continue;\r\n }\r\n\r\n // if the interaction is active, return it immediately\r\n if (interaction.interacting()) {\r\n return interaction;\r\n }\r\n // otherwise save it and look for another active interaction\r\n else if (!firstNonActive) {\r\n firstNonActive = interaction;\r\n }\r\n }\r\n }\r\n\r\n // if no active mouse interaction was found use the first inactive mouse\r\n // interaction\r\n if (firstNonActive) {\r\n return firstNonActive;\r\n }\r\n\r\n // find any mouse or pen interaction.\r\n // ignore the interaction if the eventType is a *down, and a simulation\r\n // is active\r\n for (var _iterator4 = scope.interactions, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {\r\n var _ref6;\r\n\r\n if (_isArray4) {\r\n if (_i4 >= _iterator4.length) break;\r\n _ref6 = _iterator4[_i4++];\r\n } else {\r\n _i4 = _iterator4.next();\r\n if (_i4.done) break;\r\n _ref6 = _i4.value;\r\n }\r\n\r\n var _interaction = _ref6;\r\n\r\n if (_interaction.pointerType === pointerType && !(/down/i.test(eventType) && _interaction.simulation)) {\r\n return _interaction;\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n\r\n // get interaction that has this pointer\r\n hasPointer: function hasPointer(_ref7) {\r\n var pointerId = _ref7.pointerId;\r\n\r\n for (var _iterator5 = scope.interactions, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {\r\n var _ref8;\r\n\r\n if (_isArray5) {\r\n if (_i5 >= _iterator5.length) break;\r\n _ref8 = _iterator5[_i5++];\r\n } else {\r\n _i5 = _iterator5.next();\r\n if (_i5.done) break;\r\n _ref8 = _i5.value;\r\n }\r\n\r\n var interaction = _ref8;\r\n\r\n if (utils.contains(interaction.pointerIds, pointerId)) {\r\n return interaction;\r\n }\r\n }\r\n },\r\n\r\n // get first idle interaction with a matching pointerType\r\n idle: function idle(_ref9) {\r\n var pointerType = _ref9.pointerType;\r\n\r\n for (var _iterator6 = scope.interactions, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {\r\n var _ref10;\r\n\r\n if (_isArray6) {\r\n if (_i6 >= _iterator6.length) break;\r\n _ref10 = _iterator6[_i6++];\r\n } else {\r\n _i6 = _iterator6.next();\r\n if (_i6.done) break;\r\n _ref10 = _i6.value;\r\n }\r\n\r\n var interaction = _ref10;\r\n\r\n // if there's already a pointer held down\r\n if (interaction.pointerIds.length === 1) {\r\n var target = interaction.target;\r\n // don't add this pointer if there is a target interactable and it\r\n // isn't gesturable\r\n if (target && !target.options.gesture.enabled) {\r\n continue;\r\n }\r\n }\r\n // maximum of 2 pointers per interaction\r\n else if (interaction.pointerIds.length >= 2) {\r\n continue;\r\n }\r\n\r\n if (!interaction.interacting() && pointerType === interaction.pointerType) {\r\n return interaction;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n};\r\n\r\nmodule.exports = finder;\r\n\r\n},{\"../scope\":34,\"./index\":44}],46:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\r\n\r\nvar win = require('./window');\r\nvar isWindow = require('./isWindow');\r\n\r\nvar is = {\r\n array: function array() {},\r\n\r\n window: function window(thing) {\r\n return thing === win.window || isWindow(thing);\r\n },\r\n\r\n docFrag: function docFrag(thing) {\r\n return is.object(thing) && thing.nodeType === 11;\r\n },\r\n\r\n object: function object(thing) {\r\n return !!thing && (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) === 'object';\r\n },\r\n\r\n function: function _function(thing) {\r\n return typeof thing === 'function';\r\n },\r\n\r\n number: function number(thing) {\r\n return typeof thing === 'number';\r\n },\r\n\r\n bool: function bool(thing) {\r\n return typeof thing === 'boolean';\r\n },\r\n\r\n string: function string(thing) {\r\n return typeof thing === 'string';\r\n },\r\n\r\n element: function element(thing) {\r\n if (!thing || (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) !== 'object') {\r\n return false;\r\n }\r\n\r\n var _window = win.getWindow(thing) || win.window;\r\n\r\n return (/object|function/.test(_typeof(_window.Element)) ? thing instanceof _window.Element //DOM2\r\n : thing.nodeType === 1 && typeof thing.nodeName === 'string'\r\n );\r\n }\r\n};\r\n\r\nis.array = function (thing) {\r\n return is.object(thing) && typeof thing.length !== 'undefined' && is.function(thing.splice);\r\n};\r\n\r\nmodule.exports = is;\r\n\r\n},{\"./isWindow\":47,\"./window\":52}],47:[function(require,module,exports){\r\n\"use strict\";\r\n\r\nmodule.exports = function (thing) {\r\n return !!(thing && thing.Window) && thing instanceof thing.Window;\r\n};\r\n\r\n},{}],48:[function(require,module,exports){\r\n'use strict';\r\n\r\nfunction pointerExtend(dest, source) {\r\n for (var prop in source) {\r\n var prefixedPropREs = module.exports.prefixedPropREs;\r\n var deprecated = false;\r\n\r\n // skip deprecated prefixed properties\r\n for (var vendor in prefixedPropREs) {\r\n if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {\r\n deprecated = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!deprecated && typeof source[prop] !== 'function') {\r\n dest[prop] = source[prop];\r\n }\r\n }\r\n return dest;\r\n}\r\n\r\npointerExtend.prefixedPropREs = {\r\n webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\r\n};\r\n\r\nmodule.exports = pointerExtend;\r\n\r\n},{}],49:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar hypot = require('./hypot');\r\nvar browser = require('./browser');\r\nvar dom = require('./domObjects');\r\nvar domUtils = require('./domUtils');\r\nvar domObjects = require('./domObjects');\r\nvar is = require('./is');\r\nvar pointerExtend = require('./pointerExtend');\r\n\r\nvar pointerUtils = {\r\n copyCoords: function copyCoords(dest, src) {\r\n dest.page = dest.page || {};\r\n dest.page.x = src.page.x;\r\n dest.page.y = src.page.y;\r\n\r\n dest.client = dest.client || {};\r\n dest.client.x = src.client.x;\r\n dest.client.y = src.client.y;\r\n\r\n dest.timeStamp = src.timeStamp;\r\n },\r\n\r\n setCoordDeltas: function setCoordDeltas(targetObj, prev, cur) {\r\n targetObj.page.x = cur.page.x - prev.page.x;\r\n targetObj.page.y = cur.page.y - prev.page.y;\r\n targetObj.client.x = cur.client.x - prev.client.x;\r\n targetObj.client.y = cur.client.y - prev.client.y;\r\n targetObj.timeStamp = cur.timeStamp - prev.timeStamp;\r\n\r\n // set pointer velocity\r\n var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\r\n\r\n targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\r\n targetObj.page.vx = targetObj.page.x / dt;\r\n targetObj.page.vy = targetObj.page.y / dt;\r\n\r\n targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\r\n targetObj.client.vx = targetObj.client.x / dt;\r\n targetObj.client.vy = targetObj.client.y / dt;\r\n },\r\n\r\n isNativePointer: function isNativePointer(pointer) {\r\n return pointer instanceof dom.Event || pointer instanceof dom.Touch;\r\n },\r\n\r\n // Get specified X/Y coords for mouse or event.touches[0]\r\n getXY: function getXY(type, pointer, xy) {\r\n xy = xy || {};\r\n type = type || 'page';\r\n\r\n xy.x = pointer[type + 'X'];\r\n xy.y = pointer[type + 'Y'];\r\n\r\n return xy;\r\n },\r\n\r\n getPageXY: function getPageXY(pointer, page) {\r\n page = page || {};\r\n\r\n // Opera Mobile handles the viewport and scrolling oddly\r\n if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {\r\n pointerUtils.getXY('screen', pointer, page);\r\n\r\n page.x += window.scrollX;\r\n page.y += window.scrollY;\r\n } else {\r\n pointerUtils.getXY('page', pointer, page);\r\n }\r\n\r\n return page;\r\n },\r\n\r\n getClientXY: function getClientXY(pointer, client) {\r\n client = client || {};\r\n\r\n if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {\r\n // Opera Mobile handles the viewport and scrolling oddly\r\n pointerUtils.getXY('screen', pointer, client);\r\n } else {\r\n pointerUtils.getXY('client', pointer, client);\r\n }\r\n\r\n return client;\r\n },\r\n\r\n getPointerId: function getPointerId(pointer) {\r\n return is.number(pointer.pointerId) ? pointer.pointerId : pointer.identifier;\r\n },\r\n\r\n setCoords: function setCoords(targetObj, pointers, timeStamp) {\r\n var pointer = pointers.length > 1 ? pointerUtils.pointerAverage(pointers) : pointers[0];\r\n\r\n var tmpXY = {};\r\n\r\n pointerUtils.getPageXY(pointer, tmpXY);\r\n targetObj.page.x = tmpXY.x;\r\n targetObj.page.y = tmpXY.y;\r\n\r\n pointerUtils.getClientXY(pointer, tmpXY);\r\n targetObj.client.x = tmpXY.x;\r\n targetObj.client.y = tmpXY.y;\r\n\r\n targetObj.timeStamp = is.number(timeStamp) ? timeStamp : new Date().getTime();\r\n },\r\n\r\n pointerExtend: pointerExtend,\r\n\r\n getTouchPair: function getTouchPair(event) {\r\n var touches = [];\r\n\r\n // array of touches is supplied\r\n if (is.array(event)) {\r\n touches[0] = event[0];\r\n touches[1] = event[1];\r\n }\r\n // an event\r\n else {\r\n if (event.type === 'touchend') {\r\n if (event.touches.length === 1) {\r\n touches[0] = event.touches[0];\r\n touches[1] = event.changedTouches[0];\r\n } else if (event.touches.length === 0) {\r\n touches[0] = event.changedTouches[0];\r\n touches[1] = event.changedTouches[1];\r\n }\r\n } else {\r\n touches[0] = event.touches[0];\r\n touches[1] = event.touches[1];\r\n }\r\n }\r\n\r\n return touches;\r\n },\r\n\r\n pointerAverage: function pointerAverage(pointers) {\r\n var average = {\r\n pageX: 0,\r\n pageY: 0,\r\n clientX: 0,\r\n clientY: 0,\r\n screenX: 0,\r\n screenY: 0\r\n };\r\n\r\n for (var _iterator = pointers, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\r\n var _ref;\r\n\r\n if (_isArray) {\r\n if (_i >= _iterator.length) break;\r\n _ref = _iterator[_i++];\r\n } else {\r\n _i = _iterator.next();\r\n if (_i.done) break;\r\n _ref = _i.value;\r\n }\r\n\r\n var pointer = _ref;\r\n\r\n for (var _prop in average) {\r\n average[_prop] += pointer[_prop];\r\n }\r\n }\r\n for (var prop in average) {\r\n average[prop] /= pointers.length;\r\n }\r\n\r\n return average;\r\n },\r\n\r\n touchBBox: function touchBBox(event) {\r\n if (!event.length && !(event.touches && event.touches.length > 1)) {\r\n return;\r\n }\r\n\r\n var touches = pointerUtils.getTouchPair(event);\r\n var minX = Math.min(touches[0].pageX, touches[1].pageX);\r\n var minY = Math.min(touches[0].pageY, touches[1].pageY);\r\n var maxX = Math.max(touches[0].pageX, touches[1].pageX);\r\n var maxY = Math.max(touches[0].pageY, touches[1].pageY);\r\n\r\n return {\r\n x: minX,\r\n y: minY,\r\n left: minX,\r\n top: minY,\r\n width: maxX - minX,\r\n height: maxY - minY\r\n };\r\n },\r\n\r\n touchDistance: function touchDistance(event, deltaSource) {\r\n var sourceX = deltaSource + 'X';\r\n var sourceY = deltaSource + 'Y';\r\n var touches = pointerUtils.getTouchPair(event);\r\n\r\n var dx = touches[0][sourceX] - touches[1][sourceX];\r\n var dy = touches[0][sourceY] - touches[1][sourceY];\r\n\r\n return hypot(dx, dy);\r\n },\r\n\r\n touchAngle: function touchAngle(event, prevAngle, deltaSource) {\r\n var sourceX = deltaSource + 'X';\r\n var sourceY = deltaSource + 'Y';\r\n var touches = pointerUtils.getTouchPair(event);\r\n var dx = touches[1][sourceX] - touches[0][sourceX];\r\n var dy = touches[1][sourceY] - touches[0][sourceY];\r\n var angle = 180 * Math.atan2(dy, dx) / Math.PI;\r\n\r\n return angle;\r\n },\r\n\r\n getPointerType: function getPointerType(pointer) {\r\n return is.string(pointer.pointerType) ? pointer.pointerType : is.number(pointer.pointerType) ? [undefined, undefined, 'touch', 'pen', 'mouse'][pointer.pointerType]\r\n // if the PointerEvent API isn't available, then the \"pointer\" must\r\n // be either a MouseEvent, TouchEvent, or Touch object\r\n : /touch/.test(pointer.type) || pointer instanceof domObjects.Touch ? 'touch' : 'mouse';\r\n },\r\n\r\n // [ event.target, event.currentTarget ]\r\n getEventTargets: function getEventTargets(event) {\r\n return [domUtils.getActualElement(event.path ? event.path[0] : event.target), domUtils.getActualElement(event.currentTarget)];\r\n }\r\n};\r\n\r\nmodule.exports = pointerUtils;\r\n\r\n},{\"./browser\":37,\"./domObjects\":38,\"./domUtils\":39,\"./hypot\":43,\"./is\":46,\"./pointerExtend\":48}],50:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar _require = require('./window'),\r\n window = _require.window;\r\n\r\nvar vendors = ['ms', 'moz', 'webkit', 'o'];\r\nvar lastTime = 0;\r\nvar request = void 0;\r\nvar cancel = void 0;\r\n\r\nfor (var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) {\r\n request = window[vendors[x] + 'RequestAnimationFrame'];\r\n cancel = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];\r\n}\r\n\r\nif (!request) {\r\n request = function request(callback) {\r\n var currTime = new Date().getTime();\r\n var timeToCall = Math.max(0, 16 - (currTime - lastTime));\r\n var id = setTimeout(function () {\r\n callback(currTime + timeToCall);\r\n }, timeToCall);\r\n\r\n lastTime = currTime + timeToCall;\r\n return id;\r\n };\r\n}\r\n\r\nif (!cancel) {\r\n cancel = function cancel(id) {\r\n clearTimeout(id);\r\n };\r\n}\r\n\r\nmodule.exports = {\r\n request: request,\r\n cancel: cancel\r\n};\r\n\r\n},{\"./window\":52}],51:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar extend = require('./extend');\r\nvar is = require('./is');\r\n\r\nvar _require = require('./domUtils'),\r\n closest = _require.closest,\r\n parentNode = _require.parentNode,\r\n getElementRect = _require.getElementRect;\r\n\r\nvar rectUtils = {\r\n getStringOptionResult: function getStringOptionResult(value, interactable, element) {\r\n if (!is.string(value)) {\r\n return null;\r\n }\r\n\r\n if (value === 'parent') {\r\n value = parentNode(element);\r\n } else if (value === 'self') {\r\n value = interactable.getRect(element);\r\n } else {\r\n value = closest(element, value);\r\n }\r\n\r\n return value;\r\n },\r\n\r\n resolveRectLike: function resolveRectLike(value, interactable, element, functionArgs) {\r\n value = rectUtils.getStringOptionResult(value, interactable, element) || value;\r\n\r\n if (is.function(value)) {\r\n value = value.apply(null, functionArgs);\r\n }\r\n\r\n if (is.element(value)) {\r\n value = getElementRect(value);\r\n }\r\n\r\n return value;\r\n },\r\n\r\n rectToXY: function rectToXY(rect) {\r\n return rect && {\r\n x: 'x' in rect ? rect.x : rect.left,\r\n y: 'y' in rect ? rect.y : rect.top\r\n };\r\n },\r\n\r\n xywhToTlbr: function xywhToTlbr(rect) {\r\n if (rect && !('left' in rect && 'top' in rect)) {\r\n rect = extend({}, rect);\r\n\r\n rect.left = rect.x || 0;\r\n rect.top = rect.y || 0;\r\n rect.right = rect.right || rect.left + rect.width;\r\n rect.bottom = rect.bottom || rect.top + rect.height;\r\n }\r\n\r\n return rect;\r\n },\r\n\r\n tlbrToXywh: function tlbrToXywh(rect) {\r\n if (rect && !('x' in rect && 'y' in rect)) {\r\n rect = extend({}, rect);\r\n\r\n rect.x = rect.left || 0;\r\n rect.top = rect.top || 0;\r\n rect.width = rect.width || rect.right - rect.x;\r\n rect.height = rect.height || rect.bottom - rect.y;\r\n }\r\n\r\n return rect;\r\n }\r\n};\r\n\r\nmodule.exports = rectUtils;\r\n\r\n},{\"./domUtils\":39,\"./extend\":41,\"./is\":46}],52:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar win = module.exports;\r\nvar isWindow = require('./isWindow');\r\n\r\nfunction init(window) {\r\n // get wrapped window if using Shadow DOM polyfill\r\n\r\n win.realWindow = window;\r\n\r\n // create a TextNode\r\n var el = window.document.createTextNode('');\r\n\r\n // check if it's wrapped by a polyfill\r\n if (el.ownerDocument !== window.document && typeof window.wrap === 'function' && window.wrap(el) === el) {\r\n // use wrapped window\r\n window = window.wrap(window);\r\n }\r\n\r\n win.window = window;\r\n}\r\n\r\nif (typeof window === 'undefined') {\r\n win.window = undefined;\r\n win.realWindow = undefined;\r\n} else {\r\n init(window);\r\n}\r\n\r\nwin.getWindow = function getWindow(node) {\r\n if (isWindow(node)) {\r\n return node;\r\n }\r\n\r\n var rootNode = node.ownerDocument || node;\r\n\r\n return rootNode.defaultView || rootNode.parentWindow || win.window;\r\n};\r\n\r\nwin.init = init;\r\n\r\n},{\"./isWindow\":47}]},{},[1])(1)\r\n});\r\n\r\n\r\n//# sourceMappingURL=interact.js.map\r\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW50ZXJhY3Rqcy9kaXN0L2ludGVyYWN0LmpzP2JiZmUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IllBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFNBQTJELG1CQUFtQixnREFBZ0QsYUFBYSxLQUFLLE1BQU0sZ0NBQWdDLFNBQVMscUNBQXFDLFNBQVMsbUNBQW1DLE9BQU8sS0FBSyxPQUFPLGtCQUFrQixhQUFhLDBCQUEwQiwwQkFBMEIsZ0JBQWdCLFVBQVUsVUFBVSwwQ0FBMEMsOEJBQXdCLG9CQUFvQiw4Q0FBOEMsa0NBQWtDLFlBQVksWUFBWSxtQ0FBbUMsaUJBQWlCLGdCQUFnQixzQkFBc0Isb0JBQW9CLDBDQUEwQyxZQUFZLFdBQVcsWUFBWSxTQUFTLEdBQUc7QUFDNXlCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBLENBQUMsRUFBRSx5Q0FBeUM7QUFDNUM7O0FBRUEsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdko7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHlDQUF5QywrQ0FBK0M7QUFDeEY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBNEIsZUFBZTtBQUMzQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBLENBQUMsRUFBRSx3Q0FBd0M7QUFDM0M7O0FBRUEsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdko7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLHdCQUF3QjtBQUN4QiwwQkFBMEI7O0FBRTFCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHdGQUF3RjtBQUMzRjs7QUFFQSxpREFBaUQsMENBQTBDLDBEQUEwRCxFQUFFOztBQUV2SjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtGQUFrRjs7QUFFbEY7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx3SkFBd0o7QUFDeEo7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXVELGFBQWE7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUZBQXlGO0FBQ3pGO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsc0JBQXNCO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRCQUE0Qjs7QUFFNUIsOEJBQThCOztBQUU5QjtBQUNBOztBQUVBLDBDQUEwQzs7QUFFMUM7O0FBRUE7QUFDQTs7QUFFQSw2S0FBNks7QUFDN0s7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEsMkJBQTJCLHFCQUFxQjs7QUFFaEQ7O0FBRUE7QUFDQSx5S0FBeUs7QUFDeks7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUEsaUJBQWlCLGlCQUFpQjtBQUNsQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGlCQUFpQjtBQUNsQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLG1PQUFtTztBQUN0Tzs7QUFFQSxpREFBaUQsMENBQTBDLDBEQUEwRCxFQUFFOztBQUV2SjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsdUJBQXVCO0FBQ3ZCLHdCQUF3Qjs7QUFFeEIscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsYUFBYTtBQUMxQixlQUFlLGFBQWE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLGFBQWE7QUFDMUIsZUFBZSxhQUFhO0FBQzVCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsYUFBYTtBQUMxQixlQUFlLGFBQWE7QUFDNUI7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxxQ0FBcUM7QUFDbEQsZUFBZSxxQ0FBcUM7QUFDcEQ7QUFDQTs7QUFFQSwwQkFBMEI7QUFDMUI7O0FBRUE7QUFDQTs7QUFFQSwwQkFBMEI7O0FBRTFCO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMscUJBQXFCO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixlQUFlO0FBQzdDO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUMsUUFBUSxlQUFlO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxpQkFBaUI7O0FBRXRCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEIsb0JBQW9COztBQUU5QztBQUNBLG1DQUFtQyxvQkFBb0I7QUFDdkQsa0RBQWtELG9CQUFvQjtBQUN0RTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQseUNBQXlDLFNBQVM7QUFDbEQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFCQUFxQjs7QUFFckI7QUFDQTs7QUFFQSxzQkFBc0Isa0NBQWtDO0FBQ3hEO0FBQ0E7O0FBRUEsK0RBQStELDJCQUEyQjtBQUMxRjtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EseUJBQXlCLG9EQUFvRDtBQUM3RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMENBQTBDLDJCQUEyQjtBQUNyRTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUpBQWlKO0FBQ2pKOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixpQ0FBaUM7QUFDcEQ7O0FBRUE7QUFDQSw0QkFBNEIseUNBQXlDO0FBQ3JFO0FBQ0E7O0FBRUEsaUJBQWlCO0FBQ2pCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsK0lBQStJO0FBQ2xKOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHdDQUF3QztBQUMzQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBLGtDQUFrQyxzR0FBc0c7QUFDeEksR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLG1DQUFtQztBQUNuQyxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDRHQUE0RztBQUMvRzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsMEpBQTBKO0FBQzFKOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLHlCQUF5QjtBQUM1Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLDhDQUE4QztBQUMvRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGlCQUFpQiw4Q0FBOEM7QUFDL0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsOENBQThDO0FBQy9EO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QyxvQkFBb0I7O0FBRTNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG9DQUFvQyxlQUFlOztBQUVuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3Qyx1QkFBdUI7O0FBRS9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLHlCQUF5Qjs7QUFFbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0EsZ0NBQWdDO0FBQ2hDLGlDQUFpQztBQUNqQyxvQ0FBb0M7QUFDcEMscUNBQXFDO0FBQ3JDLGdDQUFnQzs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsMklBQTJJO0FBQzlJOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsbUNBQW1DO0FBQ25DLG1DQUFtQztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsWUFBWSxhQUFhOztBQUV6QjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsNEdBQTRHO0FBQy9HOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDhCQUE4QjtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0EseUJBQXlCOztBQUV6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEscUJBQXFCLE9BQU87QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRCQUE0QjtBQUM1Qiw2QkFBNkI7QUFDN0IsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQyxtQ0FBbUM7QUFDbkMsbUNBQW1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSxrSUFBa0k7QUFDckk7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSxtSEFBbUg7QUFDdEg7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLG1EQUFtRDtBQUN6RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixvREFBb0Q7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsb0pBQW9KO0FBQ3BKOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxnRkFBZ0Y7QUFDbkY7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsdUNBQXVDLFNBQVM7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNEJBQTRCLDJCQUEyQjtBQUN2RDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLG9KQUFvSjtBQUNwSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrREFBa0QsU0FBUztBQUMzRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHNNQUFzTTtBQUN6TTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELENBQUMsRUFBRSwrQkFBK0I7QUFDbEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDRHQUE0RztBQUMvRzs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsbUNBQW1DO0FBQ3RDOztBQUVBOztBQUVBLENBQUMsRUFBRSxtQ0FBbUM7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxhQUFhLGFBQWE7O0FBRTFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEdBQUc7QUFDSjs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxDQUFDLEVBQUUsc2dCQUFzZ0I7QUFDemdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLENBQUMsRUFBRSxxRkFBcUY7QUFDeEY7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2SUFBNkk7QUFDN0k7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxtQkFBbUI7QUFDckU7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxSkFBcUo7QUFDcko7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsUUFBUTtBQUNyRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSx3R0FBd0c7QUFDM0c7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0JBQWdCLGtCQUFrQjtBQUNsQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDBKQUEwSjtBQUMxSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDRHQUE0RztBQUMvRzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJKQUEySjtBQUMzSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLG1JQUFtSTtBQUN0STs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG1CQUFtQiw0QkFBNEI7QUFDL0M7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdKQUF3SjtBQUN4Sjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFD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Q0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSwwQ0FBMEM7QUFDN0M7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLGNBQWM7QUFDakI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQSx1Q0FBdUMsU0FBUztBQUNoRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZSxxQkFBcUI7QUFDcEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHlEQUF5RDtBQUM1RDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtB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QUFDQSxtQkFBbUI7O0FBRW5CLDJKQUEySjtBQUMzSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG1LQUFtSztBQUNuSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLG1LQUFtSztBQUNuSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1LQUFtSztBQUNuSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQSxtS0FBbUs7QUFDbks7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUEsbUtBQW1LO0FBQ25LOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDJCQUEyQjtBQUM5Qjs7QUFFQSxvR0FBb0csbUJBQW1CLEVBQUUsbUJBQW1CLDhIQUE4SDs7QUFFMVE7QUFDQTs7QUFFQTtBQUNBLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDhCQUE4QjtBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxHQUFHO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEdBQUc7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpSkFBaUo7QUFDako7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSw2RkFBNkY7QUFDaEc7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLHFEQUFxRDtBQUNwRTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxjQUFjO0FBQ2pCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHdDQUF3QztBQUMzQzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRztBQUN4QixDQUFDOzs7QUFHRCIsImZpbGUiOiIxNS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBpbnRlcmFjdC5qcyB2MS4zLjAtYWxwaGEuNCtzaGEuNzk3MDQxNi1kaXJ0eVxyXG4gKlxyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNyBUYXllIEFkZXllbWkgPGRldkB0YXllLm1lPlxyXG4gKiBPcGVuIHNvdXJjZSB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXHJcbiAqIGh0dHBzOi8vcmF3LmdpdGh1Yi5jb20vdGF5ZS9pbnRlcmFjdC5qcy9tYXN0ZXIvTElDRU5TRVxyXG4gKi9cclxuKGZ1bmN0aW9uKGYpe2lmKHR5cGVvZiBleHBvcnRzPT09XCJvYmplY3RcIiYmdHlwZW9mIG1vZHVsZSE9PVwidW5kZWZpbmVkXCIpe21vZHVsZS5leHBvcnRzPWYoKX1lbHNlIGlmKHR5cGVvZiBkZWZpbmU9PT1cImZ1bmN0aW9uXCImJmRlZmluZS5hbWQpe2RlZmluZShbXSxmKX1lbHNle3ZhciBnO2lmKHR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiKXtnPXdpbmRvd31lbHNlIGlmKHR5cGVvZiBnbG9iYWwhPT1cInVuZGVmaW5lZFwiKXtnPWdsb2JhbH1lbHNlIGlmKHR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIil7Zz1zZWxmfWVsc2V7Zz10aGlzfWcuaW50ZXJhY3QgPSBmKCl9fSkoZnVuY3Rpb24oKXt2YXIgZGVmaW5lLG1vZHVsZSxleHBvcnRzO3JldHVybiAoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSh7MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbi8qXHJcbiAqIEluIGEgKHdpbmRvd2xlc3MpIHNlcnZlciBlbnZpcm9ubWVudCB0aGlzIGZpbGUgZXhwb3J0cyBhIGZhY3RvcnkgZnVuY3Rpb25cclxuICogdGhhdCB0YWtlcyB0aGUgd2luZG93IHRvIHVzZS5cclxuICpcclxuICogICAgIHZhciBpbnRlcmFjdCA9IHJlcXVpcmUoJ2ludGVyYWN0LmpzJykod2luZG93T2JqZWN0KTtcclxuICpcclxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS90YXllL2ludGVyYWN0LmpzL2lzc3Vlcy8xODdcclxuICovXHJcbmlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xyXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHdpbmRvdykge1xyXG4gICAgcmVxdWlyZSgnLi9zcmMvdXRpbHMvd2luZG93JykuaW5pdCh3aW5kb3cpO1xyXG5cclxuICAgIHJldHVybiByZXF1aXJlKCcuL3NyYy9pbmRleCcpO1xyXG4gIH07XHJcbn0gZWxzZSB7XHJcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL3NyYy9pbmRleCcpO1xyXG59XHJcblxyXG59LHtcIi4vc3JjL2luZGV4XCI6MTksXCIuL3NyYy91dGlscy93aW5kb3dcIjo1Mn1dLDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi91dGlscy9hcnInKSxcclxuICAgIGluZGV4T2YgPSBfcmVxdWlyZS5pbmRleE9mO1xyXG5cclxudmFyIGV4dGVuZCA9IHJlcXVpcmUoJy4vdXRpbHMvZXh0ZW5kLmpzJyk7XHJcblxyXG5mdW5jdGlvbiBmaXJlVW50aWxJbW1lZGlhdGVTdG9wcGVkKGV2ZW50LCBsaXN0ZW5lcnMpIHtcclxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbiAmJiAhZXZlbnQuaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOyBpKyspIHtcclxuICAgIGxpc3RlbmVyc1tpXShldmVudCk7XHJcbiAgfVxyXG59XHJcblxyXG52YXIgRXZlbnRhYmxlID0gZnVuY3Rpb24gKCkge1xyXG4gIGZ1bmN0aW9uIEV2ZW50YWJsZShvcHRpb25zKSB7XHJcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRXZlbnRhYmxlKTtcclxuXHJcbiAgICB0aGlzLm9wdGlvbnMgPSBleHRlbmQoe30sIG9wdGlvbnMgfHwge30pO1xyXG4gIH1cclxuXHJcbiAgRXZlbnRhYmxlLnByb3RvdHlwZS5maXJlID0gZnVuY3Rpb24gZmlyZShldmVudCkge1xyXG4gICAgdmFyIGxpc3RlbmVycyA9IHZvaWQgMDtcclxuICAgIHZhciBvbkV2ZW50ID0gJ29uJyArIGV2ZW50LnR5cGU7XHJcbiAgICB2YXIgZ2xvYmFsID0gdGhpcy5nbG9iYWw7XHJcblxyXG4gICAgLy8gSW50ZXJhY3RhYmxlI29uKCkgbGlzdGVuZXJzXHJcbiAgICBpZiAobGlzdGVuZXJzID0gdGhpc1tldmVudC50eXBlXSkge1xyXG4gICAgICBmaXJlVW50aWxJbW1lZGlhdGVTdG9wcGVkKGV2ZW50LCBsaXN0ZW5lcnMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGludGVyYWN0YWJsZS5vbmV2ZW50IGxpc3RlbmVyXHJcbiAgICBpZiAodGhpc1tvbkV2ZW50XSkge1xyXG4gICAgICB0aGlzW29uRXZlbnRdKGV2ZW50KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBpbnRlcmFjdC5vbigpIGxpc3RlbmVyc1xyXG4gICAgaWYgKCFldmVudC5wcm9wYWdhdGlvblN0b3BwZWQgJiYgZ2xvYmFsICYmIChsaXN0ZW5lcnMgPSBnbG9iYWxbZXZlbnQudHlwZV0pKSB7XHJcbiAgICAgIGZpcmVVbnRpbEltbWVkaWF0ZVN0b3BwZWQoZXZlbnQsIGxpc3RlbmVycyk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgRXZlbnRhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKGV2ZW50VHlwZSwgbGlzdGVuZXIpIHtcclxuICAgIC8vIGlmIHRoaXMgdHlwZSBvZiBldmVudCB3YXMgbmV2ZXIgYm91bmRcclxuICAgIGlmICh0aGlzW2V2ZW50VHlwZV0pIHtcclxuICAgICAgdGhpc1tldmVudFR5cGVdLnB1c2gobGlzdGVuZXIpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpc1tldmVudFR5cGVdID0gW2xpc3RlbmVyXTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBFdmVudGFibGUucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIG9mZihldmVudFR5cGUsIGxpc3RlbmVyKSB7XHJcbiAgICAvLyBpZiBpdCBpcyBhbiBhY3Rpb24gZXZlbnQgdHlwZVxyXG4gICAgdmFyIGV2ZW50TGlzdCA9IHRoaXNbZXZlbnRUeXBlXTtcclxuICAgIHZhciBpbmRleCA9IGV2ZW50TGlzdCA/IGluZGV4T2YoZXZlbnRMaXN0LCBsaXN0ZW5lcikgOiAtMTtcclxuXHJcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XHJcbiAgICAgIGV2ZW50TGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChldmVudExpc3QgJiYgZXZlbnRMaXN0Lmxlbmd0aCA9PT0gMCB8fCAhbGlzdGVuZXIpIHtcclxuICAgICAgdGhpc1tldmVudFR5cGVdID0gbGlzdGVuZXI7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIEV2ZW50YWJsZTtcclxufSgpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBFdmVudGFibGU7XHJcblxyXG59LHtcIi4vdXRpbHMvYXJyXCI6MzYsXCIuL3V0aWxzL2V4dGVuZC5qc1wiOjQxfV0sMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XHJcblxyXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi91dGlscy9leHRlbmQnKTtcclxudmFyIGdldE9yaWdpblhZID0gcmVxdWlyZSgnLi91dGlscy9nZXRPcmlnaW5YWScpO1xyXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2RlZmF1bHRPcHRpb25zJyk7XHJcbnZhciBzaWduYWxzID0gcmVxdWlyZSgnLi91dGlscy9TaWduYWxzJykubmV3KCk7XHJcblxyXG52YXIgSW50ZXJhY3RFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICBmdW5jdGlvbiBJbnRlcmFjdEV2ZW50KGludGVyYWN0aW9uLCBldmVudCwgYWN0aW9uLCBwaGFzZSwgZWxlbWVudCwgcmVsYXRlZCkge1xyXG4gICAgdmFyIHByZUVuZCA9IGFyZ3VtZW50cy5sZW5ndGggPiA2ICYmIGFyZ3VtZW50c1s2XSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzZdIDogZmFsc2U7XHJcblxyXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEludGVyYWN0RXZlbnQpO1xyXG5cclxuICAgIHZhciB0YXJnZXQgPSBpbnRlcmFjdGlvbi50YXJnZXQ7XHJcbiAgICB2YXIgZGVsdGFTb3VyY2UgPSAodGFyZ2V0ICYmIHRhcmdldC5vcHRpb25zIHx8IGRlZmF1bHRzKS5kZWx0YVNvdXJjZTtcclxuICAgIHZhciBvcmlnaW4gPSBnZXRPcmlnaW5YWSh0YXJnZXQsIGVsZW1lbnQsIGFjdGlvbik7XHJcbiAgICB2YXIgc3RhcnRpbmcgPSBwaGFzZSA9PT0gJ3N0YXJ0JztcclxuICAgIHZhciBlbmRpbmcgPSBwaGFzZSA9PT0gJ2VuZCc7XHJcbiAgICB2YXIgY29vcmRzID0gc3RhcnRpbmcgPyBpbnRlcmFjdGlvbi5zdGFydENvb3JkcyA6IGludGVyYWN0aW9uLmN1ckNvb3JkcztcclxuICAgIHZhciBwcmV2RXZlbnQgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQ7XHJcblxyXG4gICAgZWxlbWVudCA9IGVsZW1lbnQgfHwgaW50ZXJhY3Rpb24uZWxlbWVudDtcclxuXHJcbiAgICB2YXIgcGFnZSA9IGV4dGVuZCh7fSwgY29vcmRzLnBhZ2UpO1xyXG4gICAgdmFyIGNsaWVudCA9IGV4dGVuZCh7fSwgY29vcmRzLmNsaWVudCk7XHJcblxyXG4gICAgcGFnZS54IC09IG9yaWdpbi54O1xyXG4gICAgcGFnZS55IC09IG9yaWdpbi55O1xyXG5cclxuICAgIGNsaWVudC54IC09IG9yaWdpbi54O1xyXG4gICAgY2xpZW50LnkgLT0gb3JpZ2luLnk7XHJcblxyXG4gICAgdGhpcy5jdHJsS2V5ID0gZXZlbnQuY3RybEtleTtcclxuICAgIHRoaXMuYWx0S2V5ID0gZXZlbnQuYWx0S2V5O1xyXG4gICAgdGhpcy5zaGlmdEtleSA9IGV2ZW50LnNoaWZ0S2V5O1xyXG4gICAgdGhpcy5tZXRhS2V5ID0gZXZlbnQubWV0YUtleTtcclxuICAgIHRoaXMuYnV0dG9uID0gZXZlbnQuYnV0dG9uO1xyXG4gICAgdGhpcy5idXR0b25zID0gZXZlbnQuYnV0dG9ucztcclxuICAgIHRoaXMudGFyZ2V0ID0gZWxlbWVudDtcclxuICAgIHRoaXMuY3VycmVudFRhcmdldCA9IGVsZW1lbnQ7XHJcbiAgICB0aGlzLnJlbGF0ZWRUYXJnZXQgPSByZWxhdGVkIHx8IG51bGw7XHJcbiAgICB0aGlzLnByZUVuZCA9IHByZUVuZDtcclxuICAgIHRoaXMudHlwZSA9IGFjdGlvbiArIChwaGFzZSB8fCAnJyk7XHJcbiAgICB0aGlzLmludGVyYWN0aW9uID0gaW50ZXJhY3Rpb247XHJcbiAgICB0aGlzLmludGVyYWN0YWJsZSA9IHRhcmdldDtcclxuXHJcbiAgICB0aGlzLnQwID0gc3RhcnRpbmcgPyBpbnRlcmFjdGlvbi5kb3duVGltZXNbaW50ZXJhY3Rpb24uZG93blRpbWVzLmxlbmd0aCAtIDFdIDogcHJldkV2ZW50LnQwO1xyXG5cclxuICAgIHZhciBzaWduYWxBcmcgPSB7XHJcbiAgICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcclxuICAgICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgICBhY3Rpb246IGFjdGlvbixcclxuICAgICAgcGhhc2U6IHBoYXNlLFxyXG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICByZWxhdGVkOiByZWxhdGVkLFxyXG4gICAgICBwYWdlOiBwYWdlLFxyXG4gICAgICBjbGllbnQ6IGNsaWVudCxcclxuICAgICAgY29vcmRzOiBjb29yZHMsXHJcbiAgICAgIHN0YXJ0aW5nOiBzdGFydGluZyxcclxuICAgICAgZW5kaW5nOiBlbmRpbmcsXHJcbiAgICAgIGRlbHRhU291cmNlOiBkZWx0YVNvdXJjZSxcclxuICAgICAgaUV2ZW50OiB0aGlzXHJcbiAgICB9O1xyXG5cclxuICAgIHNpZ25hbHMuZmlyZSgnc2V0LXh5Jywgc2lnbmFsQXJnKTtcclxuXHJcbiAgICBpZiAoZW5kaW5nKSB7XHJcbiAgICAgIC8vIHVzZSBwcmV2aW91cyBjb29yZHMgd2hlbiBlbmRpbmdcclxuICAgICAgdGhpcy5wYWdlWCA9IHByZXZFdmVudC5wYWdlWDtcclxuICAgICAgdGhpcy5wYWdlWSA9IHByZXZFdmVudC5wYWdlWTtcclxuICAgICAgdGhpcy5jbGllbnRYID0gcHJldkV2ZW50LmNsaWVudFg7XHJcbiAgICAgIHRoaXMuY2xpZW50WSA9IHByZXZFdmVudC5jbGllbnRZO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5wYWdlWCA9IHBhZ2UueDtcclxuICAgICAgdGhpcy5wYWdlWSA9IHBhZ2UueTtcclxuICAgICAgdGhpcy5jbGllbnRYID0gY2xpZW50Lng7XHJcbiAgICAgIHRoaXMuY2xpZW50WSA9IGNsaWVudC55O1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMueDAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnggLSBvcmlnaW4ueDtcclxuICAgIHRoaXMueTAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnkgLSBvcmlnaW4ueTtcclxuICAgIHRoaXMuY2xpZW50WDAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueCAtIG9yaWdpbi54O1xyXG4gICAgdGhpcy5jbGllbnRZMCA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLmNsaWVudC55IC0gb3JpZ2luLnk7XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdzZXQtZGVsdGEnLCBzaWduYWxBcmcpO1xyXG5cclxuICAgIHRoaXMudGltZVN0YW1wID0gY29vcmRzLnRpbWVTdGFtcDtcclxuICAgIHRoaXMuZHQgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEudGltZVN0YW1wO1xyXG4gICAgdGhpcy5kdXJhdGlvbiA9IHRoaXMudGltZVN0YW1wIC0gdGhpcy50MDtcclxuXHJcbiAgICAvLyBzcGVlZCBhbmQgdmVsb2NpdHkgaW4gcGl4ZWxzIHBlciBzZWNvbmRcclxuICAgIHRoaXMuc3BlZWQgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGFbZGVsdGFTb3VyY2VdLnNwZWVkO1xyXG4gICAgdGhpcy52ZWxvY2l0eVggPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGFbZGVsdGFTb3VyY2VdLnZ4O1xyXG4gICAgdGhpcy52ZWxvY2l0eVkgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGFbZGVsdGFTb3VyY2VdLnZ5O1xyXG5cclxuICAgIHRoaXMuc3dpcGUgPSBlbmRpbmcgfHwgcGhhc2UgPT09ICdpbmVydGlhc3RhcnQnID8gdGhpcy5nZXRTd2lwZSgpIDogbnVsbDtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ25ldycsIHNpZ25hbEFyZyk7XHJcbiAgfVxyXG5cclxuICBJbnRlcmFjdEV2ZW50LnByb3RvdHlwZS5nZXRTd2lwZSA9IGZ1bmN0aW9uIGdldFN3aXBlKCkge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gdGhpcy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgICBpZiAoaW50ZXJhY3Rpb24ucHJldkV2ZW50LnNwZWVkIDwgNjAwIHx8IHRoaXMudGltZVN0YW1wIC0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LnRpbWVTdGFtcCA+IDE1MCkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYW5nbGUgPSAxODAgKiBNYXRoLmF0YW4yKGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVksIGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVgpIC8gTWF0aC5QSTtcclxuICAgIHZhciBvdmVybGFwID0gMjIuNTtcclxuXHJcbiAgICBpZiAoYW5nbGUgPCAwKSB7XHJcbiAgICAgIGFuZ2xlICs9IDM2MDtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgbGVmdCA9IDEzNSAtIG92ZXJsYXAgPD0gYW5nbGUgJiYgYW5nbGUgPCAyMjUgKyBvdmVybGFwO1xyXG4gICAgdmFyIHVwID0gMjI1IC0gb3ZlcmxhcCA8PSBhbmdsZSAmJiBhbmdsZSA8IDMxNSArIG92ZXJsYXA7XHJcblxyXG4gICAgdmFyIHJpZ2h0ID0gIWxlZnQgJiYgKDMxNSAtIG92ZXJsYXAgPD0gYW5nbGUgfHwgYW5nbGUgPCA0NSArIG92ZXJsYXApO1xyXG4gICAgdmFyIGRvd24gPSAhdXAgJiYgNDUgLSBvdmVybGFwIDw9IGFuZ2xlICYmIGFuZ2xlIDwgMTM1ICsgb3ZlcmxhcDtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICB1cDogdXAsXHJcbiAgICAgIGRvd246IGRvd24sXHJcbiAgICAgIGxlZnQ6IGxlZnQsXHJcbiAgICAgIHJpZ2h0OiByaWdodCxcclxuICAgICAgYW5nbGU6IGFuZ2xlLFxyXG4gICAgICBzcGVlZDogaW50ZXJhY3Rpb24ucHJldkV2ZW50LnNwZWVkLFxyXG4gICAgICB2ZWxvY2l0eToge1xyXG4gICAgICAgIHg6IGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVgsXHJcbiAgICAgICAgeTogaW50ZXJhY3Rpb24ucHJldkV2ZW50LnZlbG9jaXR5WVxyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0RXZlbnQucHJvdG90eXBlLnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gcHJldmVudERlZmF1bHQoKSB7fTtcclxuXHJcbiAgSW50ZXJhY3RFdmVudC5wcm90b3R5cGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkge1xyXG4gICAgdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3RFdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKCkge1xyXG4gICAgdGhpcy5wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBJbnRlcmFjdEV2ZW50O1xyXG59KCk7XHJcblxyXG5zaWduYWxzLm9uKCdzZXQtZGVsdGEnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciBpRXZlbnQgPSBfcmVmLmlFdmVudCxcclxuICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBzdGFydGluZyA9IF9yZWYuc3RhcnRpbmcsXHJcbiAgICAgIGRlbHRhU291cmNlID0gX3JlZi5kZWx0YVNvdXJjZTtcclxuXHJcbiAgdmFyIHByZXZFdmVudCA9IHN0YXJ0aW5nID8gaUV2ZW50IDogaW50ZXJhY3Rpb24ucHJldkV2ZW50O1xyXG5cclxuICBpZiAoZGVsdGFTb3VyY2UgPT09ICdjbGllbnQnKSB7XHJcbiAgICBpRXZlbnQuZHggPSBpRXZlbnQuY2xpZW50WCAtIHByZXZFdmVudC5jbGllbnRYO1xyXG4gICAgaUV2ZW50LmR5ID0gaUV2ZW50LmNsaWVudFkgLSBwcmV2RXZlbnQuY2xpZW50WTtcclxuICB9IGVsc2Uge1xyXG4gICAgaUV2ZW50LmR4ID0gaUV2ZW50LnBhZ2VYIC0gcHJldkV2ZW50LnBhZ2VYO1xyXG4gICAgaUV2ZW50LmR5ID0gaUV2ZW50LnBhZ2VZIC0gcHJldkV2ZW50LnBhZ2VZO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMgPSBzaWduYWxzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBJbnRlcmFjdEV2ZW50O1xyXG5cclxufSx7XCIuL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuL3V0aWxzL1NpZ25hbHNcIjozNSxcIi4vdXRpbHMvZXh0ZW5kXCI6NDEsXCIuL3V0aWxzL2dldE9yaWdpblhZXCI6NDJ9XSw0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJy4vdXRpbHMvaXMnKTtcclxudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vdXRpbHMvZXZlbnRzJyk7XHJcbnZhciBleHRlbmQgPSByZXF1aXJlKCcuL3V0aWxzL2V4dGVuZCcpO1xyXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4vYWN0aW9ucy9iYXNlJyk7XHJcbnZhciBzY29wZSA9IHJlcXVpcmUoJy4vc2NvcGUnKTtcclxudmFyIEV2ZW50YWJsZSA9IHJlcXVpcmUoJy4vRXZlbnRhYmxlJyk7XHJcbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4vZGVmYXVsdE9wdGlvbnMnKTtcclxudmFyIHNpZ25hbHMgPSByZXF1aXJlKCcuL3V0aWxzL1NpZ25hbHMnKS5uZXcoKTtcclxuXHJcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4vdXRpbHMvZG9tVXRpbHMnKSxcclxuICAgIGdldEVsZW1lbnRSZWN0ID0gX3JlcXVpcmUuZ2V0RWxlbWVudFJlY3QsXHJcbiAgICBub2RlQ29udGFpbnMgPSBfcmVxdWlyZS5ub2RlQ29udGFpbnMsXHJcbiAgICB0cnlTZWxlY3RvciA9IF9yZXF1aXJlLnRyeVNlbGVjdG9yO1xyXG5cclxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJy4vdXRpbHMvd2luZG93JyksXHJcbiAgICBnZXRXaW5kb3cgPSBfcmVxdWlyZTIuZ2V0V2luZG93O1xyXG5cclxudmFyIF9yZXF1aXJlMyA9IHJlcXVpcmUoJy4vdXRpbHMvYXJyJyksXHJcbiAgICBpbmRleE9mID0gX3JlcXVpcmUzLmluZGV4T2YsXHJcbiAgICBjb250YWlucyA9IF9yZXF1aXJlMy5jb250YWlucztcclxuXHJcbnZhciBfcmVxdWlyZTQgPSByZXF1aXJlKCcuL3V0aWxzL2Jyb3dzZXInKSxcclxuICAgIHdoZWVsRXZlbnQgPSBfcmVxdWlyZTQud2hlZWxFdmVudDtcclxuXHJcbi8vIGFsbCBzZXQgaW50ZXJhY3RhYmxlc1xyXG5cclxuXHJcbnNjb3BlLmludGVyYWN0YWJsZXMgPSBbXTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlXHJcbiBbIHByb3BlcnR5IF1cclxuICoqXHJcbiAqIE9iamVjdCB0eXBlIHJldHVybmVkIGJ5IEBpbnRlcmFjdFxyXG5cXCovXHJcblxyXG52YXIgSW50ZXJhY3RhYmxlID0gZnVuY3Rpb24gKCkge1xyXG4gIGZ1bmN0aW9uIEludGVyYWN0YWJsZSh0YXJnZXQsIG9wdGlvbnMpIHtcclxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBJbnRlcmFjdGFibGUpO1xyXG5cclxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG5cclxuICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xyXG4gICAgdGhpcy5ldmVudHMgPSBuZXcgRXZlbnRhYmxlKCk7XHJcbiAgICB0aGlzLl9jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0IHx8IHNjb3BlLmRvY3VtZW50O1xyXG4gICAgdGhpcy5fd2luID0gZ2V0V2luZG93KHRyeVNlbGVjdG9yKHRhcmdldCkgPyB0aGlzLl9jb250ZXh0IDogdGFyZ2V0KTtcclxuICAgIHRoaXMuX2RvYyA9IHRoaXMuX3dpbi5kb2N1bWVudDtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ25ldycsIHtcclxuICAgICAgdGFyZ2V0OiB0YXJnZXQsXHJcbiAgICAgIG9wdGlvbnM6IG9wdGlvbnMsXHJcbiAgICAgIGludGVyYWN0YWJsZTogdGhpcyxcclxuICAgICAgd2luOiB0aGlzLl93aW5cclxuICAgIH0pO1xyXG5cclxuICAgIHNjb3BlLmFkZERvY3VtZW50KHRoaXMuX2RvYywgdGhpcy5fd2luKTtcclxuXHJcbiAgICBzY29wZS5pbnRlcmFjdGFibGVzLnB1c2godGhpcyk7XHJcblxyXG4gICAgdGhpcy5zZXQob3B0aW9ucyk7XHJcbiAgfVxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLnNldE9uRXZlbnRzID0gZnVuY3Rpb24gc2V0T25FdmVudHMoYWN0aW9uLCBwaGFzZXMpIHtcclxuICAgIHZhciBvbkFjdGlvbiA9ICdvbicgKyBhY3Rpb247XHJcblxyXG4gICAgaWYgKGlzLmZ1bmN0aW9uKHBoYXNlcy5vbnN0YXJ0KSkge1xyXG4gICAgICB0aGlzLmV2ZW50c1tvbkFjdGlvbiArICdzdGFydCddID0gcGhhc2VzLm9uc3RhcnQ7XHJcbiAgICB9XHJcbiAgICBpZiAoaXMuZnVuY3Rpb24ocGhhc2VzLm9ubW92ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHNbb25BY3Rpb24gKyAnbW92ZSddID0gcGhhc2VzLm9ubW92ZTtcclxuICAgIH1cclxuICAgIGlmIChpcy5mdW5jdGlvbihwaGFzZXMub25lbmQpKSB7XHJcbiAgICAgIHRoaXMuZXZlbnRzW29uQWN0aW9uICsgJ2VuZCddID0gcGhhc2VzLm9uZW5kO1xyXG4gICAgfVxyXG4gICAgaWYgKGlzLmZ1bmN0aW9uKHBoYXNlcy5vbmluZXJ0aWFzdGFydCkpIHtcclxuICAgICAgdGhpcy5ldmVudHNbb25BY3Rpb24gKyAnaW5lcnRpYXN0YXJ0J10gPSBwaGFzZXMub25pbmVydGlhc3RhcnQ7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zZXRQZXJBY3Rpb24gPSBmdW5jdGlvbiBzZXRQZXJBY3Rpb24oYWN0aW9uLCBvcHRpb25zKSB7XHJcbiAgICAvLyBmb3IgYWxsIHRoZSBkZWZhdWx0IHBlci1hY3Rpb24gb3B0aW9uc1xyXG4gICAgZm9yICh2YXIgb3B0aW9uIGluIG9wdGlvbnMpIHtcclxuICAgICAgLy8gaWYgdGhpcyBvcHRpb24gZXhpc3RzIGZvciB0aGlzIGFjdGlvblxyXG4gICAgICBpZiAob3B0aW9uIGluIGRlZmF1bHRzW2FjdGlvbl0pIHtcclxuICAgICAgICAvLyBpZiB0aGUgb3B0aW9uIGluIHRoZSBvcHRpb25zIGFyZyBpcyBhbiBvYmplY3QgdmFsdWVcclxuICAgICAgICBpZiAoaXMub2JqZWN0KG9wdGlvbnNbb3B0aW9uXSkpIHtcclxuICAgICAgICAgIC8vIGR1cGxpY2F0ZSB0aGUgb2JqZWN0XHJcbiAgICAgICAgICB0aGlzLm9wdGlvbnNbYWN0aW9uXVtvcHRpb25dID0gZXh0ZW5kKHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0gfHwge30sIG9wdGlvbnNbb3B0aW9uXSk7XHJcblxyXG4gICAgICAgICAgaWYgKGlzLm9iamVjdChkZWZhdWx0cy5wZXJBY3Rpb25bb3B0aW9uXSkgJiYgJ2VuYWJsZWQnIGluIGRlZmF1bHRzLnBlckFjdGlvbltvcHRpb25dKSB7XHJcbiAgICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0uZW5hYmxlZCA9IG9wdGlvbnNbb3B0aW9uXS5lbmFibGVkID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGlzLmJvb2wob3B0aW9uc1tvcHRpb25dKSAmJiBpcy5vYmplY3QoZGVmYXVsdHMucGVyQWN0aW9uW29wdGlvbl0pKSB7XHJcbiAgICAgICAgICB0aGlzLm9wdGlvbnNbYWN0aW9uXVtvcHRpb25dLmVuYWJsZWQgPSBvcHRpb25zW29wdGlvbl07XHJcbiAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zW29wdGlvbl0gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgLy8gb3IgaWYgaXQncyBub3QgdW5kZWZpbmVkLCBkbyBhIHBsYWluIGFzc2lnbm1lbnRcclxuICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0gPSBvcHRpb25zW29wdGlvbl07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0YWJsZS5nZXRSZWN0XHJcbiAgIFsgbWV0aG9kIF1cclxuICAgKlxyXG4gICAqIFRoZSBkZWZhdWx0IGZ1bmN0aW9uIHRvIGdldCBhbiBJbnRlcmFjdGFibGVzIGJvdW5kaW5nIHJlY3QuIENhbiBiZVxyXG4gICAqIG92ZXJyaWRkZW4gdXNpbmcgQEludGVyYWN0YWJsZS5yZWN0Q2hlY2tlci5cclxuICAgKlxyXG4gICAtIGVsZW1lbnQgKEVsZW1lbnQpICNvcHRpb25hbCBUaGUgZWxlbWVudCB0byBtZWFzdXJlLlxyXG4gICA9IChvYmplY3QpIFRoZSBvYmplY3QncyBib3VuZGluZyByZWN0YW5nbGUuXHJcbiAgIG8ge1xyXG4gICBvICAgICB0b3AgICA6IDAsXHJcbiAgIG8gICAgIGxlZnQgIDogMCxcclxuICAgbyAgICAgYm90dG9tOiAwLFxyXG4gICBvICAgICByaWdodCA6IDAsXHJcbiAgIG8gICAgIHdpZHRoIDogMCxcclxuICAgbyAgICAgaGVpZ2h0OiAwXHJcbiAgIG8gfVxyXG4gIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuZ2V0UmVjdCA9IGZ1bmN0aW9uIGdldFJlY3QoZWxlbWVudCkge1xyXG4gICAgZWxlbWVudCA9IGVsZW1lbnQgfHwgdGhpcy50YXJnZXQ7XHJcblxyXG4gICAgaWYgKGlzLnN0cmluZyh0aGlzLnRhcmdldCkgJiYgIWlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgICAgZWxlbWVudCA9IHRoaXMuX2NvbnRleHQucXVlcnlTZWxlY3Rvcih0aGlzLnRhcmdldCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGdldEVsZW1lbnRSZWN0KGVsZW1lbnQpO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUucmVjdENoZWNrZXJcclxuICAgWyBtZXRob2QgXVxyXG4gICAqXHJcbiAgICogUmV0dXJucyBvciBzZXRzIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgaW50ZXJhY3RhYmxlJ3NcclxuICAgKiBlbGVtZW50J3MgcmVjdGFuZ2xlXHJcbiAgICpcclxuICAgLSBjaGVja2VyIChmdW5jdGlvbikgI29wdGlvbmFsIEEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyB0aGlzIEludGVyYWN0YWJsZSdzIGJvdW5kaW5nIHJlY3RhbmdsZS4gU2VlIEBJbnRlcmFjdGFibGUuZ2V0UmVjdFxyXG4gICA9IChmdW5jdGlvbiB8IG9iamVjdCkgVGhlIGNoZWNrZXIgZnVuY3Rpb24gb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLnJlY3RDaGVja2VyID0gZnVuY3Rpb24gcmVjdENoZWNrZXIoY2hlY2tlcikge1xyXG4gICAgaWYgKGlzLmZ1bmN0aW9uKGNoZWNrZXIpKSB7XHJcbiAgICAgIHRoaXMuZ2V0UmVjdCA9IGNoZWNrZXI7XHJcblxyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY2hlY2tlciA9PT0gbnVsbCkge1xyXG4gICAgICBkZWxldGUgdGhpcy5vcHRpb25zLmdldFJlY3Q7XHJcblxyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5nZXRSZWN0O1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuX2JhY2tDb21wYXRPcHRpb24gPSBmdW5jdGlvbiBfYmFja0NvbXBhdE9wdGlvbihvcHRpb25OYW1lLCBuZXdWYWx1ZSkge1xyXG4gICAgaWYgKHRyeVNlbGVjdG9yKG5ld1ZhbHVlKSB8fCBpcy5vYmplY3QobmV3VmFsdWUpKSB7XHJcbiAgICAgIHRoaXMub3B0aW9uc1tvcHRpb25OYW1lXSA9IG5ld1ZhbHVlO1xyXG5cclxuICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gYWN0aW9ucy5uYW1lcywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgICB2YXIgX3JlZjtcclxuXHJcbiAgICAgICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgICBfcmVmID0gX2l0ZXJhdG9yW19pKytdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgICBfcmVmID0gX2kudmFsdWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgYWN0aW9uID0gX3JlZjtcclxuXHJcbiAgICAgICAgdGhpcy5vcHRpb25zW2FjdGlvbl1bb3B0aW9uTmFtZV0gPSBuZXdWYWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMub3B0aW9uc1tvcHRpb25OYW1lXTtcclxuICB9O1xyXG5cclxuICAvKlxcXHJcbiAgICogSW50ZXJhY3RhYmxlLm9yaWdpblxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBHZXRzIG9yIHNldHMgdGhlIG9yaWdpbiBvZiB0aGUgSW50ZXJhY3RhYmxlJ3MgZWxlbWVudC4gIFRoZSB4IGFuZCB5XHJcbiAgICogb2YgdGhlIG9yaWdpbiB3aWxsIGJlIHN1YnRyYWN0ZWQgZnJvbSBhY3Rpb24gZXZlbnQgY29vcmRpbmF0ZXMuXHJcbiAgICpcclxuICAgLSBvcmlnaW4gKG9iamVjdCB8IHN0cmluZykgI29wdGlvbmFsIEFuIG9iamVjdCBlZy4geyB4OiAwLCB5OiAwIH0gb3Igc3RyaW5nICdwYXJlbnQnLCAnc2VsZicgb3IgYW55IENTUyBzZWxlY3RvclxyXG4gICAqIE9SXHJcbiAgIC0gb3JpZ2luIChFbGVtZW50KSAjb3B0aW9uYWwgQW4gSFRNTCBvciBTVkcgRWxlbWVudCB3aG9zZSByZWN0IHdpbGwgYmUgdXNlZFxyXG4gICAqKlxyXG4gICA9IChvYmplY3QpIFRoZSBjdXJyZW50IG9yaWdpbiBvciB0aGlzIEludGVyYWN0YWJsZVxyXG4gIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUub3JpZ2luID0gZnVuY3Rpb24gb3JpZ2luKG5ld1ZhbHVlKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fYmFja0NvbXBhdE9wdGlvbignb3JpZ2luJywgbmV3VmFsdWUpO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUuZGVsdGFTb3VyY2VcclxuICAgWyBtZXRob2QgXVxyXG4gICAqXHJcbiAgICogUmV0dXJucyBvciBzZXRzIHRoZSBtb3VzZSBjb29yZGluYXRlIHR5cGVzIHVzZWQgdG8gY2FsY3VsYXRlIHRoZVxyXG4gICAqIG1vdmVtZW50IG9mIHRoZSBwb2ludGVyLlxyXG4gICAqXHJcbiAgIC0gbmV3VmFsdWUgKHN0cmluZykgI29wdGlvbmFsIFVzZSAnY2xpZW50JyBpZiB5b3Ugd2lsbCBiZSBzY3JvbGxpbmcgd2hpbGUgaW50ZXJhY3Rpbmc7IFVzZSAncGFnZScgaWYgeW91IHdhbnQgYXV0b1Njcm9sbCB0byB3b3JrXHJcbiAgID0gKHN0cmluZyB8IG9iamVjdCkgVGhlIGN1cnJlbnQgZGVsdGFTb3VyY2Ugb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLmRlbHRhU291cmNlID0gZnVuY3Rpb24gZGVsdGFTb3VyY2UobmV3VmFsdWUpIHtcclxuICAgIGlmIChuZXdWYWx1ZSA9PT0gJ3BhZ2UnIHx8IG5ld1ZhbHVlID09PSAnY2xpZW50Jykge1xyXG4gICAgICB0aGlzLm9wdGlvbnMuZGVsdGFTb3VyY2UgPSBuZXdWYWx1ZTtcclxuXHJcbiAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZGVsdGFTb3VyY2U7XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0YWJsZS5jb250ZXh0XHJcbiAgIFsgbWV0aG9kIF1cclxuICAgKlxyXG4gICAqIEdldHMgdGhlIHNlbGVjdG9yIGNvbnRleHQgTm9kZSBvZiB0aGUgSW50ZXJhY3RhYmxlLiBUaGUgZGVmYXVsdCBpcyBgd2luZG93LmRvY3VtZW50YC5cclxuICAgKlxyXG4gICA9IChOb2RlKSBUaGUgY29udGV4dCBOb2RlIG9mIHRoaXMgSW50ZXJhY3RhYmxlXHJcbiAgICoqXHJcbiAgXFwqL1xyXG5cclxuXHJcbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5jb250ZXh0ID0gZnVuY3Rpb24gY29udGV4dCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9jb250ZXh0O1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuaW5Db250ZXh0ID0gZnVuY3Rpb24gaW5Db250ZXh0KGVsZW1lbnQpIHtcclxuICAgIHJldHVybiB0aGlzLl9jb250ZXh0ID09PSBlbGVtZW50Lm93bmVyRG9jdW1lbnQgfHwgbm9kZUNvbnRhaW5zKHRoaXMuX2NvbnRleHQsIGVsZW1lbnQpO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUuZmlyZVxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBDYWxscyBsaXN0ZW5lcnMgZm9yIHRoZSBnaXZlbiBJbnRlcmFjdEV2ZW50IHR5cGUgYm91bmQgZ2xvYmFsbHlcclxuICAgKiBhbmQgZGlyZWN0bHkgdG8gdGhpcyBJbnRlcmFjdGFibGVcclxuICAgKlxyXG4gICAtIGlFdmVudCAoSW50ZXJhY3RFdmVudCkgVGhlIEludGVyYWN0RXZlbnQgb2JqZWN0IHRvIGJlIGZpcmVkIG9uIHRoaXMgSW50ZXJhY3RhYmxlXHJcbiAgID0gKEludGVyYWN0YWJsZSkgdGhpcyBJbnRlcmFjdGFibGVcclxuICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLmZpcmUgPSBmdW5jdGlvbiBmaXJlKGlFdmVudCkge1xyXG4gICAgdGhpcy5ldmVudHMuZmlyZShpRXZlbnQpO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuX29uT2ZmTXVsdGlwbGUgPSBmdW5jdGlvbiBfb25PZmZNdWx0aXBsZShtZXRob2QsIGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcclxuICAgIGlmIChpcy5zdHJpbmcoZXZlbnRUeXBlKSAmJiBldmVudFR5cGUuc2VhcmNoKCcgJykgIT09IC0xKSB7XHJcbiAgICAgIGV2ZW50VHlwZSA9IGV2ZW50VHlwZS50cmltKCkuc3BsaXQoLyArLyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzLmFycmF5KGV2ZW50VHlwZSkpIHtcclxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldmVudFR5cGUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB0aGlzW21ldGhvZF0oZXZlbnRUeXBlW2ldLCBsaXN0ZW5lciwgb3B0aW9ucyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpcy5vYmplY3QoZXZlbnRUeXBlKSkge1xyXG4gICAgICBmb3IgKHZhciBwcm9wIGluIGV2ZW50VHlwZSkge1xyXG4gICAgICAgIHRoaXNbbWV0aG9kXShwcm9wLCBldmVudFR5cGVbcHJvcF0sIGxpc3RlbmVyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0YWJsZS5vblxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBCaW5kcyBhIGxpc3RlbmVyIGZvciBhbiBJbnRlcmFjdEV2ZW50LCBwb2ludGVyRXZlbnQgb3IgRE9NIGV2ZW50LlxyXG4gICAqXHJcbiAgIC0gZXZlbnRUeXBlICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdG8gbGlzdGVuIGZvclxyXG4gICAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgZnVuY3Rpb24gZXZlbnQgKHMpXHJcbiAgIC0gb3B0aW9ucyAgICAob2JqZWN0IHwgYm9vbGVhbikgI29wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IG9yIHVzZUNhcHR1cmUgZmxhZyBmb3IgYWRkRXZlbnRMaXN0ZW5lclxyXG4gICA9IChvYmplY3QpIFRoaXMgSW50ZXJhY3RhYmxlXHJcbiAgXFwqL1xyXG5cclxuXHJcbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcclxuICAgIGlmICh0aGlzLl9vbk9mZk11bHRpcGxlKCdvbicsIGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpKSB7XHJcbiAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChldmVudFR5cGUgPT09ICd3aGVlbCcpIHtcclxuICAgICAgZXZlbnRUeXBlID0gd2hlZWxFdmVudDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29udGFpbnMoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIGV2ZW50VHlwZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub24oZXZlbnRUeXBlLCBsaXN0ZW5lcik7XHJcbiAgICB9XHJcbiAgICAvLyBkZWxlZ2F0ZWQgZXZlbnQgZm9yIHNlbGVjdG9yXHJcbiAgICBlbHNlIGlmIChpcy5zdHJpbmcodGhpcy50YXJnZXQpKSB7XHJcbiAgICAgICAgZXZlbnRzLmFkZERlbGVnYXRlKHRoaXMudGFyZ2V0LCB0aGlzLl9jb250ZXh0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBldmVudHMuYWRkKHRoaXMudGFyZ2V0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcclxuICAgICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUub2ZmXHJcbiAgIFsgbWV0aG9kIF1cclxuICAgKlxyXG4gICAqIFJlbW92ZXMgYW4gSW50ZXJhY3RFdmVudCwgcG9pbnRlckV2ZW50IG9yIERPTSBldmVudCBsaXN0ZW5lclxyXG4gICAqXHJcbiAgIC0gZXZlbnRUeXBlICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdGhhdCB3ZXJlIGxpc3RlbmVkIGZvclxyXG4gICAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgbGlzdGVuZXIgZnVuY3Rpb24gdG8gYmUgcmVtb3ZlZFxyXG4gICAtIG9wdGlvbnMgICAgKG9iamVjdCB8IGJvb2xlYW4pICNvcHRpb25hbCBvcHRpb25zIG9iamVjdCBvciB1c2VDYXB0dXJlIGZsYWcgZm9yIHJlbW92ZUV2ZW50TGlzdGVuZXJcclxuICAgPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxyXG4gIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24gb2ZmKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcclxuICAgIGlmICh0aGlzLl9vbk9mZk11bHRpcGxlKCdvZmYnLCBldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSkge1xyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZXZlbnRUeXBlID09PSAnd2hlZWwnKSB7XHJcbiAgICAgIGV2ZW50VHlwZSA9IHdoZWVsRXZlbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaWYgaXQgaXMgYW4gYWN0aW9uIGV2ZW50IHR5cGVcclxuICAgIGlmIChjb250YWlucyhJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgZXZlbnRUeXBlKSkge1xyXG4gICAgICB0aGlzLmV2ZW50cy5vZmYoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XHJcbiAgICB9XHJcbiAgICAvLyBkZWxlZ2F0ZWQgZXZlbnRcclxuICAgIGVsc2UgaWYgKGlzLnN0cmluZyh0aGlzLnRhcmdldCkpIHtcclxuICAgICAgICBldmVudHMucmVtb3ZlRGVsZWdhdGUodGhpcy50YXJnZXQsIHRoaXMuX2NvbnRleHQsIGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xyXG4gICAgICB9XHJcbiAgICAgIC8vIHJlbW92ZSBsaXN0ZW5lciBmcm9tIHRoaXMgSW50ZXJhdGFibGUncyBlbGVtZW50XHJcbiAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgZXZlbnRzLnJlbW92ZSh0aGlzLnRhcmdldCwgZXZlbnRUeXBlLCBsaXN0ZW5lciwgb3B0aW9ucyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUuc2V0XHJcbiAgIFsgbWV0aG9kIF1cclxuICAgKlxyXG4gICAqIFJlc2V0IHRoZSBvcHRpb25zIG9mIHRoaXMgSW50ZXJhY3RhYmxlXHJcbiAgIC0gb3B0aW9ucyAob2JqZWN0KSBUaGUgbmV3IHNldHRpbmdzIHRvIGFwcGx5XHJcbiAgID0gKG9iamVjdCkgVGhpcyBJbnRlcmFjdGFibGVcclxuICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIHNldChvcHRpb25zKSB7XHJcbiAgICBpZiAoIWlzLm9iamVjdChvcHRpb25zKSkge1xyXG4gICAgICBvcHRpb25zID0ge307XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5vcHRpb25zID0gZXh0ZW5kKHt9LCBkZWZhdWx0cy5iYXNlKTtcclxuXHJcbiAgICB2YXIgcGVyQWN0aW9ucyA9IGV4dGVuZCh7fSwgZGVmYXVsdHMucGVyQWN0aW9uKTtcclxuXHJcbiAgICBmb3IgKHZhciBhY3Rpb25OYW1lIGluIGFjdGlvbnMubWV0aG9kRGljdCkge1xyXG4gICAgICB2YXIgbWV0aG9kTmFtZSA9IGFjdGlvbnMubWV0aG9kRGljdFthY3Rpb25OYW1lXTtcclxuXHJcbiAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25OYW1lXSA9IGV4dGVuZCh7fSwgZGVmYXVsdHNbYWN0aW9uTmFtZV0pO1xyXG5cclxuICAgICAgdGhpcy5zZXRQZXJBY3Rpb24oYWN0aW9uTmFtZSwgcGVyQWN0aW9ucyk7XHJcblxyXG4gICAgICB0aGlzW21ldGhvZE5hbWVdKG9wdGlvbnNbYWN0aW9uTmFtZV0pO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAodmFyIF9pdGVyYXRvcjIgPSBJbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWYyO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5Mikge1xyXG4gICAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yMi5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yMltfaTIrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kyID0gX2l0ZXJhdG9yMi5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmMiA9IF9pMi52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHNldHRpbmcgPSBfcmVmMjtcclxuXHJcbiAgICAgIHRoaXMub3B0aW9uc1tzZXR0aW5nXSA9IGRlZmF1bHRzLmJhc2Vbc2V0dGluZ107XHJcblxyXG4gICAgICBpZiAoc2V0dGluZyBpbiBvcHRpb25zKSB7XHJcbiAgICAgICAgdGhpc1tzZXR0aW5nXShvcHRpb25zW3NldHRpbmddKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHNpZ25hbHMuZmlyZSgnc2V0Jywge1xyXG4gICAgICBvcHRpb25zOiBvcHRpb25zLFxyXG4gICAgICBpbnRlcmFjdGFibGU6IHRoaXNcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qXFxcclxuICAgKiBJbnRlcmFjdGFibGUudW5zZXRcclxuICAgWyBtZXRob2QgXVxyXG4gICAqXHJcbiAgICogUmVtb3ZlIHRoaXMgaW50ZXJhY3RhYmxlIGZyb20gdGhlIGxpc3Qgb2YgaW50ZXJhY3RhYmxlcyBhbmQgcmVtb3ZlXHJcbiAgICogaXQncyBhY3Rpb24gY2FwYWJpbGl0aWVzIGFuZCBldmVudCBsaXN0ZW5lcnNcclxuICAgKlxyXG4gICA9IChvYmplY3QpIEBpbnRlcmFjdFxyXG4gIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUudW5zZXQgPSBmdW5jdGlvbiB1bnNldCgpIHtcclxuICAgIGV2ZW50cy5yZW1vdmUodGhpcy50YXJnZXQsICdhbGwnKTtcclxuXHJcbiAgICBpZiAoaXMuc3RyaW5nKHRoaXMudGFyZ2V0KSkge1xyXG4gICAgICAvLyByZW1vdmUgZGVsZWdhdGVkIGV2ZW50c1xyXG4gICAgICBmb3IgKHZhciB0eXBlIGluIGV2ZW50cy5kZWxlZ2F0ZWRFdmVudHMpIHtcclxuICAgICAgICB2YXIgZGVsZWdhdGVkID0gZXZlbnRzLmRlbGVnYXRlZEV2ZW50c1t0eXBlXTtcclxuXHJcbiAgICAgICAgaWYgKGRlbGVnYXRlZC5zZWxlY3RvcnNbMF0gPT09IHRoaXMudGFyZ2V0ICYmIGRlbGVnYXRlZC5jb250ZXh0c1swXSA9PT0gdGhpcy5fY29udGV4dCkge1xyXG5cclxuICAgICAgICAgIGRlbGVnYXRlZC5zZWxlY3RvcnMuc3BsaWNlKDAsIDEpO1xyXG4gICAgICAgICAgZGVsZWdhdGVkLmNvbnRleHRzLnNwbGljZSgwLCAxKTtcclxuICAgICAgICAgIGRlbGVnYXRlZC5saXN0ZW5lcnMuc3BsaWNlKDAsIDEpO1xyXG5cclxuICAgICAgICAgIC8vIHJlbW92ZSB0aGUgYXJyYXlzIGlmIHRoZXkgYXJlIGVtcHR5XHJcbiAgICAgICAgICBpZiAoIWRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGRlbGVnYXRlZFt0eXBlXSA9IG51bGw7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBldmVudHMucmVtb3ZlKHRoaXMuX2NvbnRleHQsIHR5cGUsIGV2ZW50cy5kZWxlZ2F0ZUxpc3RlbmVyKTtcclxuICAgICAgICBldmVudHMucmVtb3ZlKHRoaXMuX2NvbnRleHQsIHR5cGUsIGV2ZW50cy5kZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBldmVudHMucmVtb3ZlKHRoaXMsICdhbGwnKTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ3Vuc2V0JywgeyBpbnRlcmFjdGFibGU6IHRoaXMgfSk7XHJcblxyXG4gICAgc2NvcGUuaW50ZXJhY3RhYmxlcy5zcGxpY2UoaW5kZXhPZihzY29wZS5pbnRlcmFjdGFibGVzLCB0aGlzKSwgMSk7XHJcblxyXG4gICAgLy8gU3RvcCByZWxhdGVkIGludGVyYWN0aW9ucyB3aGVuIGFuIEludGVyYWN0YWJsZSBpcyB1bnNldFxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yMyA9IHNjb3BlLmludGVyYWN0aW9ucyB8fCBbXSwgX2lzQXJyYXkzID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IzKSwgX2kzID0gMCwgX2l0ZXJhdG9yMyA9IF9pc0FycmF5MyA/IF9pdGVyYXRvcjMgOiBfaXRlcmF0b3IzW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmMztcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheTMpIHtcclxuICAgICAgICBpZiAoX2kzID49IF9pdGVyYXRvcjMubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmMyA9IF9pdGVyYXRvcjNbX2kzKytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pMyA9IF9pdGVyYXRvcjMubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaTMuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjMgPSBfaTMudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzO1xyXG5cclxuICAgICAgaWYgKGludGVyYWN0aW9uLnRhcmdldCA9PT0gdGhpcyAmJiBpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpKSB7XHJcbiAgICAgICAgaW50ZXJhY3Rpb24uc3RvcCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHNjb3BlLmludGVyYWN0O1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBJbnRlcmFjdGFibGU7XHJcbn0oKTtcclxuXHJcbnNjb3BlLmludGVyYWN0YWJsZXMuaW5kZXhPZkVsZW1lbnQgPSBmdW5jdGlvbiBpbmRleE9mRWxlbWVudCh0YXJnZXQsIGNvbnRleHQpIHtcclxuICBjb250ZXh0ID0gY29udGV4dCB8fCBzY29wZS5kb2N1bWVudDtcclxuXHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgaW50ZXJhY3RhYmxlID0gdGhpc1tpXTtcclxuXHJcbiAgICBpZiAoaW50ZXJhY3RhYmxlLnRhcmdldCA9PT0gdGFyZ2V0ICYmIGludGVyYWN0YWJsZS5fY29udGV4dCA9PT0gY29udGV4dCkge1xyXG4gICAgICByZXR1cm4gaTtcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIC0xO1xyXG59O1xyXG5cclxuc2NvcGUuaW50ZXJhY3RhYmxlcy5nZXQgPSBmdW5jdGlvbiBpbnRlcmFjdGFibGVHZXQoZWxlbWVudCwgb3B0aW9ucywgZG9udENoZWNrSW5Db250ZXh0KSB7XHJcbiAgdmFyIHJldCA9IHRoaXNbdGhpcy5pbmRleE9mRWxlbWVudChlbGVtZW50LCBvcHRpb25zICYmIG9wdGlvbnMuY29udGV4dCldO1xyXG5cclxuICByZXR1cm4gcmV0ICYmIChpcy5zdHJpbmcoZWxlbWVudCkgfHwgZG9udENoZWNrSW5Db250ZXh0IHx8IHJldC5pbkNvbnRleHQoZWxlbWVudCkpID8gcmV0IDogbnVsbDtcclxufTtcclxuXHJcbnNjb3BlLmludGVyYWN0YWJsZXMuZm9yRWFjaFNlbGVjdG9yID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBlbGVtZW50KSB7XHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgaW50ZXJhY3RhYmxlID0gdGhpc1tpXTtcclxuXHJcbiAgICAvLyBza2lwIG5vbiBDU1Mgc2VsZWN0b3IgdGFyZ2V0cyBhbmQgb3V0IG9mIGNvbnRleHQgZWxlbWVudHNcclxuICAgIGlmICghaXMuc3RyaW5nKGludGVyYWN0YWJsZS50YXJnZXQpIHx8IGVsZW1lbnQgJiYgIWludGVyYWN0YWJsZS5pbkNvbnRleHQoZWxlbWVudCkpIHtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHJldCA9IGNhbGxiYWNrKGludGVyYWN0YWJsZSwgaW50ZXJhY3RhYmxlLnRhcmdldCwgaW50ZXJhY3RhYmxlLl9jb250ZXh0LCBpLCB0aGlzKTtcclxuXHJcbiAgICBpZiAocmV0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgcmV0dXJuIHJldDtcclxuICAgIH1cclxuICB9XHJcbn07XHJcblxyXG4vLyBhbGwgaW50ZXJhY3QuanMgZXZlbnRUeXBlc1xyXG5JbnRlcmFjdGFibGUuZXZlbnRUeXBlcyA9IHNjb3BlLmV2ZW50VHlwZXMgPSBbXTtcclxuXHJcbkludGVyYWN0YWJsZS5zaWduYWxzID0gc2lnbmFscztcclxuXHJcbkludGVyYWN0YWJsZS5zZXR0aW5nc01ldGhvZHMgPSBbJ2RlbHRhU291cmNlJywgJ29yaWdpbicsICdwcmV2ZW50RGVmYXVsdCcsICdyZWN0Q2hlY2tlciddO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBJbnRlcmFjdGFibGU7XHJcblxyXG59LHtcIi4vRXZlbnRhYmxlXCI6MixcIi4vYWN0aW9ucy9iYXNlXCI6NixcIi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4vc2NvcGVcIjozNCxcIi4vdXRpbHMvU2lnbmFsc1wiOjM1LFwiLi91dGlscy9hcnJcIjozNixcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9kb21VdGlsc1wiOjM5LFwiLi91dGlscy9ldmVudHNcIjo0MCxcIi4vdXRpbHMvZXh0ZW5kXCI6NDEsXCIuL3V0aWxzL2lzXCI6NDYsXCIuL3V0aWxzL3dpbmRvd1wiOjUyfV0sNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XHJcblxyXG52YXIgc2NvcGUgPSByZXF1aXJlKCcuL3Njb3BlJyk7XHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcclxudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vdXRpbHMvZXZlbnRzJyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi91dGlscy9icm93c2VyJyk7XHJcbnZhciBkb21PYmplY3RzID0gcmVxdWlyZSgnLi91dGlscy9kb21PYmplY3RzJyk7XHJcbnZhciBmaW5kZXIgPSByZXF1aXJlKCcuL3V0aWxzL2ludGVyYWN0aW9uRmluZGVyJyk7XHJcbnZhciBzaWduYWxzID0gcmVxdWlyZSgnLi91dGlscy9TaWduYWxzJykubmV3KCk7XHJcblxyXG52YXIgbGlzdGVuZXJzID0ge307XHJcbnZhciBtZXRob2ROYW1lcyA9IFsncG9pbnRlckRvd24nLCAncG9pbnRlck1vdmUnLCAncG9pbnRlclVwJywgJ3VwZGF0ZVBvaW50ZXInLCAncmVtb3ZlUG9pbnRlciddO1xyXG5cclxuLy8gZm9yIGlnbm9yaW5nIGJyb3dzZXIncyBzaW11bGF0ZWQgbW91c2UgZXZlbnRzXHJcbnZhciBwcmV2VG91Y2hUaW1lID0gMDtcclxuXHJcbi8vIGFsbCBhY3RpdmUgYW5kIGlkbGUgaW50ZXJhY3Rpb25zXHJcbnNjb3BlLmludGVyYWN0aW9ucyA9IFtdO1xyXG5cclxudmFyIEludGVyYWN0aW9uID0gZnVuY3Rpb24gKCkge1xyXG4gIGZ1bmN0aW9uIEludGVyYWN0aW9uKF9yZWYpIHtcclxuICAgIHZhciBwb2ludGVyVHlwZSA9IF9yZWYucG9pbnRlclR5cGU7XHJcblxyXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEludGVyYWN0aW9uKTtcclxuXHJcbiAgICB0aGlzLnRhcmdldCA9IG51bGw7IC8vIGN1cnJlbnQgaW50ZXJhY3RhYmxlIGJlaW5nIGludGVyYWN0ZWQgd2l0aFxyXG4gICAgdGhpcy5lbGVtZW50ID0gbnVsbDsgLy8gdGhlIHRhcmdldCBlbGVtZW50IG9mIHRoZSBpbnRlcmFjdGFibGVcclxuXHJcbiAgICB0aGlzLnByZXBhcmVkID0geyAvLyBhY3Rpb24gdGhhdCdzIHJlYWR5IHRvIGJlIGZpcmVkIG9uIG5leHQgbW92ZSBldmVudFxyXG4gICAgICBuYW1lOiBudWxsLFxyXG4gICAgICBheGlzOiBudWxsLFxyXG4gICAgICBlZGdlczogbnVsbFxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBrZWVwIHRyYWNrIG9mIGFkZGVkIHBvaW50ZXJzXHJcbiAgICB0aGlzLnBvaW50ZXJzID0gW107XHJcbiAgICB0aGlzLnBvaW50ZXJJZHMgPSBbXTtcclxuICAgIHRoaXMuZG93blRhcmdldHMgPSBbXTtcclxuICAgIHRoaXMuZG93blRpbWVzID0gW107XHJcblxyXG4gICAgLy8gUHJldmlvdXMgbmF0aXZlIHBvaW50ZXIgbW92ZSBldmVudCBjb29yZGluYXRlc1xyXG4gICAgdGhpcy5wcmV2Q29vcmRzID0ge1xyXG4gICAgICBwYWdlOiB7IHg6IDAsIHk6IDAgfSxcclxuICAgICAgY2xpZW50OiB7IHg6IDAsIHk6IDAgfSxcclxuICAgICAgdGltZVN0YW1wOiAwXHJcbiAgICB9O1xyXG4gICAgLy8gY3VycmVudCBuYXRpdmUgcG9pbnRlciBtb3ZlIGV2ZW50IGNvb3JkaW5hdGVzXHJcbiAgICB0aGlzLmN1ckNvb3JkcyA9IHtcclxuICAgICAgcGFnZTogeyB4OiAwLCB5OiAwIH0sXHJcbiAgICAgIGNsaWVudDogeyB4OiAwLCB5OiAwIH0sXHJcbiAgICAgIHRpbWVTdGFtcDogMFxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBTdGFydGluZyBJbnRlcmFjdEV2ZW50IHBvaW50ZXIgY29vcmRpbmF0ZXNcclxuICAgIHRoaXMuc3RhcnRDb29yZHMgPSB7XHJcbiAgICAgIHBhZ2U6IHsgeDogMCwgeTogMCB9LFxyXG4gICAgICBjbGllbnQ6IHsgeDogMCwgeTogMCB9LFxyXG4gICAgICB0aW1lU3RhbXA6IDBcclxuICAgIH07XHJcblxyXG4gICAgLy8gQ2hhbmdlIGluIGNvb3JkaW5hdGVzIGFuZCB0aW1lIG9mIHRoZSBwb2ludGVyXHJcbiAgICB0aGlzLnBvaW50ZXJEZWx0YSA9IHtcclxuICAgICAgcGFnZTogeyB4OiAwLCB5OiAwLCB2eDogMCwgdnk6IDAsIHNwZWVkOiAwIH0sXHJcbiAgICAgIGNsaWVudDogeyB4OiAwLCB5OiAwLCB2eDogMCwgdnk6IDAsIHNwZWVkOiAwIH0sXHJcbiAgICAgIHRpbWVTdGFtcDogMFxyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmRvd25FdmVudCA9IG51bGw7IC8vIHBvaW50ZXJkb3duL21vdXNlZG93bi90b3VjaHN0YXJ0IGV2ZW50XHJcbiAgICB0aGlzLmRvd25Qb2ludGVyID0ge307XHJcblxyXG4gICAgdGhpcy5fZXZlbnRUYXJnZXQgPSBudWxsO1xyXG4gICAgdGhpcy5fY3VyRXZlbnRUYXJnZXQgPSBudWxsO1xyXG5cclxuICAgIHRoaXMucHJldkV2ZW50ID0gbnVsbDsgLy8gcHJldmlvdXMgYWN0aW9uIGV2ZW50XHJcblxyXG4gICAgdGhpcy5wb2ludGVySXNEb3duID0gZmFsc2U7XHJcbiAgICB0aGlzLnBvaW50ZXJXYXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgdGhpcy5faW50ZXJhY3RpbmcgPSBmYWxzZTtcclxuXHJcbiAgICB0aGlzLnBvaW50ZXJUeXBlID0gcG9pbnRlclR5cGU7XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCduZXcnLCB0aGlzKTtcclxuXHJcbiAgICBzY29wZS5pbnRlcmFjdGlvbnMucHVzaCh0aGlzKTtcclxuICB9XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5wb2ludGVyRG93biA9IGZ1bmN0aW9uIHBvaW50ZXJEb3duKHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCkge1xyXG4gICAgdmFyIHBvaW50ZXJJbmRleCA9IHRoaXMudXBkYXRlUG9pbnRlcihwb2ludGVyLCBldmVudCwgdHJ1ZSk7XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdkb3duJywge1xyXG4gICAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgICBldmVudDogZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcclxuICAgICAgcG9pbnRlckluZGV4OiBwb2ludGVySW5kZXgsXHJcbiAgICAgIGludGVyYWN0aW9uOiB0aGlzXHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAvKlxcXHJcbiAgICogSW50ZXJhY3Rpb24uc3RhcnRcclxuICAgWyBtZXRob2QgXVxyXG4gICAqXHJcbiAgICogU3RhcnQgYW4gYWN0aW9uIHdpdGggdGhlIGdpdmVuIEludGVyYWN0YWJsZSBhbmQgRWxlbWVudCBhcyB0YXJ0Z2V0cy4gVGhlXHJcbiAgICogYWN0aW9uIG11c3QgYmUgZW5hYmxlZCBmb3IgdGhlIHRhcmdldCBJbnRlcmFjdGFibGUgYW5kIGFuIGFwcHJvcHJpYXRlIG51bWJlclxyXG4gICAqIG9mIHBvaW50ZXJzIG11c3QgYmUgaGVsZCBkb3duIC0gMSBmb3IgZHJhZy9yZXNpemUsIDIgZm9yIGdlc3R1cmUuXHJcbiAgICpcclxuICAgKiBVc2UgaXQgd2l0aCBgaW50ZXJhY3RhYmxlLjxhY3Rpb24+YWJsZSh7IG1hbnVhbFN0YXJ0OiBmYWxzZSB9KWAgdG8gYWx3YXlzXHJcbiAgICogW3N0YXJ0IGFjdGlvbnMgbWFudWFsbHldKGh0dHBzOi8vZ2l0aHViLmNvbS90YXllL2ludGVyYWN0LmpzL2lzc3Vlcy8xMTQpXHJcbiAgICpcclxuICAgLSBhY3Rpb24gIChvYmplY3QpICBUaGUgYWN0aW9uIHRvIGJlIHBlcmZvcm1lZCAtIGRyYWcsIHJlc2l6ZSwgZXRjLlxyXG4gICAtIHRhcmdldCAgKEludGVyYWN0YWJsZSkgVGhlIEludGVyYWN0YWJsZSB0byB0YXJnZXRcclxuICAgLSBlbGVtZW50IChFbGVtZW50KSBUaGUgRE9NIEVsZW1lbnQgdG8gdGFyZ2V0XHJcbiAgID0gKG9iamVjdCkgaW50ZXJhY3RcclxuICAgKipcclxuICAgfCBpbnRlcmFjdCh0YXJnZXQpXHJcbiAgIHwgICAuZHJhZ2dhYmxlKHtcclxuICAgfCAgICAgLy8gZGlzYWJsZSB0aGUgZGVmYXVsdCBkcmFnIHN0YXJ0IGJ5IGRvd24tPm1vdmVcclxuICAgfCAgICAgbWFudWFsU3RhcnQ6IHRydWVcclxuICAgfCAgIH0pXHJcbiAgIHwgICAvLyBzdGFydCBkcmFnZ2luZyBhZnRlciB0aGUgdXNlciBob2xkcyB0aGUgcG9pbnRlciBkb3duXHJcbiAgIHwgICAub24oJ2hvbGQnLCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgfCAgICAgdmFyIGludGVyYWN0aW9uID0gZXZlbnQuaW50ZXJhY3Rpb247XHJcbiAgIHxcclxuICAgfCAgICAgaWYgKCFpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpKSB7XHJcbiAgIHwgICAgICAgaW50ZXJhY3Rpb24uc3RhcnQoeyBuYW1lOiAnZHJhZycgfSxcclxuICAgfCAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5pbnRlcmFjdGFibGUsXHJcbiAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuY3VycmVudFRhcmdldCk7XHJcbiAgIHwgICAgIH1cclxuICAgfCB9KTtcclxuICAgXFwqL1xyXG5cclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gc3RhcnQoYWN0aW9uLCB0YXJnZXQsIGVsZW1lbnQpIHtcclxuICAgIGlmICh0aGlzLmludGVyYWN0aW5nKCkgfHwgIXRoaXMucG9pbnRlcklzRG93biB8fCB0aGlzLnBvaW50ZXJJZHMubGVuZ3RoIDwgKGFjdGlvbi5uYW1lID09PSAnZ2VzdHVyZScgPyAyIDogMSkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGlmIHRoaXMgaW50ZXJhY3Rpb24gaGFkIGJlZW4gcmVtb3ZlZCBhZnRlciBzdG9wcGluZ1xyXG4gICAgLy8gYWRkIGl0IGJhY2tcclxuICAgIGlmICh1dGlscy5pbmRleE9mKHNjb3BlLmludGVyYWN0aW9ucywgdGhpcykgPT09IC0xKSB7XHJcbiAgICAgIHNjb3BlLmludGVyYWN0aW9ucy5wdXNoKHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHV0aWxzLmNvcHlBY3Rpb24odGhpcy5wcmVwYXJlZCwgYWN0aW9uKTtcclxuICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xyXG4gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ2FjdGlvbi1zdGFydCcsIHtcclxuICAgICAgaW50ZXJhY3Rpb246IHRoaXMsXHJcbiAgICAgIGV2ZW50OiB0aGlzLmRvd25FdmVudFxyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnBvaW50ZXJNb3ZlID0gZnVuY3Rpb24gcG9pbnRlck1vdmUocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0KSB7XHJcbiAgICBpZiAoIXRoaXMuc2ltdWxhdGlvbikge1xyXG4gICAgICB0aGlzLnVwZGF0ZVBvaW50ZXIocG9pbnRlcik7XHJcbiAgICAgIHV0aWxzLnNldENvb3Jkcyh0aGlzLmN1ckNvb3JkcywgdGhpcy5wb2ludGVycyk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGR1cGxpY2F0ZU1vdmUgPSB0aGlzLmN1ckNvb3Jkcy5wYWdlLnggPT09IHRoaXMucHJldkNvb3Jkcy5wYWdlLnggJiYgdGhpcy5jdXJDb29yZHMucGFnZS55ID09PSB0aGlzLnByZXZDb29yZHMucGFnZS55ICYmIHRoaXMuY3VyQ29vcmRzLmNsaWVudC54ID09PSB0aGlzLnByZXZDb29yZHMuY2xpZW50LnggJiYgdGhpcy5jdXJDb29yZHMuY2xpZW50LnkgPT09IHRoaXMucHJldkNvb3Jkcy5jbGllbnQueTtcclxuXHJcbiAgICB2YXIgZHggPSB2b2lkIDA7XHJcbiAgICB2YXIgZHkgPSB2b2lkIDA7XHJcblxyXG4gICAgLy8gcmVnaXN0ZXIgbW92ZW1lbnQgZ3JlYXRlciB0aGFuIHBvaW50ZXJNb3ZlVG9sZXJhbmNlXHJcbiAgICBpZiAodGhpcy5wb2ludGVySXNEb3duICYmICF0aGlzLnBvaW50ZXJXYXNNb3ZlZCkge1xyXG4gICAgICBkeCA9IHRoaXMuY3VyQ29vcmRzLmNsaWVudC54IC0gdGhpcy5zdGFydENvb3Jkcy5jbGllbnQueDtcclxuICAgICAgZHkgPSB0aGlzLmN1ckNvb3Jkcy5jbGllbnQueSAtIHRoaXMuc3RhcnRDb29yZHMuY2xpZW50Lnk7XHJcblxyXG4gICAgICB0aGlzLnBvaW50ZXJXYXNNb3ZlZCA9IHV0aWxzLmh5cG90KGR4LCBkeSkgPiBJbnRlcmFjdGlvbi5wb2ludGVyTW92ZVRvbGVyYW5jZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgc2lnbmFsQXJnID0ge1xyXG4gICAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgICBwb2ludGVySW5kZXg6IHRoaXMuZ2V0UG9pbnRlckluZGV4KHBvaW50ZXIpLFxyXG4gICAgICBldmVudDogZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcclxuICAgICAgZHg6IGR4LFxyXG4gICAgICBkeTogZHksXHJcbiAgICAgIGR1cGxpY2F0ZTogZHVwbGljYXRlTW92ZSxcclxuICAgICAgaW50ZXJhY3Rpb246IHRoaXMsXHJcbiAgICAgIGludGVyYWN0aW5nQmVmb3JlTW92ZTogdGhpcy5pbnRlcmFjdGluZygpXHJcbiAgICB9O1xyXG5cclxuICAgIGlmICghZHVwbGljYXRlTW92ZSkge1xyXG4gICAgICAvLyBzZXQgcG9pbnRlciBjb29yZGluYXRlLCB0aW1lIGNoYW5nZXMgYW5kIHNwZWVkc1xyXG4gICAgICB1dGlscy5zZXRDb29yZERlbHRhcyh0aGlzLnBvaW50ZXJEZWx0YSwgdGhpcy5wcmV2Q29vcmRzLCB0aGlzLmN1ckNvb3Jkcyk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdtb3ZlJywgc2lnbmFsQXJnKTtcclxuXHJcbiAgICBpZiAoIWR1cGxpY2F0ZU1vdmUpIHtcclxuICAgICAgLy8gaWYgaW50ZXJhY3RpbmcsIGZpcmUgYW4gJ2FjdGlvbi1tb3ZlJyBzaWduYWwgZXRjXHJcbiAgICAgIGlmICh0aGlzLmludGVyYWN0aW5nKCkpIHtcclxuICAgICAgICB0aGlzLmRvTW92ZShzaWduYWxBcmcpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy5wb2ludGVyV2FzTW92ZWQpIHtcclxuICAgICAgICB1dGlscy5jb3B5Q29vcmRzKHRoaXMucHJldkNvb3JkcywgdGhpcy5jdXJDb29yZHMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0aW9uLmRvTW92ZVxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBGb3JjZSBhIG1vdmUgb2YgdGhlIGN1cnJlbnQgYWN0aW9uIGF0IHRoZSBzYW1lIGNvb3JkaW5hdGVzLiBVc2VmdWwgaWZcclxuICAgKiBzbmFwL3Jlc3RyaWN0IGhhcyBiZWVuIGNoYW5nZWQgYW5kIHlvdSB3YW50IGEgbW92ZW1lbnQgd2l0aCB0aGUgbmV3XHJcbiAgICogc2V0dGluZ3MuXHJcbiAgICpcclxuICAgKipcclxuICAgfCBpbnRlcmFjdCh0YXJnZXQpXHJcbiAgIHwgICAuZHJhZ2dhYmxlKHRydWUpXHJcbiAgIHwgICAub24oJ2RyYWdtb3ZlJywgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgIHwgICAgIGlmIChzb21lQ29uZGl0aW9uKSB7XHJcbiAgIHwgICAgICAgLy8gY2hhbmdlIHRoZSBzbmFwIHNldHRpbmdzXHJcbiAgIHwgICAgICAgZXZlbnQuaW50ZXJhY3RhYmxlLmRyYWdnYWJsZSh7IHNuYXA6IHsgdGFyZ2V0czogW10gfX0pO1xyXG4gICB8ICAgICAgIC8vIGZpcmUgYW5vdGhlciBtb3ZlIGV2ZW50IHdpdGggcmUtY2FsY3VsYXRlZCBzbmFwXHJcbiAgIHwgICAgICAgZXZlbnQuaW50ZXJhY3Rpb24uZG9Nb3ZlKCk7XHJcbiAgIHwgICAgIH1cclxuICAgfCAgIH0pO1xyXG4gICBcXCovXHJcblxyXG5cclxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuZG9Nb3ZlID0gZnVuY3Rpb24gZG9Nb3ZlKHNpZ25hbEFyZykge1xyXG4gICAgc2lnbmFsQXJnID0gdXRpbHMuZXh0ZW5kKHtcclxuICAgICAgcG9pbnRlcjogdGhpcy5wb2ludGVyc1swXSxcclxuICAgICAgZXZlbnQ6IHRoaXMucHJldkV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldDogdGhpcy5fZXZlbnRUYXJnZXQsXHJcbiAgICAgIGludGVyYWN0aW9uOiB0aGlzXHJcbiAgICB9LCBzaWduYWxBcmcgfHwge30pO1xyXG5cclxuICAgIHNpZ25hbHMuZmlyZSgnYmVmb3JlLWFjdGlvbi1tb3ZlJywgc2lnbmFsQXJnKTtcclxuXHJcbiAgICBpZiAoIXRoaXMuX2RvbnRGaXJlTW92ZSkge1xyXG4gICAgICBzaWduYWxzLmZpcmUoJ2FjdGlvbi1tb3ZlJywgc2lnbmFsQXJnKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9kb250RmlyZU1vdmUgPSBmYWxzZTtcclxuICB9O1xyXG5cclxuICAvLyBFbmQgaW50ZXJhY3QgbW92ZSBldmVudHMgYW5kIHN0b3AgYXV0by1zY3JvbGwgdW5sZXNzIHNpbXVsYXRpb24gaXMgcnVubmluZ1xyXG5cclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnBvaW50ZXJVcCA9IGZ1bmN0aW9uIHBvaW50ZXJVcChwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsIGN1ckV2ZW50VGFyZ2V0KSB7XHJcbiAgICB2YXIgcG9pbnRlckluZGV4ID0gdGhpcy5nZXRQb2ludGVySW5kZXgocG9pbnRlcik7XHJcblxyXG4gICAgc2lnbmFscy5maXJlKC9jYW5jZWwkL2kudGVzdChldmVudC50eXBlKSA/ICdjYW5jZWwnIDogJ3VwJywge1xyXG4gICAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgICBwb2ludGVySW5kZXg6IHBvaW50ZXJJbmRleCxcclxuICAgICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXHJcbiAgICAgIGN1ckV2ZW50VGFyZ2V0OiBjdXJFdmVudFRhcmdldCxcclxuICAgICAgaW50ZXJhY3Rpb246IHRoaXNcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICghdGhpcy5zaW11bGF0aW9uKSB7XHJcbiAgICAgIHRoaXMuZW5kKGV2ZW50KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnBvaW50ZXJJc0Rvd24gPSBmYWxzZTtcclxuICAgIHRoaXMucmVtb3ZlUG9pbnRlcihwb2ludGVyLCBldmVudCk7XHJcbiAgfTtcclxuXHJcbiAgLypcXFxyXG4gICAqIEludGVyYWN0aW9uLmVuZFxyXG4gICBbIG1ldGhvZCBdXHJcbiAgICpcclxuICAgKiBTdG9wIHRoZSBjdXJyZW50IGFjdGlvbiBhbmQgZmlyZSBhbiBlbmQgZXZlbnQuIEluZXJ0aWFsIG1vdmVtZW50IGRvZXNcclxuICAgKiBub3QgaGFwcGVuLlxyXG4gICAqXHJcbiAgIC0gZXZlbnQgKFBvaW50ZXJFdmVudCkgI29wdGlvbmFsXHJcbiAgICoqXHJcbiAgIHwgaW50ZXJhY3QodGFyZ2V0KVxyXG4gICB8ICAgLmRyYWdnYWJsZSh0cnVlKVxyXG4gICB8ICAgLm9uKCdtb3ZlJywgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgIHwgICAgIGlmIChldmVudC5wYWdlWCA+IDEwMDApIHtcclxuICAgfCAgICAgICAvLyBlbmQgdGhlIGN1cnJlbnQgYWN0aW9uXHJcbiAgIHwgICAgICAgZXZlbnQuaW50ZXJhY3Rpb24uZW5kKCk7XHJcbiAgIHwgICAgICAgLy8gc3RvcCBhbGwgZnVydGhlciBsaXN0ZW5lcnMgZnJvbSBiZWluZyBjYWxsZWRcclxuICAgfCAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuICAgfCAgICAgfVxyXG4gICB8ICAgfSk7XHJcbiAgIFxcKi9cclxuXHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiBlbmQoZXZlbnQpIHtcclxuICAgIGV2ZW50ID0gZXZlbnQgfHwgdGhpcy5wcmV2RXZlbnQ7XHJcblxyXG4gICAgaWYgKHRoaXMuaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgICBzaWduYWxzLmZpcmUoJ2FjdGlvbi1lbmQnLCB7XHJcbiAgICAgICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgICAgIGludGVyYWN0aW9uOiB0aGlzXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc3RvcCgpO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5jdXJyZW50QWN0aW9uID0gZnVuY3Rpb24gY3VycmVudEFjdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLl9pbnRlcmFjdGluZyA/IHRoaXMucHJlcGFyZWQubmFtZSA6IG51bGw7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLmludGVyYWN0aW5nID0gZnVuY3Rpb24gaW50ZXJhY3RpbmcoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5faW50ZXJhY3Rpbmc7XHJcbiAgfTtcclxuXHJcbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbiBzdG9wKCkge1xyXG4gICAgc2lnbmFscy5maXJlKCdzdG9wJywgeyBpbnRlcmFjdGlvbjogdGhpcyB9KTtcclxuXHJcbiAgICBpZiAodGhpcy5faW50ZXJhY3RpbmcpIHtcclxuICAgICAgc2lnbmFscy5maXJlKCdzdG9wLWFjdGl2ZScsIHsgaW50ZXJhY3Rpb246IHRoaXMgfSk7XHJcbiAgICAgIHNpZ25hbHMuZmlyZSgnc3RvcC0nICsgdGhpcy5wcmVwYXJlZC5uYW1lLCB7IGludGVyYWN0aW9uOiB0aGlzIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudGFyZ2V0ID0gdGhpcy5lbGVtZW50ID0gbnVsbDtcclxuXHJcbiAgICB0aGlzLl9pbnRlcmFjdGluZyA9IGZhbHNlO1xyXG4gICAgdGhpcy5wcmVwYXJlZC5uYW1lID0gdGhpcy5wcmV2RXZlbnQgPSBudWxsO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRQb2ludGVySW5kZXggPSBmdW5jdGlvbiBnZXRQb2ludGVySW5kZXgocG9pbnRlcikge1xyXG4gICAgLy8gbW91c2UgYW5kIHBlbiBpbnRlcmFjdGlvbnMgbWF5IGhhdmUgb25seSBvbmUgcG9pbnRlclxyXG4gICAgaWYgKHRoaXMucG9pbnRlclR5cGUgPT09ICdtb3VzZScgfHwgdGhpcy5wb2ludGVyVHlwZSA9PT0gJ3BlbicpIHtcclxuICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHV0aWxzLmluZGV4T2YodGhpcy5wb2ludGVySWRzLCB1dGlscy5nZXRQb2ludGVySWQocG9pbnRlcikpO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS51cGRhdGVQb2ludGVyID0gZnVuY3Rpb24gdXBkYXRlUG9pbnRlcihwb2ludGVyLCBldmVudCkge1xyXG4gICAgdmFyIGRvd24gPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IGV2ZW50ICYmIC8oZG93bnxzdGFydCkkL2kudGVzdChldmVudC50eXBlKTtcclxuXHJcbiAgICB2YXIgaWQgPSB1dGlscy5nZXRQb2ludGVySWQocG9pbnRlcik7XHJcbiAgICB2YXIgaW5kZXggPSB0aGlzLmdldFBvaW50ZXJJbmRleChwb2ludGVyKTtcclxuXHJcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XHJcbiAgICAgIGluZGV4ID0gdGhpcy5wb2ludGVySWRzLmxlbmd0aDtcclxuICAgICAgdGhpcy5wb2ludGVySWRzW2luZGV4XSA9IGlkO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkb3duKSB7XHJcbiAgICAgIHNpZ25hbHMuZmlyZSgndXBkYXRlLXBvaW50ZXItZG93bicsIHtcclxuICAgICAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgICAgIGV2ZW50OiBldmVudCxcclxuICAgICAgICBkb3duOiBkb3duLFxyXG4gICAgICAgIHBvaW50ZXJJZDogaWQsXHJcbiAgICAgICAgcG9pbnRlckluZGV4OiBpbmRleCxcclxuICAgICAgICBpbnRlcmFjdGlvbjogdGhpc1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnBvaW50ZXJzW2luZGV4XSA9IHBvaW50ZXI7XHJcblxyXG4gICAgcmV0dXJuIGluZGV4O1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5yZW1vdmVQb2ludGVyID0gZnVuY3Rpb24gcmVtb3ZlUG9pbnRlcihwb2ludGVyLCBldmVudCkge1xyXG4gICAgdmFyIGluZGV4ID0gdGhpcy5nZXRQb2ludGVySW5kZXgocG9pbnRlcik7XHJcblxyXG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdyZW1vdmUtcG9pbnRlcicsIHtcclxuICAgICAgcG9pbnRlcjogcG9pbnRlcixcclxuICAgICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgICBwb2ludGVySW5kZXg6IGluZGV4LFxyXG4gICAgICBpbnRlcmFjdGlvbjogdGhpc1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5wb2ludGVycy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgdGhpcy5wb2ludGVySWRzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB0aGlzLmRvd25UYXJnZXRzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB0aGlzLmRvd25UaW1lcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gIH07XHJcblxyXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5fdXBkYXRlRXZlbnRUYXJnZXRzID0gZnVuY3Rpb24gX3VwZGF0ZUV2ZW50VGFyZ2V0cyh0YXJnZXQsIGN1cnJlbnRUYXJnZXQpIHtcclxuICAgIHRoaXMuX2V2ZW50VGFyZ2V0ID0gdGFyZ2V0O1xyXG4gICAgdGhpcy5fY3VyRXZlbnRUYXJnZXQgPSBjdXJyZW50VGFyZ2V0O1xyXG4gIH07XHJcblxyXG4gIHJldHVybiBJbnRlcmFjdGlvbjtcclxufSgpO1xyXG5cclxuZm9yICh2YXIgaSA9IDAsIGxlbiA9IG1ldGhvZE5hbWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgdmFyIG1ldGhvZCA9IG1ldGhvZE5hbWVzW2ldO1xyXG5cclxuICBsaXN0ZW5lcnNbbWV0aG9kXSA9IGRvT25JbnRlcmFjdGlvbnMobWV0aG9kKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZG9PbkludGVyYWN0aW9ucyhtZXRob2QpIHtcclxuICByZXR1cm4gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICB2YXIgcG9pbnRlclR5cGUgPSB1dGlscy5nZXRQb2ludGVyVHlwZShldmVudCk7XHJcblxyXG4gICAgdmFyIF91dGlscyRnZXRFdmVudFRhcmdldCA9IHV0aWxzLmdldEV2ZW50VGFyZ2V0cyhldmVudCksXHJcbiAgICAgICAgZXZlbnRUYXJnZXQgPSBfdXRpbHMkZ2V0RXZlbnRUYXJnZXRbMF0sXHJcbiAgICAgICAgY3VyRXZlbnRUYXJnZXQgPSBfdXRpbHMkZ2V0RXZlbnRUYXJnZXRbMV07XHJcblxyXG4gICAgdmFyIG1hdGNoZXMgPSBbXTsgLy8gWyBbcG9pbnRlciwgaW50ZXJhY3Rpb25dLCAuLi5dXHJcblxyXG4gICAgaWYgKGJyb3dzZXIuc3VwcG9ydHNUb3VjaCAmJiAvdG91Y2gvLnRlc3QoZXZlbnQudHlwZSkpIHtcclxuICAgICAgcHJldlRvdWNoVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG5cclxuICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGV2ZW50LmNoYW5nZWRUb3VjaGVzLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgIHZhciBwb2ludGVyID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbX2ldO1xyXG4gICAgICAgIHZhciBpbnRlcmFjdGlvbiA9IGZpbmRlci5zZWFyY2gocG9pbnRlciwgZXZlbnQudHlwZSwgZXZlbnRUYXJnZXQpO1xyXG5cclxuICAgICAgICBtYXRjaGVzLnB1c2goW3BvaW50ZXIsIGludGVyYWN0aW9uIHx8IG5ldyBJbnRlcmFjdGlvbih7IHBvaW50ZXJUeXBlOiBwb2ludGVyVHlwZSB9KV0pO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YXIgaW52YWxpZFBvaW50ZXIgPSBmYWxzZTtcclxuXHJcbiAgICAgIGlmICghYnJvd3Nlci5zdXBwb3J0c1BvaW50ZXJFdmVudCAmJiAvbW91c2UvLnRlc3QoZXZlbnQudHlwZSkpIHtcclxuICAgICAgICAvLyBpZ25vcmUgbW91c2UgZXZlbnRzIHdoaWxlIHRvdWNoIGludGVyYWN0aW9ucyBhcmUgYWN0aXZlXHJcbiAgICAgICAgZm9yICh2YXIgX2kyID0gMDsgX2kyIDwgc2NvcGUuaW50ZXJhY3Rpb25zLmxlbmd0aCAmJiAhaW52YWxpZFBvaW50ZXI7IF9pMisrKSB7XHJcbiAgICAgICAgICBpbnZhbGlkUG9pbnRlciA9IHNjb3BlLmludGVyYWN0aW9uc1tfaTJdLnBvaW50ZXJUeXBlICE9PSAnbW91c2UnICYmIHNjb3BlLmludGVyYWN0aW9uc1tfaTJdLnBvaW50ZXJJc0Rvd247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyB0cnkgdG8gaWdub3JlIG1vdXNlIGV2ZW50cyB0aGF0IGFyZSBzaW11bGF0ZWQgYnkgdGhlIGJyb3dzZXJcclxuICAgICAgICAvLyBhZnRlciBhIHRvdWNoIGV2ZW50XHJcbiAgICAgICAgaW52YWxpZFBvaW50ZXIgPSBpbnZhbGlkUG9pbnRlciB8fCBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHByZXZUb3VjaFRpbWUgPCA1MDBcclxuICAgICAgICAvLyBvbiBpT1MgYW5kIEZpcmVmb3ggTW9iaWxlLCBNb3VzZUV2ZW50LnRpbWVTdGFtcCBpcyB6ZXJvIGlmIHNpbXVsYXRlZFxyXG4gICAgICAgIHx8IGV2ZW50LnRpbWVTdGFtcCA9PT0gMDtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFpbnZhbGlkUG9pbnRlcikge1xyXG4gICAgICAgIHZhciBfaW50ZXJhY3Rpb24gPSBmaW5kZXIuc2VhcmNoKGV2ZW50LCBldmVudC50eXBlLCBldmVudFRhcmdldCk7XHJcblxyXG4gICAgICAgIGlmICghX2ludGVyYWN0aW9uKSB7XHJcbiAgICAgICAgICBfaW50ZXJhY3Rpb24gPSBuZXcgSW50ZXJhY3Rpb24oeyBwb2ludGVyVHlwZTogcG9pbnRlclR5cGUgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBtYXRjaGVzLnB1c2goW2V2ZW50LCBfaW50ZXJhY3Rpb25dKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGZvciAodmFyIF9pdGVyYXRvciA9IG1hdGNoZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaTMgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICB2YXIgX3JlZjI7XHJcblxyXG4gICAgICBpZiAoX2lzQXJyYXkpIHtcclxuICAgICAgICBpZiAoX2kzID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yW19pMysrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaTMgPSBfaXRlcmF0b3IubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaTMuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjIgPSBfaTMudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBfcmVmMyA9IF9yZWYyLFxyXG4gICAgICAgICAgX3BvaW50ZXIgPSBfcmVmM1swXSxcclxuICAgICAgICAgIF9pbnRlcmFjdGlvbjIgPSBfcmVmM1sxXTtcclxuXHJcbiAgICAgIF9pbnRlcmFjdGlvbjIuX3VwZGF0ZUV2ZW50VGFyZ2V0cyhldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQpO1xyXG4gICAgICBfaW50ZXJhY3Rpb24yW21ldGhvZF0oX3BvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQpO1xyXG4gICAgfVxyXG4gIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGVuZEFsbChldmVudCkge1xyXG4gIGZvciAodmFyIF9pNCA9IDA7IF9pNCA8IHNjb3BlLmludGVyYWN0aW9ucy5sZW5ndGg7IF9pNCsrKSB7XHJcbiAgICB2YXIgaW50ZXJhY3Rpb24gPSBzY29wZS5pbnRlcmFjdGlvbnNbX2k0XTtcclxuXHJcbiAgICBpbnRlcmFjdGlvbi5lbmQoZXZlbnQpO1xyXG4gICAgc2lnbmFscy5maXJlKCdlbmRhbGwnLCB7IGV2ZW50OiBldmVudCwgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uIH0pO1xyXG4gIH1cclxufVxyXG5cclxudmFyIGRvY0V2ZW50cyA9IHsvKiAnZXZlbnRUeXBlJzogbGlzdGVuZXJGdW5jICovfTtcclxudmFyIHBFdmVudFR5cGVzID0gYnJvd3Nlci5wRXZlbnRUeXBlcztcclxuXHJcbmlmIChkb21PYmplY3RzLlBvaW50ZXJFdmVudCkge1xyXG4gIGRvY0V2ZW50c1twRXZlbnRUeXBlcy5kb3duXSA9IGxpc3RlbmVycy5wb2ludGVyRG93bjtcclxuICBkb2NFdmVudHNbcEV2ZW50VHlwZXMubW92ZV0gPSBsaXN0ZW5lcnMucG9pbnRlck1vdmU7XHJcbiAgZG9jRXZlbnRzW3BFdmVudFR5cGVzLnVwXSA9IGxpc3RlbmVycy5wb2ludGVyVXA7XHJcbiAgZG9jRXZlbnRzW3BFdmVudFR5cGVzLmNhbmNlbF0gPSBsaXN0ZW5lcnMucG9pbnRlclVwO1xyXG59IGVsc2Uge1xyXG4gIGRvY0V2ZW50cy5tb3VzZWRvd24gPSBsaXN0ZW5lcnMucG9pbnRlckRvd247XHJcbiAgZG9jRXZlbnRzLm1vdXNlbW92ZSA9IGxpc3RlbmVycy5wb2ludGVyTW92ZTtcclxuICBkb2NFdmVudHMubW91c2V1cCA9IGxpc3RlbmVycy5wb2ludGVyVXA7XHJcblxyXG4gIGRvY0V2ZW50cy50b3VjaHN0YXJ0ID0gbGlzdGVuZXJzLnBvaW50ZXJEb3duO1xyXG4gIGRvY0V2ZW50cy50b3VjaG1vdmUgPSBsaXN0ZW5lcnMucG9pbnRlck1vdmU7XHJcbiAgZG9jRXZlbnRzLnRvdWNoZW5kID0gbGlzdGVuZXJzLnBvaW50ZXJVcDtcclxuICBkb2NFdmVudHMudG91Y2hjYW5jZWwgPSBsaXN0ZW5lcnMucG9pbnRlclVwO1xyXG59XHJcblxyXG5kb2NFdmVudHMuYmx1ciA9IGVuZEFsbDtcclxuXHJcbmZ1bmN0aW9uIG9uRG9jU2lnbmFsKF9yZWY0LCBzaWduYWxOYW1lKSB7XHJcbiAgdmFyIGRvYyA9IF9yZWY0LmRvYztcclxuXHJcbiAgdmFyIGV2ZW50TWV0aG9kID0gc2lnbmFsTmFtZS5pbmRleE9mKCdhZGQnKSA9PT0gMCA/IGV2ZW50cy5hZGQgOiBldmVudHMucmVtb3ZlO1xyXG5cclxuICAvLyBkZWxlZ2F0ZSBldmVudCBsaXN0ZW5lclxyXG4gIGZvciAodmFyIGV2ZW50VHlwZSBpbiBzY29wZS5kZWxlZ2F0ZWRFdmVudHMpIHtcclxuICAgIGV2ZW50TWV0aG9kKGRvYywgZXZlbnRUeXBlLCBldmVudHMuZGVsZWdhdGVMaXN0ZW5lcik7XHJcbiAgICBldmVudE1ldGhvZChkb2MsIGV2ZW50VHlwZSwgZXZlbnRzLmRlbGVnYXRlVXNlQ2FwdHVyZSwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBmb3IgKHZhciBfZXZlbnRUeXBlIGluIGRvY0V2ZW50cykge1xyXG4gICAgZXZlbnRNZXRob2QoZG9jLCBfZXZlbnRUeXBlLCBkb2NFdmVudHNbX2V2ZW50VHlwZV0pO1xyXG4gIH1cclxufVxyXG5cclxuc2lnbmFscy5vbigndXBkYXRlLXBvaW50ZXItZG93bicsIGZ1bmN0aW9uIChfcmVmNSkge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY1LmludGVyYWN0aW9uLFxyXG4gICAgICBwb2ludGVyID0gX3JlZjUucG9pbnRlcixcclxuICAgICAgcG9pbnRlcklkID0gX3JlZjUucG9pbnRlcklkLFxyXG4gICAgICBwb2ludGVySW5kZXggPSBfcmVmNS5wb2ludGVySW5kZXgsXHJcbiAgICAgIGV2ZW50ID0gX3JlZjUuZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZjUuZXZlbnRUYXJnZXQsXHJcbiAgICAgIGRvd24gPSBfcmVmNS5kb3duO1xyXG5cclxuICBpbnRlcmFjdGlvbi5wb2ludGVySWRzW3BvaW50ZXJJbmRleF0gPSBwb2ludGVySWQ7XHJcbiAgaW50ZXJhY3Rpb24ucG9pbnRlcnNbcG9pbnRlckluZGV4XSA9IHBvaW50ZXI7XHJcblxyXG4gIGlmIChkb3duKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVySXNEb3duID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIGlmICghaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgdXRpbHMuc2V0Q29vcmRzKGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLCBpbnRlcmFjdGlvbi5wb2ludGVycyk7XHJcblxyXG4gICAgdXRpbHMuY29weUNvb3JkcyhpbnRlcmFjdGlvbi5jdXJDb29yZHMsIGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzKTtcclxuICAgIHV0aWxzLmNvcHlDb29yZHMoaW50ZXJhY3Rpb24ucHJldkNvb3JkcywgaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMpO1xyXG5cclxuICAgIGludGVyYWN0aW9uLmRvd25FdmVudCA9IGV2ZW50O1xyXG4gICAgaW50ZXJhY3Rpb24uZG93blRpbWVzW3BvaW50ZXJJbmRleF0gPSBpbnRlcmFjdGlvbi5jdXJDb29yZHMudGltZVN0YW1wO1xyXG4gICAgaW50ZXJhY3Rpb24uZG93blRhcmdldHNbcG9pbnRlckluZGV4XSA9IGV2ZW50VGFyZ2V0IHx8IGV2ZW50ICYmIHV0aWxzLmdldEV2ZW50VGFyZ2V0cyhldmVudClbMF07XHJcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyV2FzTW92ZWQgPSBmYWxzZTtcclxuXHJcbiAgICB1dGlscy5wb2ludGVyRXh0ZW5kKGludGVyYWN0aW9uLmRvd25Qb2ludGVyLCBwb2ludGVyKTtcclxuICB9XHJcbn0pO1xyXG5cclxuc2NvcGUuc2lnbmFscy5vbignYWRkLWRvY3VtZW50Jywgb25Eb2NTaWduYWwpO1xyXG5zY29wZS5zaWduYWxzLm9uKCdyZW1vdmUtZG9jdW1lbnQnLCBvbkRvY1NpZ25hbCk7XHJcblxyXG5JbnRlcmFjdGlvbi5wb2ludGVyTW92ZVRvbGVyYW5jZSA9IDE7XHJcbkludGVyYWN0aW9uLmRvT25JbnRlcmFjdGlvbnMgPSBkb09uSW50ZXJhY3Rpb25zO1xyXG5JbnRlcmFjdGlvbi5lbmRBbGwgPSBlbmRBbGw7XHJcbkludGVyYWN0aW9uLnNpZ25hbHMgPSBzaWduYWxzO1xyXG5JbnRlcmFjdGlvbi5kb2NFdmVudHMgPSBkb2NFdmVudHM7XHJcblxyXG5zY29wZS5lbmRBbGxJbnRlcmFjdGlvbnMgPSBlbmRBbGw7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEludGVyYWN0aW9uO1xyXG5cclxufSx7XCIuL3Njb3BlXCI6MzQsXCIuL3V0aWxzXCI6NDQsXCIuL3V0aWxzL1NpZ25hbHNcIjozNSxcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9kb21PYmplY3RzXCI6MzgsXCIuL3V0aWxzL2V2ZW50c1wiOjQwLFwiLi91dGlscy9pbnRlcmFjdGlvbkZpbmRlclwiOjQ1fV0sNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XHJcbnZhciBJbnRlcmFjdEV2ZW50ID0gcmVxdWlyZSgnLi4vSW50ZXJhY3RFdmVudCcpO1xyXG5cclxudmFyIGFjdGlvbnMgPSB7XHJcbiAgZmlyZVByZXBhcmVkOiBmaXJlUHJlcGFyZWQsXHJcbiAgbmFtZXM6IFtdLFxyXG4gIG1ldGhvZERpY3Q6IHt9XHJcbn07XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tc3RhcnQnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb24sXHJcbiAgICAgIGV2ZW50ID0gX3JlZi5ldmVudDtcclxuXHJcbiAgaW50ZXJhY3Rpb24uX2ludGVyYWN0aW5nID0gdHJ1ZTtcclxuICBmaXJlUHJlcGFyZWQoaW50ZXJhY3Rpb24sIGV2ZW50LCAnc3RhcnQnKTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tbW92ZScsIGZ1bmN0aW9uIChfcmVmMikge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IF9yZWYyLmV2ZW50LFxyXG4gICAgICBwcmVFbmQgPSBfcmVmMi5wcmVFbmQ7XHJcblxyXG4gIGZpcmVQcmVwYXJlZChpbnRlcmFjdGlvbiwgZXZlbnQsICdtb3ZlJywgcHJlRW5kKTtcclxuXHJcbiAgLy8gaWYgdGhlIGFjdGlvbiB3YXMgZW5kZWQgaW4gYSBsaXN0ZW5lclxyXG4gIGlmICghaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tZW5kJywgZnVuY3Rpb24gKF9yZWYzKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjMuaW50ZXJhY3Rpb24sXHJcbiAgICAgIGV2ZW50ID0gX3JlZjMuZXZlbnQ7XHJcblxyXG4gIGZpcmVQcmVwYXJlZChpbnRlcmFjdGlvbiwgZXZlbnQsICdlbmQnKTtcclxufSk7XHJcblxyXG5mdW5jdGlvbiBmaXJlUHJlcGFyZWQoaW50ZXJhY3Rpb24sIGV2ZW50LCBwaGFzZSwgcHJlRW5kKSB7XHJcbiAgdmFyIGFjdGlvbk5hbWUgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lO1xyXG5cclxuICB2YXIgbmV3RXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudChpbnRlcmFjdGlvbiwgZXZlbnQsIGFjdGlvbk5hbWUsIHBoYXNlLCBpbnRlcmFjdGlvbi5lbGVtZW50LCBudWxsLCBwcmVFbmQpO1xyXG5cclxuICBpbnRlcmFjdGlvbi50YXJnZXQuZmlyZShuZXdFdmVudCk7XHJcbiAgaW50ZXJhY3Rpb24ucHJldkV2ZW50ID0gbmV3RXZlbnQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYWN0aW9ucztcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGlvblwiOjV9XSw3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIEludGVyYWN0RXZlbnQgPSByZXF1aXJlKCcuLi9JbnRlcmFjdEV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcclxudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbnZhciBkcmFnID0ge1xyXG4gIGRlZmF1bHRzOiB7XHJcbiAgICBlbmFibGVkOiBmYWxzZSxcclxuICAgIG1vdXNlQnV0dG9uczogbnVsbCxcclxuXHJcbiAgICBvcmlnaW46IG51bGwsXHJcbiAgICBzbmFwOiBudWxsLFxyXG4gICAgcmVzdHJpY3Q6IG51bGwsXHJcbiAgICBpbmVydGlhOiBudWxsLFxyXG4gICAgYXV0b1Njcm9sbDogbnVsbCxcclxuXHJcbiAgICBzdGFydEF4aXM6ICd4eScsXHJcbiAgICBsb2NrQXhpczogJ3h5J1xyXG4gIH0sXHJcblxyXG4gIGNoZWNrZXI6IGZ1bmN0aW9uIGNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0YWJsZSkge1xyXG4gICAgdmFyIGRyYWdPcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnMuZHJhZztcclxuXHJcbiAgICByZXR1cm4gZHJhZ09wdGlvbnMuZW5hYmxlZCA/IHsgbmFtZTogJ2RyYWcnLCBheGlzOiBkcmFnT3B0aW9ucy5sb2NrQXhpcyA9PT0gJ3N0YXJ0JyA/IGRyYWdPcHRpb25zLnN0YXJ0QXhpcyA6IGRyYWdPcHRpb25zLmxvY2tBeGlzIH0gOiBudWxsO1xyXG4gIH0sXHJcblxyXG4gIGdldEN1cnNvcjogZnVuY3Rpb24gZ2V0Q3Vyc29yKCkge1xyXG4gICAgcmV0dXJuICdtb3ZlJztcclxuICB9XHJcbn07XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdiZWZvcmUtYWN0aW9uLW1vdmUnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb247XHJcblxyXG4gIGlmIChpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lICE9PSAnZHJhZycpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBheGlzID0gaW50ZXJhY3Rpb24ucHJlcGFyZWQuYXhpcztcclxuXHJcbiAgaWYgKGF4aXMgPT09ICd4Jykge1xyXG4gICAgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UueSA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLnBhZ2UueTtcclxuICAgIGludGVyYWN0aW9uLmN1ckNvb3Jkcy5jbGllbnQueSA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLmNsaWVudC55O1xyXG5cclxuICAgIGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5wYWdlLnNwZWVkID0gTWF0aC5hYnMoaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLnBhZ2UudngpO1xyXG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC5zcGVlZCA9IE1hdGguYWJzKGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5jbGllbnQudngpO1xyXG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC52eSA9IDA7XHJcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEucGFnZS52eSA9IDA7XHJcbiAgfSBlbHNlIGlmIChheGlzID09PSAneScpIHtcclxuICAgIGludGVyYWN0aW9uLmN1ckNvb3Jkcy5wYWdlLnggPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLng7XHJcbiAgICBpbnRlcmFjdGlvbi5jdXJDb29yZHMuY2xpZW50LnggPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueDtcclxuXHJcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEucGFnZS5zcGVlZCA9IE1hdGguYWJzKGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5wYWdlLnZ5KTtcclxuICAgIGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5jbGllbnQuc3BlZWQgPSBNYXRoLmFicyhpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnZ5KTtcclxuICAgIGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5jbGllbnQudnggPSAwO1xyXG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLnBhZ2UudnggPSAwO1xyXG4gIH1cclxufSk7XHJcblxyXG4vLyBkcmFnbW92ZVxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmMikge1xyXG4gIHZhciBpRXZlbnQgPSBfcmVmMi5pRXZlbnQsXHJcbiAgICAgIGludGVyYWN0aW9uID0gX3JlZjIuaW50ZXJhY3Rpb247XHJcblxyXG4gIGlmIChpRXZlbnQudHlwZSAhPT0gJ2RyYWdtb3ZlJykge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIGF4aXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5heGlzO1xyXG5cclxuICBpZiAoYXhpcyA9PT0gJ3gnKSB7XHJcbiAgICBpRXZlbnQucGFnZVkgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnk7XHJcbiAgICBpRXZlbnQuY2xpZW50WSA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLmNsaWVudC55O1xyXG4gICAgaUV2ZW50LmR5ID0gMDtcclxuICB9IGVsc2UgaWYgKGF4aXMgPT09ICd5Jykge1xyXG4gICAgaUV2ZW50LnBhZ2VYID0gaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMucGFnZS54O1xyXG4gICAgaUV2ZW50LmNsaWVudFggPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueDtcclxuICAgIGlFdmVudC5keCA9IDA7XHJcbiAgfVxyXG59KTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmRyYWdnYWJsZVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBHZXRzIG9yIHNldHMgd2hldGhlciBkcmFnIGFjdGlvbnMgY2FuIGJlIHBlcmZvcm1lZCBvbiB0aGVcclxuICogSW50ZXJhY3RhYmxlXHJcbiAqXHJcbiA9IChib29sZWFuKSBJbmRpY2F0ZXMgaWYgdGhpcyBjYW4gYmUgdGhlIHRhcmdldCBvZiBkcmFnIGV2ZW50c1xyXG4gfCB2YXIgaXNEcmFnZ2FibGUgPSBpbnRlcmFjdCgndWwgbGknKS5kcmFnZ2FibGUoKTtcclxuICogb3JcclxuIC0gb3B0aW9ucyAoYm9vbGVhbiB8IG9iamVjdCkgI29wdGlvbmFsIHRydWUvZmFsc2Ugb3IgQW4gb2JqZWN0IHdpdGggZXZlbnQgbGlzdGVuZXJzIHRvIGJlIGZpcmVkIG9uIGRyYWcgZXZlbnRzIChvYmplY3QgbWFrZXMgdGhlIEludGVyYWN0YWJsZSBkcmFnZ2FibGUpXHJcbiA9IChvYmplY3QpIFRoaXMgSW50ZXJhY3RhYmxlXHJcbiB8IGludGVyYWN0KGVsZW1lbnQpLmRyYWdnYWJsZSh7XHJcbiB8ICAgICBvbnN0YXJ0OiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxyXG4gfCAgICAgb25tb3ZlIDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcclxuIHwgICAgIG9uZW5kICA6IGZ1bmN0aW9uIChldmVudCkge30sXHJcbiB8XHJcbiB8ICAgICAvLyB0aGUgYXhpcyBpbiB3aGljaCB0aGUgZmlyc3QgbW92ZW1lbnQgbXVzdCBiZVxyXG4gfCAgICAgLy8gZm9yIHRoZSBkcmFnIHNlcXVlbmNlIHRvIHN0YXJ0XHJcbiB8ICAgICAvLyAneHknIGJ5IGRlZmF1bHQgLSBhbnkgZGlyZWN0aW9uXHJcbiB8ICAgICBzdGFydEF4aXM6ICd4JyB8fCAneScgfHwgJ3h5JyxcclxuIHxcclxuIHwgICAgIC8vICd4eScgYnkgZGVmYXVsdCAtIGRvbid0IHJlc3RyaWN0IHRvIG9uZSBheGlzIChtb3ZlIGluIGFueSBkaXJlY3Rpb24pXHJcbiB8ICAgICAvLyAneCcgb3IgJ3knIHRvIHJlc3RyaWN0IG1vdmVtZW50IHRvIGVpdGhlciBheGlzXHJcbiB8ICAgICAvLyAnc3RhcnQnIHRvIHJlc3RyaWN0IG1vdmVtZW50IHRvIHRoZSBheGlzIHRoZSBkcmFnIHN0YXJ0ZWQgaW5cclxuIHwgICAgIGxvY2tBeGlzOiAneCcgfHwgJ3knIHx8ICd4eScgfHwgJ3N0YXJ0JyxcclxuIHxcclxuIHwgICAgIC8vIG1heCBudW1iZXIgb2YgZHJhZ3MgdGhhdCBjYW4gaGFwcGVuIGNvbmN1cnJlbnRseVxyXG4gfCAgICAgLy8gd2l0aCBlbGVtZW50cyBvZiB0aGlzIEludGVyYWN0YWJsZS4gSW5maW5pdHkgYnkgZGVmYXVsdFxyXG4gfCAgICAgbWF4OiBJbmZpbml0eSxcclxuIHxcclxuIHwgICAgIC8vIG1heCBudW1iZXIgb2YgZHJhZ3MgdGhhdCBjYW4gdGFyZ2V0IHRoZSBzYW1lIGVsZW1lbnQrSW50ZXJhY3RhYmxlXHJcbiB8ICAgICAvLyAxIGJ5IGRlZmF1bHRcclxuIHwgICAgIG1heFBlckVsZW1lbnQ6IDJcclxuIHwgfSk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5kcmFnZ2FibGUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gIGlmICh1dGlscy5pcy5vYmplY3Qob3B0aW9ucykpIHtcclxuICAgIHRoaXMub3B0aW9ucy5kcmFnLmVuYWJsZWQgPSBvcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlO1xyXG4gICAgdGhpcy5zZXRQZXJBY3Rpb24oJ2RyYWcnLCBvcHRpb25zKTtcclxuICAgIHRoaXMuc2V0T25FdmVudHMoJ2RyYWcnLCBvcHRpb25zKTtcclxuXHJcbiAgICBpZiAoL14oeHl8eHx5fHN0YXJ0KSQvLnRlc3Qob3B0aW9ucy5sb2NrQXhpcykpIHtcclxuICAgICAgdGhpcy5vcHRpb25zLmRyYWcubG9ja0F4aXMgPSBvcHRpb25zLmxvY2tBeGlzO1xyXG4gICAgfVxyXG4gICAgaWYgKC9eKHh5fHh8eSkkLy50ZXN0KG9wdGlvbnMuc3RhcnRBeGlzKSkge1xyXG4gICAgICB0aGlzLm9wdGlvbnMuZHJhZy5zdGFydEF4aXMgPSBvcHRpb25zLnN0YXJ0QXhpcztcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGlmICh1dGlscy5pcy5ib29sKG9wdGlvbnMpKSB7XHJcbiAgICB0aGlzLm9wdGlvbnMuZHJhZy5lbmFibGVkID0gb3B0aW9ucztcclxuXHJcbiAgICBpZiAoIW9wdGlvbnMpIHtcclxuICAgICAgdGhpcy5vbmRyYWdzdGFydCA9IHRoaXMub25kcmFnc3RhcnQgPSB0aGlzLm9uZHJhZ2VuZCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLmRyYWc7XHJcbn07XHJcblxyXG5hY3Rpb25zLmRyYWcgPSBkcmFnO1xyXG5hY3Rpb25zLm5hbWVzLnB1c2goJ2RyYWcnKTtcclxudXRpbHMubWVyZ2UoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIFsnZHJhZ3N0YXJ0JywgJ2RyYWdtb3ZlJywgJ2RyYWdpbmVydGlhc3RhcnQnLCAnZHJhZ2luZXJ0aWFyZXN1bWUnLCAnZHJhZ2VuZCddKTtcclxuYWN0aW9ucy5tZXRob2REaWN0LmRyYWcgPSAnZHJhZ2dhYmxlJztcclxuXHJcbmRlZmF1bHRPcHRpb25zLmRyYWcgPSBkcmFnLmRlZmF1bHRzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBkcmFnO1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdEV2ZW50XCI6MyxcIi4uL0ludGVyYWN0YWJsZVwiOjQsXCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuLi9kZWZhdWx0T3B0aW9uc1wiOjE4LFwiLi4vdXRpbHNcIjo0NCxcIi4vYmFzZVwiOjZ9XSw4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcclxudmFyIGludGVyYWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJhY3QnKTtcclxudmFyIEludGVyYWN0RXZlbnQgPSByZXF1aXJlKCcuLi9JbnRlcmFjdEV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcclxudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbnZhciBkcm9wID0ge1xyXG4gIGRlZmF1bHRzOiB7XHJcbiAgICBlbmFibGVkOiBmYWxzZSxcclxuICAgIGFjY2VwdDogbnVsbCxcclxuICAgIG92ZXJsYXA6ICdwb2ludGVyJ1xyXG4gIH1cclxufTtcclxuXHJcbnZhciBkeW5hbWljRHJvcCA9IGZhbHNlO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYWN0aW9uLXN0YXJ0JywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQ7XHJcblxyXG4gIGlmIChpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lICE9PSAnZHJhZycpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIHJlc2V0IGFjdGl2ZSBkcm9wem9uZXNcclxuICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXMgPSBbXTtcclxuICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5lbGVtZW50cyA9IFtdO1xyXG4gIGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLnJlY3RzID0gW107XHJcblxyXG4gIGludGVyYWN0aW9uLmRyb3BFdmVudHMgPSBudWxsO1xyXG5cclxuICBpZiAoIWludGVyYWN0aW9uLmR5bmFtaWNEcm9wKSB7XHJcbiAgICBzZXRBY3RpdmVEcm9wcyhpbnRlcmFjdGlvbiwgaW50ZXJhY3Rpb24uZWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICB2YXIgZHJhZ0V2ZW50ID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50O1xyXG4gIHZhciBkcm9wRXZlbnRzID0gZ2V0RHJvcEV2ZW50cyhpbnRlcmFjdGlvbiwgZXZlbnQsIGRyYWdFdmVudCk7XHJcblxyXG4gIGlmIChkcm9wRXZlbnRzLmFjdGl2YXRlKSB7XHJcbiAgICBmaXJlQWN0aXZlRHJvcHMoaW50ZXJhY3Rpb24sIGRyb3BFdmVudHMuYWN0aXZhdGUpO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmMikge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxyXG4gICAgICBpRXZlbnQgPSBfcmVmMi5pRXZlbnQsXHJcbiAgICAgIGV2ZW50ID0gX3JlZjIuZXZlbnQ7XHJcblxyXG4gIGlmIChpRXZlbnQudHlwZSAhPT0gJ2RyYWdtb3ZlJyAmJiBpRXZlbnQudHlwZSAhPT0gJ2RyYWdlbmQnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgZHJhZ2dhYmxlRWxlbWVudCA9IGludGVyYWN0aW9uLmVsZW1lbnQ7XHJcbiAgdmFyIGRyYWdFdmVudCA9IGlFdmVudDtcclxuICB2YXIgZHJvcFJlc3VsdCA9IGdldERyb3AoZHJhZ0V2ZW50LCBldmVudCwgZHJhZ2dhYmxlRWxlbWVudCk7XHJcblxyXG4gIGludGVyYWN0aW9uLmRyb3BUYXJnZXQgPSBkcm9wUmVzdWx0LmRyb3B6b25lO1xyXG4gIGludGVyYWN0aW9uLmRyb3BFbGVtZW50ID0gZHJvcFJlc3VsdC5lbGVtZW50O1xyXG5cclxuICBpbnRlcmFjdGlvbi5kcm9wRXZlbnRzID0gZ2V0RHJvcEV2ZW50cyhpbnRlcmFjdGlvbiwgZXZlbnQsIGRyYWdFdmVudCk7XHJcbn0pO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYWN0aW9uLW1vdmUnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgIT09ICdkcmFnJykge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgZmlyZURyb3BFdmVudHMoaW50ZXJhY3Rpb24sIGludGVyYWN0aW9uLmRyb3BFdmVudHMpO1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ2FjdGlvbi1lbmQnLCBmdW5jdGlvbiAoX3JlZjQpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmNC5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgPT09ICdkcmFnJykge1xyXG4gICAgZmlyZURyb3BFdmVudHMoaW50ZXJhY3Rpb24sIGludGVyYWN0aW9uLmRyb3BFdmVudHMpO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdzdG9wLWRyYWcnLCBmdW5jdGlvbiAoX3JlZjUpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmNS5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzID0gaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZWxlbWVudHMgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5yZWN0cyA9IGludGVyYWN0aW9uLmRyb3BFdmVudHMgPSBudWxsO1xyXG59KTtcclxuXHJcbmZ1bmN0aW9uIGNvbGxlY3REcm9wcyhpbnRlcmFjdGlvbiwgZWxlbWVudCkge1xyXG4gIHZhciBkcm9wcyA9IFtdO1xyXG4gIHZhciBlbGVtZW50cyA9IFtdO1xyXG5cclxuICBlbGVtZW50ID0gZWxlbWVudCB8fCBpbnRlcmFjdGlvbi5lbGVtZW50O1xyXG5cclxuICAvLyBjb2xsZWN0IGFsbCBkcm9wem9uZXMgYW5kIHRoZWlyIGVsZW1lbnRzIHdoaWNoIHF1YWxpZnkgZm9yIGEgZHJvcFxyXG4gIGZvciAodmFyIF9pdGVyYXRvciA9IHNjb3BlLmludGVyYWN0YWJsZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICB2YXIgX3JlZjY7XHJcblxyXG4gICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgX3JlZjYgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgX3JlZjYgPSBfaS52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgY3VycmVudCA9IF9yZWY2O1xyXG5cclxuICAgIGlmICghY3VycmVudC5vcHRpb25zLmRyb3AuZW5hYmxlZCkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYWNjZXB0ID0gY3VycmVudC5vcHRpb25zLmRyb3AuYWNjZXB0O1xyXG5cclxuICAgIC8vIHRlc3QgdGhlIGRyYWdnYWJsZSBlbGVtZW50IGFnYWluc3QgdGhlIGRyb3B6b25lJ3MgYWNjZXB0IHNldHRpbmdcclxuICAgIGlmICh1dGlscy5pcy5lbGVtZW50KGFjY2VwdCkgJiYgYWNjZXB0ICE9PSBlbGVtZW50IHx8IHV0aWxzLmlzLnN0cmluZyhhY2NlcHQpICYmICF1dGlscy5tYXRjaGVzU2VsZWN0b3IoZWxlbWVudCwgYWNjZXB0KSkge1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcXVlcnkgZm9yIG5ldyBlbGVtZW50cyBpZiBuZWNlc3NhcnlcclxuICAgIHZhciBkcm9wRWxlbWVudHMgPSB1dGlscy5pcy5zdHJpbmcoY3VycmVudC50YXJnZXQpID8gY3VycmVudC5fY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKGN1cnJlbnQudGFyZ2V0KSA6IFtjdXJyZW50LnRhcmdldF07XHJcblxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkcm9wRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgdmFyIGN1cnJlbnRFbGVtZW50ID0gZHJvcEVsZW1lbnRzW2ldO1xyXG5cclxuICAgICAgaWYgKGN1cnJlbnRFbGVtZW50ICE9PSBlbGVtZW50KSB7XHJcbiAgICAgICAgZHJvcHMucHVzaChjdXJyZW50KTtcclxuICAgICAgICBlbGVtZW50cy5wdXNoKGN1cnJlbnRFbGVtZW50KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcclxuICAgIGRyb3B6b25lczogZHJvcHNcclxuICB9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBmaXJlQWN0aXZlRHJvcHMoaW50ZXJhY3Rpb24sIGV2ZW50KSB7XHJcbiAgdmFyIHByZXZFbGVtZW50ID0gdm9pZCAwO1xyXG5cclxuICAvLyBsb29wIHRocm91Z2ggYWxsIGFjdGl2ZSBkcm9wem9uZXMgYW5kIHRyaWdnZXIgZXZlbnRcclxuICBmb3IgKHZhciBpID0gMDsgaSA8IGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmRyb3B6b25lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgdmFyIGN1cnJlbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXNbaV07XHJcbiAgICB2YXIgY3VycmVudEVsZW1lbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5lbGVtZW50c1tpXTtcclxuXHJcbiAgICAvLyBwcmV2ZW50IHRyaWdnZXIgb2YgZHVwbGljYXRlIGV2ZW50cyBvbiBzYW1lIGVsZW1lbnRcclxuICAgIGlmIChjdXJyZW50RWxlbWVudCAhPT0gcHJldkVsZW1lbnQpIHtcclxuICAgICAgLy8gc2V0IGN1cnJlbnQgZWxlbWVudCBhcyBldmVudCB0YXJnZXRcclxuICAgICAgZXZlbnQudGFyZ2V0ID0gY3VycmVudEVsZW1lbnQ7XHJcbiAgICAgIGN1cnJlbnQuZmlyZShldmVudCk7XHJcbiAgICB9XHJcbiAgICBwcmV2RWxlbWVudCA9IGN1cnJlbnRFbGVtZW50O1xyXG4gIH1cclxufVxyXG5cclxuLy8gQ29sbGVjdCBhIG5ldyBzZXQgb2YgcG9zc2libGUgZHJvcHMgYW5kIHNhdmUgdGhlbSBpbiBhY3RpdmVEcm9wcy5cclxuLy8gc2V0QWN0aXZlRHJvcHMgc2hvdWxkIGFsd2F5cyBiZSBjYWxsZWQgd2hlbiBhIGRyYWcgaGFzIGp1c3Qgc3RhcnRlZCBvciBhXHJcbi8vIGRyYWcgZXZlbnQgaGFwcGVucyB3aGlsZSBkeW5hbWljRHJvcCBpcyB0cnVlXHJcbmZ1bmN0aW9uIHNldEFjdGl2ZURyb3BzKGludGVyYWN0aW9uLCBkcmFnRWxlbWVudCkge1xyXG4gIC8vIGdldCBkcm9wem9uZXMgYW5kIHRoZWlyIGVsZW1lbnRzIHRoYXQgY291bGQgcmVjZWl2ZSB0aGUgZHJhZ2dhYmxlXHJcbiAgdmFyIHBvc3NpYmxlRHJvcHMgPSBjb2xsZWN0RHJvcHMoaW50ZXJhY3Rpb24sIGRyYWdFbGVtZW50LCB0cnVlKTtcclxuXHJcbiAgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzID0gcG9zc2libGVEcm9wcy5kcm9wem9uZXM7XHJcbiAgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZWxlbWVudHMgPSBwb3NzaWJsZURyb3BzLmVsZW1lbnRzO1xyXG4gIGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLnJlY3RzID0gW107XHJcblxyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5yZWN0c1tpXSA9IGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmRyb3B6b25lc1tpXS5nZXRSZWN0KGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmVsZW1lbnRzW2ldKTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldERyb3AoZHJhZ0V2ZW50LCBldmVudCwgZHJhZ0VsZW1lbnQpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBkcmFnRXZlbnQuaW50ZXJhY3Rpb247XHJcbiAgdmFyIHZhbGlkRHJvcHMgPSBbXTtcclxuXHJcbiAgaWYgKGR5bmFtaWNEcm9wKSB7XHJcbiAgICBzZXRBY3RpdmVEcm9wcyhpbnRlcmFjdGlvbiwgZHJhZ0VsZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgLy8gY29sbGVjdCBhbGwgZHJvcHpvbmVzIGFuZCB0aGVpciBlbGVtZW50cyB3aGljaCBxdWFsaWZ5IGZvciBhIGRyb3BcclxuICBmb3IgKHZhciBqID0gMDsgaiA8IGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmRyb3B6b25lcy5sZW5ndGg7IGorKykge1xyXG4gICAgdmFyIGN1cnJlbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXNbal07XHJcbiAgICB2YXIgY3VycmVudEVsZW1lbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5lbGVtZW50c1tqXTtcclxuICAgIHZhciByZWN0ID0gaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMucmVjdHNbal07XHJcblxyXG4gICAgdmFsaWREcm9wcy5wdXNoKGN1cnJlbnQuZHJvcENoZWNrKGRyYWdFdmVudCwgZXZlbnQsIGludGVyYWN0aW9uLnRhcmdldCwgZHJhZ0VsZW1lbnQsIGN1cnJlbnRFbGVtZW50LCByZWN0KSA/IGN1cnJlbnRFbGVtZW50IDogbnVsbCk7XHJcbiAgfVxyXG5cclxuICAvLyBnZXQgdGhlIG1vc3QgYXBwcm9wcmlhdGUgZHJvcHpvbmUgYmFzZWQgb24gRE9NIGRlcHRoIGFuZCBvcmRlclxyXG4gIHZhciBkcm9wSW5kZXggPSB1dGlscy5pbmRleE9mRGVlcGVzdEVsZW1lbnQodmFsaWREcm9wcyk7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBkcm9wem9uZTogaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzW2Ryb3BJbmRleF0gfHwgbnVsbCxcclxuICAgIGVsZW1lbnQ6IGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmVsZW1lbnRzW2Ryb3BJbmRleF0gfHwgbnVsbFxyXG4gIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldERyb3BFdmVudHMoaW50ZXJhY3Rpb24sIHBvaW50ZXJFdmVudCwgZHJhZ0V2ZW50KSB7XHJcbiAgdmFyIGRyb3BFdmVudHMgPSB7XHJcbiAgICBlbnRlcjogbnVsbCxcclxuICAgIGxlYXZlOiBudWxsLFxyXG4gICAgYWN0aXZhdGU6IG51bGwsXHJcbiAgICBkZWFjdGl2YXRlOiBudWxsLFxyXG4gICAgbW92ZTogbnVsbCxcclxuICAgIGRyb3A6IG51bGxcclxuICB9O1xyXG5cclxuICB2YXIgdG1wbCA9IHtcclxuICAgIGRyYWdFdmVudDogZHJhZ0V2ZW50LFxyXG4gICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgdGFyZ2V0OiBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudCxcclxuICAgIGRyb3B6b25lOiBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0LFxyXG4gICAgcmVsYXRlZFRhcmdldDogZHJhZ0V2ZW50LnRhcmdldCxcclxuICAgIGRyYWdnYWJsZTogZHJhZ0V2ZW50LmludGVyYWN0YWJsZSxcclxuICAgIHRpbWVTdGFtcDogZHJhZ0V2ZW50LnRpbWVTdGFtcFxyXG4gIH07XHJcblxyXG4gIGlmIChpbnRlcmFjdGlvbi5kcm9wRWxlbWVudCAhPT0gaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50KSB7XHJcbiAgICAvLyBpZiB0aGVyZSB3YXMgYSBwcmV2RHJvcFRhcmdldCwgY3JlYXRlIGEgZHJhZ2xlYXZlIGV2ZW50XHJcbiAgICBpZiAoaW50ZXJhY3Rpb24ucHJldkRyb3BUYXJnZXQpIHtcclxuICAgICAgZHJvcEV2ZW50cy5sZWF2ZSA9IHV0aWxzLmV4dGVuZCh7IHR5cGU6ICdkcmFnbGVhdmUnIH0sIHRtcGwpO1xyXG5cclxuICAgICAgZHJhZ0V2ZW50LmRyYWdMZWF2ZSA9IGRyb3BFdmVudHMubGVhdmUudGFyZ2V0ID0gaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50O1xyXG4gICAgICBkcmFnRXZlbnQucHJldkRyb3B6b25lID0gZHJvcEV2ZW50cy5sZWF2ZS5kcm9wem9uZSA9IGludGVyYWN0aW9uLnByZXZEcm9wVGFyZ2V0O1xyXG4gICAgfVxyXG4gICAgLy8gaWYgdGhlIGRyb3BUYXJnZXQgaXMgbm90IG51bGwsIGNyZWF0ZSBhIGRyYWdlbnRlciBldmVudFxyXG4gICAgaWYgKGludGVyYWN0aW9uLmRyb3BUYXJnZXQpIHtcclxuICAgICAgZHJvcEV2ZW50cy5lbnRlciA9IHtcclxuICAgICAgICBkcmFnRXZlbnQ6IGRyYWdFdmVudCxcclxuICAgICAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXHJcbiAgICAgICAgdGFyZ2V0OiBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudCxcclxuICAgICAgICBkcm9wem9uZTogaW50ZXJhY3Rpb24uZHJvcFRhcmdldCxcclxuICAgICAgICByZWxhdGVkVGFyZ2V0OiBkcmFnRXZlbnQudGFyZ2V0LFxyXG4gICAgICAgIGRyYWdnYWJsZTogZHJhZ0V2ZW50LmludGVyYWN0YWJsZSxcclxuICAgICAgICB0aW1lU3RhbXA6IGRyYWdFdmVudC50aW1lU3RhbXAsXHJcbiAgICAgICAgdHlwZTogJ2RyYWdlbnRlcidcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGRyYWdFdmVudC5kcmFnRW50ZXIgPSBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudDtcclxuICAgICAgZHJhZ0V2ZW50LmRyb3B6b25lID0gaW50ZXJhY3Rpb24uZHJvcFRhcmdldDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChkcmFnRXZlbnQudHlwZSA9PT0gJ2RyYWdlbmQnICYmIGludGVyYWN0aW9uLmRyb3BUYXJnZXQpIHtcclxuICAgIGRyb3BFdmVudHMuZHJvcCA9IHV0aWxzLmV4dGVuZCh7IHR5cGU6ICdkcm9wJyB9LCB0bXBsKTtcclxuXHJcbiAgICBkcmFnRXZlbnQuZHJvcHpvbmUgPSBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0O1xyXG4gICAgZHJhZ0V2ZW50LnJlbGF0ZWRUYXJnZXQgPSBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudDtcclxuICB9XHJcbiAgaWYgKGRyYWdFdmVudC50eXBlID09PSAnZHJhZ3N0YXJ0Jykge1xyXG4gICAgZHJvcEV2ZW50cy5hY3RpdmF0ZSA9IHV0aWxzLmV4dGVuZCh7IHR5cGU6ICdkcm9wYWN0aXZhdGUnIH0sIHRtcGwpO1xyXG5cclxuICAgIGRyb3BFdmVudHMuYWN0aXZhdGUudGFyZ2V0ID0gbnVsbDtcclxuICAgIGRyb3BFdmVudHMuYWN0aXZhdGUuZHJvcHpvbmUgPSBudWxsO1xyXG4gIH1cclxuICBpZiAoZHJhZ0V2ZW50LnR5cGUgPT09ICdkcmFnZW5kJykge1xyXG4gICAgZHJvcEV2ZW50cy5kZWFjdGl2YXRlID0gdXRpbHMuZXh0ZW5kKHsgdHlwZTogJ2Ryb3BkZWFjdGl2YXRlJyB9LCB0bXBsKTtcclxuXHJcbiAgICBkcm9wRXZlbnRzLmRlYWN0aXZhdGUudGFyZ2V0ID0gbnVsbDtcclxuICAgIGRyb3BFdmVudHMuZGVhY3RpdmF0ZS5kcm9wem9uZSA9IG51bGw7XHJcbiAgfVxyXG4gIGlmIChkcmFnRXZlbnQudHlwZSA9PT0gJ2RyYWdtb3ZlJyAmJiBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0KSB7XHJcbiAgICBkcm9wRXZlbnRzLm1vdmUgPSB1dGlscy5leHRlbmQoe1xyXG4gICAgICBkcmFnbW92ZTogZHJhZ0V2ZW50LFxyXG4gICAgICB0eXBlOiAnZHJvcG1vdmUnXHJcbiAgICB9LCB0bXBsKTtcclxuXHJcbiAgICBkcmFnRXZlbnQuZHJvcHpvbmUgPSBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0O1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGRyb3BFdmVudHM7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGZpcmVEcm9wRXZlbnRzKGludGVyYWN0aW9uLCBkcm9wRXZlbnRzKSB7XHJcbiAgaWYgKGRyb3BFdmVudHMubGVhdmUpIHtcclxuICAgIGludGVyYWN0aW9uLnByZXZEcm9wVGFyZ2V0LmZpcmUoZHJvcEV2ZW50cy5sZWF2ZSk7XHJcbiAgfVxyXG4gIGlmIChkcm9wRXZlbnRzLm1vdmUpIHtcclxuICAgIGludGVyYWN0aW9uLmRyb3BUYXJnZXQuZmlyZShkcm9wRXZlbnRzLm1vdmUpO1xyXG4gIH1cclxuICBpZiAoZHJvcEV2ZW50cy5lbnRlcikge1xyXG4gICAgaW50ZXJhY3Rpb24uZHJvcFRhcmdldC5maXJlKGRyb3BFdmVudHMuZW50ZXIpO1xyXG4gIH1cclxuICBpZiAoZHJvcEV2ZW50cy5kcm9wKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0LmZpcmUoZHJvcEV2ZW50cy5kcm9wKTtcclxuICB9XHJcbiAgaWYgKGRyb3BFdmVudHMuZGVhY3RpdmF0ZSkge1xyXG4gICAgZmlyZUFjdGl2ZURyb3BzKGludGVyYWN0aW9uLCBkcm9wRXZlbnRzLmRlYWN0aXZhdGUpO1xyXG4gIH1cclxuXHJcbiAgaW50ZXJhY3Rpb24ucHJldkRyb3BUYXJnZXQgPSBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0O1xyXG4gIGludGVyYWN0aW9uLnByZXZEcm9wRWxlbWVudCA9IGludGVyYWN0aW9uLmRyb3BFbGVtZW50O1xyXG59XHJcblxyXG4vKlxcXHJcbiAqIEludGVyYWN0YWJsZS5kcm9wem9uZVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciBlbGVtZW50cyBjYW4gYmUgZHJvcHBlZCBvbnRvIHRoaXNcclxuICogSW50ZXJhY3RhYmxlIHRvIHRyaWdnZXIgZHJvcCBldmVudHNcclxuICpcclxuICogRHJvcHpvbmVzIGNhbiByZWNlaXZlIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxyXG4gKiAgLSBgZHJvcGFjdGl2YXRlYCBhbmQgYGRyb3BkZWFjdGl2YXRlYCB3aGVuIGFuIGFjY2VwdGFibGUgZHJhZyBzdGFydHMgYW5kIGVuZHNcclxuICogIC0gYGRyYWdlbnRlcmAgYW5kIGBkcmFnbGVhdmVgIHdoZW4gYSBkcmFnZ2FibGUgZW50ZXJzIGFuZCBsZWF2ZXMgdGhlIGRyb3B6b25lXHJcbiAqICAtIGBkcmFnbW92ZWAgd2hlbiBhIGRyYWdnYWJsZSB0aGF0IGhhcyBlbnRlcmVkIHRoZSBkcm9wem9uZSBpcyBtb3ZlZFxyXG4gKiAgLSBgZHJvcGAgd2hlbiBhIGRyYWdnYWJsZSBpcyBkcm9wcGVkIGludG8gdGhpcyBkcm9wem9uZVxyXG4gKlxyXG4gKiBVc2UgdGhlIGBhY2NlcHRgIG9wdGlvbiB0byBhbGxvdyBvbmx5IGVsZW1lbnRzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIENTU1xyXG4gKiBzZWxlY3RvciBvciBlbGVtZW50LiBUaGUgdmFsdWUgY2FuIGJlOlxyXG4gKlxyXG4gKiAgLSAqKmFuIEVsZW1lbnQqKiAtIG9ubHkgdGhhdCBlbGVtZW50IGNhbiBiZSBkcm9wcGVkIGludG8gdGhpcyBkcm9wem9uZS5cclxuICogIC0gKiphIHN0cmluZyoqLCAtIHRoZSBlbGVtZW50IGJlaW5nIGRyYWdnZWQgbXVzdCBtYXRjaCBpdCBhcyBhIENTUyBzZWxlY3Rvci5cclxuICogIC0gKipgbnVsbGAqKiAtIGFjY2VwdCBvcHRpb25zIGlzIGNsZWFyZWQgLSBpdCBhY2NlcHRzIGFueSBlbGVtZW50LlxyXG4gKlxyXG4gKiBVc2UgdGhlIGBvdmVybGFwYCBvcHRpb24gdG8gc2V0IGhvdyBkcm9wcyBhcmUgY2hlY2tlZCBmb3IuIFRoZSBhbGxvd2VkXHJcbiAqIHZhbHVlcyBhcmU6XHJcbiAqXHJcbiAqICAgLSBgJ3BvaW50ZXInYCwgdGhlIHBvaW50ZXIgbXVzdCBiZSBvdmVyIHRoZSBkcm9wem9uZSAoZGVmYXVsdClcclxuICogICAtIGAnY2VudGVyJ2AsIHRoZSBkcmFnZ2FibGUgZWxlbWVudCdzIGNlbnRlciBtdXN0IGJlIG92ZXIgdGhlIGRyb3B6b25lXHJcbiAqICAgLSBhIG51bWJlciBmcm9tIDAtMSB3aGljaCBpcyB0aGUgYChpbnRlcnNlY3Rpb24gYXJlYSkgLyAoZHJhZ2dhYmxlIGFyZWEpYC5cclxuICogICBlLmcuIGAwLjVgIGZvciBkcm9wIHRvIGhhcHBlbiB3aGVuIGhhbGYgb2YgdGhlIGFyZWEgb2YgdGhlIGRyYWdnYWJsZSBpc1xyXG4gKiAgIG92ZXIgdGhlIGRyb3B6b25lXHJcbiAqXHJcbiAqIFVzZSB0aGUgYGNoZWNrZXJgIG9wdGlvbiB0byBzcGVjaWZ5IGEgZnVuY3Rpb24gdG8gY2hlY2sgaWYgYSBkcmFnZ2VkXHJcbiAqIGVsZW1lbnQgaXMgb3ZlciB0aGlzIEludGVyYWN0YWJsZS5cclxuICpcclxuIHwgaW50ZXJhY3QodGFyZ2V0KVxyXG4gfCAuZHJvcENoZWNrZXIoZnVuY3Rpb24oZHJhZ0V2ZW50LCAgICAgICAgIC8vIHJlbGF0ZWQgZHJhZ21vdmUgb3IgZHJhZ2VuZCBldmVudFxyXG4gfCAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQsICAgICAgICAgICAgIC8vIFRvdWNoRXZlbnQvUG9pbnRlckV2ZW50L01vdXNlRXZlbnRcclxuIHwgICAgICAgICAgICAgICAgICAgICAgIGRyb3BwZWQsICAgICAgICAgICAvLyBib29sIHJlc3VsdCBvZiB0aGUgZGVmYXVsdCBjaGVja2VyXHJcbiB8ICAgICAgICAgICAgICAgICAgICAgICBkcm9wem9uZSwgICAgICAgICAgLy8gZHJvcHpvbmUgSW50ZXJhY3RhYmxlXHJcbiB8ICAgICAgICAgICAgICAgICAgICAgICBkcm9wRWxlbWVudCwgICAgICAgLy8gZHJvcHpvbmUgZWxlbW50XHJcbiB8ICAgICAgICAgICAgICAgICAgICAgICBkcmFnZ2FibGUsICAgICAgICAgLy8gZHJhZ2dhYmxlIEludGVyYWN0YWJsZVxyXG4gfCAgICAgICAgICAgICAgICAgICAgICAgZHJhZ2dhYmxlRWxlbWVudCkgey8vIGRyYWdnYWJsZSBlbGVtZW50XHJcbiB8XHJcbiB8ICAgcmV0dXJuIGRyb3BwZWQgJiYgZXZlbnQudGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnYWxsb3ctZHJvcCcpO1xyXG4gfCB9XHJcbiAqXHJcbiAqXHJcbiAtIG9wdGlvbnMgKGJvb2xlYW4gfCBvYmplY3QgfCBudWxsKSAjb3B0aW9uYWwgVGhlIG5ldyB2YWx1ZSB0byBiZSBzZXQuXHJcbiB8IGludGVyYWN0KCcuZHJvcCcpLmRyb3B6b25lKHtcclxuIHwgICBhY2NlcHQ6ICcuY2FuLWRyb3AnIHx8IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaW5nbGUtZHJvcCcpLFxyXG4gfCAgIG92ZXJsYXA6ICdwb2ludGVyJyB8fCAnY2VudGVyJyB8fCB6ZXJvVG9PbmVcclxuIHwgfVxyXG4gPSAoYm9vbGVhbiB8IG9iamVjdCkgVGhlIGN1cnJlbnQgc2V0dGluZyBvciB0aGlzIEludGVyYWN0YWJsZVxyXG5cXCovXHJcbkludGVyYWN0YWJsZS5wcm90b3R5cGUuZHJvcHpvbmUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gIGlmICh1dGlscy5pcy5vYmplY3Qob3B0aW9ucykpIHtcclxuICAgIHRoaXMub3B0aW9ucy5kcm9wLmVuYWJsZWQgPSBvcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlO1xyXG5cclxuICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihvcHRpb25zLm9uZHJvcCkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcm9wID0gb3B0aW9ucy5vbmRyb3A7XHJcbiAgICB9XHJcbiAgICBpZiAodXRpbHMuaXMuZnVuY3Rpb24ob3B0aW9ucy5vbmRyb3BhY3RpdmF0ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcm9wYWN0aXZhdGUgPSBvcHRpb25zLm9uZHJvcGFjdGl2YXRlO1xyXG4gICAgfVxyXG4gICAgaWYgKHV0aWxzLmlzLmZ1bmN0aW9uKG9wdGlvbnMub25kcm9wZGVhY3RpdmF0ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcm9wZGVhY3RpdmF0ZSA9IG9wdGlvbnMub25kcm9wZGVhY3RpdmF0ZTtcclxuICAgIH1cclxuICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihvcHRpb25zLm9uZHJhZ2VudGVyKSkge1xyXG4gICAgICB0aGlzLmV2ZW50cy5vbmRyYWdlbnRlciA9IG9wdGlvbnMub25kcmFnZW50ZXI7XHJcbiAgICB9XHJcbiAgICBpZiAodXRpbHMuaXMuZnVuY3Rpb24ob3B0aW9ucy5vbmRyYWdsZWF2ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcmFnbGVhdmUgPSBvcHRpb25zLm9uZHJhZ2xlYXZlO1xyXG4gICAgfVxyXG4gICAgaWYgKHV0aWxzLmlzLmZ1bmN0aW9uKG9wdGlvbnMub25kcm9wbW92ZSkpIHtcclxuICAgICAgdGhpcy5ldmVudHMub25kcm9wbW92ZSA9IG9wdGlvbnMub25kcm9wbW92ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoL14ocG9pbnRlcnxjZW50ZXIpJC8udGVzdChvcHRpb25zLm92ZXJsYXApKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kcm9wLm92ZXJsYXAgPSBvcHRpb25zLm92ZXJsYXA7XHJcbiAgICB9IGVsc2UgaWYgKHV0aWxzLmlzLm51bWJlcihvcHRpb25zLm92ZXJsYXApKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kcm9wLm92ZXJsYXAgPSBNYXRoLm1heChNYXRoLm1pbigxLCBvcHRpb25zLm92ZXJsYXApLCAwKTtcclxuICAgIH1cclxuICAgIGlmICgnYWNjZXB0JyBpbiBvcHRpb25zKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kcm9wLmFjY2VwdCA9IG9wdGlvbnMuYWNjZXB0O1xyXG4gICAgfVxyXG4gICAgaWYgKCdjaGVja2VyJyBpbiBvcHRpb25zKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXIgPSBvcHRpb25zLmNoZWNrZXI7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAodXRpbHMuaXMuYm9vbChvcHRpb25zKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLmRyb3AuZW5hYmxlZCA9IG9wdGlvbnM7XHJcblxyXG4gICAgaWYgKCFvcHRpb25zKSB7XHJcbiAgICAgIHRoaXMub25kcmFnZW50ZXIgPSB0aGlzLm9uZHJhZ2xlYXZlID0gdGhpcy5vbmRyb3AgPSB0aGlzLm9uZHJvcGFjdGl2YXRlID0gdGhpcy5vbmRyb3BkZWFjdGl2YXRlID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHJldHVybiB0aGlzLm9wdGlvbnMuZHJvcDtcclxufTtcclxuXHJcbkludGVyYWN0YWJsZS5wcm90b3R5cGUuZHJvcENoZWNrID0gZnVuY3Rpb24gKGRyYWdFdmVudCwgZXZlbnQsIGRyYWdnYWJsZSwgZHJhZ2dhYmxlRWxlbWVudCwgZHJvcEVsZW1lbnQsIHJlY3QpIHtcclxuICB2YXIgZHJvcHBlZCA9IGZhbHNlO1xyXG5cclxuICAvLyBpZiB0aGUgZHJvcHpvbmUgaGFzIG5vIHJlY3QgKGVnLiBkaXNwbGF5OiBub25lKVxyXG4gIC8vIGNhbGwgdGhlIGN1c3RvbSBkcm9wQ2hlY2tlciBvciBqdXN0IHJldHVybiBmYWxzZVxyXG4gIGlmICghKHJlY3QgPSByZWN0IHx8IHRoaXMuZ2V0UmVjdChkcm9wRWxlbWVudCkpKSB7XHJcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmRyb3AuY2hlY2tlciA/IHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXIoZHJhZ0V2ZW50LCBldmVudCwgZHJvcHBlZCwgdGhpcywgZHJvcEVsZW1lbnQsIGRyYWdnYWJsZSwgZHJhZ2dhYmxlRWxlbWVudCkgOiBmYWxzZTtcclxuICB9XHJcblxyXG4gIHZhciBkcm9wT3ZlcmxhcCA9IHRoaXMub3B0aW9ucy5kcm9wLm92ZXJsYXA7XHJcblxyXG4gIGlmIChkcm9wT3ZlcmxhcCA9PT0gJ3BvaW50ZXInKSB7XHJcbiAgICB2YXIgb3JpZ2luID0gdXRpbHMuZ2V0T3JpZ2luWFkoZHJhZ2dhYmxlLCBkcmFnZ2FibGVFbGVtZW50LCAnZHJhZycpO1xyXG4gICAgdmFyIHBhZ2UgPSB1dGlscy5nZXRQYWdlWFkoZHJhZ0V2ZW50KTtcclxuXHJcbiAgICBwYWdlLnggKz0gb3JpZ2luLng7XHJcbiAgICBwYWdlLnkgKz0gb3JpZ2luLnk7XHJcblxyXG4gICAgdmFyIGhvcml6b250YWwgPSBwYWdlLnggPiByZWN0LmxlZnQgJiYgcGFnZS54IDwgcmVjdC5yaWdodDtcclxuICAgIHZhciB2ZXJ0aWNhbCA9IHBhZ2UueSA+IHJlY3QudG9wICYmIHBhZ2UueSA8IHJlY3QuYm90dG9tO1xyXG5cclxuICAgIGRyb3BwZWQgPSBob3Jpem9udGFsICYmIHZlcnRpY2FsO1xyXG4gIH1cclxuXHJcbiAgdmFyIGRyYWdSZWN0ID0gZHJhZ2dhYmxlLmdldFJlY3QoZHJhZ2dhYmxlRWxlbWVudCk7XHJcblxyXG4gIGlmIChkcmFnUmVjdCAmJiBkcm9wT3ZlcmxhcCA9PT0gJ2NlbnRlcicpIHtcclxuICAgIHZhciBjeCA9IGRyYWdSZWN0LmxlZnQgKyBkcmFnUmVjdC53aWR0aCAvIDI7XHJcbiAgICB2YXIgY3kgPSBkcmFnUmVjdC50b3AgKyBkcmFnUmVjdC5oZWlnaHQgLyAyO1xyXG5cclxuICAgIGRyb3BwZWQgPSBjeCA+PSByZWN0LmxlZnQgJiYgY3ggPD0gcmVjdC5yaWdodCAmJiBjeSA+PSByZWN0LnRvcCAmJiBjeSA8PSByZWN0LmJvdHRvbTtcclxuICB9XHJcblxyXG4gIGlmIChkcmFnUmVjdCAmJiB1dGlscy5pcy5udW1iZXIoZHJvcE92ZXJsYXApKSB7XHJcbiAgICB2YXIgb3ZlcmxhcEFyZWEgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihyZWN0LnJpZ2h0LCBkcmFnUmVjdC5yaWdodCkgLSBNYXRoLm1heChyZWN0LmxlZnQsIGRyYWdSZWN0LmxlZnQpKSAqIE1hdGgubWF4KDAsIE1hdGgubWluKHJlY3QuYm90dG9tLCBkcmFnUmVjdC5ib3R0b20pIC0gTWF0aC5tYXgocmVjdC50b3AsIGRyYWdSZWN0LnRvcCkpO1xyXG5cclxuICAgIHZhciBvdmVybGFwUmF0aW8gPSBvdmVybGFwQXJlYSAvIChkcmFnUmVjdC53aWR0aCAqIGRyYWdSZWN0LmhlaWdodCk7XHJcblxyXG4gICAgZHJvcHBlZCA9IG92ZXJsYXBSYXRpbyA+PSBkcm9wT3ZlcmxhcDtcclxuICB9XHJcblxyXG4gIGlmICh0aGlzLm9wdGlvbnMuZHJvcC5jaGVja2VyKSB7XHJcbiAgICBkcm9wcGVkID0gdGhpcy5vcHRpb25zLmRyb3AuY2hlY2tlcihkcmFnRXZlbnQsIGV2ZW50LCBkcm9wcGVkLCB0aGlzLCBkcm9wRWxlbWVudCwgZHJhZ2dhYmxlLCBkcmFnZ2FibGVFbGVtZW50KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBkcm9wcGVkO1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnNpZ25hbHMub24oJ3Vuc2V0JywgZnVuY3Rpb24gKF9yZWY3KSB7XHJcbiAgdmFyIGludGVyYWN0YWJsZSA9IF9yZWY3LmludGVyYWN0YWJsZTtcclxuXHJcbiAgaW50ZXJhY3RhYmxlLmRyb3B6b25lKGZhbHNlKTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLnB1c2goJ2Ryb3BDaGVja2VyJyk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCduZXcnLCBmdW5jdGlvbiAoaW50ZXJhY3Rpb24pIHtcclxuICBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0ID0gbnVsbDsgLy8gdGhlIGRyb3B6b25lIGEgZHJhZyB0YXJnZXQgbWlnaHQgYmUgZHJvcHBlZCBpbnRvXHJcbiAgaW50ZXJhY3Rpb24uZHJvcEVsZW1lbnQgPSBudWxsOyAvLyB0aGUgZWxlbWVudCBhdCB0aGUgdGltZSBvZiBjaGVja2luZ1xyXG4gIGludGVyYWN0aW9uLnByZXZEcm9wVGFyZ2V0ID0gbnVsbDsgLy8gdGhlIGRyb3B6b25lIHRoYXQgd2FzIHJlY2VudGx5IGRyYWdnZWQgYXdheSBmcm9tXHJcbiAgaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50ID0gbnVsbDsgLy8gdGhlIGVsZW1lbnQgYXQgdGhlIHRpbWUgb2YgY2hlY2tpbmdcclxuICBpbnRlcmFjdGlvbi5kcm9wRXZlbnRzID0gbnVsbDsgLy8gdGhlIGRyb3BFdmVudHMgcmVsYXRlZCB0byB0aGUgY3VycmVudCBkcmFnIGV2ZW50XHJcblxyXG4gIGludGVyYWN0aW9uLmFjdGl2ZURyb3BzID0ge1xyXG4gICAgZHJvcHpvbmVzOiBbXSwgLy8gdGhlIGRyb3B6b25lcyB0aGF0IGFyZSBtZW50aW9uZWQgYmVsb3dcclxuICAgIGVsZW1lbnRzOiBbXSwgLy8gZWxlbWVudHMgb2YgZHJvcHpvbmVzIHRoYXQgYWNjZXB0IHRoZSB0YXJnZXQgZHJhZ2dhYmxlXHJcbiAgICByZWN0czogW10gLy8gdGhlIHJlY3RzIG9mIHRoZSBlbGVtZW50cyBtZW50aW9uZWQgYWJvdmVcclxuICB9O1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3N0b3AnLCBmdW5jdGlvbiAoX3JlZjgpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmOC5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaW50ZXJhY3Rpb24uZHJvcFRhcmdldCA9IGludGVyYWN0aW9uLmRyb3BFbGVtZW50ID0gaW50ZXJhY3Rpb24ucHJldkRyb3BUYXJnZXQgPSBpbnRlcmFjdGlvbi5wcmV2RHJvcEVsZW1lbnQgPSBudWxsO1xyXG59KTtcclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3QuZHluYW1pY0Ryb3BcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogUmV0dXJucyBvciBzZXRzIHdoZXRoZXIgdGhlIGRpbWVuc2lvbnMgb2YgZHJvcHpvbmUgZWxlbWVudHMgYXJlXHJcbiAqIGNhbGN1bGF0ZWQgb24gZXZlcnkgZHJhZ21vdmUgb3Igb25seSBvbiBkcmFnc3RhcnQgZm9yIHRoZSBkZWZhdWx0XHJcbiAqIGRyb3BDaGVja2VyXHJcbiAqXHJcbiAtIG5ld1ZhbHVlIChib29sZWFuKSAjb3B0aW9uYWwgVHJ1ZSB0byBjaGVjayBvbiBlYWNoIG1vdmUuIEZhbHNlIHRvIGNoZWNrIG9ubHkgYmVmb3JlIHN0YXJ0XHJcbiA9IChib29sZWFuIHwgaW50ZXJhY3QpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgaW50ZXJhY3RcclxuXFwqL1xyXG5pbnRlcmFjdC5keW5hbWljRHJvcCA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmICh1dGlscy5pcy5ib29sKG5ld1ZhbHVlKSkge1xyXG4gICAgLy9pZiAoZHJhZ2dpbmcgJiYgZHluYW1pY0Ryb3AgIT09IG5ld1ZhbHVlICYmICFuZXdWYWx1ZSkge1xyXG4gICAgLy9jYWxjUmVjdHMoZHJvcHpvbmVzKTtcclxuICAgIC8vfVxyXG5cclxuICAgIGR5bmFtaWNEcm9wID0gbmV3VmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIGludGVyYWN0O1xyXG4gIH1cclxuICByZXR1cm4gZHluYW1pY0Ryb3A7XHJcbn07XHJcblxyXG51dGlscy5tZXJnZShJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgWydkcmFnZW50ZXInLCAnZHJhZ2xlYXZlJywgJ2Ryb3BhY3RpdmF0ZScsICdkcm9wZGVhY3RpdmF0ZScsICdkcm9wbW92ZScsICdkcm9wJ10pO1xyXG5hY3Rpb25zLm1ldGhvZERpY3QuZHJvcCA9ICdkcm9wem9uZSc7XHJcblxyXG5kZWZhdWx0T3B0aW9ucy5kcm9wID0gZHJvcC5kZWZhdWx0cztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZHJvcDtcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vSW50ZXJhY3Rpb25cIjo1LFwiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL2ludGVyYWN0XCI6MjEsXCIuLi9zY29wZVwiOjM0LFwiLi4vdXRpbHNcIjo0NCxcIi4vYmFzZVwiOjZ9XSw5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIEludGVyYWN0RXZlbnQgPSByZXF1aXJlKCcuLi9JbnRlcmFjdEV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcclxudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbnZhciBnZXN0dXJlID0ge1xyXG4gIGRlZmF1bHRzOiB7XHJcbiAgICBlbmFibGVkOiBmYWxzZSxcclxuICAgIG9yaWdpbjogbnVsbCxcclxuICAgIHJlc3RyaWN0OiBudWxsXHJcbiAgfSxcclxuXHJcbiAgY2hlY2tlcjogZnVuY3Rpb24gY2hlY2tlcihwb2ludGVyLCBldmVudCwgaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBpbnRlcmFjdGlvbikge1xyXG4gICAgaWYgKGludGVyYWN0aW9uLnBvaW50ZXJJZHMubGVuZ3RoID49IDIpIHtcclxuICAgICAgcmV0dXJuIHsgbmFtZTogJ2dlc3R1cmUnIH07XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfSxcclxuXHJcbiAgZ2V0Q3Vyc29yOiBmdW5jdGlvbiBnZXRDdXJzb3IoKSB7XHJcbiAgICByZXR1cm4gJyc7XHJcbiAgfVxyXG59O1xyXG5cclxuSW50ZXJhY3RFdmVudC5zaWduYWxzLm9uKCduZXcnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciBpRXZlbnQgPSBfcmVmLmlFdmVudCxcclxuICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uO1xyXG5cclxuICBpZiAoaUV2ZW50LnR5cGUgIT09ICdnZXN0dXJlc3RhcnQnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG4gIGlFdmVudC5kcyA9IDA7XHJcblxyXG4gIGludGVyYWN0aW9uLmdlc3R1cmUuc3RhcnREaXN0YW5jZSA9IGludGVyYWN0aW9uLmdlc3R1cmUucHJldkRpc3RhbmNlID0gaUV2ZW50LmRpc3RhbmNlO1xyXG4gIGludGVyYWN0aW9uLmdlc3R1cmUuc3RhcnRBbmdsZSA9IGludGVyYWN0aW9uLmdlc3R1cmUucHJldkFuZ2xlID0gaUV2ZW50LmFuZ2xlO1xyXG4gIGludGVyYWN0aW9uLmdlc3R1cmUuc2NhbGUgPSAxO1xyXG59KTtcclxuXHJcbkludGVyYWN0RXZlbnQuc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKF9yZWYyKSB7XHJcbiAgdmFyIGlFdmVudCA9IF9yZWYyLmlFdmVudCxcclxuICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbjtcclxuXHJcbiAgaWYgKGlFdmVudC50eXBlICE9PSAnZ2VzdHVyZW1vdmUnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBpRXZlbnQuZHMgPSBpRXZlbnQuc2NhbGUgLSBpbnRlcmFjdGlvbi5nZXN0dXJlLnNjYWxlO1xyXG5cclxuICBpbnRlcmFjdGlvbi50YXJnZXQuZmlyZShpRXZlbnQpO1xyXG5cclxuICBpbnRlcmFjdGlvbi5nZXN0dXJlLnByZXZBbmdsZSA9IGlFdmVudC5hbmdsZTtcclxuICBpbnRlcmFjdGlvbi5nZXN0dXJlLnByZXZEaXN0YW5jZSA9IGlFdmVudC5kaXN0YW5jZTtcclxuXHJcbiAgaWYgKGlFdmVudC5zY2FsZSAhPT0gSW5maW5pdHkgJiYgaUV2ZW50LnNjYWxlICE9PSBudWxsICYmIGlFdmVudC5zY2FsZSAhPT0gdW5kZWZpbmVkICYmICFpc05hTihpRXZlbnQuc2NhbGUpKSB7XHJcblxyXG4gICAgaW50ZXJhY3Rpb24uZ2VzdHVyZS5zY2FsZSA9IGlFdmVudC5zY2FsZTtcclxuICB9XHJcbn0pO1xyXG5cclxuLypcXFxyXG4gKiBJbnRlcmFjdGFibGUuZ2VzdHVyYWJsZVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBHZXRzIG9yIHNldHMgd2hldGhlciBtdWx0aXRvdWNoIGdlc3R1cmVzIGNhbiBiZSBwZXJmb3JtZWQgb24gdGhlXHJcbiAqIEludGVyYWN0YWJsZSdzIGVsZW1lbnRcclxuICpcclxuID0gKGJvb2xlYW4pIEluZGljYXRlcyBpZiB0aGlzIGNhbiBiZSB0aGUgdGFyZ2V0IG9mIGdlc3R1cmUgZXZlbnRzXHJcbiAgIHwgdmFyIGlzR2VzdHVyZWFibGUgPSBpbnRlcmFjdChlbGVtZW50KS5nZXN0dXJhYmxlKCk7XHJcbiAqIG9yXHJcbiAtIG9wdGlvbnMgKGJvb2xlYW4gfCBvYmplY3QpICNvcHRpb25hbCB0cnVlL2ZhbHNlIG9yIEFuIG9iamVjdCB3aXRoIGV2ZW50IGxpc3RlbmVycyB0byBiZSBmaXJlZCBvbiBnZXN0dXJlIGV2ZW50cyAobWFrZXMgdGhlIEludGVyYWN0YWJsZSBnZXN0dXJhYmxlKVxyXG4gPSAob2JqZWN0KSB0aGlzIEludGVyYWN0YWJsZVxyXG4gfCBpbnRlcmFjdChlbGVtZW50KS5nZXN0dXJhYmxlKHtcclxuIHwgICAgIG9uc3RhcnQ6IGZ1bmN0aW9uIChldmVudCkge30sXHJcbiB8ICAgICBvbm1vdmUgOiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxyXG4gfCAgICAgb25lbmQgIDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcclxuIHxcclxuIHwgICAgIC8vIGxpbWl0IG11bHRpcGxlIGdlc3R1cmVzLlxyXG4gfCAgICAgLy8gU2VlIHRoZSBleHBsYW5hdGlvbiBpbiBASW50ZXJhY3RhYmxlLmRyYWdnYWJsZSBleGFtcGxlXHJcbiB8ICAgICBtYXg6IEluZmluaXR5LFxyXG4gfCAgICAgbWF4UGVyRWxlbWVudDogMSxcclxuIHwgfSk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5nZXN0dXJhYmxlID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICBpZiAodXRpbHMuaXMub2JqZWN0KG9wdGlvbnMpKSB7XHJcbiAgICB0aGlzLm9wdGlvbnMuZ2VzdHVyZS5lbmFibGVkID0gb3B0aW9ucy5lbmFibGVkID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZTtcclxuICAgIHRoaXMuc2V0UGVyQWN0aW9uKCdnZXN0dXJlJywgb3B0aW9ucyk7XHJcbiAgICB0aGlzLnNldE9uRXZlbnRzKCdnZXN0dXJlJywgb3B0aW9ucyk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAodXRpbHMuaXMuYm9vbChvcHRpb25zKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLmdlc3R1cmUuZW5hYmxlZCA9IG9wdGlvbnM7XHJcblxyXG4gICAgaWYgKCFvcHRpb25zKSB7XHJcbiAgICAgIHRoaXMub25nZXN0dXJlc3RhcnQgPSB0aGlzLm9uZ2VzdHVyZXN0YXJ0ID0gdGhpcy5vbmdlc3R1cmVlbmQgPSBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHRoaXMub3B0aW9ucy5nZXN0dXJlO1xyXG59O1xyXG5cclxuSW50ZXJhY3RFdmVudC5zaWduYWxzLm9uKCdzZXQtZGVsdGEnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbixcclxuICAgICAgaUV2ZW50ID0gX3JlZjMuaUV2ZW50LFxyXG4gICAgICBhY3Rpb24gPSBfcmVmMy5hY3Rpb24sXHJcbiAgICAgIGV2ZW50ID0gX3JlZjMuZXZlbnQsXHJcbiAgICAgIHN0YXJ0aW5nID0gX3JlZjMuc3RhcnRpbmcsXHJcbiAgICAgIGVuZGluZyA9IF9yZWYzLmVuZGluZyxcclxuICAgICAgZGVsdGFTb3VyY2UgPSBfcmVmMy5kZWx0YVNvdXJjZTtcclxuXHJcbiAgaWYgKGFjdGlvbiAhPT0gJ2dlc3R1cmUnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgcG9pbnRlcnMgPSBpbnRlcmFjdGlvbi5wb2ludGVycztcclxuXHJcbiAgaUV2ZW50LnRvdWNoZXMgPSBbcG9pbnRlcnNbMF0sIHBvaW50ZXJzWzFdXTtcclxuXHJcbiAgaWYgKHN0YXJ0aW5nKSB7XHJcbiAgICBpRXZlbnQuZGlzdGFuY2UgPSB1dGlscy50b3VjaERpc3RhbmNlKHBvaW50ZXJzLCBkZWx0YVNvdXJjZSk7XHJcbiAgICBpRXZlbnQuYm94ID0gdXRpbHMudG91Y2hCQm94KHBvaW50ZXJzKTtcclxuICAgIGlFdmVudC5zY2FsZSA9IDE7XHJcbiAgICBpRXZlbnQuZHMgPSAwO1xyXG4gICAgaUV2ZW50LmFuZ2xlID0gdXRpbHMudG91Y2hBbmdsZShwb2ludGVycywgdW5kZWZpbmVkLCBkZWx0YVNvdXJjZSk7XHJcbiAgICBpRXZlbnQuZGEgPSAwO1xyXG4gIH0gZWxzZSBpZiAoZW5kaW5nIHx8IGV2ZW50IGluc3RhbmNlb2YgSW50ZXJhY3RFdmVudCkge1xyXG4gICAgaUV2ZW50LmRpc3RhbmNlID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LmRpc3RhbmNlO1xyXG4gICAgaUV2ZW50LmJveCA9IGludGVyYWN0aW9uLnByZXZFdmVudC5ib3g7XHJcbiAgICBpRXZlbnQuc2NhbGUgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQuc2NhbGU7XHJcbiAgICBpRXZlbnQuZHMgPSBpRXZlbnQuc2NhbGUgLSAxO1xyXG4gICAgaUV2ZW50LmFuZ2xlID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LmFuZ2xlO1xyXG4gICAgaUV2ZW50LmRhID0gaUV2ZW50LmFuZ2xlIC0gaW50ZXJhY3Rpb24uZ2VzdHVyZS5zdGFydEFuZ2xlO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBpRXZlbnQuZGlzdGFuY2UgPSB1dGlscy50b3VjaERpc3RhbmNlKHBvaW50ZXJzLCBkZWx0YVNvdXJjZSk7XHJcbiAgICBpRXZlbnQuYm94ID0gdXRpbHMudG91Y2hCQm94KHBvaW50ZXJzKTtcclxuICAgIGlFdmVudC5zY2FsZSA9IGlFdmVudC5kaXN0YW5jZSAvIGludGVyYWN0aW9uLmdlc3R1cmUuc3RhcnREaXN0YW5jZTtcclxuICAgIGlFdmVudC5hbmdsZSA9IHV0aWxzLnRvdWNoQW5nbGUocG9pbnRlcnMsIGludGVyYWN0aW9uLmdlc3R1cmUucHJldkFuZ2xlLCBkZWx0YVNvdXJjZSk7XHJcblxyXG4gICAgaUV2ZW50LmRzID0gaUV2ZW50LnNjYWxlIC0gaW50ZXJhY3Rpb24uZ2VzdHVyZS5wcmV2U2NhbGU7XHJcbiAgICBpRXZlbnQuZGEgPSBpRXZlbnQuYW5nbGUgLSBpbnRlcmFjdGlvbi5nZXN0dXJlLnByZXZBbmdsZTtcclxuICB9XHJcbn0pO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XHJcbiAgaW50ZXJhY3Rpb24uZ2VzdHVyZSA9IHtcclxuICAgIHN0YXJ0OiB7IHg6IDAsIHk6IDAgfSxcclxuXHJcbiAgICBzdGFydERpc3RhbmNlOiAwLCAvLyBkaXN0YW5jZSBiZXR3ZWVuIHR3byB0b3VjaGVzIG9mIHRvdWNoU3RhcnRcclxuICAgIHByZXZEaXN0YW5jZTogMCxcclxuICAgIGRpc3RhbmNlOiAwLFxyXG5cclxuICAgIHNjYWxlOiAxLCAvLyBnZXN0dXJlLmRpc3RhbmNlIC8gZ2VzdHVyZS5zdGFydERpc3RhbmNlXHJcblxyXG4gICAgc3RhcnRBbmdsZTogMCwgLy8gYW5nbGUgb2YgbGluZSBqb2luaW5nIHR3byB0b3VjaGVzXHJcbiAgICBwcmV2QW5nbGU6IDAgLy8gYW5nbGUgb2YgdGhlIHByZXZpb3VzIGdlc3R1cmUgZXZlbnRcclxuICB9O1xyXG59KTtcclxuXHJcbmFjdGlvbnMuZ2VzdHVyZSA9IGdlc3R1cmU7XHJcbmFjdGlvbnMubmFtZXMucHVzaCgnZ2VzdHVyZScpO1xyXG51dGlscy5tZXJnZShJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgWydnZXN0dXJlc3RhcnQnLCAnZ2VzdHVyZW1vdmUnLCAnZ2VzdHVyZWVuZCddKTtcclxuYWN0aW9ucy5tZXRob2REaWN0Lmdlc3R1cmUgPSAnZ2VzdHVyYWJsZSc7XHJcblxyXG5kZWZhdWx0T3B0aW9ucy5nZXN0dXJlID0gZ2VzdHVyZS5kZWZhdWx0cztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZ2VzdHVyZTtcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vSW50ZXJhY3Rpb25cIjo1LFwiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL3V0aWxzXCI6NDQsXCIuL2Jhc2VcIjo2fV0sMTA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4vYmFzZScpO1xyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xyXG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcclxudmFyIEludGVyYWN0RXZlbnQgPSByZXF1aXJlKCcuLi9JbnRlcmFjdEV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcclxudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbi8vIExlc3MgUHJlY2lzaW9uIHdpdGggdG91Y2ggaW5wdXRcclxudmFyIGRlZmF1bHRNYXJnaW4gPSBicm93c2VyLnN1cHBvcnRzVG91Y2ggfHwgYnJvd3Nlci5zdXBwb3J0c1BvaW50ZXJFdmVudCA/IDIwIDogMTA7XHJcblxyXG52YXIgcmVzaXplID0ge1xyXG4gIGRlZmF1bHRzOiB7XHJcbiAgICBlbmFibGVkOiBmYWxzZSxcclxuICAgIG1vdXNlQnV0dG9uczogbnVsbCxcclxuXHJcbiAgICBvcmlnaW46IG51bGwsXHJcbiAgICBzbmFwOiBudWxsLFxyXG4gICAgcmVzdHJpY3Q6IG51bGwsXHJcbiAgICBpbmVydGlhOiBudWxsLFxyXG4gICAgYXV0b1Njcm9sbDogbnVsbCxcclxuXHJcbiAgICBzcXVhcmU6IGZhbHNlLFxyXG4gICAgcHJlc2VydmVBc3BlY3RSYXRpbzogZmFsc2UsXHJcbiAgICBheGlzOiAneHknLFxyXG5cclxuICAgIC8vIHVzZSBkZWZhdWx0IG1hcmdpblxyXG4gICAgbWFyZ2luOiBOYU4sXHJcblxyXG4gICAgLy8gb2JqZWN0IHdpdGggcHJvcHMgbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tIHdoaWNoIGFyZVxyXG4gICAgLy8gdHJ1ZS9mYWxzZSB2YWx1ZXMgdG8gcmVzaXplIHdoZW4gdGhlIHBvaW50ZXIgaXMgb3ZlciB0aGF0IGVkZ2UsXHJcbiAgICAvLyBDU1Mgc2VsZWN0b3JzIHRvIG1hdGNoIHRoZSBoYW5kbGVzIGZvciBlYWNoIGRpcmVjdGlvblxyXG4gICAgLy8gb3IgdGhlIEVsZW1lbnRzIGZvciBlYWNoIGhhbmRsZVxyXG4gICAgZWRnZXM6IG51bGwsXHJcblxyXG4gICAgLy8gYSB2YWx1ZSBvZiAnbm9uZScgd2lsbCBsaW1pdCB0aGUgcmVzaXplIHJlY3QgdG8gYSBtaW5pbXVtIG9mIDB4MFxyXG4gICAgLy8gJ25lZ2F0ZScgd2lsbCBhbG93IHRoZSByZWN0IHRvIGhhdmUgbmVnYXRpdmUgd2lkdGgvaGVpZ2h0XHJcbiAgICAvLyAncmVwb3NpdGlvbicgd2lsbCBrZWVwIHRoZSB3aWR0aC9oZWlnaHQgcG9zaXRpdmUgYnkgc3dhcHBpbmdcclxuICAgIC8vIHRoZSB0b3AgYW5kIGJvdHRvbSBlZGdlcyBhbmQvb3Igc3dhcHBpbmcgdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzXHJcbiAgICBpbnZlcnQ6ICdub25lJ1xyXG4gIH0sXHJcblxyXG4gIGNoZWNrZXI6IGZ1bmN0aW9uIGNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0YWJsZSwgZWxlbWVudCwgaW50ZXJhY3Rpb24sIHJlY3QpIHtcclxuICAgIGlmICghcmVjdCkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcGFnZSA9IHV0aWxzLmV4dGVuZCh7fSwgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UpO1xyXG4gICAgdmFyIG9wdGlvbnMgPSBpbnRlcmFjdGFibGUub3B0aW9ucztcclxuXHJcbiAgICBpZiAob3B0aW9ucy5yZXNpemUuZW5hYmxlZCkge1xyXG4gICAgICB2YXIgcmVzaXplT3B0aW9ucyA9IG9wdGlvbnMucmVzaXplO1xyXG4gICAgICB2YXIgcmVzaXplRWRnZXMgPSB7IGxlZnQ6IGZhbHNlLCByaWdodDogZmFsc2UsIHRvcDogZmFsc2UsIGJvdHRvbTogZmFsc2UgfTtcclxuXHJcbiAgICAgIC8vIGlmIHVzaW5nIHJlc2l6ZS5lZGdlc1xyXG4gICAgICBpZiAodXRpbHMuaXMub2JqZWN0KHJlc2l6ZU9wdGlvbnMuZWRnZXMpKSB7XHJcbiAgICAgICAgZm9yICh2YXIgZWRnZSBpbiByZXNpemVFZGdlcykge1xyXG4gICAgICAgICAgcmVzaXplRWRnZXNbZWRnZV0gPSBjaGVja1Jlc2l6ZUVkZ2UoZWRnZSwgcmVzaXplT3B0aW9ucy5lZGdlc1tlZGdlXSwgcGFnZSwgaW50ZXJhY3Rpb24uX2V2ZW50VGFyZ2V0LCBlbGVtZW50LCByZWN0LCByZXNpemVPcHRpb25zLm1hcmdpbiB8fCBkZWZhdWx0TWFyZ2luKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJlc2l6ZUVkZ2VzLmxlZnQgPSByZXNpemVFZGdlcy5sZWZ0ICYmICFyZXNpemVFZGdlcy5yaWdodDtcclxuICAgICAgICByZXNpemVFZGdlcy50b3AgPSByZXNpemVFZGdlcy50b3AgJiYgIXJlc2l6ZUVkZ2VzLmJvdHRvbTtcclxuXHJcbiAgICAgICAgaWYgKHJlc2l6ZUVkZ2VzLmxlZnQgfHwgcmVzaXplRWRnZXMucmlnaHQgfHwgcmVzaXplRWRnZXMudG9wIHx8IHJlc2l6ZUVkZ2VzLmJvdHRvbSkge1xyXG4gICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgbmFtZTogJ3Jlc2l6ZScsXHJcbiAgICAgICAgICAgIGVkZ2VzOiByZXNpemVFZGdlc1xyXG4gICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFyIHJpZ2h0ID0gb3B0aW9ucy5yZXNpemUuYXhpcyAhPT0gJ3knICYmIHBhZ2UueCA+IHJlY3QucmlnaHQgLSBkZWZhdWx0TWFyZ2luO1xyXG4gICAgICAgIHZhciBib3R0b20gPSBvcHRpb25zLnJlc2l6ZS5heGlzICE9PSAneCcgJiYgcGFnZS55ID4gcmVjdC5ib3R0b20gLSBkZWZhdWx0TWFyZ2luO1xyXG5cclxuICAgICAgICBpZiAocmlnaHQgfHwgYm90dG9tKSB7XHJcbiAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBuYW1lOiAncmVzaXplJyxcclxuICAgICAgICAgICAgYXhlczogKHJpZ2h0ID8gJ3gnIDogJycpICsgKGJvdHRvbSA/ICd5JyA6ICcnKVxyXG4gICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9LFxyXG5cclxuICBjdXJzb3JzOiBicm93c2VyLmlzSWU5T3JPbGRlciA/IHtcclxuICAgIHg6ICdlLXJlc2l6ZScsXHJcbiAgICB5OiAncy1yZXNpemUnLFxyXG4gICAgeHk6ICdzZS1yZXNpemUnLFxyXG5cclxuICAgIHRvcDogJ24tcmVzaXplJyxcclxuICAgIGxlZnQ6ICd3LXJlc2l6ZScsXHJcbiAgICBib3R0b206ICdzLXJlc2l6ZScsXHJcbiAgICByaWdodDogJ2UtcmVzaXplJyxcclxuICAgIHRvcGxlZnQ6ICdzZS1yZXNpemUnLFxyXG4gICAgYm90dG9tcmlnaHQ6ICdzZS1yZXNpemUnLFxyXG4gICAgdG9wcmlnaHQ6ICduZS1yZXNpemUnLFxyXG4gICAgYm90dG9tbGVmdDogJ25lLXJlc2l6ZSdcclxuICB9IDoge1xyXG4gICAgeDogJ2V3LXJlc2l6ZScsXHJcbiAgICB5OiAnbnMtcmVzaXplJyxcclxuICAgIHh5OiAnbndzZS1yZXNpemUnLFxyXG5cclxuICAgIHRvcDogJ25zLXJlc2l6ZScsXHJcbiAgICBsZWZ0OiAnZXctcmVzaXplJyxcclxuICAgIGJvdHRvbTogJ25zLXJlc2l6ZScsXHJcbiAgICByaWdodDogJ2V3LXJlc2l6ZScsXHJcbiAgICB0b3BsZWZ0OiAnbndzZS1yZXNpemUnLFxyXG4gICAgYm90dG9tcmlnaHQ6ICdud3NlLXJlc2l6ZScsXHJcbiAgICB0b3ByaWdodDogJ25lc3ctcmVzaXplJyxcclxuICAgIGJvdHRvbWxlZnQ6ICduZXN3LXJlc2l6ZSdcclxuICB9LFxyXG5cclxuICBnZXRDdXJzb3I6IGZ1bmN0aW9uIGdldEN1cnNvcihhY3Rpb24pIHtcclxuICAgIGlmIChhY3Rpb24uYXhpcykge1xyXG4gICAgICByZXR1cm4gcmVzaXplLmN1cnNvcnNbYWN0aW9uLm5hbWUgKyBhY3Rpb24uYXhpc107XHJcbiAgICB9IGVsc2UgaWYgKGFjdGlvbi5lZGdlcykge1xyXG4gICAgICB2YXIgY3Vyc29yS2V5ID0gJyc7XHJcbiAgICAgIHZhciBlZGdlTmFtZXMgPSBbJ3RvcCcsICdib3R0b20nLCAnbGVmdCcsICdyaWdodCddO1xyXG5cclxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcclxuICAgICAgICBpZiAoYWN0aW9uLmVkZ2VzW2VkZ2VOYW1lc1tpXV0pIHtcclxuICAgICAgICAgIGN1cnNvcktleSArPSBlZGdlTmFtZXNbaV07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gcmVzaXplLmN1cnNvcnNbY3Vyc29yS2V5XTtcclxuICAgIH1cclxuICB9XHJcbn07XHJcblxyXG4vLyByZXNpemVzdGFydFxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmKSB7XHJcbiAgdmFyIGlFdmVudCA9IF9yZWYuaUV2ZW50LFxyXG4gICAgICBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb247XHJcblxyXG4gIGlmIChpRXZlbnQudHlwZSAhPT0gJ3Jlc2l6ZXN0YXJ0JyB8fCAhaW50ZXJhY3Rpb24ucHJlcGFyZWQuZWRnZXMpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBzdGFydFJlY3QgPSBpbnRlcmFjdGlvbi50YXJnZXQuZ2V0UmVjdChpbnRlcmFjdGlvbi5lbGVtZW50KTtcclxuICB2YXIgcmVzaXplT3B0aW9ucyA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zLnJlc2l6ZTtcclxuXHJcbiAgLypcclxuICAgKiBXaGVuIHVzaW5nIHRoZSBgcmVzaXphYmxlLnNxdWFyZWAgb3IgYHJlc2l6YWJsZS5wcmVzZXJ2ZUFzcGVjdFJhdGlvYCBvcHRpb25zLCByZXNpemluZyBmcm9tIG9uZSBlZGdlXHJcbiAgICogd2lsbCBhZmZlY3QgYW5vdGhlci4gRS5nLiB3aXRoIGByZXNpemFibGUuc3F1YXJlYCwgcmVzaXppbmcgdG8gbWFrZSB0aGUgcmlnaHQgZWRnZSBsYXJnZXIgd2lsbCBtYWtlXHJcbiAgICogdGhlIGJvdHRvbSBlZGdlIGxhcmdlciBieSB0aGUgc2FtZSBhbW91bnQuIFdlIGNhbGwgdGhlc2UgJ2xpbmtlZCcgZWRnZXMuIEFueSBsaW5rZWQgZWRnZXMgd2lsbCBkZXBlbmRcclxuICAgKiBvbiB0aGUgYWN0aXZlIGVkZ2VzIGFuZCB0aGUgZWRnZSBiZWluZyBpbnRlcmFjdGVkIHdpdGguXHJcbiAgICovXHJcbiAgaWYgKHJlc2l6ZU9wdGlvbnMuc3F1YXJlIHx8IHJlc2l6ZU9wdGlvbnMucHJlc2VydmVBc3BlY3RSYXRpbykge1xyXG4gICAgdmFyIGxpbmtlZEVkZ2VzID0gdXRpbHMuZXh0ZW5kKHt9LCBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcyk7XHJcblxyXG4gICAgbGlua2VkRWRnZXMudG9wID0gbGlua2VkRWRnZXMudG9wIHx8IGxpbmtlZEVkZ2VzLmxlZnQgJiYgIWxpbmtlZEVkZ2VzLmJvdHRvbTtcclxuICAgIGxpbmtlZEVkZ2VzLmxlZnQgPSBsaW5rZWRFZGdlcy5sZWZ0IHx8IGxpbmtlZEVkZ2VzLnRvcCAmJiAhbGlua2VkRWRnZXMucmlnaHQ7XHJcbiAgICBsaW5rZWRFZGdlcy5ib3R0b20gPSBsaW5rZWRFZGdlcy5ib3R0b20gfHwgbGlua2VkRWRnZXMucmlnaHQgJiYgIWxpbmtlZEVkZ2VzLnRvcDtcclxuICAgIGxpbmtlZEVkZ2VzLnJpZ2h0ID0gbGlua2VkRWRnZXMucmlnaHQgfHwgbGlua2VkRWRnZXMuYm90dG9tICYmICFsaW5rZWRFZGdlcy5sZWZ0O1xyXG5cclxuICAgIGludGVyYWN0aW9uLnByZXBhcmVkLl9saW5rZWRFZGdlcyA9IGxpbmtlZEVkZ2VzO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBpbnRlcmFjdGlvbi5wcmVwYXJlZC5fbGlua2VkRWRnZXMgPSBudWxsO1xyXG4gIH1cclxuXHJcbiAgLy8gaWYgdXNpbmcgYHJlc2l6YWJsZS5wcmVzZXJ2ZUFzcGVjdFJhdGlvYCBvcHRpb24sIHJlY29yZCBhc3BlY3QgcmF0aW8gYXQgdGhlIHN0YXJ0IG9mIHRoZSByZXNpemVcclxuICBpZiAocmVzaXplT3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5yZXNpemVTdGFydEFzcGVjdFJhdGlvID0gc3RhcnRSZWN0LndpZHRoIC8gc3RhcnRSZWN0LmhlaWdodDtcclxuICB9XHJcblxyXG4gIGludGVyYWN0aW9uLnJlc2l6ZVJlY3RzID0ge1xyXG4gICAgc3RhcnQ6IHN0YXJ0UmVjdCxcclxuICAgIGN1cnJlbnQ6IHV0aWxzLmV4dGVuZCh7fSwgc3RhcnRSZWN0KSxcclxuICAgIGludmVydGVkOiB1dGlscy5leHRlbmQoe30sIHN0YXJ0UmVjdCksXHJcbiAgICBwcmV2aW91czogdXRpbHMuZXh0ZW5kKHt9LCBzdGFydFJlY3QpLFxyXG4gICAgZGVsdGE6IHtcclxuICAgICAgbGVmdDogMCwgcmlnaHQ6IDAsIHdpZHRoOiAwLFxyXG4gICAgICB0b3A6IDAsIGJvdHRvbTogMCwgaGVpZ2h0OiAwXHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgaUV2ZW50LnJlY3QgPSBpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5pbnZlcnRlZDtcclxuICBpRXZlbnQuZGVsdGFSZWN0ID0gaW50ZXJhY3Rpb24ucmVzaXplUmVjdHMuZGVsdGE7XHJcbn0pO1xyXG5cclxuLy8gcmVzaXplbW92ZVxyXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmMikge1xyXG4gIHZhciBpRXZlbnQgPSBfcmVmMi5pRXZlbnQsXHJcbiAgICAgIHBoYXNlID0gX3JlZjIucGhhc2UsXHJcbiAgICAgIGludGVyYWN0aW9uID0gX3JlZjIuaW50ZXJhY3Rpb247XHJcblxyXG4gIGlmIChwaGFzZSAhPT0gJ21vdmUnIHx8ICFpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcykge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIHJlc2l6ZU9wdGlvbnMgPSBpbnRlcmFjdGlvbi50YXJnZXQub3B0aW9ucy5yZXNpemU7XHJcbiAgdmFyIGludmVydCA9IHJlc2l6ZU9wdGlvbnMuaW52ZXJ0O1xyXG4gIHZhciBpbnZlcnRpYmxlID0gaW52ZXJ0ID09PSAncmVwb3NpdGlvbicgfHwgaW52ZXJ0ID09PSAnbmVnYXRlJztcclxuXHJcbiAgdmFyIGVkZ2VzID0gaW50ZXJhY3Rpb24ucHJlcGFyZWQuZWRnZXM7XHJcblxyXG4gIHZhciBzdGFydCA9IGludGVyYWN0aW9uLnJlc2l6ZVJlY3RzLnN0YXJ0O1xyXG4gIHZhciBjdXJyZW50ID0gaW50ZXJhY3Rpb24ucmVzaXplUmVjdHMuY3VycmVudDtcclxuICB2YXIgaW52ZXJ0ZWQgPSBpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5pbnZlcnRlZDtcclxuICB2YXIgZGVsdGEgPSBpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5kZWx0YTtcclxuICB2YXIgcHJldmlvdXMgPSB1dGlscy5leHRlbmQoaW50ZXJhY3Rpb24ucmVzaXplUmVjdHMucHJldmlvdXMsIGludmVydGVkKTtcclxuICB2YXIgb3JpZ2luYWxFZGdlcyA9IGVkZ2VzO1xyXG5cclxuICB2YXIgZHggPSBpRXZlbnQuZHg7XHJcbiAgdmFyIGR5ID0gaUV2ZW50LmR5O1xyXG5cclxuICBpZiAocmVzaXplT3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvIHx8IHJlc2l6ZU9wdGlvbnMuc3F1YXJlKSB7XHJcbiAgICAvLyBgcmVzaXplLnByZXNlcnZlQXNwZWN0UmF0aW9gIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBgcmVzaXplLnNxdWFyZWBcclxuICAgIHZhciBzdGFydEFzcGVjdFJhdGlvID0gcmVzaXplT3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvID8gaW50ZXJhY3Rpb24ucmVzaXplU3RhcnRBc3BlY3RSYXRpbyA6IDE7XHJcblxyXG4gICAgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5fbGlua2VkRWRnZXM7XHJcblxyXG4gICAgaWYgKG9yaWdpbmFsRWRnZXMubGVmdCAmJiBvcmlnaW5hbEVkZ2VzLmJvdHRvbSB8fCBvcmlnaW5hbEVkZ2VzLnJpZ2h0ICYmIG9yaWdpbmFsRWRnZXMudG9wKSB7XHJcbiAgICAgIGR5ID0gLWR4IC8gc3RhcnRBc3BlY3RSYXRpbztcclxuICAgIH0gZWxzZSBpZiAob3JpZ2luYWxFZGdlcy5sZWZ0IHx8IG9yaWdpbmFsRWRnZXMucmlnaHQpIHtcclxuICAgICAgZHkgPSBkeCAvIHN0YXJ0QXNwZWN0UmF0aW87XHJcbiAgICB9IGVsc2UgaWYgKG9yaWdpbmFsRWRnZXMudG9wIHx8IG9yaWdpbmFsRWRnZXMuYm90dG9tKSB7XHJcbiAgICAgIGR4ID0gZHkgKiBzdGFydEFzcGVjdFJhdGlvO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gdXBkYXRlIHRoZSAnY3VycmVudCcgcmVjdCB3aXRob3V0IG1vZGlmaWNhdGlvbnNcclxuICBpZiAoZWRnZXMudG9wKSB7XHJcbiAgICBjdXJyZW50LnRvcCArPSBkeTtcclxuICB9XHJcbiAgaWYgKGVkZ2VzLmJvdHRvbSkge1xyXG4gICAgY3VycmVudC5ib3R0b20gKz0gZHk7XHJcbiAgfVxyXG4gIGlmIChlZGdlcy5sZWZ0KSB7XHJcbiAgICBjdXJyZW50LmxlZnQgKz0gZHg7XHJcbiAgfVxyXG4gIGlmIChlZGdlcy5yaWdodCkge1xyXG4gICAgY3VycmVudC5yaWdodCArPSBkeDtcclxuICB9XHJcblxyXG4gIGlmIChpbnZlcnRpYmxlKSB7XHJcbiAgICAvLyBpZiBpbnZlcnRpYmxlLCBjb3B5IHRoZSBjdXJyZW50IHJlY3RcclxuICAgIHV0aWxzLmV4dGVuZChpbnZlcnRlZCwgY3VycmVudCk7XHJcblxyXG4gICAgaWYgKGludmVydCA9PT0gJ3JlcG9zaXRpb24nKSB7XHJcbiAgICAgIC8vIHN3YXAgZWRnZSB2YWx1ZXMgaWYgbmVjZXNzYXJ5IHRvIGtlZXAgd2lkdGgvaGVpZ2h0IHBvc2l0aXZlXHJcbiAgICAgIHZhciBzd2FwID0gdm9pZCAwO1xyXG5cclxuICAgICAgaWYgKGludmVydGVkLnRvcCA+IGludmVydGVkLmJvdHRvbSkge1xyXG4gICAgICAgIHN3YXAgPSBpbnZlcnRlZC50b3A7XHJcblxyXG4gICAgICAgIGludmVydGVkLnRvcCA9IGludmVydGVkLmJvdHRvbTtcclxuICAgICAgICBpbnZlcnRlZC5ib3R0b20gPSBzd2FwO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChpbnZlcnRlZC5sZWZ0ID4gaW52ZXJ0ZWQucmlnaHQpIHtcclxuICAgICAgICBzd2FwID0gaW52ZXJ0ZWQubGVmdDtcclxuXHJcbiAgICAgICAgaW52ZXJ0ZWQubGVmdCA9IGludmVydGVkLnJpZ2h0O1xyXG4gICAgICAgIGludmVydGVkLnJpZ2h0ID0gc3dhcDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICAvLyBpZiBub3QgaW52ZXJ0aWJsZSwgcmVzdHJpY3QgdG8gbWluaW11bSBvZiAweDAgcmVjdFxyXG4gICAgaW52ZXJ0ZWQudG9wID0gTWF0aC5taW4oY3VycmVudC50b3AsIHN0YXJ0LmJvdHRvbSk7XHJcbiAgICBpbnZlcnRlZC5ib3R0b20gPSBNYXRoLm1heChjdXJyZW50LmJvdHRvbSwgc3RhcnQudG9wKTtcclxuICAgIGludmVydGVkLmxlZnQgPSBNYXRoLm1pbihjdXJyZW50LmxlZnQsIHN0YXJ0LnJpZ2h0KTtcclxuICAgIGludmVydGVkLnJpZ2h0ID0gTWF0aC5tYXgoY3VycmVudC5yaWdodCwgc3RhcnQubGVmdCk7XHJcbiAgfVxyXG5cclxuICBpbnZlcnRlZC53aWR0aCA9IGludmVydGVkLnJpZ2h0IC0gaW52ZXJ0ZWQubGVmdDtcclxuICBpbnZlcnRlZC5oZWlnaHQgPSBpbnZlcnRlZC5ib3R0b20gLSBpbnZlcnRlZC50b3A7XHJcblxyXG4gIGZvciAodmFyIGVkZ2UgaW4gaW52ZXJ0ZWQpIHtcclxuICAgIGRlbHRhW2VkZ2VdID0gaW52ZXJ0ZWRbZWRnZV0gLSBwcmV2aW91c1tlZGdlXTtcclxuICB9XHJcblxyXG4gIGlFdmVudC5lZGdlcyA9IGludGVyYWN0aW9uLnByZXBhcmVkLmVkZ2VzO1xyXG4gIGlFdmVudC5yZWN0ID0gaW52ZXJ0ZWQ7XHJcbiAgaUV2ZW50LmRlbHRhUmVjdCA9IGRlbHRhO1xyXG59KTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLnJlc2l6YWJsZVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBHZXRzIG9yIHNldHMgd2hldGhlciByZXNpemUgYWN0aW9ucyBjYW4gYmUgcGVyZm9ybWVkIG9uIHRoZVxyXG4gKiBJbnRlcmFjdGFibGVcclxuICpcclxuID0gKGJvb2xlYW4pIEluZGljYXRlcyBpZiB0aGlzIGNhbiBiZSB0aGUgdGFyZ2V0IG9mIHJlc2l6ZSBlbGVtZW50c1xyXG4gICB8IHZhciBpc1Jlc2l6ZWFibGUgPSBpbnRlcmFjdCgnaW5wdXRbdHlwZT10ZXh0XScpLnJlc2l6YWJsZSgpO1xyXG4gKiBvclxyXG4gLSBvcHRpb25zIChib29sZWFuIHwgb2JqZWN0KSAjb3B0aW9uYWwgdHJ1ZS9mYWxzZSBvciBBbiBvYmplY3Qgd2l0aCBldmVudCBsaXN0ZW5lcnMgdG8gYmUgZmlyZWQgb24gcmVzaXplIGV2ZW50cyAob2JqZWN0IG1ha2VzIHRoZSBJbnRlcmFjdGFibGUgcmVzaXphYmxlKVxyXG4gPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxyXG4gICB8IGludGVyYWN0KGVsZW1lbnQpLnJlc2l6YWJsZSh7XHJcbiAgIHwgICBvbnN0YXJ0OiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxyXG4gICB8ICAgb25tb3ZlIDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcclxuICAgfCAgIG9uZW5kICA6IGZ1bmN0aW9uIChldmVudCkge30sXHJcbiAgIHxcclxuICAgfCAgIGVkZ2VzOiB7XHJcbiAgIHwgICAgIHRvcCAgIDogdHJ1ZSwgICAgICAgLy8gVXNlIHBvaW50ZXIgY29vcmRzIHRvIGNoZWNrIGZvciByZXNpemUuXHJcbiAgIHwgICAgIGxlZnQgIDogZmFsc2UsICAgICAgLy8gRGlzYWJsZSByZXNpemluZyBmcm9tIGxlZnQgZWRnZS5cclxuICAgfCAgICAgYm90dG9tOiAnLnJlc2l6ZS1zJywvLyBSZXNpemUgaWYgcG9pbnRlciB0YXJnZXQgbWF0Y2hlcyBzZWxlY3RvclxyXG4gICB8ICAgICByaWdodCA6IGhhbmRsZUVsICAgIC8vIFJlc2l6ZSBpZiBwb2ludGVyIHRhcmdldCBpcyB0aGUgZ2l2ZW4gRWxlbWVudFxyXG4gICB8ICAgfSxcclxuICAgfFxyXG4gICB8ICAgICAvLyBXaWR0aCBhbmQgaGVpZ2h0IGNhbiBiZSBhZGp1c3RlZCBpbmRlcGVuZGVudGx5LiBXaGVuIGB0cnVlYCwgd2lkdGggYW5kXHJcbiAgIHwgICAgIC8vIGhlaWdodCBhcmUgYWRqdXN0ZWQgYXQgYSAxOjEgcmF0aW8uXHJcbiAgIHwgICAgIHNxdWFyZTogZmFsc2UsXHJcbiAgIHxcclxuICAgfCAgICAgLy8gV2lkdGggYW5kIGhlaWdodCBjYW4gYmUgYWRqdXN0ZWQgaW5kZXBlbmRlbnRseS4gV2hlbiBgdHJ1ZWAsIHdpZHRoIGFuZFxyXG4gICB8ICAgICAvLyBoZWlnaHQgbWFpbnRhaW4gdGhlIGFzcGVjdCByYXRpbyB0aGV5IGhhZCB3aGVuIHJlc2l6aW5nIHN0YXJ0ZWQuXHJcbiAgIHwgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IGZhbHNlLFxyXG4gICB8XHJcbiAgIHwgICAvLyBhIHZhbHVlIG9mICdub25lJyB3aWxsIGxpbWl0IHRoZSByZXNpemUgcmVjdCB0byBhIG1pbmltdW0gb2YgMHgwXHJcbiAgIHwgICAvLyAnbmVnYXRlJyB3aWxsIGFsbG93IHRoZSByZWN0IHRvIGhhdmUgbmVnYXRpdmUgd2lkdGgvaGVpZ2h0XHJcbiAgIHwgICAvLyAncmVwb3NpdGlvbicgd2lsbCBrZWVwIHRoZSB3aWR0aC9oZWlnaHQgcG9zaXRpdmUgYnkgc3dhcHBpbmdcclxuICAgfCAgIC8vIHRoZSB0b3AgYW5kIGJvdHRvbSBlZGdlcyBhbmQvb3Igc3dhcHBpbmcgdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzXHJcbiAgIHwgICBpbnZlcnQ6ICdub25lJyB8fCAnbmVnYXRlJyB8fCAncmVwb3NpdGlvbidcclxuICAgfFxyXG4gICB8ICAgLy8gbGltaXQgbXVsdGlwbGUgcmVzaXplcy5cclxuICAgfCAgIC8vIFNlZSB0aGUgZXhwbGFuYXRpb24gaW4gdGhlIEBJbnRlcmFjdGFibGUuZHJhZ2dhYmxlIGV4YW1wbGVcclxuICAgfCAgIG1heDogSW5maW5pdHksXHJcbiAgIHwgICBtYXhQZXJFbGVtZW50OiAxLFxyXG4gICB8IH0pO1xyXG4gIFxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5yZXNpemFibGUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gIGlmICh1dGlscy5pcy5vYmplY3Qob3B0aW9ucykpIHtcclxuICAgIHRoaXMub3B0aW9ucy5yZXNpemUuZW5hYmxlZCA9IG9wdGlvbnMuZW5hYmxlZCA9PT0gZmFsc2UgPyBmYWxzZSA6IHRydWU7XHJcbiAgICB0aGlzLnNldFBlckFjdGlvbigncmVzaXplJywgb3B0aW9ucyk7XHJcbiAgICB0aGlzLnNldE9uRXZlbnRzKCdyZXNpemUnLCBvcHRpb25zKTtcclxuXHJcbiAgICBpZiAoL154JHxeeSR8Xnh5JC8udGVzdChvcHRpb25zLmF4aXMpKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5yZXNpemUuYXhpcyA9IG9wdGlvbnMuYXhpcztcclxuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5heGlzID09PSBudWxsKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5yZXNpemUuYXhpcyA9IGRlZmF1bHRPcHRpb25zLnJlc2l6ZS5heGlzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh1dGlscy5pcy5ib29sKG9wdGlvbnMucHJlc2VydmVBc3BlY3RSYXRpbykpIHtcclxuICAgICAgdGhpcy5vcHRpb25zLnJlc2l6ZS5wcmVzZXJ2ZUFzcGVjdFJhdGlvID0gb3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvO1xyXG4gICAgfSBlbHNlIGlmICh1dGlscy5pcy5ib29sKG9wdGlvbnMuc3F1YXJlKSkge1xyXG4gICAgICB0aGlzLm9wdGlvbnMucmVzaXplLnNxdWFyZSA9IG9wdGlvbnMuc3F1YXJlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICBpZiAodXRpbHMuaXMuYm9vbChvcHRpb25zKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLnJlc2l6ZS5lbmFibGVkID0gb3B0aW9ucztcclxuXHJcbiAgICBpZiAoIW9wdGlvbnMpIHtcclxuICAgICAgdGhpcy5vbnJlc2l6ZXN0YXJ0ID0gdGhpcy5vbnJlc2l6ZXN0YXJ0ID0gdGhpcy5vbnJlc2l6ZWVuZCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIHJldHVybiB0aGlzLm9wdGlvbnMucmVzaXplO1xyXG59O1xyXG5cclxuZnVuY3Rpb24gY2hlY2tSZXNpemVFZGdlKG5hbWUsIHZhbHVlLCBwYWdlLCBlbGVtZW50LCBpbnRlcmFjdGFibGVFbGVtZW50LCByZWN0LCBtYXJnaW4pIHtcclxuICAvLyBmYWxzZSwgJycsIHVuZGVmaW5lZCwgbnVsbFxyXG4gIGlmICghdmFsdWUpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8vIHRydWUgdmFsdWUsIHVzZSBwb2ludGVyIGNvb3JkcyBhbmQgZWxlbWVudCByZWN0XHJcbiAgaWYgKHZhbHVlID09PSB0cnVlKSB7XHJcbiAgICAvLyBpZiBkaW1lbnNpb25zIGFyZSBuZWdhdGl2ZSwgXCJzd2l0Y2hcIiBlZGdlc1xyXG4gICAgdmFyIHdpZHRoID0gdXRpbHMuaXMubnVtYmVyKHJlY3Qud2lkdGgpID8gcmVjdC53aWR0aCA6IHJlY3QucmlnaHQgLSByZWN0LmxlZnQ7XHJcbiAgICB2YXIgaGVpZ2h0ID0gdXRpbHMuaXMubnVtYmVyKHJlY3QuaGVpZ2h0KSA/IHJlY3QuaGVpZ2h0IDogcmVjdC5ib3R0b20gLSByZWN0LnRvcDtcclxuXHJcbiAgICBpZiAod2lkdGggPCAwKSB7XHJcbiAgICAgIGlmIChuYW1lID09PSAnbGVmdCcpIHtcclxuICAgICAgICBuYW1lID0gJ3JpZ2h0JztcclxuICAgICAgfSBlbHNlIGlmIChuYW1lID09PSAncmlnaHQnKSB7XHJcbiAgICAgICAgbmFtZSA9ICdsZWZ0JztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGhlaWdodCA8IDApIHtcclxuICAgICAgaWYgKG5hbWUgPT09ICd0b3AnKSB7XHJcbiAgICAgICAgbmFtZSA9ICdib3R0b20nO1xyXG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdib3R0b20nKSB7XHJcbiAgICAgICAgbmFtZSA9ICd0b3AnO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG5hbWUgPT09ICdsZWZ0Jykge1xyXG4gICAgICByZXR1cm4gcGFnZS54IDwgKHdpZHRoID49IDAgPyByZWN0LmxlZnQgOiByZWN0LnJpZ2h0KSArIG1hcmdpbjtcclxuICAgIH1cclxuICAgIGlmIChuYW1lID09PSAndG9wJykge1xyXG4gICAgICByZXR1cm4gcGFnZS55IDwgKGhlaWdodCA+PSAwID8gcmVjdC50b3AgOiByZWN0LmJvdHRvbSkgKyBtYXJnaW47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG5hbWUgPT09ICdyaWdodCcpIHtcclxuICAgICAgcmV0dXJuIHBhZ2UueCA+ICh3aWR0aCA+PSAwID8gcmVjdC5yaWdodCA6IHJlY3QubGVmdCkgLSBtYXJnaW47XHJcbiAgICB9XHJcbiAgICBpZiAobmFtZSA9PT0gJ2JvdHRvbScpIHtcclxuICAgICAgcmV0dXJuIHBhZ2UueSA+IChoZWlnaHQgPj0gMCA/IHJlY3QuYm90dG9tIDogcmVjdC50b3ApIC0gbWFyZ2luO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gdGhlIHJlbWFpbmluZyBjaGVja3MgcmVxdWlyZSBhbiBlbGVtZW50XHJcbiAgaWYgKCF1dGlscy5pcy5lbGVtZW50KGVsZW1lbnQpKSB7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdXRpbHMuaXMuZWxlbWVudCh2YWx1ZSlcclxuICAvLyB0aGUgdmFsdWUgaXMgYW4gZWxlbWVudCB0byB1c2UgYXMgYSByZXNpemUgaGFuZGxlXHJcbiAgPyB2YWx1ZSA9PT0gZWxlbWVudFxyXG4gIC8vIG90aGVyd2lzZSBjaGVjayBpZiBlbGVtZW50IG1hdGNoZXMgdmFsdWUgYXMgc2VsZWN0b3JcclxuICA6IHV0aWxzLm1hdGNoZXNVcFRvKGVsZW1lbnQsIHZhbHVlLCBpbnRlcmFjdGFibGVFbGVtZW50KTtcclxufVxyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XHJcbiAgaW50ZXJhY3Rpb24ucmVzaXplQXhlcyA9ICd4eSc7XHJcbn0pO1xyXG5cclxuSW50ZXJhY3RFdmVudC5zaWduYWxzLm9uKCdzZXQtZGVsdGEnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbixcclxuICAgICAgaUV2ZW50ID0gX3JlZjMuaUV2ZW50LFxyXG4gICAgICBhY3Rpb24gPSBfcmVmMy5hY3Rpb247XHJcblxyXG4gIGlmIChhY3Rpb24gIT09ICdyZXNpemUnIHx8ICFpbnRlcmFjdGlvbi5yZXNpemVBeGVzKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgb3B0aW9ucyA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zO1xyXG5cclxuICBpZiAob3B0aW9ucy5yZXNpemUuc3F1YXJlKSB7XHJcbiAgICBpZiAoaW50ZXJhY3Rpb24ucmVzaXplQXhlcyA9PT0gJ3knKSB7XHJcbiAgICAgIGlFdmVudC5keCA9IGlFdmVudC5keTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlFdmVudC5keSA9IGlFdmVudC5keDtcclxuICAgIH1cclxuICAgIGlFdmVudC5heGVzID0gJ3h5JztcclxuICB9IGVsc2Uge1xyXG4gICAgaUV2ZW50LmF4ZXMgPSBpbnRlcmFjdGlvbi5yZXNpemVBeGVzO1xyXG5cclxuICAgIGlmIChpbnRlcmFjdGlvbi5yZXNpemVBeGVzID09PSAneCcpIHtcclxuICAgICAgaUV2ZW50LmR5ID0gMDtcclxuICAgIH0gZWxzZSBpZiAoaW50ZXJhY3Rpb24ucmVzaXplQXhlcyA9PT0gJ3knKSB7XHJcbiAgICAgIGlFdmVudC5keCA9IDA7XHJcbiAgICB9XHJcbiAgfVxyXG59KTtcclxuXHJcbmFjdGlvbnMucmVzaXplID0gcmVzaXplO1xyXG5hY3Rpb25zLm5hbWVzLnB1c2goJ3Jlc2l6ZScpO1xyXG51dGlscy5tZXJnZShJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgWydyZXNpemVzdGFydCcsICdyZXNpemVtb3ZlJywgJ3Jlc2l6ZWluZXJ0aWFzdGFydCcsICdyZXNpemVpbmVydGlhcmVzdW1lJywgJ3Jlc2l6ZWVuZCddKTtcclxuYWN0aW9ucy5tZXRob2REaWN0LnJlc2l6ZSA9ICdyZXNpemFibGUnO1xyXG5cclxuZGVmYXVsdE9wdGlvbnMucmVzaXplID0gcmVzaXplLmRlZmF1bHRzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZXNpemU7XHJcblxyXG59LHtcIi4uL0ludGVyYWN0RXZlbnRcIjozLFwiLi4vSW50ZXJhY3RhYmxlXCI6NCxcIi4uL0ludGVyYWN0aW9uXCI6NSxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi9iYXNlXCI6Nn1dLDExOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHJhZiA9IHJlcXVpcmUoJy4vdXRpbHMvcmFmJyk7XHJcbnZhciBnZXRXaW5kb3cgPSByZXF1aXJlKCcuL3V0aWxzL3dpbmRvdycpLmdldFdpbmRvdztcclxudmFyIGlzID0gcmVxdWlyZSgnLi91dGlscy9pcycpO1xyXG52YXIgZG9tVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzL2RvbVV0aWxzJyk7XHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4vSW50ZXJhY3Rpb24nKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi9kZWZhdWx0T3B0aW9ucycpO1xyXG5cclxudmFyIGF1dG9TY3JvbGwgPSB7XHJcbiAgZGVmYXVsdHM6IHtcclxuICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgY29udGFpbmVyOiBudWxsLCAvLyB0aGUgaXRlbSB0aGF0IGlzIHNjcm9sbGVkIChXaW5kb3cgb3IgSFRNTEVsZW1lbnQpXHJcbiAgICBtYXJnaW46IDYwLFxyXG4gICAgc3BlZWQ6IDMwMCAvLyB0aGUgc2Nyb2xsIHNwZWVkIGluIHBpeGVscyBwZXIgc2Vjb25kXHJcbiAgfSxcclxuXHJcbiAgaW50ZXJhY3Rpb246IG51bGwsXHJcbiAgaTogbnVsbCwgLy8gdGhlIGhhbmRsZSByZXR1cm5lZCBieSB3aW5kb3cuc2V0SW50ZXJ2YWxcclxuICB4OiAwLCB5OiAwLCAvLyBEaXJlY3Rpb24gZWFjaCBwdWxzZSBpcyB0byBzY3JvbGwgaW5cclxuXHJcbiAgaXNTY3JvbGxpbmc6IGZhbHNlLFxyXG4gIHByZXZUaW1lOiAwLFxyXG5cclxuICBzdGFydDogZnVuY3Rpb24gc3RhcnQoaW50ZXJhY3Rpb24pIHtcclxuICAgIGF1dG9TY3JvbGwuaXNTY3JvbGxpbmcgPSB0cnVlO1xyXG4gICAgcmFmLmNhbmNlbChhdXRvU2Nyb2xsLmkpO1xyXG5cclxuICAgIGF1dG9TY3JvbGwuaW50ZXJhY3Rpb24gPSBpbnRlcmFjdGlvbjtcclxuICAgIGF1dG9TY3JvbGwucHJldlRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgIGF1dG9TY3JvbGwuaSA9IHJhZi5yZXF1ZXN0KGF1dG9TY3JvbGwuc2Nyb2xsKTtcclxuICB9LFxyXG5cclxuICBzdG9wOiBmdW5jdGlvbiBzdG9wKCkge1xyXG4gICAgYXV0b1Njcm9sbC5pc1Njcm9sbGluZyA9IGZhbHNlO1xyXG4gICAgcmFmLmNhbmNlbChhdXRvU2Nyb2xsLmkpO1xyXG4gIH0sXHJcblxyXG4gIC8vIHNjcm9sbCB0aGUgd2luZG93IGJ5IHRoZSB2YWx1ZXMgaW4gc2Nyb2xsLngveVxyXG4gIHNjcm9sbDogZnVuY3Rpb24gc2Nyb2xsKCkge1xyXG4gICAgdmFyIG9wdGlvbnMgPSBhdXRvU2Nyb2xsLmludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zW2F1dG9TY3JvbGwuaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uYXV0b1Njcm9sbDtcclxuICAgIHZhciBjb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lciB8fCBnZXRXaW5kb3coYXV0b1Njcm9sbC5pbnRlcmFjdGlvbi5lbGVtZW50KTtcclxuICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgIC8vIGNoYW5nZSBpbiB0aW1lIGluIHNlY29uZHNcclxuICAgIHZhciBkdCA9IChub3cgLSBhdXRvU2Nyb2xsLnByZXZUaW1lKSAvIDEwMDA7XHJcbiAgICAvLyBkaXNwbGFjZW1lbnRcclxuICAgIHZhciBzID0gb3B0aW9ucy5zcGVlZCAqIGR0O1xyXG5cclxuICAgIGlmIChzID49IDEpIHtcclxuICAgICAgaWYgKGlzLndpbmRvdyhjb250YWluZXIpKSB7XHJcbiAgICAgICAgY29udGFpbmVyLnNjcm9sbEJ5KGF1dG9TY3JvbGwueCAqIHMsIGF1dG9TY3JvbGwueSAqIHMpO1xyXG4gICAgICB9IGVsc2UgaWYgKGNvbnRhaW5lcikge1xyXG4gICAgICAgIGNvbnRhaW5lci5zY3JvbGxMZWZ0ICs9IGF1dG9TY3JvbGwueCAqIHM7XHJcbiAgICAgICAgY29udGFpbmVyLnNjcm9sbFRvcCArPSBhdXRvU2Nyb2xsLnkgKiBzO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhdXRvU2Nyb2xsLnByZXZUaW1lID0gbm93O1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChhdXRvU2Nyb2xsLmlzU2Nyb2xsaW5nKSB7XHJcbiAgICAgIHJhZi5jYW5jZWwoYXV0b1Njcm9sbC5pKTtcclxuICAgICAgYXV0b1Njcm9sbC5pID0gcmFmLnJlcXVlc3QoYXV0b1Njcm9sbC5zY3JvbGwpO1xyXG4gICAgfVxyXG4gIH0sXHJcbiAgY2hlY2s6IGZ1bmN0aW9uIGNoZWNrKGludGVyYWN0YWJsZSwgYWN0aW9uTmFtZSkge1xyXG4gICAgdmFyIG9wdGlvbnMgPSBpbnRlcmFjdGFibGUub3B0aW9ucztcclxuXHJcbiAgICByZXR1cm4gb3B0aW9uc1thY3Rpb25OYW1lXS5hdXRvU2Nyb2xsICYmIG9wdGlvbnNbYWN0aW9uTmFtZV0uYXV0b1Njcm9sbC5lbmFibGVkO1xyXG4gIH0sXHJcbiAgb25JbnRlcmFjdGlvbk1vdmU6IGZ1bmN0aW9uIG9uSW50ZXJhY3Rpb25Nb3ZlKF9yZWYpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb24sXHJcbiAgICAgICAgcG9pbnRlciA9IF9yZWYucG9pbnRlcjtcclxuXHJcbiAgICBpZiAoIShpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpICYmIGF1dG9TY3JvbGwuY2hlY2soaW50ZXJhY3Rpb24udGFyZ2V0LCBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lKSkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpbnRlcmFjdGlvbi5zaW11bGF0aW9uKSB7XHJcbiAgICAgIGF1dG9TY3JvbGwueCA9IGF1dG9TY3JvbGwueSA9IDA7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgdG9wID0gdm9pZCAwO1xyXG4gICAgdmFyIHJpZ2h0ID0gdm9pZCAwO1xyXG4gICAgdmFyIGJvdHRvbSA9IHZvaWQgMDtcclxuICAgIHZhciBsZWZ0ID0gdm9pZCAwO1xyXG5cclxuICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uYXV0b1Njcm9sbDtcclxuICAgIHZhciBjb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lciB8fCBnZXRXaW5kb3coaW50ZXJhY3Rpb24uZWxlbWVudCk7XHJcblxyXG4gICAgaWYgKGlzLndpbmRvdyhjb250YWluZXIpKSB7XHJcbiAgICAgIGxlZnQgPSBwb2ludGVyLmNsaWVudFggPCBhdXRvU2Nyb2xsLm1hcmdpbjtcclxuICAgICAgdG9wID0gcG9pbnRlci5jbGllbnRZIDwgYXV0b1Njcm9sbC5tYXJnaW47XHJcbiAgICAgIHJpZ2h0ID0gcG9pbnRlci5jbGllbnRYID4gY29udGFpbmVyLmlubmVyV2lkdGggLSBhdXRvU2Nyb2xsLm1hcmdpbjtcclxuICAgICAgYm90dG9tID0gcG9pbnRlci5jbGllbnRZID4gY29udGFpbmVyLmlubmVySGVpZ2h0IC0gYXV0b1Njcm9sbC5tYXJnaW47XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YXIgcmVjdCA9IGRvbVV0aWxzLmdldEVsZW1lbnRDbGllbnRSZWN0KGNvbnRhaW5lcik7XHJcblxyXG4gICAgICBsZWZ0ID0gcG9pbnRlci5jbGllbnRYIDwgcmVjdC5sZWZ0ICsgYXV0b1Njcm9sbC5tYXJnaW47XHJcbiAgICAgIHRvcCA9IHBvaW50ZXIuY2xpZW50WSA8IHJlY3QudG9wICsgYXV0b1Njcm9sbC5tYXJnaW47XHJcbiAgICAgIHJpZ2h0ID0gcG9pbnRlci5jbGllbnRYID4gcmVjdC5yaWdodCAtIGF1dG9TY3JvbGwubWFyZ2luO1xyXG4gICAgICBib3R0b20gPSBwb2ludGVyLmNsaWVudFkgPiByZWN0LmJvdHRvbSAtIGF1dG9TY3JvbGwubWFyZ2luO1xyXG4gICAgfVxyXG5cclxuICAgIGF1dG9TY3JvbGwueCA9IHJpZ2h0ID8gMSA6IGxlZnQgPyAtMSA6IDA7XHJcbiAgICBhdXRvU2Nyb2xsLnkgPSBib3R0b20gPyAxIDogdG9wID8gLTEgOiAwO1xyXG5cclxuICAgIGlmICghYXV0b1Njcm9sbC5pc1Njcm9sbGluZykge1xyXG4gICAgICAvLyBzZXQgdGhlIGF1dG9TY3JvbGwgcHJvcGVydGllcyB0byB0aG9zZSBvZiB0aGUgdGFyZ2V0XHJcbiAgICAgIGF1dG9TY3JvbGwubWFyZ2luID0gb3B0aW9ucy5tYXJnaW47XHJcbiAgICAgIGF1dG9TY3JvbGwuc3BlZWQgPSBvcHRpb25zLnNwZWVkO1xyXG5cclxuICAgICAgYXV0b1Njcm9sbC5zdGFydChpbnRlcmFjdGlvbik7XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignc3RvcC1hY3RpdmUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgYXV0b1Njcm9sbC5zdG9wKCk7XHJcbn0pO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYWN0aW9uLW1vdmUnLCBhdXRvU2Nyb2xsLm9uSW50ZXJhY3Rpb25Nb3ZlKTtcclxuXHJcbmRlZmF1bHRPcHRpb25zLnBlckFjdGlvbi5hdXRvU2Nyb2xsID0gYXV0b1Njcm9sbC5kZWZhdWx0cztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYXV0b1Njcm9sbDtcclxuXHJcbn0se1wiLi9JbnRlcmFjdGlvblwiOjUsXCIuL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuL3V0aWxzL2RvbVV0aWxzXCI6MzksXCIuL3V0aWxzL2lzXCI6NDYsXCIuL3V0aWxzL3JhZlwiOjUwLFwiLi91dGlscy93aW5kb3dcIjo1Mn1dLDEyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4uL0ludGVyYWN0YWJsZScpO1xyXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4uL2FjdGlvbnMvYmFzZScpO1xyXG52YXIgaXMgPSByZXF1aXJlKCcuLi91dGlscy9pcycpO1xyXG52YXIgZG9tVXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9kb21VdGlscycpO1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5nZXRBY3Rpb24gPSBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KSB7XHJcbiAgdmFyIGFjdGlvbiA9IHRoaXMuZGVmYXVsdEFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KTtcclxuXHJcbiAgaWYgKHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyKSB7XHJcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgdGhpcywgZWxlbWVudCwgaW50ZXJhY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGFjdGlvbjtcclxufTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmlnbm9yZUZyb21cclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogSWYgdGhlIHRhcmdldCBvZiB0aGUgYG1vdXNlZG93bmAsIGBwb2ludGVyZG93bmAgb3IgYHRvdWNoc3RhcnRgXHJcbiAqIGV2ZW50IG9yIGFueSBvZiBpdCdzIHBhcmVudHMgbWF0Y2ggdGhlIGdpdmVuIENTUyBzZWxlY3RvciBvclxyXG4gKiBFbGVtZW50LCBubyBkcmFnL3Jlc2l6ZS9nZXN0dXJlIGlzIHN0YXJ0ZWQuXHJcbiAqXHJcbiAtIG5ld1ZhbHVlIChzdHJpbmcgfCBFbGVtZW50IHwgbnVsbCkgI29wdGlvbmFsIGEgQ1NTIHNlbGVjdG9yIHN0cmluZywgYW4gRWxlbWVudCBvciBgbnVsbGAgdG8gbm90IGlnbm9yZSBhbnkgZWxlbWVudHNcclxuID0gKHN0cmluZyB8IEVsZW1lbnQgfCBvYmplY3QpIFRoZSBjdXJyZW50IGlnbm9yZUZyb20gdmFsdWUgb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICoqXHJcbiB8IGludGVyYWN0KGVsZW1lbnQsIHsgaWdub3JlRnJvbTogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25vLWFjdGlvbicpIH0pO1xyXG4gfCAvLyBvclxyXG4gfCBpbnRlcmFjdChlbGVtZW50KS5pZ25vcmVGcm9tKCdpbnB1dCwgdGV4dGFyZWEsIGEnKTtcclxuXFwqL1xyXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLmlnbm9yZUZyb20gPSBmdW5jdGlvbiAobmV3VmFsdWUpIHtcclxuICByZXR1cm4gdGhpcy5fYmFja0NvbXBhdE9wdGlvbignaWdub3JlRnJvbScsIG5ld1ZhbHVlKTtcclxufTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmFsbG93RnJvbVxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBBIGRyYWcvcmVzaXplL2dlc3R1cmUgaXMgc3RhcnRlZCBvbmx5IElmIHRoZSB0YXJnZXQgb2YgdGhlXHJcbiAqIGBtb3VzZWRvd25gLCBgcG9pbnRlcmRvd25gIG9yIGB0b3VjaHN0YXJ0YCBldmVudCBvciBhbnkgb2YgaXQnc1xyXG4gKiBwYXJlbnRzIG1hdGNoIHRoZSBnaXZlbiBDU1Mgc2VsZWN0b3Igb3IgRWxlbWVudC5cclxuICpcclxuIC0gbmV3VmFsdWUgKHN0cmluZyB8IEVsZW1lbnQgfCBudWxsKSAjb3B0aW9uYWwgYSBDU1Mgc2VsZWN0b3Igc3RyaW5nLCBhbiBFbGVtZW50IG9yIGBudWxsYCB0byBhbGxvdyBmcm9tIGFueSBlbGVtZW50XHJcbiA9IChzdHJpbmcgfCBFbGVtZW50IHwgb2JqZWN0KSBUaGUgY3VycmVudCBhbGxvd0Zyb20gdmFsdWUgb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICoqXHJcbiB8IGludGVyYWN0KGVsZW1lbnQsIHsgYWxsb3dGcm9tOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHJhZy1oYW5kbGUnKSB9KTtcclxuIHwgLy8gb3JcclxuIHwgaW50ZXJhY3QoZWxlbWVudCkuYWxsb3dGcm9tKCcuaGFuZGxlJyk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hbGxvd0Zyb20gPSBmdW5jdGlvbiAobmV3VmFsdWUpIHtcclxuICByZXR1cm4gdGhpcy5fYmFja0NvbXBhdE9wdGlvbignYWxsb3dGcm9tJywgbmV3VmFsdWUpO1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS50ZXN0SWdub3JlID0gZnVuY3Rpb24gKGlnbm9yZUZyb20sIGludGVyYWN0YWJsZUVsZW1lbnQsIGVsZW1lbnQpIHtcclxuICBpZiAoIWlnbm9yZUZyb20gfHwgIWlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIGlmIChpcy5zdHJpbmcoaWdub3JlRnJvbSkpIHtcclxuICAgIHJldHVybiBkb21VdGlscy5tYXRjaGVzVXBUbyhlbGVtZW50LCBpZ25vcmVGcm9tLCBpbnRlcmFjdGFibGVFbGVtZW50KTtcclxuICB9IGVsc2UgaWYgKGlzLmVsZW1lbnQoaWdub3JlRnJvbSkpIHtcclxuICAgIHJldHVybiBkb21VdGlscy5ub2RlQ29udGFpbnMoaWdub3JlRnJvbSwgZWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZmFsc2U7XHJcbn07XHJcblxyXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLnRlc3RBbGxvdyA9IGZ1bmN0aW9uIChhbGxvd0Zyb20sIGludGVyYWN0YWJsZUVsZW1lbnQsIGVsZW1lbnQpIHtcclxuICBpZiAoIWFsbG93RnJvbSkge1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICBpZiAoIWlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIGlmIChpcy5zdHJpbmcoYWxsb3dGcm9tKSkge1xyXG4gICAgcmV0dXJuIGRvbVV0aWxzLm1hdGNoZXNVcFRvKGVsZW1lbnQsIGFsbG93RnJvbSwgaW50ZXJhY3RhYmxlRWxlbWVudCk7XHJcbiAgfSBlbHNlIGlmIChpcy5lbGVtZW50KGFsbG93RnJvbSkpIHtcclxuICAgIHJldHVybiBkb21VdGlscy5ub2RlQ29udGFpbnMoYWxsb3dGcm9tLCBlbGVtZW50KTtcclxuICB9XHJcblxyXG4gIHJldHVybiBmYWxzZTtcclxufTtcclxuXHJcbkludGVyYWN0YWJsZS5wcm90b3R5cGUudGVzdElnbm9yZUFsbG93ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGludGVyYWN0YWJsZUVsZW1lbnQsIGV2ZW50VGFyZ2V0KSB7XHJcbiAgcmV0dXJuICF0aGlzLnRlc3RJZ25vcmUob3B0aW9ucy5pZ25vcmVGcm9tLCBpbnRlcmFjdGFibGVFbGVtZW50LCBldmVudFRhcmdldCkgJiYgdGhpcy50ZXN0QWxsb3cob3B0aW9ucy5hbGxvd0Zyb20sIGludGVyYWN0YWJsZUVsZW1lbnQsIGV2ZW50VGFyZ2V0KTtcclxufTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmFjdGlvbkNoZWNrZXJcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogR2V0cyBvciBzZXRzIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNoZWNrIGFjdGlvbiB0byBiZSBwZXJmb3JtZWQgb25cclxuICogcG9pbnRlckRvd25cclxuICpcclxuIC0gY2hlY2tlciAoZnVuY3Rpb24gfCBudWxsKSAjb3B0aW9uYWwgQSBmdW5jdGlvbiB3aGljaCB0YWtlcyBhIHBvaW50ZXIgZXZlbnQsIGRlZmF1bHRBY3Rpb24gc3RyaW5nLCBpbnRlcmFjdGFibGUsIGVsZW1lbnQgYW5kIGludGVyYWN0aW9uIGFzIHBhcmFtZXRlcnMgYW5kIHJldHVybnMgYW4gb2JqZWN0IHdpdGggbmFtZSBwcm9wZXJ0eSAnZHJhZycgJ3Jlc2l6ZScgb3IgJ2dlc3R1cmUnIGFuZCBvcHRpb25hbGx5IGFuIGBlZGdlc2Agb2JqZWN0IHdpdGggYm9vbGVhbiAndG9wJywgJ2xlZnQnLCAnYm90dG9tJyBhbmQgcmlnaHQgcHJvcHMuXHJcbiA9IChGdW5jdGlvbiB8IEludGVyYWN0YWJsZSkgVGhlIGNoZWNrZXIgZnVuY3Rpb24gb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICpcclxuIHwgaW50ZXJhY3QoJy5yZXNpemUtZHJhZycpXHJcbiB8ICAgLnJlc2l6YWJsZSh0cnVlKVxyXG4gfCAgIC5kcmFnZ2FibGUodHJ1ZSlcclxuIHwgICAuYWN0aW9uQ2hlY2tlcihmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBpbnRlcmFjdGlvbikge1xyXG4gfFxyXG4gfCAgIGlmIChpbnRlcmFjdC5tYXRjaGVzU2VsZWN0b3IoZXZlbnQudGFyZ2V0LCAnLmRyYWctaGFuZGxlJykge1xyXG4gfCAgICAgLy8gZm9yY2UgZHJhZyB3aXRoIGhhbmRsZSB0YXJnZXRcclxuIHwgICAgIGFjdGlvbi5uYW1lID0gZHJhZztcclxuIHwgICB9XHJcbiB8ICAgZWxzZSB7XHJcbiB8ICAgICAvLyByZXNpemUgZnJvbSB0aGUgdG9wIGFuZCByaWdodCBlZGdlc1xyXG4gfCAgICAgYWN0aW9uLm5hbWUgID0gJ3Jlc2l6ZSc7XHJcbiB8ICAgICBhY3Rpb24uZWRnZXMgPSB7IHRvcDogdHJ1ZSwgcmlnaHQ6IHRydWUgfTtcclxuIHwgICB9XHJcbiB8XHJcbiB8ICAgcmV0dXJuIGFjdGlvbjtcclxuIHwgfSk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hY3Rpb25DaGVja2VyID0gZnVuY3Rpb24gKGNoZWNrZXIpIHtcclxuICBpZiAoaXMuZnVuY3Rpb24oY2hlY2tlcikpIHtcclxuICAgIHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyID0gY2hlY2tlcjtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGlmIChjaGVja2VyID09PSBudWxsKSB7XHJcbiAgICBkZWxldGUgdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XHJcbn07XHJcblxyXG4vKlxcXHJcbiAqIEludGVyYWN0YWJsZS5zdHlsZUN1cnNvclxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciB0aGUgdGhlIGN1cnNvciBzaG91bGQgYmUgY2hhbmdlZCBkZXBlbmRpbmcgb24gdGhlXHJcbiAqIGFjdGlvbiB0aGF0IHdvdWxkIGJlIHBlcmZvcm1lZCBpZiB0aGUgbW91c2Ugd2VyZSBwcmVzc2VkIGFuZCBkcmFnZ2VkLlxyXG4gKlxyXG4gLSBuZXdWYWx1ZSAoYm9vbGVhbikgI29wdGlvbmFsXHJcbiA9IChib29sZWFuIHwgSW50ZXJhY3RhYmxlKSBUaGUgY3VycmVudCBzZXR0aW5nIG9yIHRoaXMgSW50ZXJhY3RhYmxlXHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zdHlsZUN1cnNvciA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmIChpcy5ib29sKG5ld1ZhbHVlKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yID0gbmV3VmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAobmV3VmFsdWUgPT09IG51bGwpIHtcclxuICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMuc3R5bGVDdXJzb3I7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yO1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5kZWZhdWx0QWN0aW9uQ2hlY2tlciA9IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpIHtcclxuICB2YXIgcmVjdCA9IHRoaXMuZ2V0UmVjdChlbGVtZW50KTtcclxuICB2YXIgYWN0aW9uID0gbnVsbDtcclxuXHJcbiAgZm9yICh2YXIgX2l0ZXJhdG9yID0gYWN0aW9ucy5uYW1lcywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgIHZhciBfcmVmO1xyXG5cclxuICAgIGlmIChfaXNBcnJheSkge1xyXG4gICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgX3JlZiA9IF9pLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBhY3Rpb25OYW1lID0gX3JlZjtcclxuXHJcbiAgICAvLyBjaGVjayBtb3VzZUJ1dHRvbiBzZXR0aW5nIGlmIHRoZSBwb2ludGVyIGlzIGRvd25cclxuICAgIGlmIChpbnRlcmFjdGlvbi5wb2ludGVySXNEb3duICYmIGludGVyYWN0aW9uLm1vdXNlICYmIChldmVudC5idXR0b25zICYgdGhpcy5vcHRpb25zW2FjdGlvbk5hbWVdLm1vdXNlQnV0dG9ucykgPT09IDApIHtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgYWN0aW9uID0gYWN0aW9uc1thY3Rpb25OYW1lXS5jaGVja2VyKHBvaW50ZXIsIGV2ZW50LCB0aGlzLCBlbGVtZW50LCBpbnRlcmFjdGlvbiwgcmVjdCk7XHJcblxyXG4gICAgaWYgKGFjdGlvbikge1xyXG4gICAgICByZXR1cm4gYWN0aW9uO1xyXG4gICAgfVxyXG4gIH1cclxufTtcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RhYmxlXCI6NCxcIi4uL2FjdGlvbnMvYmFzZVwiOjYsXCIuLi91dGlscy9kb21VdGlsc1wiOjM5LFwiLi4vdXRpbHMvaXNcIjo0Nn1dLDEzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGludGVyYWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJhY3QnKTtcclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4uL0ludGVyYWN0YWJsZScpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuLi9JbnRlcmFjdGlvbicpO1xyXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4uL2FjdGlvbnMvYmFzZScpO1xyXG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xyXG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIHNpZ25hbHMgPSByZXF1aXJlKCcuLi91dGlscy9TaWduYWxzJykubmV3KCk7XHJcblxyXG5yZXF1aXJlKCcuL0ludGVyYWN0YWJsZU1ldGhvZHMnKTtcclxuXHJcbnZhciBhdXRvU3RhcnQgPSB7XHJcbiAgc2lnbmFsczogc2lnbmFscyxcclxuICB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0OiB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0LFxyXG4gIC8vIEFsbG93IHRoaXMgbWFueSBpbnRlcmFjdGlvbnMgdG8gaGFwcGVuIHNpbXVsdGFuZW91c2x5XHJcbiAgbWF4SW50ZXJhY3Rpb25zOiBJbmZpbml0eSxcclxuICBkZWZhdWx0czoge1xyXG4gICAgcGVyQWN0aW9uOiB7XHJcbiAgICAgIG1hbnVhbFN0YXJ0OiBmYWxzZSxcclxuICAgICAgbWF4OiBJbmZpbml0eSxcclxuICAgICAgbWF4UGVyRWxlbWVudDogMSxcclxuICAgICAgYWxsb3dGcm9tOiBudWxsLFxyXG4gICAgICBpZ25vcmVGcm9tOiBudWxsXHJcbiAgICB9XHJcbiAgfSxcclxuICBzZXRBY3Rpb25EZWZhdWx0czogZnVuY3Rpb24gc2V0QWN0aW9uRGVmYXVsdHMoYWN0aW9uKSB7XHJcbiAgICB1dGlscy5leHRlbmQoYWN0aW9uLmRlZmF1bHRzLCBhdXRvU3RhcnQuZGVmYXVsdHMucGVyQWN0aW9uKTtcclxuICB9XHJcbn07XHJcblxyXG4vLyBzZXQgY3Vyc29yIHN0eWxlIG9uIG1vdXNlZG93blxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdkb3duJywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBwb2ludGVyID0gX3JlZi5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZi5ldmVudFRhcmdldDtcclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLmludGVyYWN0aW5nKCkpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBhY3Rpb25JbmZvID0gZ2V0QWN0aW9uSW5mbyhpbnRlcmFjdGlvbiwgcG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0KTtcclxuICBwcmVwYXJlKGludGVyYWN0aW9uLCBhY3Rpb25JbmZvKTtcclxufSk7XHJcblxyXG4vLyBzZXQgY3Vyc29yIHN0eWxlIG9uIG1vdXNlbW92ZVxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdtb3ZlJywgZnVuY3Rpb24gKF9yZWYyKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjIuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXIgPSBfcmVmMi5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWYyLmV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWYyLmV2ZW50VGFyZ2V0O1xyXG5cclxuICBpZiAoIWludGVyYWN0aW9uLm1vdXNlIHx8IGludGVyYWN0aW9uLnBvaW50ZXJJc0Rvd24gfHwgaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIGFjdGlvbkluZm8gPSBnZXRBY3Rpb25JbmZvKGludGVyYWN0aW9uLCBwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQpO1xyXG4gIHByZXBhcmUoaW50ZXJhY3Rpb24sIGFjdGlvbkluZm8pO1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ21vdmUnLCBmdW5jdGlvbiAoYXJnKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IGFyZy5ldmVudDtcclxuXHJcblxyXG4gIGlmICghaW50ZXJhY3Rpb24ucG9pbnRlcklzRG93biB8fCBpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpIHx8ICFpbnRlcmFjdGlvbi5wb2ludGVyV2FzTW92ZWQgfHwgIWludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHNpZ25hbHMuZmlyZSgnYmVmb3JlLXN0YXJ0JywgYXJnKTtcclxuXHJcbiAgdmFyIHRhcmdldCA9IGludGVyYWN0aW9uLnRhcmdldDtcclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgJiYgdGFyZ2V0KSB7XHJcbiAgICAvLyBjaGVjayBtYW51YWxTdGFydCBhbmQgaW50ZXJhY3Rpb24gbGltaXRcclxuICAgIGlmICh0YXJnZXQub3B0aW9uc1tpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXS5tYW51YWxTdGFydCB8fCAhd2l0aGluSW50ZXJhY3Rpb25MaW1pdCh0YXJnZXQsIGludGVyYWN0aW9uLmVsZW1lbnQsIGludGVyYWN0aW9uLnByZXBhcmVkKSkge1xyXG4gICAgICBpbnRlcmFjdGlvbi5zdG9wKGV2ZW50KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGludGVyYWN0aW9uLnN0YXJ0KGludGVyYWN0aW9uLnByZXBhcmVkLCB0YXJnZXQsIGludGVyYWN0aW9uLmVsZW1lbnQpO1xyXG4gICAgfVxyXG4gIH1cclxufSk7XHJcblxyXG4vLyBDaGVjayBpZiB0aGUgY3VycmVudCB0YXJnZXQgc3VwcG9ydHMgdGhlIGFjdGlvbi5cclxuLy8gSWYgc28sIHJldHVybiB0aGUgdmFsaWRhdGVkIGFjdGlvbi4gT3RoZXJ3aXNlLCByZXR1cm4gbnVsbFxyXG5mdW5jdGlvbiB2YWxpZGF0ZUFjdGlvbihhY3Rpb24sIGludGVyYWN0YWJsZSwgZWxlbWVudCwgZXZlbnRUYXJnZXQpIHtcclxuICBpZiAodXRpbHMuaXMub2JqZWN0KGFjdGlvbikgJiYgaW50ZXJhY3RhYmxlLnRlc3RJZ25vcmVBbGxvdyhpbnRlcmFjdGFibGUub3B0aW9uc1thY3Rpb24ubmFtZV0sIGVsZW1lbnQsIGV2ZW50VGFyZ2V0KSAmJiBpbnRlcmFjdGFibGUub3B0aW9uc1thY3Rpb24ubmFtZV0uZW5hYmxlZCAmJiB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0KGludGVyYWN0YWJsZSwgZWxlbWVudCwgYWN0aW9uKSkge1xyXG4gICAgcmV0dXJuIGFjdGlvbjtcclxuICB9XHJcblxyXG4gIHJldHVybiBudWxsO1xyXG59XHJcblxyXG5mdW5jdGlvbiB2YWxpZGF0ZVNlbGVjdG9yKGludGVyYWN0aW9uLCBwb2ludGVyLCBldmVudCwgbWF0Y2hlcywgbWF0Y2hFbGVtZW50cywgZXZlbnRUYXJnZXQpIHtcclxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbWF0Y2hlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgdmFyIG1hdGNoID0gbWF0Y2hlc1tpXTtcclxuICAgIHZhciBtYXRjaEVsZW1lbnQgPSBtYXRjaEVsZW1lbnRzW2ldO1xyXG4gICAgdmFyIGFjdGlvbiA9IHZhbGlkYXRlQWN0aW9uKG1hdGNoLmdldEFjdGlvbihwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIG1hdGNoRWxlbWVudCksIG1hdGNoLCBtYXRjaEVsZW1lbnQsIGV2ZW50VGFyZ2V0KTtcclxuXHJcbiAgICBpZiAoYWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgYWN0aW9uOiBhY3Rpb24sXHJcbiAgICAgICAgdGFyZ2V0OiBtYXRjaCxcclxuICAgICAgICBlbGVtZW50OiBtYXRjaEVsZW1lbnRcclxuICAgICAgfTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiB7fTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0QWN0aW9uSW5mbyhpbnRlcmFjdGlvbiwgcG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0KSB7XHJcbiAgdmFyIG1hdGNoZXMgPSBbXTtcclxuICB2YXIgbWF0Y2hFbGVtZW50cyA9IFtdO1xyXG5cclxuICB2YXIgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xyXG4gIHZhciBhY3Rpb24gPSBudWxsO1xyXG5cclxuICBmdW5jdGlvbiBwdXNoTWF0Y2hlcyhpbnRlcmFjdGFibGUsIHNlbGVjdG9yLCBjb250ZXh0KSB7XHJcbiAgICB2YXIgZWxlbWVudHMgPSBicm93c2VyLnVzZU1hdGNoZXNTZWxlY3RvclBvbHlmaWxsID8gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSA6IHVuZGVmaW5lZDtcclxuXHJcbiAgICBpZiAodXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yLCBlbGVtZW50cykpIHtcclxuXHJcbiAgICAgIG1hdGNoZXMucHVzaChpbnRlcmFjdGFibGUpO1xyXG4gICAgICBtYXRjaEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB3aGlsZSAodXRpbHMuaXMuZWxlbWVudChlbGVtZW50KSkge1xyXG4gICAgbWF0Y2hlcyA9IFtdO1xyXG4gICAgbWF0Y2hFbGVtZW50cyA9IFtdO1xyXG5cclxuICAgIHZhciBlbGVtZW50SW50ZXJhY3RhYmxlID0gc2NvcGUuaW50ZXJhY3RhYmxlcy5nZXQoZWxlbWVudCk7XHJcblxyXG4gICAgaWYgKGVsZW1lbnRJbnRlcmFjdGFibGUgJiYgKGFjdGlvbiA9IHZhbGlkYXRlQWN0aW9uKGVsZW1lbnRJbnRlcmFjdGFibGUuZ2V0QWN0aW9uKHBvaW50ZXIsIGV2ZW50LCBpbnRlcmFjdGlvbiwgZWxlbWVudCwgZXZlbnRUYXJnZXQpLCBlbGVtZW50SW50ZXJhY3RhYmxlLCBlbGVtZW50LCBldmVudFRhcmdldCkpICYmICFlbGVtZW50SW50ZXJhY3RhYmxlLm9wdGlvbnNbYWN0aW9uLm5hbWVdLm1hbnVhbFN0YXJ0KSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBhY3Rpb246IGFjdGlvbixcclxuICAgICAgICB0YXJnZXQ6IGVsZW1lbnRJbnRlcmFjdGFibGVcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHNjb3BlLmludGVyYWN0YWJsZXMuZm9yRWFjaFNlbGVjdG9yKHB1c2hNYXRjaGVzLCBlbGVtZW50KTtcclxuXHJcbiAgICAgIHZhciBhY3Rpb25JbmZvID0gdmFsaWRhdGVTZWxlY3RvcihpbnRlcmFjdGlvbiwgcG9pbnRlciwgZXZlbnQsIG1hdGNoZXMsIG1hdGNoRWxlbWVudHMsIGV2ZW50VGFyZ2V0KTtcclxuXHJcbiAgICAgIGlmIChhY3Rpb25JbmZvLmFjdGlvbiAmJiAhYWN0aW9uSW5mby50YXJnZXQub3B0aW9uc1thY3Rpb25JbmZvLmFjdGlvbi5uYW1lXS5tYW51YWxTdGFydCkge1xyXG4gICAgICAgIHJldHVybiBhY3Rpb25JbmZvO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZWxlbWVudCA9IHV0aWxzLnBhcmVudE5vZGUoZWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4ge307XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHByZXBhcmUoaW50ZXJhY3Rpb24sIF9yZWYzKSB7XHJcbiAgdmFyIGFjdGlvbiA9IF9yZWYzLmFjdGlvbixcclxuICAgICAgdGFyZ2V0ID0gX3JlZjMudGFyZ2V0LFxyXG4gICAgICBlbGVtZW50ID0gX3JlZjMuZWxlbWVudDtcclxuXHJcbiAgYWN0aW9uID0gYWN0aW9uIHx8IHt9O1xyXG5cclxuICBpZiAoaW50ZXJhY3Rpb24udGFyZ2V0ICYmIGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zLnN0eWxlQ3Vyc29yKSB7XHJcbiAgICBpbnRlcmFjdGlvbi50YXJnZXQuX2RvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gJyc7XHJcbiAgfVxyXG5cclxuICBpbnRlcmFjdGlvbi50YXJnZXQgPSB0YXJnZXQ7XHJcbiAgaW50ZXJhY3Rpb24uZWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgdXRpbHMuY29weUFjdGlvbihpbnRlcmFjdGlvbi5wcmVwYXJlZCwgYWN0aW9uKTtcclxuXHJcbiAgaWYgKHRhcmdldCAmJiB0YXJnZXQub3B0aW9ucy5zdHlsZUN1cnNvcikge1xyXG4gICAgdmFyIGN1cnNvciA9IGFjdGlvbiA/IGFjdGlvbnNbYWN0aW9uLm5hbWVdLmdldEN1cnNvcihhY3Rpb24pIDogJyc7XHJcbiAgICBpbnRlcmFjdGlvbi50YXJnZXQuX2RvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gY3Vyc29yO1xyXG4gIH1cclxuXHJcbiAgc2lnbmFscy5maXJlKCdwcmVwYXJlZCcsIHsgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uIH0pO1xyXG59XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdzdG9wJywgZnVuY3Rpb24gKF9yZWY0KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjQuaW50ZXJhY3Rpb247XHJcblxyXG4gIHZhciB0YXJnZXQgPSBpbnRlcmFjdGlvbi50YXJnZXQ7XHJcblxyXG4gIGlmICh0YXJnZXQgJiYgdGFyZ2V0Lm9wdGlvbnMuc3R5bGVDdXJzb3IpIHtcclxuICAgIHRhcmdldC5fZG9jLmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3IgPSAnJztcclxuICB9XHJcbn0pO1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5nZXRBY3Rpb24gPSBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KSB7XHJcbiAgdmFyIGFjdGlvbiA9IHRoaXMuZGVmYXVsdEFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KTtcclxuXHJcbiAgaWYgKHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyKSB7XHJcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgdGhpcywgZWxlbWVudCwgaW50ZXJhY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGFjdGlvbjtcclxufTtcclxuXHJcbi8qXFxcclxuICogSW50ZXJhY3RhYmxlLmFjdGlvbkNoZWNrZXJcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogR2V0cyBvciBzZXRzIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNoZWNrIGFjdGlvbiB0byBiZSBwZXJmb3JtZWQgb25cclxuICogcG9pbnRlckRvd25cclxuICpcclxuIC0gY2hlY2tlciAoZnVuY3Rpb24gfCBudWxsKSAjb3B0aW9uYWwgQSBmdW5jdGlvbiB3aGljaCB0YWtlcyBhIHBvaW50ZXIgZXZlbnQsIGRlZmF1bHRBY3Rpb24gc3RyaW5nLCBpbnRlcmFjdGFibGUsIGVsZW1lbnQgYW5kIGludGVyYWN0aW9uIGFzIHBhcmFtZXRlcnMgYW5kIHJldHVybnMgYW4gb2JqZWN0IHdpdGggbmFtZSBwcm9wZXJ0eSAnZHJhZycgJ3Jlc2l6ZScgb3IgJ2dlc3R1cmUnIGFuZCBvcHRpb25hbGx5IGFuIGBlZGdlc2Agb2JqZWN0IHdpdGggYm9vbGVhbiAndG9wJywgJ2xlZnQnLCAnYm90dG9tJyBhbmQgcmlnaHQgcHJvcHMuXHJcbiA9IChGdW5jdGlvbiB8IEludGVyYWN0YWJsZSkgVGhlIGNoZWNrZXIgZnVuY3Rpb24gb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuICpcclxuIHwgaW50ZXJhY3QoJy5yZXNpemUtZHJhZycpXHJcbiB8ICAgLnJlc2l6YWJsZSh0cnVlKVxyXG4gfCAgIC5kcmFnZ2FibGUodHJ1ZSlcclxuIHwgICAuYWN0aW9uQ2hlY2tlcihmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBpbnRlcmFjdGlvbikge1xyXG4gfFxyXG4gfCAgIGlmIChpbnRlcmFjdC5tYXRjaGVzU2VsZWN0b3IoZXZlbnQudGFyZ2V0LCAnLmRyYWctaGFuZGxlJykge1xyXG4gfCAgICAgLy8gZm9yY2UgZHJhZyB3aXRoIGhhbmRsZSB0YXJnZXRcclxuIHwgICAgIGFjdGlvbi5uYW1lID0gZHJhZztcclxuIHwgICB9XHJcbiB8ICAgZWxzZSB7XHJcbiB8ICAgICAvLyByZXNpemUgZnJvbSB0aGUgdG9wIGFuZCByaWdodCBlZGdlc1xyXG4gfCAgICAgYWN0aW9uLm5hbWUgID0gJ3Jlc2l6ZSc7XHJcbiB8ICAgICBhY3Rpb24uZWRnZXMgPSB7IHRvcDogdHJ1ZSwgcmlnaHQ6IHRydWUgfTtcclxuIHwgICB9XHJcbiB8XHJcbiB8ICAgcmV0dXJuIGFjdGlvbjtcclxuIHwgfSk7XHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hY3Rpb25DaGVja2VyID0gZnVuY3Rpb24gKGNoZWNrZXIpIHtcclxuICBpZiAodXRpbHMuaXMuZnVuY3Rpb24oY2hlY2tlcikpIHtcclxuICAgIHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyID0gY2hlY2tlcjtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGlmIChjaGVja2VyID09PSBudWxsKSB7XHJcbiAgICBkZWxldGUgdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XHJcbn07XHJcblxyXG4vKlxcXHJcbiAqIEludGVyYWN0YWJsZS5zdHlsZUN1cnNvclxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciB0aGUgdGhlIGN1cnNvciBzaG91bGQgYmUgY2hhbmdlZCBkZXBlbmRpbmcgb24gdGhlXHJcbiAqIGFjdGlvbiB0aGF0IHdvdWxkIGJlIHBlcmZvcm1lZCBpZiB0aGUgbW91c2Ugd2VyZSBwcmVzc2VkIGFuZCBkcmFnZ2VkLlxyXG4gKlxyXG4gLSBuZXdWYWx1ZSAoYm9vbGVhbikgI29wdGlvbmFsXHJcbiA9IChib29sZWFuIHwgSW50ZXJhY3RhYmxlKSBUaGUgY3VycmVudCBzZXR0aW5nIG9yIHRoaXMgSW50ZXJhY3RhYmxlXHJcblxcKi9cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zdHlsZUN1cnNvciA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmICh1dGlscy5pcy5ib29sKG5ld1ZhbHVlKSkge1xyXG4gICAgdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yID0gbmV3VmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAobmV3VmFsdWUgPT09IG51bGwpIHtcclxuICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMuc3R5bGVDdXJzb3I7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yO1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5kZWZhdWx0QWN0aW9uQ2hlY2tlciA9IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpIHtcclxuICB2YXIgcmVjdCA9IHRoaXMuZ2V0UmVjdChlbGVtZW50KTtcclxuICB2YXIgYnV0dG9ucyA9IGV2ZW50LmJ1dHRvbnMgfHwge1xyXG4gICAgMDogMSxcclxuICAgIDE6IDQsXHJcbiAgICAzOiA4LFxyXG4gICAgNDogMTZcclxuICB9W2V2ZW50LmJ1dHRvbl07XHJcbiAgdmFyIGFjdGlvbiA9IG51bGw7XHJcblxyXG4gIGZvciAodmFyIF9pdGVyYXRvciA9IGFjdGlvbnMubmFtZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICB2YXIgX3JlZjU7XHJcblxyXG4gICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgX3JlZjUgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgX3JlZjUgPSBfaS52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYWN0aW9uTmFtZSA9IF9yZWY1O1xyXG5cclxuICAgIC8vIGNoZWNrIG1vdXNlQnV0dG9uIHNldHRpbmcgaWYgdGhlIHBvaW50ZXIgaXMgZG93blxyXG4gICAgaWYgKGludGVyYWN0aW9uLnBvaW50ZXJJc0Rvd24gJiYgaW50ZXJhY3Rpb24ubW91c2UgJiYgKGJ1dHRvbnMgJiB0aGlzLm9wdGlvbnNbYWN0aW9uTmFtZV0ubW91c2VCdXR0b25zKSA9PT0gMCkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBhY3Rpb24gPSBhY3Rpb25zW2FjdGlvbk5hbWVdLmNoZWNrZXIocG9pbnRlciwgZXZlbnQsIHRoaXMsIGVsZW1lbnQsIGludGVyYWN0aW9uLCByZWN0KTtcclxuXHJcbiAgICBpZiAoYWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiBhY3Rpb247XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG5cclxuZnVuY3Rpb24gd2l0aGluSW50ZXJhY3Rpb25MaW1pdChpbnRlcmFjdGFibGUsIGVsZW1lbnQsIGFjdGlvbikge1xyXG4gIHZhciBvcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnM7XHJcbiAgdmFyIG1heEFjdGlvbnMgPSBvcHRpb25zW2FjdGlvbi5uYW1lXS5tYXg7XHJcbiAgdmFyIG1heFBlckVsZW1lbnQgPSBvcHRpb25zW2FjdGlvbi5uYW1lXS5tYXhQZXJFbGVtZW50O1xyXG4gIHZhciBhY3RpdmVJbnRlcmFjdGlvbnMgPSAwO1xyXG4gIHZhciB0YXJnZXRDb3VudCA9IDA7XHJcbiAgdmFyIHRhcmdldEVsZW1lbnRDb3VudCA9IDA7XHJcblxyXG4gIC8vIG5vIGFjdGlvbnMgaWYgYW55IG9mIHRoZXNlIHZhbHVlcyA9PSAwXHJcbiAgaWYgKCEobWF4QWN0aW9ucyAmJiBtYXhQZXJFbGVtZW50ICYmIGF1dG9TdGFydC5tYXhJbnRlcmFjdGlvbnMpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2NvcGUuaW50ZXJhY3Rpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICB2YXIgaW50ZXJhY3Rpb24gPSBzY29wZS5pbnRlcmFjdGlvbnNbaV07XHJcbiAgICB2YXIgb3RoZXJBY3Rpb24gPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lO1xyXG5cclxuICAgIGlmICghaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBhY3RpdmVJbnRlcmFjdGlvbnMrKztcclxuXHJcbiAgICBpZiAoYWN0aXZlSW50ZXJhY3Rpb25zID49IGF1dG9TdGFydC5tYXhJbnRlcmFjdGlvbnMpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpbnRlcmFjdGlvbi50YXJnZXQgIT09IGludGVyYWN0YWJsZSkge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICB0YXJnZXRDb3VudCArPSBvdGhlckFjdGlvbiA9PT0gYWN0aW9uLm5hbWUgfCAwO1xyXG5cclxuICAgIGlmICh0YXJnZXRDb3VudCA+PSBtYXhBY3Rpb25zKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaW50ZXJhY3Rpb24uZWxlbWVudCA9PT0gZWxlbWVudCkge1xyXG4gICAgICB0YXJnZXRFbGVtZW50Q291bnQrKztcclxuXHJcbiAgICAgIGlmIChvdGhlckFjdGlvbiAhPT0gYWN0aW9uLm5hbWUgfHwgdGFyZ2V0RWxlbWVudENvdW50ID49IG1heFBlckVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBhdXRvU3RhcnQubWF4SW50ZXJhY3Rpb25zID4gMDtcclxufVxyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5tYXhJbnRlcmFjdGlvbnNcclxuIFsgbWV0aG9kIF1cclxuICoqXHJcbiAqIFJldHVybnMgb3Igc2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgY29uY3VycmVudCBpbnRlcmFjdGlvbnMgYWxsb3dlZC5cclxuICogQnkgZGVmYXVsdCBvbmx5IDEgaW50ZXJhY3Rpb24gaXMgYWxsb3dlZCBhdCBhIHRpbWUgKGZvciBiYWNrd2FyZHNcclxuICogY29tcGF0aWJpbGl0eSkuIFRvIGFsbG93IG11bHRpcGxlIGludGVyYWN0aW9ucyBvbiB0aGUgc2FtZSBJbnRlcmFjdGFibGVzXHJcbiAqIGFuZCBlbGVtZW50cywgeW91IG5lZWQgdG8gZW5hYmxlIGl0IGluIHRoZSBkcmFnZ2FibGUsIHJlc2l6YWJsZSBhbmRcclxuICogZ2VzdHVyYWJsZSBgJ21heCdgIGFuZCBgJ21heFBlckVsZW1lbnQnYCBvcHRpb25zLlxyXG4gKipcclxuIC0gbmV3VmFsdWUgKG51bWJlcikgI29wdGlvbmFsIEFueSBudW1iZXIuIG5ld1ZhbHVlIDw9IDAgbWVhbnMgbm8gaW50ZXJhY3Rpb25zLlxyXG5cXCovXHJcbmludGVyYWN0Lm1heEludGVyYWN0aW9ucyA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmICh1dGlscy5pcy5udW1iZXIobmV3VmFsdWUpKSB7XHJcbiAgICBhdXRvU3RhcnQubWF4SW50ZXJhY3Rpb25zID0gbmV3VmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gYXV0b1N0YXJ0Lm1heEludGVyYWN0aW9ucztcclxufTtcclxuXHJcbkludGVyYWN0YWJsZS5zZXR0aW5nc01ldGhvZHMucHVzaCgnc3R5bGVDdXJzb3InKTtcclxuSW50ZXJhY3RhYmxlLnNldHRpbmdzTWV0aG9kcy5wdXNoKCdhY3Rpb25DaGVja2VyJyk7XHJcbkludGVyYWN0YWJsZS5zZXR0aW5nc01ldGhvZHMucHVzaCgnaWdub3JlRnJvbScpO1xyXG5JbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLnB1c2goJ2FsbG93RnJvbScpO1xyXG5cclxuZGVmYXVsdE9wdGlvbnMuYmFzZS5hY3Rpb25DaGVja2VyID0gbnVsbDtcclxuZGVmYXVsdE9wdGlvbnMuYmFzZS5zdHlsZUN1cnNvciA9IHRydWU7XHJcblxyXG51dGlscy5leHRlbmQoZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uLCBhdXRvU3RhcnQuZGVmYXVsdHMucGVyQWN0aW9uKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYXV0b1N0YXJ0O1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vSW50ZXJhY3Rpb25cIjo1LFwiLi4vYWN0aW9ucy9iYXNlXCI6NixcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi9pbnRlcmFjdFwiOjIxLFwiLi4vc2NvcGVcIjozNCxcIi4uL3V0aWxzXCI6NDQsXCIuLi91dGlscy9TaWduYWxzXCI6MzUsXCIuLi91dGlscy9icm93c2VyXCI6MzcsXCIuL0ludGVyYWN0YWJsZU1ldGhvZHNcIjoxMn1dLDE0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGF1dG9TdGFydCA9IHJlcXVpcmUoJy4vYmFzZScpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuLi9JbnRlcmFjdGlvbicpO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XHJcbiAgaW50ZXJhY3Rpb24uZGVsYXlUaW1lciA9IG51bGw7XHJcbn0pO1xyXG5cclxuYXV0b1N0YXJ0LnNpZ25hbHMub24oJ3ByZXBhcmVkJywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uO1xyXG5cclxuICB2YXIgYWN0aW9uTmFtZSA9IGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWU7XHJcblxyXG4gIGlmICghYWN0aW9uTmFtZSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIGRlbGF5ID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbYWN0aW9uTmFtZV0uZGVsYXk7XHJcblxyXG4gIGlmIChkZWxheSA+IDApIHtcclxuICAgIGludGVyYWN0aW9uLmRlbGF5VGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgaW50ZXJhY3Rpb24uc3RhcnQoaW50ZXJhY3Rpb24ucHJlcGFyZWQsIGludGVyYWN0aW9uLnRhcmdldCwgaW50ZXJhY3Rpb24uZWxlbWVudCk7XHJcbiAgICB9LCBkZWxheSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ21vdmUnLCBmdW5jdGlvbiAoX3JlZjIpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbixcclxuICAgICAgZHVwbGljYXRlID0gX3JlZjIuZHVwbGljYXRlO1xyXG5cclxuICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlcldhc01vdmVkICYmICFkdXBsaWNhdGUpIHtcclxuICAgIGNsZWFyVGltZW91dChpbnRlcmFjdGlvbi5kZWxheVRpbWVyKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLy8gcHJldmVudCByZWd1bGFyIGRvd24tPm1vdmUgYXV0b1N0YXJ0XHJcbmF1dG9TdGFydC5zaWduYWxzLm9uKCdiZWZvcmUtc3RhcnQnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgdmFyIGFjdGlvbk5hbWUgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lO1xyXG5cclxuICBpZiAoIWFjdGlvbk5hbWUpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBkZWxheSA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zW2FjdGlvbk5hbWVdLmRlbGF5O1xyXG5cclxuICBpZiAoZGVsYXkgPiAwKSB7XHJcbiAgICBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lID0gbnVsbDtcclxuICB9XHJcbn0pO1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuL2Jhc2VcIjoxM31dLDE1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGF1dG9TdGFydCA9IHJlcXVpcmUoJy4vYmFzZScpO1xyXG52YXIgc2NvcGUgPSByZXF1aXJlKCcuLi9zY29wZScpO1xyXG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcclxudmFyIGlzID0gcmVxdWlyZSgnLi4vdXRpbHMvaXMnKTtcclxuXHJcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4uL3V0aWxzL2RvbVV0aWxzJyksXHJcbiAgICBtYXRjaGVzU2VsZWN0b3IgPSBfcmVxdWlyZS5tYXRjaGVzU2VsZWN0b3IsXHJcbiAgICBwYXJlbnROb2RlID0gX3JlcXVpcmUucGFyZW50Tm9kZTtcclxuXHJcbmF1dG9TdGFydC5zZXRBY3Rpb25EZWZhdWx0cyhyZXF1aXJlKCcuLi9hY3Rpb25zL2RyYWcnKSk7XHJcblxyXG5hdXRvU3RhcnQuc2lnbmFscy5vbignYmVmb3JlLXN0YXJ0JywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWYuZXZlbnRUYXJnZXQsXHJcbiAgICAgIGR4ID0gX3JlZi5keCxcclxuICAgICAgZHkgPSBfcmVmLmR5O1xyXG5cclxuICBpZiAoaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSAhPT0gJ2RyYWcnKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvLyBjaGVjayBpZiBhIGRyYWcgaXMgaW4gdGhlIGNvcnJlY3QgYXhpc1xyXG4gIHZhciBhYnNYID0gTWF0aC5hYnMoZHgpO1xyXG4gIHZhciBhYnNZID0gTWF0aC5hYnMoZHkpO1xyXG4gIHZhciBvcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnMuZHJhZztcclxuICB2YXIgc3RhcnRBeGlzID0gb3B0aW9ucy5zdGFydEF4aXM7XHJcbiAgdmFyIGN1cnJlbnRBeGlzID0gYWJzWCA+IGFic1kgPyAneCcgOiBhYnNYIDwgYWJzWSA/ICd5JyA6ICd4eSc7XHJcblxyXG4gIGludGVyYWN0aW9uLnByZXBhcmVkLmF4aXMgPSBvcHRpb25zLmxvY2tBeGlzID09PSAnc3RhcnQnID8gY3VycmVudEF4aXNbMF0gLy8gYWx3YXlzIGxvY2sgdG8gb25lIGF4aXMgZXZlbiBpZiBjdXJyZW50QXhpcyA9PT0gJ3h5J1xyXG4gIDogb3B0aW9ucy5sb2NrQXhpcztcclxuXHJcbiAgLy8gaWYgdGhlIG1vdmVtZW50IGlzbid0IGluIHRoZSBzdGFydEF4aXMgb2YgdGhlIGludGVyYWN0YWJsZVxyXG4gIGlmIChjdXJyZW50QXhpcyAhPT0gJ3h5JyAmJiBzdGFydEF4aXMgIT09ICd4eScgJiYgc3RhcnRBeGlzICE9PSBjdXJyZW50QXhpcykge1xyXG4gICAgLy8gY2FuY2VsIHRoZSBwcmVwYXJlZCBhY3Rpb25cclxuICAgIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgPSBudWxsO1xyXG5cclxuICAgIC8vIHRoZW4gdHJ5IHRvIGdldCBhIGRyYWcgZnJvbSBhbm90aGVyIGluZXJhY3RhYmxlXHJcblxyXG4gICAgaWYgKCFpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lKSB7XHJcblxyXG4gICAgICB2YXIgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xyXG5cclxuICAgICAgdmFyIGdldERyYWdnYWJsZSA9IGZ1bmN0aW9uIGdldERyYWdnYWJsZShpbnRlcmFjdGFibGUsIHNlbGVjdG9yLCBjb250ZXh0KSB7XHJcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gYnJvd3Nlci51c2VNYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbCA/IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikgOiB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgIGlmIChpbnRlcmFjdGFibGUgPT09IGludGVyYWN0aW9uLnRhcmdldCkge1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFvcHRpb25zLm1hbnVhbFN0YXJ0ICYmICFpbnRlcmFjdGFibGUudGVzdElnbm9yZUFsbG93KG9wdGlvbnMsIGVsZW1lbnQsIGV2ZW50VGFyZ2V0KSAmJiBtYXRjaGVzU2VsZWN0b3IoZWxlbWVudCwgc2VsZWN0b3IsIGVsZW1lbnRzKSkge1xyXG5cclxuICAgICAgICAgIHZhciBfYWN0aW9uID0gaW50ZXJhY3RhYmxlLmdldEFjdGlvbihpbnRlcmFjdGlvbi5kb3duUG9pbnRlciwgaW50ZXJhY3Rpb24uZG93bkV2ZW50LCBpbnRlcmFjdGlvbiwgZWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgaWYgKF9hY3Rpb24gJiYgX2FjdGlvbi5uYW1lID09PSAnZHJhZycgJiYgY2hlY2tTdGFydEF4aXMoY3VycmVudEF4aXMsIGludGVyYWN0YWJsZSkgJiYgYXV0b1N0YXJ0LnZhbGlkYXRlQWN0aW9uKF9hY3Rpb24sIGludGVyYWN0YWJsZSwgZWxlbWVudCwgZXZlbnRUYXJnZXQpKSB7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gaW50ZXJhY3RhYmxlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBhY3Rpb24gPSBudWxsO1xyXG5cclxuICAgICAgLy8gY2hlY2sgYWxsIGludGVyYWN0YWJsZXNcclxuICAgICAgd2hpbGUgKGlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgICAgICB2YXIgZWxlbWVudEludGVyYWN0YWJsZSA9IHNjb3BlLmludGVyYWN0YWJsZXMuZ2V0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgICBpZiAoZWxlbWVudEludGVyYWN0YWJsZSAmJiBlbGVtZW50SW50ZXJhY3RhYmxlICE9PSBpbnRlcmFjdGlvbi50YXJnZXQgJiYgIWVsZW1lbnRJbnRlcmFjdGFibGUub3B0aW9ucy5kcmFnLm1hbnVhbFN0YXJ0KSB7XHJcblxyXG4gICAgICAgICAgYWN0aW9uID0gZWxlbWVudEludGVyYWN0YWJsZS5nZXRBY3Rpb24oaW50ZXJhY3Rpb24uZG93blBvaW50ZXIsIGludGVyYWN0aW9uLmRvd25FdmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYWN0aW9uICYmIGFjdGlvbi5uYW1lID09PSAnZHJhZycgJiYgY2hlY2tTdGFydEF4aXMoY3VycmVudEF4aXMsIGVsZW1lbnRJbnRlcmFjdGFibGUpKSB7XHJcblxyXG4gICAgICAgICAgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSA9ICdkcmFnJztcclxuICAgICAgICAgIGludGVyYWN0aW9uLnRhcmdldCA9IGVsZW1lbnRJbnRlcmFjdGFibGU7XHJcbiAgICAgICAgICBpbnRlcmFjdGlvbi5lbGVtZW50ID0gZWxlbWVudDtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHNlbGVjdG9ySW50ZXJhY3RhYmxlID0gc2NvcGUuaW50ZXJhY3RhYmxlcy5mb3JFYWNoU2VsZWN0b3IoZ2V0RHJhZ2dhYmxlLCBlbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKHNlbGVjdG9ySW50ZXJhY3RhYmxlKSB7XHJcbiAgICAgICAgICBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lID0gJ2RyYWcnO1xyXG4gICAgICAgICAgaW50ZXJhY3Rpb24udGFyZ2V0ID0gc2VsZWN0b3JJbnRlcmFjdGFibGU7XHJcbiAgICAgICAgICBpbnRlcmFjdGlvbi5lbGVtZW50ID0gZWxlbWVudDtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZWxlbWVudCA9IHBhcmVudE5vZGUoZWxlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn0pO1xyXG5cclxuZnVuY3Rpb24gY2hlY2tTdGFydEF4aXMoc3RhcnRBeGlzLCBpbnRlcmFjdGFibGUpIHtcclxuICBpZiAoIWludGVyYWN0YWJsZSkge1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgdmFyIHRoaXNBeGlzID0gaW50ZXJhY3RhYmxlLm9wdGlvbnMuZHJhZy5zdGFydEF4aXM7XHJcblxyXG4gIHJldHVybiBzdGFydEF4aXMgPT09ICd4eScgfHwgdGhpc0F4aXMgPT09ICd4eScgfHwgdGhpc0F4aXMgPT09IHN0YXJ0QXhpcztcclxufVxyXG5cclxufSx7XCIuLi9hY3Rpb25zL2RyYWdcIjo3LFwiLi4vc2NvcGVcIjozNCxcIi4uL3V0aWxzL2Jyb3dzZXJcIjozNyxcIi4uL3V0aWxzL2RvbVV0aWxzXCI6MzksXCIuLi91dGlscy9pc1wiOjQ2LFwiLi9iYXNlXCI6MTN9XSwxNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnJlcXVpcmUoJy4vYmFzZScpLnNldEFjdGlvbkRlZmF1bHRzKHJlcXVpcmUoJy4uL2FjdGlvbnMvZ2VzdHVyZScpKTtcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9nZXN0dXJlXCI6OSxcIi4vYmFzZVwiOjEzfV0sMTc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5yZXF1aXJlKCcuL2Jhc2UnKS5zZXRBY3Rpb25EZWZhdWx0cyhyZXF1aXJlKCcuLi9hY3Rpb25zL3Jlc2l6ZScpKTtcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4vYmFzZVwiOjEzfV0sMTg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHtcclxuICBiYXNlOiB7XHJcbiAgICBhY2NlcHQ6IG51bGwsXHJcbiAgICBwcmV2ZW50RGVmYXVsdDogJ2F1dG8nLFxyXG4gICAgZGVsdGFTb3VyY2U6ICdwYWdlJ1xyXG4gIH0sXHJcblxyXG4gIHBlckFjdGlvbjoge1xyXG4gICAgb3JpZ2luOiB7IHg6IDAsIHk6IDAgfSxcclxuXHJcbiAgICAvLyBvbmx5IGFsbG93IGxlZnQgYnV0dG9uIGJ5IGRlZmF1bHRcclxuICAgIC8vIHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTW91c2VFdmVudC9idXR0b25zI1JldHVybl92YWx1ZVxyXG4gICAgbW91c2VCdXR0b25zOiAxLFxyXG5cclxuICAgIGluZXJ0aWE6IHtcclxuICAgICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICAgIHJlc2lzdGFuY2U6IDEwLCAvLyB0aGUgbGFtYmRhIGluIGV4cG9uZW50aWFsIGRlY2F5XHJcbiAgICAgIG1pblNwZWVkOiAxMDAsIC8vIHRhcmdldCBzcGVlZCBtdXN0IGJlIGFib3ZlIHRoaXMgZm9yIGluZXJ0aWEgdG8gc3RhcnRcclxuICAgICAgZW5kU3BlZWQ6IDEwLCAvLyB0aGUgc3BlZWQgYXQgd2hpY2ggaW5lcnRpYSBpcyBzbG93IGVub3VnaCB0byBzdG9wXHJcbiAgICAgIGFsbG93UmVzdW1lOiB0cnVlLCAvLyBhbGxvdyByZXN1bWluZyBhbiBhY3Rpb24gaW4gaW5lcnRpYSBwaGFzZVxyXG4gICAgICBzbW9vdGhFbmREdXJhdGlvbjogMzAwIC8vIGFuaW1hdGUgdG8gc25hcC9yZXN0cmljdCBlbmRPbmx5IGlmIHRoZXJlJ3Mgbm8gaW5lcnRpYVxyXG4gICAgfVxyXG4gIH1cclxufTtcclxuXHJcbn0se31dLDE5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuLyogYnJvd3NlciBlbnRyeSBwb2ludCAqL1xyXG5cclxuLy8gTGVnYWN5IGJyb3dzZXIgc3VwcG9ydFxyXG5yZXF1aXJlKCcuL2xlZ2FjeUJyb3dzZXJzJyk7XHJcblxyXG4vLyBpbmVydGlhXHJcbnJlcXVpcmUoJy4vaW5lcnRpYScpO1xyXG5cclxuLy8gbW9kaWZpZXJzXHJcbnJlcXVpcmUoJy4vbW9kaWZpZXJzL3NuYXAnKTtcclxucmVxdWlyZSgnLi9tb2RpZmllcnMvcmVzdHJpY3QnKTtcclxuXHJcbi8vIHBvaW50ZXJFdmVudHNcclxucmVxdWlyZSgnLi9wb2ludGVyRXZlbnRzL2Jhc2UnKTtcclxucmVxdWlyZSgnLi9wb2ludGVyRXZlbnRzL2hvbGRSZXBlYXQnKTtcclxucmVxdWlyZSgnLi9wb2ludGVyRXZlbnRzL2ludGVyYWN0YWJsZVRhcmdldHMnKTtcclxuXHJcbi8vIGRlbGF5XHJcbnJlcXVpcmUoJy4vYXV0b1N0YXJ0L2RlbGF5Jyk7XHJcblxyXG4vLyBhY3Rpb25zXHJcbnJlcXVpcmUoJy4vYWN0aW9ucy9nZXN0dXJlJyk7XHJcbnJlcXVpcmUoJy4vYWN0aW9ucy9yZXNpemUnKTtcclxucmVxdWlyZSgnLi9hY3Rpb25zL2RyYWcnKTtcclxucmVxdWlyZSgnLi9hY3Rpb25zL2Ryb3AnKTtcclxuXHJcbi8vIGxvYWQgdGhlc2UgbW9kaWZpZXJzIGFmdGVyIHJlc2l6ZSBpcyBsb2FkZWRcclxucmVxdWlyZSgnLi9tb2RpZmllcnMvc25hcFNpemUnKTtcclxucmVxdWlyZSgnLi9tb2RpZmllcnMvcmVzdHJpY3RFZGdlcycpO1xyXG5yZXF1aXJlKCcuL21vZGlmaWVycy9yZXN0cmljdFNpemUnKTtcclxuXHJcbi8vIGF1dG9TdGFydCBhY3Rpb25zXHJcbnJlcXVpcmUoJy4vYXV0b1N0YXJ0L2dlc3R1cmUnKTtcclxucmVxdWlyZSgnLi9hdXRvU3RhcnQvcmVzaXplJyk7XHJcbnJlcXVpcmUoJy4vYXV0b1N0YXJ0L2RyYWcnKTtcclxuXHJcbi8vIEludGVyYWN0YWJsZSBwcmV2ZW50RGVmYXVsdCBzZXR0aW5nXHJcbnJlcXVpcmUoJy4vaW50ZXJhY3RhYmxlUHJldmVudERlZmF1bHQuanMnKTtcclxuXHJcbi8vIGF1dG9TY3JvbGxcclxucmVxdWlyZSgnLi9hdXRvU2Nyb2xsJyk7XHJcblxyXG4vLyBleHBvcnQgaW50ZXJhY3RcclxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2ludGVyYWN0Jyk7XHJcblxyXG59LHtcIi4vYWN0aW9ucy9kcmFnXCI6NyxcIi4vYWN0aW9ucy9kcm9wXCI6OCxcIi4vYWN0aW9ucy9nZXN0dXJlXCI6OSxcIi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4vYXV0b1Njcm9sbFwiOjExLFwiLi9hdXRvU3RhcnQvZGVsYXlcIjoxNCxcIi4vYXV0b1N0YXJ0L2RyYWdcIjoxNSxcIi4vYXV0b1N0YXJ0L2dlc3R1cmVcIjoxNixcIi4vYXV0b1N0YXJ0L3Jlc2l6ZVwiOjE3LFwiLi9pbmVydGlhXCI6MjAsXCIuL2ludGVyYWN0XCI6MjEsXCIuL2ludGVyYWN0YWJsZVByZXZlbnREZWZhdWx0LmpzXCI6MjIsXCIuL2xlZ2FjeUJyb3dzZXJzXCI6MjMsXCIuL21vZGlmaWVycy9yZXN0cmljdFwiOjI1LFwiLi9tb2RpZmllcnMvcmVzdHJpY3RFZGdlc1wiOjI2LFwiLi9tb2RpZmllcnMvcmVzdHJpY3RTaXplXCI6MjcsXCIuL21vZGlmaWVycy9zbmFwXCI6MjgsXCIuL21vZGlmaWVycy9zbmFwU2l6ZVwiOjI5LFwiLi9wb2ludGVyRXZlbnRzL2Jhc2VcIjozMSxcIi4vcG9pbnRlckV2ZW50cy9ob2xkUmVwZWF0XCI6MzIsXCIuL3BvaW50ZXJFdmVudHMvaW50ZXJhY3RhYmxlVGFyZ2V0c1wiOjMzfV0sMjA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgSW50ZXJhY3RFdmVudCA9IHJlcXVpcmUoJy4vSW50ZXJhY3RFdmVudCcpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuL0ludGVyYWN0aW9uJyk7XHJcbnZhciBtb2RpZmllcnMgPSByZXF1aXJlKCcuL21vZGlmaWVycycpO1xyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XHJcbnZhciBhbmltYXRpb25GcmFtZSA9IHJlcXVpcmUoJy4vdXRpbHMvcmFmJyk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCduZXcnLCBmdW5jdGlvbiAoaW50ZXJhY3Rpb24pIHtcclxuICBpbnRlcmFjdGlvbi5pbmVydGlhU3RhdHVzID0ge1xyXG4gICAgYWN0aXZlOiBmYWxzZSxcclxuICAgIHNtb290aEVuZDogZmFsc2UsXHJcbiAgICBhbGxvd1Jlc3VtZTogZmFsc2UsXHJcblxyXG4gICAgc3RhcnRFdmVudDogbnVsbCxcclxuICAgIHVwQ29vcmRzOiB7fSxcclxuXHJcbiAgICB4ZTogMCwgeWU6IDAsXHJcbiAgICBzeDogMCwgc3k6IDAsXHJcblxyXG4gICAgdDA6IDAsXHJcbiAgICB2eDA6IDAsIHZ5czogMCxcclxuICAgIGR1cmF0aW9uOiAwLFxyXG5cclxuICAgIGxhbWJkYV92MDogMCxcclxuICAgIG9uZV92ZV92MDogMCxcclxuICAgIGk6IG51bGxcclxuICB9O1xyXG5cclxuICBpbnRlcmFjdGlvbi5ib3VuZEluZXJ0aWFGcmFtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiBpbmVydGlhRnJhbWUuYXBwbHkoaW50ZXJhY3Rpb24pO1xyXG4gIH07XHJcbiAgaW50ZXJhY3Rpb24uYm91bmRTbW9vdGhFbmRGcmFtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiBzbW9vdGhFbmRGcmFtZS5hcHBseShpbnRlcmFjdGlvbik7XHJcbiAgfTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdkb3duJywgZnVuY3Rpb24gKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQsXHJcbiAgICAgIHBvaW50ZXIgPSBfcmVmLnBvaW50ZXIsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZi5ldmVudFRhcmdldDtcclxuXHJcbiAgdmFyIHN0YXR1cyA9IGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXM7XHJcblxyXG4gIC8vIENoZWNrIGlmIHRoZSBkb3duIGV2ZW50IGhpdHMgdGhlIGN1cnJlbnQgaW5lcnRpYSB0YXJnZXRcclxuICBpZiAoc3RhdHVzLmFjdGl2ZSkge1xyXG4gICAgdmFyIGVsZW1lbnQgPSBldmVudFRhcmdldDtcclxuXHJcbiAgICAvLyBjbGltYiB1cCB0aGUgRE9NIHRyZWUgZnJvbSB0aGUgZXZlbnQgdGFyZ2V0XHJcbiAgICB3aGlsZSAodXRpbHMuaXMuZWxlbWVudChlbGVtZW50KSkge1xyXG5cclxuICAgICAgLy8gaWYgaW50ZXJhY3Rpb24gZWxlbWVudCBpcyB0aGUgY3VycmVudCBpbmVydGlhIHRhcmdldCBlbGVtZW50XHJcbiAgICAgIGlmIChlbGVtZW50ID09PSBpbnRlcmFjdGlvbi5lbGVtZW50KSB7XHJcbiAgICAgICAgLy8gc3RvcCBpbmVydGlhXHJcbiAgICAgICAgYW5pbWF0aW9uRnJhbWUuY2FuY2VsKHN0YXR1cy5pKTtcclxuICAgICAgICBzdGF0dXMuYWN0aXZlID0gZmFsc2U7XHJcbiAgICAgICAgaW50ZXJhY3Rpb24uc2ltdWxhdGlvbiA9IG51bGw7XHJcblxyXG4gICAgICAgIC8vIHVwZGF0ZSBwb2ludGVycyB0byB0aGUgZG93biBldmVudCdzIGNvb3JkaW5hdGVzXHJcbiAgICAgICAgaW50ZXJhY3Rpb24udXBkYXRlUG9pbnRlcihwb2ludGVyKTtcclxuICAgICAgICB1dGlscy5zZXRDb29yZHMoaW50ZXJhY3Rpb24uY3VyQ29vcmRzLCBpbnRlcmFjdGlvbi5wb2ludGVycyk7XHJcblxyXG4gICAgICAgIC8vIGZpcmUgYXBwcm9wcmlhdGUgc2lnbmFsc1xyXG4gICAgICAgIHZhciBzaWduYWxBcmcgPSB7IGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbiB9O1xyXG4gICAgICAgIEludGVyYWN0aW9uLnNpZ25hbHMuZmlyZSgnYmVmb3JlLWFjdGlvbi1tb3ZlJywgc2lnbmFsQXJnKTtcclxuICAgICAgICBJbnRlcmFjdGlvbi5zaWduYWxzLmZpcmUoJ2FjdGlvbi1yZXN1bWUnLCBzaWduYWxBcmcpO1xyXG5cclxuICAgICAgICAvLyBmaXJlIGEgcmV1bWUgZXZlbnRcclxuICAgICAgICB2YXIgcmVzdW1lRXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudChpbnRlcmFjdGlvbiwgZXZlbnQsIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUsICdpbmVydGlhcmVzdW1lJywgaW50ZXJhY3Rpb24uZWxlbWVudCk7XHJcblxyXG4gICAgICAgIGludGVyYWN0aW9uLnRhcmdldC5maXJlKHJlc3VtZUV2ZW50KTtcclxuICAgICAgICBpbnRlcmFjdGlvbi5wcmV2RXZlbnQgPSByZXN1bWVFdmVudDtcclxuICAgICAgICBtb2RpZmllcnMucmVzZXRTdGF0dXNlcyhpbnRlcmFjdGlvbi5tb2RpZmllclN0YXR1c2VzKTtcclxuXHJcbiAgICAgICAgdXRpbHMuY29weUNvb3JkcyhpbnRlcmFjdGlvbi5wcmV2Q29vcmRzLCBpbnRlcmFjdGlvbi5jdXJDb29yZHMpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBlbGVtZW50ID0gdXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcclxuICAgIH1cclxuICB9XHJcbn0pO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbigndXAnLCBmdW5jdGlvbiAoX3JlZjIpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbixcclxuICAgICAgZXZlbnQgPSBfcmVmMi5ldmVudDtcclxuXHJcbiAgdmFyIHN0YXR1cyA9IGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXM7XHJcblxyXG4gIGlmICghaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSB8fCBzdGF0dXMuYWN0aXZlKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgdGFyZ2V0ID0gaW50ZXJhY3Rpb24udGFyZ2V0O1xyXG4gIHZhciBvcHRpb25zID0gdGFyZ2V0ICYmIHRhcmdldC5vcHRpb25zO1xyXG4gIHZhciBpbmVydGlhT3B0aW9ucyA9IG9wdGlvbnMgJiYgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSAmJiBvcHRpb25zW2ludGVyYWN0aW9uLnByZXBhcmVkLm5hbWVdLmluZXJ0aWE7XHJcblxyXG4gIHZhciBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICB2YXIgc3RhdHVzZXMgPSB7fTtcclxuICB2YXIgcGFnZSA9IHV0aWxzLmV4dGVuZCh7fSwgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UpO1xyXG4gIHZhciBwb2ludGVyU3BlZWQgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnNwZWVkO1xyXG5cclxuICB2YXIgc21vb3RoRW5kID0gZmFsc2U7XHJcbiAgdmFyIG1vZGlmaWVyUmVzdWx0ID0gdm9pZCAwO1xyXG5cclxuICAvLyBjaGVjayBpZiBpbmVydGlhIHNob3VsZCBiZSBzdGFydGVkXHJcbiAgdmFyIGluZXJ0aWFQb3NzaWJsZSA9IGluZXJ0aWFPcHRpb25zICYmIGluZXJ0aWFPcHRpb25zLmVuYWJsZWQgJiYgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSAhPT0gJ2dlc3R1cmUnICYmIGV2ZW50ICE9PSBzdGF0dXMuc3RhcnRFdmVudDtcclxuXHJcbiAgdmFyIGluZXJ0aWEgPSBpbmVydGlhUG9zc2libGUgJiYgbm93IC0gaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnRpbWVTdGFtcCA8IDUwICYmIHBvaW50ZXJTcGVlZCA+IGluZXJ0aWFPcHRpb25zLm1pblNwZWVkICYmIHBvaW50ZXJTcGVlZCA+IGluZXJ0aWFPcHRpb25zLmVuZFNwZWVkO1xyXG5cclxuICB2YXIgbW9kaWZpZXJBcmcgPSB7XHJcbiAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXHJcbiAgICBwYWdlQ29vcmRzOiBwYWdlLFxyXG4gICAgc3RhdHVzZXM6IHN0YXR1c2VzLFxyXG4gICAgcHJlRW5kOiB0cnVlLFxyXG4gICAgcmVxdWlyZUVuZE9ubHk6IHRydWVcclxuICB9O1xyXG5cclxuICAvLyBzbW9vdGhFbmRcclxuICBpZiAoaW5lcnRpYVBvc3NpYmxlICYmICFpbmVydGlhKSB7XHJcbiAgICBtb2RpZmllcnMucmVzZXRTdGF0dXNlcyhzdGF0dXNlcyk7XHJcblxyXG4gICAgbW9kaWZpZXJSZXN1bHQgPSBtb2RpZmllcnMuc2V0QWxsKG1vZGlmaWVyQXJnKTtcclxuXHJcbiAgICBpZiAobW9kaWZpZXJSZXN1bHQuc2hvdWxkTW92ZSAmJiBtb2RpZmllclJlc3VsdC5sb2NrZWQpIHtcclxuICAgICAgc21vb3RoRW5kID0gdHJ1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmICghKGluZXJ0aWEgfHwgc21vb3RoRW5kKSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdXRpbHMuY29weUNvb3JkcyhzdGF0dXMudXBDb29yZHMsIGludGVyYWN0aW9uLmN1ckNvb3Jkcyk7XHJcblxyXG4gIGludGVyYWN0aW9uLnBvaW50ZXJzWzBdID0gc3RhdHVzLnN0YXJ0RXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudChpbnRlcmFjdGlvbiwgZXZlbnQsIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUsICdpbmVydGlhc3RhcnQnLCBpbnRlcmFjdGlvbi5lbGVtZW50KTtcclxuXHJcbiAgc3RhdHVzLnQwID0gbm93O1xyXG5cclxuICBzdGF0dXMuYWN0aXZlID0gdHJ1ZTtcclxuICBzdGF0dXMuYWxsb3dSZXN1bWUgPSBpbmVydGlhT3B0aW9ucy5hbGxvd1Jlc3VtZTtcclxuICBpbnRlcmFjdGlvbi5zaW11bGF0aW9uID0gc3RhdHVzO1xyXG5cclxuICB0YXJnZXQuZmlyZShzdGF0dXMuc3RhcnRFdmVudCk7XHJcblxyXG4gIGlmIChpbmVydGlhKSB7XHJcbiAgICBzdGF0dXMudngwID0gaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC52eDtcclxuICAgIHN0YXR1cy52eTAgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnZ5O1xyXG4gICAgc3RhdHVzLnYwID0gcG9pbnRlclNwZWVkO1xyXG5cclxuICAgIGNhbGNJbmVydGlhKGludGVyYWN0aW9uLCBzdGF0dXMpO1xyXG5cclxuICAgIHV0aWxzLmV4dGVuZChwYWdlLCBpbnRlcmFjdGlvbi5jdXJDb29yZHMucGFnZSk7XHJcblxyXG4gICAgcGFnZS54ICs9IHN0YXR1cy54ZTtcclxuICAgIHBhZ2UueSArPSBzdGF0dXMueWU7XHJcblxyXG4gICAgbW9kaWZpZXJzLnJlc2V0U3RhdHVzZXMoc3RhdHVzZXMpO1xyXG5cclxuICAgIG1vZGlmaWVyUmVzdWx0ID0gbW9kaWZpZXJzLnNldEFsbChtb2RpZmllckFyZyk7XHJcblxyXG4gICAgc3RhdHVzLm1vZGlmaWVkWGUgKz0gbW9kaWZpZXJSZXN1bHQuZHg7XHJcbiAgICBzdGF0dXMubW9kaWZpZWRZZSArPSBtb2RpZmllclJlc3VsdC5keTtcclxuXHJcbiAgICBzdGF0dXMuaSA9IGFuaW1hdGlvbkZyYW1lLnJlcXVlc3QoaW50ZXJhY3Rpb24uYm91bmRJbmVydGlhRnJhbWUpO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBzdGF0dXMuc21vb3RoRW5kID0gdHJ1ZTtcclxuICAgIHN0YXR1cy54ZSA9IG1vZGlmaWVyUmVzdWx0LmR4O1xyXG4gICAgc3RhdHVzLnllID0gbW9kaWZpZXJSZXN1bHQuZHk7XHJcblxyXG4gICAgc3RhdHVzLnN4ID0gc3RhdHVzLnN5ID0gMDtcclxuXHJcbiAgICBzdGF0dXMuaSA9IGFuaW1hdGlvbkZyYW1lLnJlcXVlc3QoaW50ZXJhY3Rpb24uYm91bmRTbW9vdGhFbmRGcmFtZSk7XHJcbiAgfVxyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3N0b3AtYWN0aXZlJywgZnVuY3Rpb24gKF9yZWYzKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjMuaW50ZXJhY3Rpb247XHJcblxyXG4gIHZhciBzdGF0dXMgPSBpbnRlcmFjdGlvbi5pbmVydGlhU3RhdHVzO1xyXG5cclxuICBpZiAoc3RhdHVzLmFjdGl2ZSkge1xyXG4gICAgYW5pbWF0aW9uRnJhbWUuY2FuY2VsKHN0YXR1cy5pKTtcclxuICAgIHN0YXR1cy5hY3RpdmUgPSBmYWxzZTtcclxuICAgIGludGVyYWN0aW9uLnNpbXVsYXRpb24gPSBudWxsO1xyXG4gIH1cclxufSk7XHJcblxyXG5mdW5jdGlvbiBjYWxjSW5lcnRpYShpbnRlcmFjdGlvbiwgc3RhdHVzKSB7XHJcbiAgdmFyIGluZXJ0aWFPcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uaW5lcnRpYTtcclxuICB2YXIgbGFtYmRhID0gaW5lcnRpYU9wdGlvbnMucmVzaXN0YW5jZTtcclxuICB2YXIgaW5lcnRpYUR1ciA9IC1NYXRoLmxvZyhpbmVydGlhT3B0aW9ucy5lbmRTcGVlZCAvIHN0YXR1cy52MCkgLyBsYW1iZGE7XHJcblxyXG4gIHN0YXR1cy54MCA9IGludGVyYWN0aW9uLnByZXZFdmVudC5wYWdlWDtcclxuICBzdGF0dXMueTAgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQucGFnZVk7XHJcbiAgc3RhdHVzLnQwID0gc3RhdHVzLnN0YXJ0RXZlbnQudGltZVN0YW1wIC8gMTAwMDtcclxuICBzdGF0dXMuc3ggPSBzdGF0dXMuc3kgPSAwO1xyXG5cclxuICBzdGF0dXMubW9kaWZpZWRYZSA9IHN0YXR1cy54ZSA9IChzdGF0dXMudngwIC0gaW5lcnRpYUR1cikgLyBsYW1iZGE7XHJcbiAgc3RhdHVzLm1vZGlmaWVkWWUgPSBzdGF0dXMueWUgPSAoc3RhdHVzLnZ5MCAtIGluZXJ0aWFEdXIpIC8gbGFtYmRhO1xyXG4gIHN0YXR1cy50ZSA9IGluZXJ0aWFEdXI7XHJcblxyXG4gIHN0YXR1cy5sYW1iZGFfdjAgPSBsYW1iZGEgLyBzdGF0dXMudjA7XHJcbiAgc3RhdHVzLm9uZV92ZV92MCA9IDEgLSBpbmVydGlhT3B0aW9ucy5lbmRTcGVlZCAvIHN0YXR1cy52MDtcclxufVxyXG5cclxuZnVuY3Rpb24gaW5lcnRpYUZyYW1lKCkge1xyXG4gIHVwZGF0ZUluZXJ0aWFDb29yZHModGhpcyk7XHJcbiAgdXRpbHMuc2V0Q29vcmREZWx0YXModGhpcy5wb2ludGVyRGVsdGEsIHRoaXMucHJldkNvb3JkcywgdGhpcy5jdXJDb29yZHMpO1xyXG5cclxuICB2YXIgc3RhdHVzID0gdGhpcy5pbmVydGlhU3RhdHVzO1xyXG4gIHZhciBvcHRpb25zID0gdGhpcy50YXJnZXQub3B0aW9uc1t0aGlzLnByZXBhcmVkLm5hbWVdLmluZXJ0aWE7XHJcbiAgdmFyIGxhbWJkYSA9IG9wdGlvbnMucmVzaXN0YW5jZTtcclxuICB2YXIgdCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCAtIHN0YXR1cy50MDtcclxuXHJcbiAgaWYgKHQgPCBzdGF0dXMudGUpIHtcclxuXHJcbiAgICB2YXIgcHJvZ3Jlc3MgPSAxIC0gKE1hdGguZXhwKC1sYW1iZGEgKiB0KSAtIHN0YXR1cy5sYW1iZGFfdjApIC8gc3RhdHVzLm9uZV92ZV92MDtcclxuXHJcbiAgICBpZiAoc3RhdHVzLm1vZGlmaWVkWGUgPT09IHN0YXR1cy54ZSAmJiBzdGF0dXMubW9kaWZpZWRZZSA9PT0gc3RhdHVzLnllKSB7XHJcbiAgICAgIHN0YXR1cy5zeCA9IHN0YXR1cy54ZSAqIHByb2dyZXNzO1xyXG4gICAgICBzdGF0dXMuc3kgPSBzdGF0dXMueWUgKiBwcm9ncmVzcztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHZhciBxdWFkUG9pbnQgPSB1dGlscy5nZXRRdWFkcmF0aWNDdXJ2ZVBvaW50KDAsIDAsIHN0YXR1cy54ZSwgc3RhdHVzLnllLCBzdGF0dXMubW9kaWZpZWRYZSwgc3RhdHVzLm1vZGlmaWVkWWUsIHByb2dyZXNzKTtcclxuXHJcbiAgICAgIHN0YXR1cy5zeCA9IHF1YWRQb2ludC54O1xyXG4gICAgICBzdGF0dXMuc3kgPSBxdWFkUG9pbnQueTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmRvTW92ZSgpO1xyXG5cclxuICAgIHN0YXR1cy5pID0gYW5pbWF0aW9uRnJhbWUucmVxdWVzdCh0aGlzLmJvdW5kSW5lcnRpYUZyYW1lKTtcclxuICB9IGVsc2Uge1xyXG4gICAgc3RhdHVzLnN4ID0gc3RhdHVzLm1vZGlmaWVkWGU7XHJcbiAgICBzdGF0dXMuc3kgPSBzdGF0dXMubW9kaWZpZWRZZTtcclxuXHJcbiAgICB0aGlzLmRvTW92ZSgpO1xyXG4gICAgdGhpcy5lbmQoc3RhdHVzLnN0YXJ0RXZlbnQpO1xyXG4gICAgc3RhdHVzLmFjdGl2ZSA9IGZhbHNlO1xyXG4gICAgdGhpcy5zaW11bGF0aW9uID0gbnVsbDtcclxuICB9XHJcblxyXG4gIHV0aWxzLmNvcHlDb29yZHModGhpcy5wcmV2Q29vcmRzLCB0aGlzLmN1ckNvb3Jkcyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNtb290aEVuZEZyYW1lKCkge1xyXG4gIHVwZGF0ZUluZXJ0aWFDb29yZHModGhpcyk7XHJcblxyXG4gIHZhciBzdGF0dXMgPSB0aGlzLmluZXJ0aWFTdGF0dXM7XHJcbiAgdmFyIHQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHN0YXR1cy50MDtcclxuICB2YXIgZHVyYXRpb24gPSB0aGlzLnRhcmdldC5vcHRpb25zW3RoaXMucHJlcGFyZWQubmFtZV0uaW5lcnRpYS5zbW9vdGhFbmREdXJhdGlvbjtcclxuXHJcbiAgaWYgKHQgPCBkdXJhdGlvbikge1xyXG4gICAgc3RhdHVzLnN4ID0gdXRpbHMuZWFzZU91dFF1YWQodCwgMCwgc3RhdHVzLnhlLCBkdXJhdGlvbik7XHJcbiAgICBzdGF0dXMuc3kgPSB1dGlscy5lYXNlT3V0UXVhZCh0LCAwLCBzdGF0dXMueWUsIGR1cmF0aW9uKTtcclxuXHJcbiAgICB0aGlzLnBvaW50ZXJNb3ZlKHN0YXR1cy5zdGFydEV2ZW50LCBzdGF0dXMuc3RhcnRFdmVudCk7XHJcblxyXG4gICAgc3RhdHVzLmkgPSBhbmltYXRpb25GcmFtZS5yZXF1ZXN0KHRoaXMuYm91bmRTbW9vdGhFbmRGcmFtZSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHN0YXR1cy5zeCA9IHN0YXR1cy54ZTtcclxuICAgIHN0YXR1cy5zeSA9IHN0YXR1cy55ZTtcclxuXHJcbiAgICB0aGlzLnBvaW50ZXJNb3ZlKHN0YXR1cy5zdGFydEV2ZW50LCBzdGF0dXMuc3RhcnRFdmVudCk7XHJcbiAgICB0aGlzLmVuZChzdGF0dXMuc3RhcnRFdmVudCk7XHJcblxyXG4gICAgc3RhdHVzLnNtb290aEVuZCA9IHN0YXR1cy5hY3RpdmUgPSBmYWxzZTtcclxuICAgIHRoaXMuc2ltdWxhdGlvbiA9IG51bGw7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVJbmVydGlhQ29vcmRzKGludGVyYWN0aW9uKSB7XHJcbiAgdmFyIHN0YXR1cyA9IGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXM7XHJcblxyXG4gIC8vIHJldHVybiBpZiBpbmVydGlhIGlzbid0IHJ1bm5pbmdcclxuICBpZiAoIXN0YXR1cy5hY3RpdmUpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBwYWdlVXAgPSBzdGF0dXMudXBDb29yZHMucGFnZTtcclxuICB2YXIgY2xpZW50VXAgPSBzdGF0dXMudXBDb29yZHMuY2xpZW50O1xyXG5cclxuICB1dGlscy5zZXRDb29yZHMoaW50ZXJhY3Rpb24uY3VyQ29vcmRzLCBbe1xyXG4gICAgcGFnZVg6IHBhZ2VVcC54ICsgc3RhdHVzLnN4LFxyXG4gICAgcGFnZVk6IHBhZ2VVcC55ICsgc3RhdHVzLnN5LFxyXG4gICAgY2xpZW50WDogY2xpZW50VXAueCArIHN0YXR1cy5zeCxcclxuICAgIGNsaWVudFk6IGNsaWVudFVwLnkgKyBzdGF0dXMuc3lcclxuICB9XSk7XHJcbn1cclxuXHJcbn0se1wiLi9JbnRlcmFjdEV2ZW50XCI6MyxcIi4vSW50ZXJhY3Rpb25cIjo1LFwiLi9tb2RpZmllcnNcIjoyNCxcIi4vdXRpbHNcIjo0NCxcIi4vdXRpbHMvcmFmXCI6NTB9XSwyMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi91dGlscy9icm93c2VyJyk7XHJcbnZhciBldmVudHMgPSByZXF1aXJlKCcuL3V0aWxzL2V2ZW50cycpO1xyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XHJcbnZhciBzY29wZSA9IHJlcXVpcmUoJy4vc2NvcGUnKTtcclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4vSW50ZXJhY3RhYmxlJyk7XHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4vSW50ZXJhY3Rpb24nKTtcclxuXHJcbnZhciBnbG9iYWxFdmVudHMgPSB7fTtcclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3RcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogVGhlIG1ldGhvZHMgb2YgdGhpcyB2YXJpYWJsZSBjYW4gYmUgdXNlZCB0byBzZXQgZWxlbWVudHMgYXNcclxuICogaW50ZXJhY3RhYmxlcyBhbmQgYWxzbyB0byBjaGFuZ2UgdmFyaW91cyBkZWZhdWx0IHNldHRpbmdzLlxyXG4gKlxyXG4gKiBDYWxsaW5nIGl0IGFzIGEgZnVuY3Rpb24gYW5kIHBhc3NpbmcgYW4gZWxlbWVudCBvciBhIHZhbGlkIENTUyBzZWxlY3RvclxyXG4gKiBzdHJpbmcgcmV0dXJucyBhbiBJbnRlcmFjdGFibGUgb2JqZWN0IHdoaWNoIGhhcyB2YXJpb3VzIG1ldGhvZHMgdG9cclxuICogY29uZmlndXJlIGl0LlxyXG4gKlxyXG4gLSBlbGVtZW50IChFbGVtZW50IHwgc3RyaW5nKSBUaGUgSFRNTCBvciBTVkcgRWxlbWVudCB0byBpbnRlcmFjdCB3aXRoIG9yIENTUyBzZWxlY3RvclxyXG4gPSAob2JqZWN0KSBBbiBASW50ZXJhY3RhYmxlXHJcbiAqXHJcbiA+IFVzYWdlXHJcbiB8IGludGVyYWN0KCcjZHJhZ2dhYmxlJykuZHJhZ2dhYmxlKHRydWUpO1xyXG4gfFxyXG4gfCB2YXIgcmVjdGFibGVzID0gaW50ZXJhY3QoJ3JlY3QnKTtcclxuIHwgcmVjdGFibGVzXHJcbiB8ICAgICAuZ2VzdHVyYWJsZSh0cnVlKVxyXG4gfCAgICAgLm9uKCdnZXN0dXJlbW92ZScsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gfCAgICAgICAgIC8vIC4uLlxyXG4gfCAgICAgfSk7XHJcblxcKi9cclxuZnVuY3Rpb24gaW50ZXJhY3QoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gIHZhciBpbnRlcmFjdGFibGUgPSBzY29wZS5pbnRlcmFjdGFibGVzLmdldChlbGVtZW50LCBvcHRpb25zKTtcclxuXHJcbiAgaWYgKCFpbnRlcmFjdGFibGUpIHtcclxuICAgIGludGVyYWN0YWJsZSA9IG5ldyBJbnRlcmFjdGFibGUoZWxlbWVudCwgb3B0aW9ucyk7XHJcbiAgICBpbnRlcmFjdGFibGUuZXZlbnRzLmdsb2JhbCA9IGdsb2JhbEV2ZW50cztcclxuICB9XHJcblxyXG4gIHJldHVybiBpbnRlcmFjdGFibGU7XHJcbn1cclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3QuaXNTZXRcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogQ2hlY2sgaWYgYW4gZWxlbWVudCBoYXMgYmVlbiBzZXRcclxuIC0gZWxlbWVudCAoRWxlbWVudCkgVGhlIEVsZW1lbnQgYmVpbmcgc2VhcmNoZWQgZm9yXHJcbiA9IChib29sZWFuKSBJbmRpY2F0ZXMgaWYgdGhlIGVsZW1lbnQgb3IgQ1NTIHNlbGVjdG9yIHdhcyBwcmV2aW91c2x5IHBhc3NlZCB0byBpbnRlcmFjdFxyXG5cXCovXHJcbmludGVyYWN0LmlzU2V0ID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICByZXR1cm4gc2NvcGUuaW50ZXJhY3RhYmxlcy5pbmRleE9mRWxlbWVudChlbGVtZW50LCBvcHRpb25zICYmIG9wdGlvbnMuY29udGV4dCkgIT09IC0xO1xyXG59O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5vblxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBBZGRzIGEgZ2xvYmFsIGxpc3RlbmVyIGZvciBhbiBJbnRlcmFjdEV2ZW50IG9yIGFkZHMgYSBET00gZXZlbnQgdG9cclxuICogYGRvY3VtZW50YFxyXG4gKlxyXG4gLSB0eXBlICAgICAgIChzdHJpbmcgfCBhcnJheSB8IG9iamVjdCkgVGhlIHR5cGVzIG9mIGV2ZW50cyB0byBsaXN0ZW4gZm9yXHJcbiAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgZnVuY3Rpb24gZXZlbnQgKHMpXHJcbiAtIG9wdGlvbnMgICAgKG9iamVjdCB8IGJvb2xlYW4pICNvcHRpb25hbCBvcHRpb25zIG9iamVjdCBvciB1c2VDYXB0dXJlIGZsYWcgZm9yIGFkZEV2ZW50TGlzdGVuZXJcclxuID0gKG9iamVjdCkgaW50ZXJhY3RcclxuXFwqL1xyXG5pbnRlcmFjdC5vbiA9IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lciwgb3B0aW9ucykge1xyXG4gIGlmICh1dGlscy5pcy5zdHJpbmcodHlwZSkgJiYgdHlwZS5zZWFyY2goJyAnKSAhPT0gLTEpIHtcclxuICAgIHR5cGUgPSB0eXBlLnRyaW0oKS5zcGxpdCgvICsvKTtcclxuICB9XHJcblxyXG4gIGlmICh1dGlscy5pcy5hcnJheSh0eXBlKSkge1xyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gdHlwZSwgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWY7XHJcblxyXG4gICAgICBpZiAoX2lzQXJyYXkpIHtcclxuICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgX3JlZiA9IF9pdGVyYXRvcltfaSsrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYgPSBfaS52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGV2ZW50VHlwZSA9IF9yZWY7XHJcblxyXG4gICAgICBpbnRlcmFjdC5vbihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gaW50ZXJhY3Q7XHJcbiAgfVxyXG5cclxuICBpZiAodXRpbHMuaXMub2JqZWN0KHR5cGUpKSB7XHJcbiAgICBmb3IgKHZhciBwcm9wIGluIHR5cGUpIHtcclxuICAgICAgaW50ZXJhY3Qub24ocHJvcCwgdHlwZVtwcm9wXSwgbGlzdGVuZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBpbnRlcmFjdDtcclxuICB9XHJcblxyXG4gIC8vIGlmIGl0IGlzIGFuIEludGVyYWN0RXZlbnQgdHlwZSwgYWRkIGxpc3RlbmVyIHRvIGdsb2JhbEV2ZW50c1xyXG4gIGlmICh1dGlscy5jb250YWlucyhJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgdHlwZSkpIHtcclxuICAgIC8vIGlmIHRoaXMgdHlwZSBvZiBldmVudCB3YXMgbmV2ZXIgYm91bmRcclxuICAgIGlmICghZ2xvYmFsRXZlbnRzW3R5cGVdKSB7XHJcbiAgICAgIGdsb2JhbEV2ZW50c1t0eXBlXSA9IFtsaXN0ZW5lcl07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBnbG9iYWxFdmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8vIElmIG5vbiBJbnRlcmFjdEV2ZW50IHR5cGUsIGFkZEV2ZW50TGlzdGVuZXIgdG8gZG9jdW1lbnRcclxuICBlbHNlIHtcclxuICAgICAgZXZlbnRzLmFkZChzY29wZS5kb2N1bWVudCwgdHlwZSwgbGlzdGVuZXIsIHsgb3B0aW9uczogb3B0aW9ucyB9KTtcclxuICAgIH1cclxuXHJcbiAgcmV0dXJuIGludGVyYWN0O1xyXG59O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5vZmZcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogUmVtb3ZlcyBhIGdsb2JhbCBJbnRlcmFjdEV2ZW50IGxpc3RlbmVyIG9yIERPTSBldmVudCBmcm9tIGBkb2N1bWVudGBcclxuICpcclxuIC0gdHlwZSAgICAgICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdGhhdCB3ZXJlIGxpc3RlbmVkIGZvclxyXG4gLSBsaXN0ZW5lciAgIChmdW5jdGlvbikgVGhlIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIGJlIHJlbW92ZWRcclxuIC0gb3B0aW9ucyAgICAob2JqZWN0IHwgYm9vbGVhbikgI29wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IG9yIHVzZUNhcHR1cmUgZmxhZyBmb3IgcmVtb3ZlRXZlbnRMaXN0ZW5lclxyXG4gPSAob2JqZWN0KSBpbnRlcmFjdFxyXG4gXFwqL1xyXG5pbnRlcmFjdC5vZmYgPSBmdW5jdGlvbiAodHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcclxuICBpZiAodXRpbHMuaXMuc3RyaW5nKHR5cGUpICYmIHR5cGUuc2VhcmNoKCcgJykgIT09IC0xKSB7XHJcbiAgICB0eXBlID0gdHlwZS50cmltKCkuc3BsaXQoLyArLyk7XHJcbiAgfVxyXG5cclxuICBpZiAodXRpbHMuaXMuYXJyYXkodHlwZSkpIHtcclxuICAgIGZvciAodmFyIF9pdGVyYXRvcjIgPSB0eXBlLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWYyO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5Mikge1xyXG4gICAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yMi5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yMltfaTIrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kyID0gX2l0ZXJhdG9yMi5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmMiA9IF9pMi52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGV2ZW50VHlwZSA9IF9yZWYyO1xyXG5cclxuICAgICAgaW50ZXJhY3Qub2ZmKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBpbnRlcmFjdDtcclxuICB9XHJcblxyXG4gIGlmICh1dGlscy5pcy5vYmplY3QodHlwZSkpIHtcclxuICAgIGZvciAodmFyIHByb3AgaW4gdHlwZSkge1xyXG4gICAgICBpbnRlcmFjdC5vZmYocHJvcCwgdHlwZVtwcm9wXSwgbGlzdGVuZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBpbnRlcmFjdDtcclxuICB9XHJcblxyXG4gIGlmICghdXRpbHMuY29udGFpbnMoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIHR5cGUpKSB7XHJcbiAgICBldmVudHMucmVtb3ZlKHNjb3BlLmRvY3VtZW50LCB0eXBlLCBsaXN0ZW5lciwgb3B0aW9ucyk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHZhciBpbmRleCA9IHZvaWQgMDtcclxuXHJcbiAgICBpZiAodHlwZSBpbiBnbG9iYWxFdmVudHMgJiYgKGluZGV4ID0gdXRpbHMuaW5kZXhPZihnbG9iYWxFdmVudHNbdHlwZV0sIGxpc3RlbmVyKSkgIT09IC0xKSB7XHJcbiAgICAgIGdsb2JhbEV2ZW50c1t0eXBlXS5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGludGVyYWN0O1xyXG59O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5kZWJ1Z1xyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBSZXR1cm5zIGFuIG9iamVjdCB3aGljaCBleHBvc2VzIGludGVybmFsIGRhdGFcclxuID0gKG9iamVjdCkgQW4gb2JqZWN0IHdpdGggcHJvcGVydGllcyB0aGF0IG91dGxpbmUgdGhlIGN1cnJlbnQgc3RhdGUgYW5kIGV4cG9zZSBpbnRlcm5hbCBmdW5jdGlvbnMgYW5kIHZhcmlhYmxlc1xyXG5cXCovXHJcbmludGVyYWN0LmRlYnVnID0gZnVuY3Rpb24gKCkge1xyXG4gIHJldHVybiBzY29wZTtcclxufTtcclxuXHJcbi8vIGV4cG9zZSB0aGUgZnVuY3Rpb25zIHVzZWQgdG8gY2FsY3VsYXRlIG11bHRpLXRvdWNoIHByb3BlcnRpZXNcclxuaW50ZXJhY3QuZ2V0UG9pbnRlckF2ZXJhZ2UgPSB1dGlscy5wb2ludGVyQXZlcmFnZTtcclxuaW50ZXJhY3QuZ2V0VG91Y2hCQm94ID0gdXRpbHMudG91Y2hCQm94O1xyXG5pbnRlcmFjdC5nZXRUb3VjaERpc3RhbmNlID0gdXRpbHMudG91Y2hEaXN0YW5jZTtcclxuaW50ZXJhY3QuZ2V0VG91Y2hBbmdsZSA9IHV0aWxzLnRvdWNoQW5nbGU7XHJcblxyXG5pbnRlcmFjdC5nZXRFbGVtZW50UmVjdCA9IHV0aWxzLmdldEVsZW1lbnRSZWN0O1xyXG5pbnRlcmFjdC5nZXRFbGVtZW50Q2xpZW50UmVjdCA9IHV0aWxzLmdldEVsZW1lbnRDbGllbnRSZWN0O1xyXG5pbnRlcmFjdC5tYXRjaGVzU2VsZWN0b3IgPSB1dGlscy5tYXRjaGVzU2VsZWN0b3I7XHJcbmludGVyYWN0LmNsb3Nlc3QgPSB1dGlscy5jbG9zZXN0O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5zdXBwb3J0c1RvdWNoXHJcbiBbIG1ldGhvZCBdXHJcbiAqXHJcbiA9IChib29sZWFuKSBXaGV0aGVyIG9yIG5vdCB0aGUgYnJvd3NlciBzdXBwb3J0cyB0b3VjaCBpbnB1dFxyXG5cXCovXHJcbmludGVyYWN0LnN1cHBvcnRzVG91Y2ggPSBmdW5jdGlvbiAoKSB7XHJcbiAgcmV0dXJuIGJyb3dzZXIuc3VwcG9ydHNUb3VjaDtcclxufTtcclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3Quc3VwcG9ydHNQb2ludGVyRXZlbnRcclxuIFsgbWV0aG9kIF1cclxuICpcclxuID0gKGJvb2xlYW4pIFdoZXRoZXIgb3Igbm90IHRoZSBicm93c2VyIHN1cHBvcnRzIFBvaW50ZXJFdmVudHNcclxuXFwqL1xyXG5pbnRlcmFjdC5zdXBwb3J0c1BvaW50ZXJFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICByZXR1cm4gYnJvd3Nlci5zdXBwb3J0c1BvaW50ZXJFdmVudDtcclxufTtcclxuXHJcbi8qXFxcclxuICogaW50ZXJhY3Quc3RvcFxyXG4gWyBtZXRob2QgXVxyXG4gKlxyXG4gKiBDYW5jZWxzIGFsbCBpbnRlcmFjdGlvbnMgKGVuZCBldmVudHMgYXJlIG5vdCBmaXJlZClcclxuICpcclxuIC0gZXZlbnQgKEV2ZW50KSBBbiBldmVudCBvbiB3aGljaCB0byBjYWxsIHByZXZlbnREZWZhdWx0KClcclxuID0gKG9iamVjdCkgaW50ZXJhY3RcclxuXFwqL1xyXG5pbnRlcmFjdC5zdG9wID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgZm9yICh2YXIgaSA9IHNjb3BlLmludGVyYWN0aW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgc2NvcGUuaW50ZXJhY3Rpb25zW2ldLnN0b3AoZXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGludGVyYWN0O1xyXG59O1xyXG5cclxuLypcXFxyXG4gKiBpbnRlcmFjdC5wb2ludGVyTW92ZVRvbGVyYW5jZVxyXG4gWyBtZXRob2QgXVxyXG4gKiBSZXR1cm5zIG9yIHNldHMgdGhlIGRpc3RhbmNlIHRoZSBwb2ludGVyIG11c3QgYmUgbW92ZWQgYmVmb3JlIGFuIGFjdGlvblxyXG4gKiBzZXF1ZW5jZSBvY2N1cnMuIFRoaXMgYWxzbyBhZmZlY3RzIHRvbGVyYW5jZSBmb3IgdGFwIGV2ZW50cy5cclxuICpcclxuIC0gbmV3VmFsdWUgKG51bWJlcikgI29wdGlvbmFsIFRoZSBtb3ZlbWVudCBmcm9tIHRoZSBzdGFydCBwb3NpdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aGlzIHZhbHVlXHJcbiA9IChudW1iZXIgfCBJbnRlcmFjdGFibGUpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgaW50ZXJhY3RcclxuXFwqL1xyXG5pbnRlcmFjdC5wb2ludGVyTW92ZVRvbGVyYW5jZSA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gIGlmICh1dGlscy5pcy5udW1iZXIobmV3VmFsdWUpKSB7XHJcbiAgICBJbnRlcmFjdGlvbi5wb2ludGVyTW92ZVRvbGVyYW5jZSA9IG5ld1ZhbHVlO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIEludGVyYWN0aW9uLnBvaW50ZXJNb3ZlVG9sZXJhbmNlO1xyXG59O1xyXG5cclxuaW50ZXJhY3QuYWRkRG9jdW1lbnQgPSBzY29wZS5hZGREb2N1bWVudDtcclxuaW50ZXJhY3QucmVtb3ZlRG9jdW1lbnQgPSBzY29wZS5yZW1vdmVEb2N1bWVudDtcclxuXHJcbnNjb3BlLmludGVyYWN0ID0gaW50ZXJhY3Q7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGludGVyYWN0O1xyXG5cclxufSx7XCIuL0ludGVyYWN0YWJsZVwiOjQsXCIuL0ludGVyYWN0aW9uXCI6NSxcIi4vc2NvcGVcIjozNCxcIi4vdXRpbHNcIjo0NCxcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9ldmVudHNcIjo0MH1dLDIyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4vSW50ZXJhY3RhYmxlJyk7XHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4vSW50ZXJhY3Rpb24nKTtcclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi9zY29wZScpO1xyXG52YXIgaXMgPSByZXF1aXJlKCcuL3V0aWxzL2lzJyk7XHJcbnZhciBldmVudHMgPSByZXF1aXJlKCcuL3V0aWxzL2V2ZW50cycpO1xyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi91dGlscy9kb21VdGlscycpLFxyXG4gICAgbm9kZUNvbnRhaW5zID0gX3JlcXVpcmUubm9kZUNvbnRhaW5zLFxyXG4gICAgbWF0Y2hlc1NlbGVjdG9yID0gX3JlcXVpcmUubWF0Y2hlc1NlbGVjdG9yO1xyXG5cclxuLypcXFxyXG4gKiBJbnRlcmFjdGFibGUucHJldmVudERlZmF1bHRcclxuIFsgbWV0aG9kIF1cclxuICpcclxuICogUmV0dXJucyBvciBzZXRzIHdoZXRoZXIgdG8gcHJldmVudCB0aGUgYnJvd3NlcidzIGRlZmF1bHQgYmVoYXZpb3VyXHJcbiAqIGluIHJlc3BvbnNlIHRvIHBvaW50ZXIgZXZlbnRzLiBDYW4gYmUgc2V0IHRvOlxyXG4gKiAgLSBgJ2Fsd2F5cydgIHRvIGFsd2F5cyBwcmV2ZW50XHJcbiAqICAtIGAnbmV2ZXInYCB0byBuZXZlciBwcmV2ZW50XHJcbiAqICAtIGAnYXV0bydgIHRvIGxldCBpbnRlcmFjdC5qcyB0cnkgdG8gZGV0ZXJtaW5lIHdoYXQgd291bGQgYmUgYmVzdFxyXG4gKlxyXG4gLSBuZXdWYWx1ZSAoc3RyaW5nKSAjb3B0aW9uYWwgYHRydWVgLCBgZmFsc2VgIG9yIGAnYXV0bydgXHJcbiA9IChzdHJpbmcgfCBJbnRlcmFjdGFibGUpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgdGhpcyBJbnRlcmFjdGFibGVcclxuXFwqL1xyXG5cclxuXHJcbkludGVyYWN0YWJsZS5wcm90b3R5cGUucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbiAobmV3VmFsdWUpIHtcclxuICBpZiAoL14oYWx3YXlzfG5ldmVyfGF1dG8pJC8udGVzdChuZXdWYWx1ZSkpIHtcclxuICAgIHRoaXMub3B0aW9ucy5wcmV2ZW50RGVmYXVsdCA9IG5ld1ZhbHVlO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBpZiAoaXMuYm9vbChuZXdWYWx1ZSkpIHtcclxuICAgIHRoaXMub3B0aW9ucy5wcmV2ZW50RGVmYXVsdCA9IG5ld1ZhbHVlID8gJ2Fsd2F5cycgOiAnbmV2ZXInO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5vcHRpb25zLnByZXZlbnREZWZhdWx0O1xyXG59O1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5jaGVja0FuZFByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgdmFyIHNldHRpbmcgPSB0aGlzLm9wdGlvbnMucHJldmVudERlZmF1bHQ7XHJcblxyXG4gIGlmIChzZXR0aW5nID09PSAnbmV2ZXInKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBpZiAoc2V0dGluZyA9PT0gJ2Fsd2F5cycpIHtcclxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvLyBzZXR0aW5nID09PSAnYXV0bydcclxuXHJcbiAgLy8gZG9uJ3QgcHJldmVudERlZmF1bHQgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgcGFzc2l2ZUV2ZW50c1xyXG4gIC8vIENTUyB0b3VjaC1hY3Rpb24gYW5kIHVzZXItc2VsZWNjdCBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkXHJcbiAgaWYgKGV2ZW50cy5zdXBwb3J0c09wdGlvbnMpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIGRvbid0IHByZXZlbnREZWZhdWx0IG9mIHBvaW50ZXJkb3duIGV2ZW50c1xyXG4gIGlmICgvXihtb3VzZXxwb2ludGVyfHRvdWNoKSooZG93bnxzdGFydCkvaS50ZXN0KGV2ZW50LnR5cGUpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvLyBkb24ndCBwcmV2ZW50RGVmYXVsdCBvbiBlZGl0YWJsZSBlbGVtZW50c1xyXG4gIGlmIChpcy5lbGVtZW50KGV2ZW50LnRhcmdldCkgJiYgbWF0Y2hlc1NlbGVjdG9yKGV2ZW50LnRhcmdldCwgJ2lucHV0LHNlbGVjdCx0ZXh0YXJlYSxbY29udGVudGVkaXRhYmxlPXRydWVdLFtjb250ZW50ZWRpdGFibGU9dHJ1ZV0gKicpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG59O1xyXG5cclxuZnVuY3Rpb24gb25JbnRlcmFjdGlvbkV2ZW50KF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQ7XHJcblxyXG4gIGlmIChpbnRlcmFjdGlvbi50YXJnZXQpIHtcclxuICAgIGludGVyYWN0aW9uLnRhcmdldC5jaGVja0FuZFByZXZlbnREZWZhdWx0KGV2ZW50KTtcclxuICB9XHJcbn1cclxuXHJcbnZhciBfYXJyID0gWydkb3duJywgJ21vdmUnLCAndXAnLCAnY2FuY2VsJ107XHJcbmZvciAodmFyIF9pID0gMDsgX2kgPCBfYXJyLmxlbmd0aDsgX2krKykge1xyXG4gIHZhciBldmVudFNpZ25hbCA9IF9hcnJbX2ldO1xyXG4gIEludGVyYWN0aW9uLnNpZ25hbHMub24oZXZlbnRTaWduYWwsIG9uSW50ZXJhY3Rpb25FdmVudCk7XHJcbn1cclxuXHJcbi8vIHByZXZlbnQgbmF0aXZlIEhUTUw1IGRyYWcgb24gaW50ZXJhY3QuanMgdGFyZ2V0IGVsZW1lbnRzXHJcbkludGVyYWN0aW9uLmRvY0V2ZW50cy5kcmFnc3RhcnQgPSBmdW5jdGlvbiBwcmV2ZW50TmF0aXZlRHJhZyhldmVudCkge1xyXG4gIGZvciAodmFyIF9pdGVyYXRvciA9IHNjb3BlLmludGVyYWN0aW9ucywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pMiA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICB2YXIgX3JlZjI7XHJcblxyXG4gICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgIF9yZWYyID0gX2l0ZXJhdG9yW19pMisrXTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIF9pMiA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaTIuZG9uZSkgYnJlYWs7XHJcbiAgICAgIF9yZWYyID0gX2kyLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYyO1xyXG5cclxuXHJcbiAgICBpZiAoaW50ZXJhY3Rpb24uZWxlbWVudCAmJiAoaW50ZXJhY3Rpb24uZWxlbWVudCA9PT0gZXZlbnQudGFyZ2V0IHx8IG5vZGVDb250YWlucyhpbnRlcmFjdGlvbi5lbGVtZW50LCBldmVudC50YXJnZXQpKSkge1xyXG5cclxuICAgICAgaW50ZXJhY3Rpb24udGFyZ2V0LmNoZWNrQW5kUHJldmVudERlZmF1bHQoZXZlbnQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG5cclxufSx7XCIuL0ludGVyYWN0YWJsZVwiOjQsXCIuL0ludGVyYWN0aW9uXCI6NSxcIi4vc2NvcGVcIjozNCxcIi4vdXRpbHMvZG9tVXRpbHNcIjozOSxcIi4vdXRpbHMvZXZlbnRzXCI6NDAsXCIuL3V0aWxzL2lzXCI6NDZ9XSwyMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBzY29wZSA9IHJlcXVpcmUoJy4vc2NvcGUnKTtcclxudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vdXRpbHMvZXZlbnRzJyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi91dGlscy9icm93c2VyJyk7XHJcbnZhciBpRmluZGVyID0gcmVxdWlyZSgnLi91dGlscy9pbnRlcmFjdGlvbkZpbmRlcicpO1xyXG52YXIgcG9pbnRlckV2ZW50cyA9IHJlcXVpcmUoJy4vcG9pbnRlckV2ZW50cy9iYXNlJyk7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL3V0aWxzL3dpbmRvdycpLFxyXG4gICAgd2luZG93ID0gX3JlcXVpcmUud2luZG93O1xyXG5cclxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcclxuXHJcbmlmICghd2luZG93LkFycmF5LmlzQXJyYXkpIHtcclxuICB3aW5kb3cuQXJyYXkuaXNBcnJheSA9IGZ1bmN0aW9uIChvYmopIHtcclxuICAgIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEFycmF5XSc7XHJcbiAgfTtcclxufVxyXG5cclxuaWYgKCFTdHJpbmcucHJvdG90eXBlLnRyaW0pIHtcclxuICBTdHJpbmcucHJvdG90eXBlLnRyaW0gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZywgJycpO1xyXG4gIH07XHJcbn1cclxuXHJcbi8vIGh0dHA6Ly93d3cucXVpcmtzbW9kZS5vcmcvZG9tL2V2ZW50cy9jbGljay5odG1sXHJcbi8vID5FdmVudHMgbGVhZGluZyB0byBkYmxjbGlja1xyXG4vL1xyXG4vLyBJRTggZG9lc24ndCBmaXJlIGRvd24gZXZlbnQgYmVmb3JlIGRibGNsaWNrLlxyXG4vLyBUaGlzIHdvcmthcm91bmQgdHJpZXMgdG8gZmlyZSBhIHRhcCBhbmQgZG91YmxldGFwIGFmdGVyIGRibGNsaWNrXHJcbmZ1bmN0aW9uIG9uSUU4RGJsY2xpY2soZXZlbnQpIHtcclxuICB2YXIgZXZlbnRUYXJnZXQgPSBldmVudC50YXJnZXQ7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gaUZpbmRlci5zZWFyY2goZXZlbnQsIGV2ZW50LnR5cGUsIGV2ZW50VGFyZ2V0KTtcclxuXHJcbiAgaWYgKCFpbnRlcmFjdGlvbikge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgaWYgKGludGVyYWN0aW9uLnByZXZUYXAgJiYgZXZlbnQuY2xpZW50WCA9PT0gaW50ZXJhY3Rpb24ucHJldlRhcC5jbGllbnRYICYmIGV2ZW50LmNsaWVudFkgPT09IGludGVyYWN0aW9uLnByZXZUYXAuY2xpZW50WSAmJiBldmVudFRhcmdldCA9PT0gaW50ZXJhY3Rpb24ucHJldlRhcC50YXJnZXQpIHtcclxuXHJcbiAgICBpbnRlcmFjdGlvbi5kb3duVGFyZ2V0c1swXSA9IGV2ZW50VGFyZ2V0O1xyXG4gICAgaW50ZXJhY3Rpb24uZG93blRpbWVzWzBdID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcblxyXG4gICAgcG9pbnRlckV2ZW50cy5maXJlKHtcclxuICAgICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgICBldmVudDogZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcclxuICAgICAgcG9pbnRlcjogZXZlbnQsXHJcbiAgICAgIHR5cGU6ICd0YXAnXHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuXHJcbmlmIChicm93c2VyLmlzSUU4KSB7XHJcbiAgdmFyIHNlbGVjdEZpeCA9IGZ1bmN0aW9uIHNlbGVjdEZpeChldmVudCkge1xyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICB2YXIgX3JlZjtcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheSkge1xyXG4gICAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmID0gX2l0ZXJhdG9yW19pKytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcclxuICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZiA9IF9pLnZhbHVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmO1xyXG5cclxuICAgICAgaWYgKGludGVyYWN0aW9uLmludGVyYWN0aW5nKCkpIHtcclxuICAgICAgICBpbnRlcmFjdGlvbi50YXJnZXQuY2hlY2tBbmRQcmV2ZW50RGVmYXVsdChldmVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9O1xyXG5cclxuICB2YXIgb25Eb2NJRTggPSBmdW5jdGlvbiBvbkRvY0lFOChfcmVmMiwgc2lnbmFsTmFtZSkge1xyXG4gICAgdmFyIGRvYyA9IF9yZWYyLmRvYyxcclxuICAgICAgICB3aW4gPSBfcmVmMi53aW47XHJcblxyXG4gICAgdmFyIGV2ZW50TWV0aG9kID0gc2lnbmFsTmFtZS5pbmRleE9mKCdsaXN0ZW4nKSA9PT0gMCA/IGV2ZW50cy5hZGQgOiBldmVudHMucmVtb3ZlO1xyXG5cclxuICAgIC8vIEZvciBJRSdzIGxhY2sgb2YgRXZlbnQjcHJldmVudERlZmF1bHRcclxuICAgIGV2ZW50TWV0aG9kKGRvYywgJ3NlbGVjdHN0YXJ0Jywgc2VsZWN0Rml4KTtcclxuXHJcbiAgICBpZiAocG9pbnRlckV2ZW50cykge1xyXG4gICAgICBldmVudE1ldGhvZChkb2MsICdkYmxjbGljaycsIG9uSUU4RGJsY2xpY2spO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIHNjb3BlLnNpZ25hbHMub24oJ2FkZC1kb2N1bWVudCcsIG9uRG9jSUU4KTtcclxuICBzY29wZS5zaWduYWxzLm9uKCdyZW1vdmUtZG9jdW1lbnQnLCBvbkRvY0lFOCk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbnVsbDtcclxuXHJcbn0se1wiLi9wb2ludGVyRXZlbnRzL2Jhc2VcIjozMSxcIi4vc2NvcGVcIjozNCxcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9ldmVudHNcIjo0MCxcIi4vdXRpbHMvaW50ZXJhY3Rpb25GaW5kZXJcIjo0NSxcIi4vdXRpbHMvd2luZG93XCI6NTJ9XSwyNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBJbnRlcmFjdEV2ZW50ID0gcmVxdWlyZSgnLi4vSW50ZXJhY3RFdmVudCcpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuLi9JbnRlcmFjdGlvbicpO1xyXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi4vdXRpbHMvZXh0ZW5kJyk7XHJcblxyXG52YXIgbW9kaWZpZXJzID0ge1xyXG4gIG5hbWVzOiBbXSxcclxuXHJcbiAgc2V0T2Zmc2V0czogZnVuY3Rpb24gc2V0T2Zmc2V0cyhhcmcpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IGFyZy5pbnRlcmFjdGlvbixcclxuICAgICAgICBwYWdlID0gYXJnLnBhZ2VDb29yZHM7XHJcbiAgICB2YXIgdGFyZ2V0ID0gaW50ZXJhY3Rpb24udGFyZ2V0LFxyXG4gICAgICAgIGVsZW1lbnQgPSBpbnRlcmFjdGlvbi5lbGVtZW50LFxyXG4gICAgICAgIHN0YXJ0T2Zmc2V0ID0gaW50ZXJhY3Rpb24uc3RhcnRPZmZzZXQ7XHJcblxyXG4gICAgdmFyIHJlY3QgPSB0YXJnZXQuZ2V0UmVjdChlbGVtZW50KTtcclxuXHJcbiAgICBpZiAocmVjdCkge1xyXG4gICAgICBzdGFydE9mZnNldC5sZWZ0ID0gcGFnZS54IC0gcmVjdC5sZWZ0O1xyXG4gICAgICBzdGFydE9mZnNldC50b3AgPSBwYWdlLnkgLSByZWN0LnRvcDtcclxuXHJcbiAgICAgIHN0YXJ0T2Zmc2V0LnJpZ2h0ID0gcmVjdC5yaWdodCAtIHBhZ2UueDtcclxuICAgICAgc3RhcnRPZmZzZXQuYm90dG9tID0gcmVjdC5ib3R0b20gLSBwYWdlLnk7XHJcblxyXG4gICAgICBpZiAoISgnd2lkdGgnIGluIHJlY3QpKSB7XHJcbiAgICAgICAgcmVjdC53aWR0aCA9IHJlY3QucmlnaHQgLSByZWN0LmxlZnQ7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCEoJ2hlaWdodCcgaW4gcmVjdCkpIHtcclxuICAgICAgICByZWN0LmhlaWdodCA9IHJlY3QuYm90dG9tIC0gcmVjdC50b3A7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHN0YXJ0T2Zmc2V0LmxlZnQgPSBzdGFydE9mZnNldC50b3AgPSBzdGFydE9mZnNldC5yaWdodCA9IHN0YXJ0T2Zmc2V0LmJvdHRvbSA9IDA7XHJcbiAgICB9XHJcblxyXG4gICAgYXJnLnJlY3QgPSByZWN0O1xyXG4gICAgYXJnLmludGVyYWN0YWJsZSA9IHRhcmdldDtcclxuICAgIGFyZy5lbGVtZW50ID0gZWxlbWVudDtcclxuXHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1vZGlmaWVycy5uYW1lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICB2YXIgbW9kaWZpZXJOYW1lID0gbW9kaWZpZXJzLm5hbWVzW2ldO1xyXG5cclxuICAgICAgYXJnLm9wdGlvbnMgPSB0YXJnZXQub3B0aW9uc1tpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXVttb2RpZmllck5hbWVdO1xyXG5cclxuICAgICAgaWYgKCFhcmcub3B0aW9ucykge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpbnRlcmFjdGlvbi5tb2RpZmllck9mZnNldHNbbW9kaWZpZXJOYW1lXSA9IG1vZGlmaWVyc1ttb2RpZmllck5hbWVdLnNldE9mZnNldChhcmcpO1xyXG4gICAgfVxyXG4gIH0sXHJcblxyXG4gIHNldEFsbDogZnVuY3Rpb24gc2V0QWxsKGFyZykge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICAgIHN0YXR1c2VzID0gYXJnLnN0YXR1c2VzLFxyXG4gICAgICAgIHByZUVuZCA9IGFyZy5wcmVFbmQsXHJcbiAgICAgICAgcmVxdWlyZUVuZE9ubHkgPSBhcmcucmVxdWlyZUVuZE9ubHk7XHJcblxyXG4gICAgdmFyIGNvb3JkcyA9IGV4dGVuZCh7fSwgYXJnLnBhZ2VDb29yZHMpO1xyXG4gICAgdmFyIHJlc3VsdCA9IHtcclxuICAgICAgZHg6IDAsXHJcbiAgICAgIGR5OiAwLFxyXG4gICAgICBjaGFuZ2VkOiBmYWxzZSxcclxuICAgICAgbG9ja2VkOiBmYWxzZSxcclxuICAgICAgc2hvdWxkTW92ZTogdHJ1ZVxyXG4gICAgfTtcclxuXHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBtb2RpZmllcnMubmFtZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgICAgaWYgKF9pID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kgPSBfaXRlcmF0b3IubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmID0gX2kudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBtb2RpZmllck5hbWUgPSBfcmVmO1xyXG5cclxuICAgICAgdmFyIG1vZGlmaWVyID0gbW9kaWZpZXJzW21vZGlmaWVyTmFtZV07XHJcbiAgICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV1bbW9kaWZpZXJOYW1lXTtcclxuXHJcbiAgICAgIGlmICghc2hvdWxkRG8ob3B0aW9ucywgcHJlRW5kLCByZXF1aXJlRW5kT25seSkpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgYXJnLnN0YXR1cyA9IGFyZy5zdGF0dXMgPSBzdGF0dXNlc1ttb2RpZmllck5hbWVdO1xyXG4gICAgICBhcmcub3B0aW9ucyA9IG9wdGlvbnM7XHJcbiAgICAgIGFyZy5vZmZzZXQgPSBhcmcuaW50ZXJhY3Rpb24ubW9kaWZpZXJPZmZzZXRzW21vZGlmaWVyTmFtZV07XHJcblxyXG4gICAgICBtb2RpZmllci5zZXQoYXJnKTtcclxuXHJcbiAgICAgIGlmIChhcmcuc3RhdHVzLmxvY2tlZCkge1xyXG4gICAgICAgIGNvb3Jkcy54ICs9IGFyZy5zdGF0dXMuZHg7XHJcbiAgICAgICAgY29vcmRzLnkgKz0gYXJnLnN0YXR1cy5keTtcclxuXHJcbiAgICAgICAgcmVzdWx0LmR4ICs9IGFyZy5zdGF0dXMuZHg7XHJcbiAgICAgICAgcmVzdWx0LmR5ICs9IGFyZy5zdGF0dXMuZHk7XHJcblxyXG4gICAgICAgIHJlc3VsdC5sb2NrZWQgPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYSBtb3ZlIHNob3VsZCBiZSBmaXJlZCBpZjpcclxuICAgIC8vICAtIHRoZXJlIGFyZSBubyBtb2RpZmllcnMgZW5hYmxlZCxcclxuICAgIC8vICAtIG5vIG1vZGlmaWVycyBhcmUgXCJsb2NrZWRcIiBpLmUuIGhhdmUgY2hhbmdlZCB0aGUgcG9pbnRlcidzIGNvb3JkaW5hdGVzLCBvclxyXG4gICAgLy8gIC0gdGhlIGxvY2tlZCBjb29yZHMgaGF2ZSBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IHBvaW50ZXIgbW92ZVxyXG4gICAgcmVzdWx0LnNob3VsZE1vdmUgPSAhYXJnLnN0YXR1cyB8fCAhcmVzdWx0LmxvY2tlZCB8fCBhcmcuc3RhdHVzLmNoYW5nZWQ7XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9LFxyXG5cclxuICByZXNldFN0YXR1c2VzOiBmdW5jdGlvbiByZXNldFN0YXR1c2VzKHN0YXR1c2VzKSB7XHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3IyID0gbW9kaWZpZXJzLm5hbWVzLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWYyO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5Mikge1xyXG4gICAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yMi5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yMltfaTIrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kyID0gX2l0ZXJhdG9yMi5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmMiA9IF9pMi52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIG1vZGlmaWVyTmFtZSA9IF9yZWYyO1xyXG5cclxuICAgICAgdmFyIHN0YXR1cyA9IHN0YXR1c2VzW21vZGlmaWVyTmFtZV0gfHwge307XHJcblxyXG4gICAgICBzdGF0dXMuZHggPSBzdGF0dXMuZHkgPSAwO1xyXG4gICAgICBzdGF0dXMubW9kaWZpZWRYID0gc3RhdHVzLm1vZGlmaWVkWSA9IE5hTjtcclxuICAgICAgc3RhdHVzLmxvY2tlZCA9IGZhbHNlO1xyXG4gICAgICBzdGF0dXMuY2hhbmdlZCA9IHRydWU7XHJcblxyXG4gICAgICBzdGF0dXNlc1ttb2RpZmllck5hbWVdID0gc3RhdHVzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzdGF0dXNlcztcclxuICB9LFxyXG5cclxuICBzdGFydDogZnVuY3Rpb24gc3RhcnQoX3JlZjMsIHNpZ25hbE5hbWUpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzLmludGVyYWN0aW9uO1xyXG5cclxuICAgIHZhciBhcmcgPSB7XHJcbiAgICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcclxuICAgICAgcGFnZUNvb3JkczogKHNpZ25hbE5hbWUgPT09ICdhY3Rpb24tcmVzdW1lJyA/IGludGVyYWN0aW9uLmN1ckNvb3JkcyA6IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzKS5wYWdlLFxyXG4gICAgICBzdGFydE9mZnNldDogaW50ZXJhY3Rpb24uc3RhcnRPZmZzZXQsXHJcbiAgICAgIHN0YXR1c2VzOiBpbnRlcmFjdGlvbi5tb2RpZmllclN0YXR1c2VzLFxyXG4gICAgICBwcmVFbmQ6IGZhbHNlLFxyXG4gICAgICByZXF1aXJlRW5kT25seTogZmFsc2VcclxuICAgIH07XHJcblxyXG4gICAgbW9kaWZpZXJzLnNldE9mZnNldHMoYXJnKTtcclxuICAgIG1vZGlmaWVycy5yZXNldFN0YXR1c2VzKGFyZy5zdGF0dXNlcyk7XHJcblxyXG4gICAgYXJnLnBhZ2VDb29yZHMgPSBleHRlbmQoe30sIGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLnBhZ2UpO1xyXG4gICAgaW50ZXJhY3Rpb24ubW9kaWZpZXJSZXN1bHQgPSBtb2RpZmllcnMuc2V0QWxsKGFyZyk7XHJcbiAgfVxyXG59O1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XHJcbiAgaW50ZXJhY3Rpb24uc3RhcnRPZmZzZXQgPSB7IGxlZnQ6IDAsIHJpZ2h0OiAwLCB0b3A6IDAsIGJvdHRvbTogMCB9O1xyXG4gIGludGVyYWN0aW9uLm1vZGlmaWVyT2Zmc2V0cyA9IHt9O1xyXG4gIGludGVyYWN0aW9uLm1vZGlmaWVyU3RhdHVzZXMgPSBtb2RpZmllcnMucmVzZXRTdGF0dXNlcyh7fSk7XHJcbiAgaW50ZXJhY3Rpb24ubW9kaWZpZXJSZXN1bHQgPSBudWxsO1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ2FjdGlvbi1zdGFydCcsIG1vZGlmaWVycy5zdGFydCk7XHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ2FjdGlvbi1yZXN1bWUnLCBtb2RpZmllcnMuc3RhcnQpO1xyXG5cclxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYmVmb3JlLWFjdGlvbi1tb3ZlJywgZnVuY3Rpb24gKF9yZWY0KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjQuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHByZUVuZCA9IF9yZWY0LnByZUVuZCxcclxuICAgICAgaW50ZXJhY3RpbmdCZWZvcmVNb3ZlID0gX3JlZjQuaW50ZXJhY3RpbmdCZWZvcmVNb3ZlO1xyXG5cclxuICB2YXIgbW9kaWZpZXJSZXN1bHQgPSBtb2RpZmllcnMuc2V0QWxsKHtcclxuICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcclxuICAgIHByZUVuZDogcHJlRW5kLFxyXG4gICAgcGFnZUNvb3JkczogaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UsXHJcbiAgICBzdGF0dXNlczogaW50ZXJhY3Rpb24ubW9kaWZpZXJTdGF0dXNlcyxcclxuICAgIHJlcXVpcmVFbmRPbmx5OiBmYWxzZVxyXG4gIH0pO1xyXG5cclxuICAvLyBkb24ndCBmaXJlIGFuIGFjdGlvbiBtb3ZlIGlmIGEgbW9kaWZpZXIgd291bGQga2VlcCB0aGUgZXZlbnQgaW4gdGhlIHNhbWVcclxuICAvLyBjb3JkaW5hdGVzIGFzIGJlZm9yZVxyXG4gIGlmICghbW9kaWZpZXJSZXN1bHQuc2hvdWxkTW92ZSAmJiBpbnRlcmFjdGluZ0JlZm9yZU1vdmUpIHtcclxuICAgIGludGVyYWN0aW9uLl9kb250RmlyZU1vdmUgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgaW50ZXJhY3Rpb24ubW9kaWZpZXJSZXN1bHQgPSBtb2RpZmllclJlc3VsdDtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tZW5kJywgZnVuY3Rpb24gKF9yZWY1KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjUuaW50ZXJhY3Rpb24sXHJcbiAgICAgIGV2ZW50ID0gX3JlZjUuZXZlbnQ7XHJcblxyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbW9kaWZpZXJzLm5hbWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICB2YXIgb3B0aW9ucyA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zW2ludGVyYWN0aW9uLnByZXBhcmVkLm5hbWVdW21vZGlmaWVycy5uYW1lc1tpXV07XHJcblxyXG4gICAgLy8gaWYgdGhlIGVuZE9ubHkgb3B0aW9uIGlzIHRydWUgZm9yIGFueSBtb2RpZmllclxyXG4gICAgaWYgKHNob3VsZERvKG9wdGlvbnMsIHRydWUsIHRydWUpKSB7XHJcbiAgICAgIC8vIGZpcmUgYSBtb3ZlIGV2ZW50IGF0IHRoZSBtb2RpZmllZCBjb29yZGluYXRlc1xyXG4gICAgICBpbnRlcmFjdGlvbi5kb01vdmUoeyBldmVudDogZXZlbnQsIHByZUVuZDogdHJ1ZSB9KTtcclxuICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgfVxyXG59KTtcclxuXHJcbkludGVyYWN0RXZlbnQuc2lnbmFscy5vbignc2V0LXh5JywgZnVuY3Rpb24gKGFyZykge1xyXG4gIHZhciBpRXZlbnQgPSBhcmcuaUV2ZW50LFxyXG4gICAgICBpbnRlcmFjdGlvbiA9IGFyZy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgdmFyIG1vZGlmaWVyQXJnID0gZXh0ZW5kKHt9LCBhcmcpO1xyXG5cclxuICBmb3IgKHZhciBpID0gMDsgaSA8IG1vZGlmaWVycy5uYW1lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgdmFyIG1vZGlmaWVyTmFtZSA9IG1vZGlmaWVycy5uYW1lc1tpXTtcclxuICAgIG1vZGlmaWVyQXJnLm9wdGlvbnMgPSBpbnRlcmFjdGlvbi50YXJnZXQub3B0aW9uc1tpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXVttb2RpZmllck5hbWVdO1xyXG5cclxuICAgIGlmICghbW9kaWZpZXJBcmcub3B0aW9ucykge1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgbW9kaWZpZXIgPSBtb2RpZmllcnNbbW9kaWZpZXJOYW1lXTtcclxuXHJcbiAgICBtb2RpZmllckFyZy5zdGF0dXMgPSBpbnRlcmFjdGlvbi5tb2RpZmllclN0YXR1c2VzW21vZGlmaWVyTmFtZV07XHJcblxyXG4gICAgaUV2ZW50W21vZGlmaWVyTmFtZV0gPSBtb2RpZmllci5tb2RpZnlDb29yZHMobW9kaWZpZXJBcmcpO1xyXG4gIH1cclxufSk7XHJcblxyXG5mdW5jdGlvbiBzaG91bGREbyhvcHRpb25zLCBwcmVFbmQsIHJlcXVpcmVFbmRPbmx5KSB7XHJcbiAgcmV0dXJuIG9wdGlvbnMgJiYgb3B0aW9ucy5lbmFibGVkICYmIChwcmVFbmQgfHwgIW9wdGlvbnMuZW5kT25seSkgJiYgKCFyZXF1aXJlRW5kT25seSB8fCBvcHRpb25zLmVuZE9ubHkpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IG1vZGlmaWVycztcclxuXHJcbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuLi91dGlscy9leHRlbmRcIjo0MX1dLDI1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIG1vZGlmaWVycyA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxuXHJcbnZhciByZXN0cmljdCA9IHtcclxuICBkZWZhdWx0czoge1xyXG4gICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICBlbmRPbmx5OiBmYWxzZSxcclxuICAgIHJlc3RyaWN0aW9uOiBudWxsLFxyXG4gICAgZWxlbWVudFJlY3Q6IG51bGxcclxuICB9LFxyXG5cclxuICBzZXRPZmZzZXQ6IGZ1bmN0aW9uIHNldE9mZnNldChfcmVmKSB7XHJcbiAgICB2YXIgcmVjdCA9IF9yZWYucmVjdCxcclxuICAgICAgICBzdGFydE9mZnNldCA9IF9yZWYuc3RhcnRPZmZzZXQsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucztcclxuXHJcbiAgICB2YXIgZWxlbWVudFJlY3QgPSBvcHRpb25zICYmIG9wdGlvbnMuZWxlbWVudFJlY3Q7XHJcbiAgICB2YXIgb2Zmc2V0ID0ge307XHJcblxyXG4gICAgaWYgKHJlY3QgJiYgZWxlbWVudFJlY3QpIHtcclxuICAgICAgb2Zmc2V0LmxlZnQgPSBzdGFydE9mZnNldC5sZWZ0IC0gcmVjdC53aWR0aCAqIGVsZW1lbnRSZWN0LmxlZnQ7XHJcbiAgICAgIG9mZnNldC50b3AgPSBzdGFydE9mZnNldC50b3AgLSByZWN0LmhlaWdodCAqIGVsZW1lbnRSZWN0LnRvcDtcclxuXHJcbiAgICAgIG9mZnNldC5yaWdodCA9IHN0YXJ0T2Zmc2V0LnJpZ2h0IC0gcmVjdC53aWR0aCAqICgxIC0gZWxlbWVudFJlY3QucmlnaHQpO1xyXG4gICAgICBvZmZzZXQuYm90dG9tID0gc3RhcnRPZmZzZXQuYm90dG9tIC0gcmVjdC5oZWlnaHQgKiAoMSAtIGVsZW1lbnRSZWN0LmJvdHRvbSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBvZmZzZXQubGVmdCA9IG9mZnNldC50b3AgPSBvZmZzZXQucmlnaHQgPSBvZmZzZXQuYm90dG9tID0gMDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gb2Zmc2V0O1xyXG4gIH0sXHJcblxyXG4gIHNldDogZnVuY3Rpb24gc2V0KF9yZWYyKSB7XHJcbiAgICB2YXIgcGFnZUNvb3JkcyA9IF9yZWYyLnBhZ2VDb29yZHMsXHJcbiAgICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbixcclxuICAgICAgICBzdGF0dXMgPSBfcmVmMi5zdGF0dXMsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYyLm9wdGlvbnM7XHJcblxyXG4gICAgaWYgKCFvcHRpb25zKSB7XHJcbiAgICAgIHJldHVybiBzdGF0dXM7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHBhZ2UgPSBzdGF0dXMudXNlU3RhdHVzWFkgPyB7IHg6IHN0YXR1cy54LCB5OiBzdGF0dXMueSB9IDogdXRpbHMuZXh0ZW5kKHt9LCBwYWdlQ29vcmRzKTtcclxuXHJcbiAgICB2YXIgcmVzdHJpY3Rpb24gPSBnZXRSZXN0cmljdGlvblJlY3Qob3B0aW9ucy5yZXN0cmljdGlvbiwgaW50ZXJhY3Rpb24sIHBhZ2UpO1xyXG5cclxuICAgIGlmICghcmVzdHJpY3Rpb24pIHtcclxuICAgICAgcmV0dXJuIHN0YXR1cztcclxuICAgIH1cclxuXHJcbiAgICBzdGF0dXMuZHggPSAwO1xyXG4gICAgc3RhdHVzLmR5ID0gMDtcclxuICAgIHN0YXR1cy5sb2NrZWQgPSBmYWxzZTtcclxuXHJcbiAgICB2YXIgcmVjdCA9IHJlc3RyaWN0aW9uO1xyXG4gICAgdmFyIG1vZGlmaWVkWCA9IHBhZ2UueDtcclxuICAgIHZhciBtb2RpZmllZFkgPSBwYWdlLnk7XHJcblxyXG4gICAgdmFyIG9mZnNldCA9IGludGVyYWN0aW9uLm1vZGlmaWVyT2Zmc2V0cy5yZXN0cmljdDtcclxuXHJcbiAgICAvLyBvYmplY3QgaXMgYXNzdW1lZCB0byBoYXZlXHJcbiAgICAvLyB4LCB5LCB3aWR0aCwgaGVpZ2h0IG9yXHJcbiAgICAvLyBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b21cclxuICAgIGlmICgneCcgaW4gcmVzdHJpY3Rpb24gJiYgJ3knIGluIHJlc3RyaWN0aW9uKSB7XHJcbiAgICAgIG1vZGlmaWVkWCA9IE1hdGgubWF4KE1hdGgubWluKHJlY3QueCArIHJlY3Qud2lkdGggLSBvZmZzZXQucmlnaHQsIHBhZ2UueCksIHJlY3QueCArIG9mZnNldC5sZWZ0KTtcclxuICAgICAgbW9kaWZpZWRZID0gTWF0aC5tYXgoTWF0aC5taW4ocmVjdC55ICsgcmVjdC5oZWlnaHQgLSBvZmZzZXQuYm90dG9tLCBwYWdlLnkpLCByZWN0LnkgKyBvZmZzZXQudG9wKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG1vZGlmaWVkWCA9IE1hdGgubWF4KE1hdGgubWluKHJlY3QucmlnaHQgLSBvZmZzZXQucmlnaHQsIHBhZ2UueCksIHJlY3QubGVmdCArIG9mZnNldC5sZWZ0KTtcclxuICAgICAgbW9kaWZpZWRZID0gTWF0aC5tYXgoTWF0aC5taW4ocmVjdC5ib3R0b20gLSBvZmZzZXQuYm90dG9tLCBwYWdlLnkpLCByZWN0LnRvcCArIG9mZnNldC50b3ApO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXR1cy5keCA9IG1vZGlmaWVkWCAtIHBhZ2UueDtcclxuICAgIHN0YXR1cy5keSA9IG1vZGlmaWVkWSAtIHBhZ2UueTtcclxuXHJcbiAgICBzdGF0dXMuY2hhbmdlZCA9IHN0YXR1cy5tb2RpZmllZFggIT09IG1vZGlmaWVkWCB8fCBzdGF0dXMubW9kaWZpZWRZICE9PSBtb2RpZmllZFk7XHJcbiAgICBzdGF0dXMubG9ja2VkID0gISEoc3RhdHVzLmR4IHx8IHN0YXR1cy5keSk7XHJcblxyXG4gICAgc3RhdHVzLm1vZGlmaWVkWCA9IG1vZGlmaWVkWDtcclxuICAgIHN0YXR1cy5tb2RpZmllZFkgPSBtb2RpZmllZFk7XHJcbiAgfSxcclxuXHJcbiAgbW9kaWZ5Q29vcmRzOiBmdW5jdGlvbiBtb2RpZnlDb29yZHMoX3JlZjMpIHtcclxuICAgIHZhciBwYWdlID0gX3JlZjMucGFnZSxcclxuICAgICAgICBjbGllbnQgPSBfcmVmMy5jbGllbnQsXHJcbiAgICAgICAgc3RhdHVzID0gX3JlZjMuc3RhdHVzLFxyXG4gICAgICAgIHBoYXNlID0gX3JlZjMucGhhc2UsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYzLm9wdGlvbnM7XHJcblxyXG4gICAgdmFyIGVsZW1lbnRSZWN0ID0gb3B0aW9ucyAmJiBvcHRpb25zLmVsZW1lbnRSZWN0O1xyXG5cclxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZW5hYmxlZCAmJiAhKHBoYXNlID09PSAnc3RhcnQnICYmIGVsZW1lbnRSZWN0ICYmIHN0YXR1cy5sb2NrZWQpKSB7XHJcblxyXG4gICAgICBpZiAoc3RhdHVzLmxvY2tlZCkge1xyXG4gICAgICAgIHBhZ2UueCArPSBzdGF0dXMuZHg7XHJcbiAgICAgICAgcGFnZS55ICs9IHN0YXR1cy5keTtcclxuICAgICAgICBjbGllbnQueCArPSBzdGF0dXMuZHg7XHJcbiAgICAgICAgY2xpZW50LnkgKz0gc3RhdHVzLmR5O1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgZHg6IHN0YXR1cy5keCxcclxuICAgICAgICAgIGR5OiBzdGF0dXMuZHlcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgZ2V0UmVzdHJpY3Rpb25SZWN0OiBnZXRSZXN0cmljdGlvblJlY3RcclxufTtcclxuXHJcbmZ1bmN0aW9uIGdldFJlc3RyaWN0aW9uUmVjdCh2YWx1ZSwgaW50ZXJhY3Rpb24sIHBhZ2UpIHtcclxuICBpZiAodXRpbHMuaXMuZnVuY3Rpb24odmFsdWUpKSB7XHJcbiAgICByZXR1cm4gdXRpbHMucmVzb2x2ZVJlY3RMaWtlKHZhbHVlLCBpbnRlcmFjdGlvbi50YXJnZXQsIGludGVyYWN0aW9uLmVsZW1lbnQsIFtwYWdlLngsIHBhZ2UueSwgaW50ZXJhY3Rpb25dKTtcclxuICB9IGVsc2Uge1xyXG4gICAgcmV0dXJuIHV0aWxzLnJlc29sdmVSZWN0TGlrZSh2YWx1ZSwgaW50ZXJhY3Rpb24udGFyZ2V0LCBpbnRlcmFjdGlvbi5lbGVtZW50KTtcclxuICB9XHJcbn1cclxuXHJcbm1vZGlmaWVycy5yZXN0cmljdCA9IHJlc3RyaWN0O1xyXG5tb2RpZmllcnMubmFtZXMucHVzaCgncmVzdHJpY3QnKTtcclxuXHJcbmRlZmF1bHRPcHRpb25zLnBlckFjdGlvbi5yZXN0cmljdCA9IHJlc3RyaWN0LmRlZmF1bHRzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZXN0cmljdDtcclxuXHJcbn0se1wiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL3V0aWxzXCI6NDQsXCIuL2luZGV4XCI6MjR9XSwyNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbi8vIFRoaXMgbW9kdWxlIGFkZHMgdGhlIG9wdGlvbnMucmVzaXplLnJlc3RyaWN0RWRnZXMgc2V0dGluZyB3aGljaCBzZXRzIG1pbiBhbmRcclxuLy8gbWF4IGZvciB0aGUgdG9wLCBsZWZ0LCBib3R0b20gYW5kIHJpZ2h0IGVkZ2VzIG9mIHRoZSB0YXJnZXQgYmVpbmcgcmVzaXplZC5cclxuLy9cclxuLy8gaW50ZXJhY3QodGFyZ2V0KS5yZXNpemUoe1xyXG4vLyAgIGVkZ2VzOiB7IHRvcDogdHJ1ZSwgbGVmdDogdHJ1ZSB9LFxyXG4vLyAgIHJlc3RyaWN0RWRnZXM6IHtcclxuLy8gICAgIGlubmVyOiB7IHRvcDogMjAwLCBsZWZ0OiAyMDAsIHJpZ2h0OiA0MDAsIGJvdHRvbTogNDAwIH0sXHJcbi8vICAgICBvdXRlcjogeyB0b3A6ICAgMCwgbGVmdDogICAwLCByaWdodDogNjAwLCBib3R0b206IDYwMCB9LFxyXG4vLyAgIH0sXHJcbi8vIH0pO1xyXG5cclxudmFyIG1vZGlmaWVycyA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcclxudmFyIHJlY3RVdGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzL3JlY3QnKTtcclxudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcclxudmFyIHJlc2l6ZSA9IHJlcXVpcmUoJy4uL2FjdGlvbnMvcmVzaXplJyk7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL3Jlc3RyaWN0JyksXHJcbiAgICBnZXRSZXN0cmljdGlvblJlY3QgPSBfcmVxdWlyZS5nZXRSZXN0cmljdGlvblJlY3Q7XHJcblxyXG52YXIgbm9Jbm5lciA9IHsgdG9wOiArSW5maW5pdHksIGxlZnQ6ICtJbmZpbml0eSwgYm90dG9tOiAtSW5maW5pdHksIHJpZ2h0OiAtSW5maW5pdHkgfTtcclxudmFyIG5vT3V0ZXIgPSB7IHRvcDogLUluZmluaXR5LCBsZWZ0OiAtSW5maW5pdHksIGJvdHRvbTogK0luZmluaXR5LCByaWdodDogK0luZmluaXR5IH07XHJcblxyXG52YXIgcmVzdHJpY3RFZGdlcyA9IHtcclxuICBkZWZhdWx0czoge1xyXG4gICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICBlbmRPbmx5OiBmYWxzZSxcclxuICAgIG1pbjogbnVsbCxcclxuICAgIG1heDogbnVsbCxcclxuICAgIG9mZnNldDogbnVsbFxyXG4gIH0sXHJcblxyXG4gIHNldE9mZnNldDogZnVuY3Rpb24gc2V0T2Zmc2V0KF9yZWYpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb24sXHJcbiAgICAgICAgc3RhcnRPZmZzZXQgPSBfcmVmLnN0YXJ0T2Zmc2V0LFxyXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XHJcblxyXG4gICAgaWYgKCFvcHRpb25zKSB7XHJcbiAgICAgIHJldHVybiB1dGlscy5leHRlbmQoe30sIHN0YXJ0T2Zmc2V0KTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgb2Zmc2V0ID0gZ2V0UmVzdHJpY3Rpb25SZWN0KG9wdGlvbnMub2Zmc2V0LCBpbnRlcmFjdGlvbiwgaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMucGFnZSk7XHJcblxyXG4gICAgaWYgKG9mZnNldCkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHRvcDogc3RhcnRPZmZzZXQudG9wICsgb2Zmc2V0LnksXHJcbiAgICAgICAgbGVmdDogc3RhcnRPZmZzZXQubGVmdCArIG9mZnNldC54LFxyXG4gICAgICAgIGJvdHRvbTogc3RhcnRPZmZzZXQuYm90dG9tICsgb2Zmc2V0LnksXHJcbiAgICAgICAgcmlnaHQ6IHN0YXJ0T2Zmc2V0LnJpZ2h0ICsgb2Zmc2V0LnhcclxuICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc3RhcnRPZmZzZXQ7XHJcbiAgfSxcclxuXHJcbiAgc2V0OiBmdW5jdGlvbiBzZXQoX3JlZjIpIHtcclxuICAgIHZhciBwYWdlQ29vcmRzID0gX3JlZjIucGFnZUNvb3JkcyxcclxuICAgICAgICBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxyXG4gICAgICAgIHN0YXR1cyA9IF9yZWYyLnN0YXR1cyxcclxuICAgICAgICBvZmZzZXQgPSBfcmVmMi5vZmZzZXQsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYyLm9wdGlvbnM7XHJcblxyXG4gICAgdmFyIGVkZ2VzID0gaW50ZXJhY3Rpb24ucHJlcGFyZWQubGlua2VkRWRnZXMgfHwgaW50ZXJhY3Rpb24ucHJlcGFyZWQuZWRnZXM7XHJcblxyXG4gICAgaWYgKCFpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpIHx8ICFlZGdlcykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHBhZ2UgPSBzdGF0dXMudXNlU3RhdHVzWFkgPyB7IHg6IHN0YXR1cy54LCB5OiBzdGF0dXMueSB9IDogdXRpbHMuZXh0ZW5kKHt9LCBwYWdlQ29vcmRzKTtcclxuICAgIHZhciBpbm5lciA9IHJlY3RVdGlscy54eXdoVG9UbGJyKGdldFJlc3RyaWN0aW9uUmVjdChvcHRpb25zLmlubmVyLCBpbnRlcmFjdGlvbiwgcGFnZSkpIHx8IG5vSW5uZXI7XHJcbiAgICB2YXIgb3V0ZXIgPSByZWN0VXRpbHMueHl3aFRvVGxicihnZXRSZXN0cmljdGlvblJlY3Qob3B0aW9ucy5vdXRlciwgaW50ZXJhY3Rpb24sIHBhZ2UpKSB8fCBub091dGVyO1xyXG5cclxuICAgIHZhciBtb2RpZmllZFggPSBwYWdlLng7XHJcbiAgICB2YXIgbW9kaWZpZWRZID0gcGFnZS55O1xyXG5cclxuICAgIHN0YXR1cy5keCA9IDA7XHJcbiAgICBzdGF0dXMuZHkgPSAwO1xyXG4gICAgc3RhdHVzLmxvY2tlZCA9IGZhbHNlO1xyXG5cclxuICAgIGlmIChlZGdlcy50b3ApIHtcclxuICAgICAgbW9kaWZpZWRZID0gTWF0aC5taW4oTWF0aC5tYXgob3V0ZXIudG9wICsgb2Zmc2V0LnRvcCwgcGFnZS55KSwgaW5uZXIudG9wICsgb2Zmc2V0LnRvcCk7XHJcbiAgICB9IGVsc2UgaWYgKGVkZ2VzLmJvdHRvbSkge1xyXG4gICAgICBtb2RpZmllZFkgPSBNYXRoLm1heChNYXRoLm1pbihvdXRlci5ib3R0b20gLSBvZmZzZXQuYm90dG9tLCBwYWdlLnkpLCBpbm5lci5ib3R0b20gLSBvZmZzZXQuYm90dG9tKTtcclxuICAgIH1cclxuICAgIGlmIChlZGdlcy5sZWZ0KSB7XHJcbiAgICAgIG1vZGlmaWVkWCA9IE1hdGgubWluKE1hdGgubWF4KG91dGVyLmxlZnQgKyBvZmZzZXQubGVmdCwgcGFnZS54KSwgaW5uZXIubGVmdCArIG9mZnNldC5sZWZ0KTtcclxuICAgIH0gZWxzZSBpZiAoZWRnZXMucmlnaHQpIHtcclxuICAgICAgbW9kaWZpZWRYID0gTWF0aC5tYXgoTWF0aC5taW4ob3V0ZXIucmlnaHQgLSBvZmZzZXQucmlnaHQsIHBhZ2UueCksIGlubmVyLnJpZ2h0IC0gb2Zmc2V0LnJpZ2h0KTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0dXMuZHggPSBtb2RpZmllZFggLSBwYWdlLng7XHJcbiAgICBzdGF0dXMuZHkgPSBtb2RpZmllZFkgLSBwYWdlLnk7XHJcblxyXG4gICAgc3RhdHVzLmNoYW5nZWQgPSBzdGF0dXMubW9kaWZpZWRYICE9PSBtb2RpZmllZFggfHwgc3RhdHVzLm1vZGlmaWVkWSAhPT0gbW9kaWZpZWRZO1xyXG4gICAgc3RhdHVzLmxvY2tlZCA9ICEhKHN0YXR1cy5keCB8fCBzdGF0dXMuZHkpO1xyXG5cclxuICAgIHN0YXR1cy5tb2RpZmllZFggPSBtb2RpZmllZFg7XHJcbiAgICBzdGF0dXMubW9kaWZpZWRZID0gbW9kaWZpZWRZO1xyXG4gIH0sXHJcblxyXG4gIG1vZGlmeUNvb3JkczogZnVuY3Rpb24gbW9kaWZ5Q29vcmRzKF9yZWYzKSB7XHJcbiAgICB2YXIgcGFnZSA9IF9yZWYzLnBhZ2UsXHJcbiAgICAgICAgY2xpZW50ID0gX3JlZjMuY2xpZW50LFxyXG4gICAgICAgIHN0YXR1cyA9IF9yZWYzLnN0YXR1cyxcclxuICAgICAgICBwaGFzZSA9IF9yZWYzLnBoYXNlLFxyXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmMy5vcHRpb25zO1xyXG5cclxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZW5hYmxlZCAmJiAhKHBoYXNlID09PSAnc3RhcnQnICYmIHN0YXR1cy5sb2NrZWQpKSB7XHJcblxyXG4gICAgICBpZiAoc3RhdHVzLmxvY2tlZCkge1xyXG4gICAgICAgIHBhZ2UueCArPSBzdGF0dXMuZHg7XHJcbiAgICAgICAgcGFnZS55ICs9IHN0YXR1cy5keTtcclxuICAgICAgICBjbGllbnQueCArPSBzdGF0dXMuZHg7XHJcbiAgICAgICAgY2xpZW50LnkgKz0gc3RhdHVzLmR5O1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgZHg6IHN0YXR1cy5keCxcclxuICAgICAgICAgIGR5OiBzdGF0dXMuZHlcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgbm9Jbm5lcjogbm9Jbm5lcixcclxuICBub091dGVyOiBub091dGVyLFxyXG4gIGdldFJlc3RyaWN0aW9uUmVjdDogZ2V0UmVzdHJpY3Rpb25SZWN0XHJcbn07XHJcblxyXG5tb2RpZmllcnMucmVzdHJpY3RFZGdlcyA9IHJlc3RyaWN0RWRnZXM7XHJcbm1vZGlmaWVycy5uYW1lcy5wdXNoKCdyZXN0cmljdEVkZ2VzJyk7XHJcblxyXG5kZWZhdWx0T3B0aW9ucy5wZXJBY3Rpb24ucmVzdHJpY3RFZGdlcyA9IHJlc3RyaWN0RWRnZXMuZGVmYXVsdHM7XHJcbnJlc2l6ZS5kZWZhdWx0cy5yZXN0cmljdEVkZ2VzID0gcmVzdHJpY3RFZGdlcy5kZWZhdWx0cztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcmVzdHJpY3RFZGdlcztcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvcmVjdFwiOjUxLFwiLi9pbmRleFwiOjI0LFwiLi9yZXN0cmljdFwiOjI1fV0sMjc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG4vLyBUaGlzIG1vZHVsZSBhZGRzIHRoZSBvcHRpb25zLnJlc2l6ZS5yZXN0cmljdFNpemUgc2V0dGluZyB3aGljaCBzZXRzIG1pbiBhbmRcclxuLy8gbWF4IHdpZHRoIGFuZCBoZWlnaHQgZm9yIHRoZSB0YXJnZXQgYmVpbmcgcmVzaXplZC5cclxuLy9cclxuLy8gaW50ZXJhY3QodGFyZ2V0KS5yZXNpemUoe1xyXG4vLyAgIGVkZ2VzOiB7IHRvcDogdHJ1ZSwgbGVmdDogdHJ1ZSB9LFxyXG4vLyAgIHJlc3RyaWN0U2l6ZToge1xyXG4vLyAgICAgbWluOiB7IHdpZHRoOiAtNjAwLCBoZWlnaHQ6IC02MDAgfSxcclxuLy8gICAgIG1heDogeyB3aWR0aDogIDYwMCwgaGVpZ2h0OiAgNjAwIH0sXHJcbi8vICAgfSxcclxuLy8gfSk7XHJcblxyXG52YXIgbW9kaWZpZXJzID0gcmVxdWlyZSgnLi9pbmRleCcpO1xyXG52YXIgcmVzdHJpY3RFZGdlcyA9IHJlcXVpcmUoJy4vcmVzdHJpY3RFZGdlcycpO1xyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xyXG52YXIgcmVjdFV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvcmVjdCcpO1xyXG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xyXG52YXIgcmVzaXplID0gcmVxdWlyZSgnLi4vYWN0aW9ucy9yZXNpemUnKTtcclxuXHJcbnZhciBub01pbiA9IHsgd2lkdGg6IC1JbmZpbml0eSwgaGVpZ2h0OiAtSW5maW5pdHkgfTtcclxudmFyIG5vTWF4ID0geyB3aWR0aDogK0luZmluaXR5LCBoZWlnaHQ6ICtJbmZpbml0eSB9O1xyXG5cclxudmFyIHJlc3RyaWN0U2l6ZSA9IHtcclxuICBkZWZhdWx0czoge1xyXG4gICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICBlbmRPbmx5OiBmYWxzZSxcclxuICAgIG1pbjogbnVsbCxcclxuICAgIG1heDogbnVsbFxyXG4gIH0sXHJcblxyXG4gIHNldE9mZnNldDogZnVuY3Rpb24gc2V0T2Zmc2V0KF9yZWYpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb247XHJcblxyXG4gICAgcmV0dXJuIGludGVyYWN0aW9uLnN0YXJ0T2Zmc2V0O1xyXG4gIH0sXHJcblxyXG4gIHNldDogZnVuY3Rpb24gc2V0KGFyZykge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICAgIG9wdGlvbnMgPSBhcmcub3B0aW9ucztcclxuXHJcbiAgICB2YXIgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5saW5rZWRFZGdlcyB8fCBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcztcclxuXHJcbiAgICBpZiAoIWludGVyYWN0aW9uLmludGVyYWN0aW5nKCkgfHwgIWVkZ2VzKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcmVjdCA9IHJlY3RVdGlscy54eXdoVG9UbGJyKGludGVyYWN0aW9uLnJlc2l6ZVJlY3RzLmludmVydGVkKTtcclxuXHJcbiAgICB2YXIgbWluU2l6ZSA9IHJlY3RVdGlscy50bGJyVG9YeXdoKHJlc3RyaWN0RWRnZXMuZ2V0UmVzdHJpY3Rpb25SZWN0KG9wdGlvbnMubWluLCBpbnRlcmFjdGlvbikpIHx8IG5vTWluO1xyXG4gICAgdmFyIG1heFNpemUgPSByZWN0VXRpbHMudGxiclRvWHl3aChyZXN0cmljdEVkZ2VzLmdldFJlc3RyaWN0aW9uUmVjdChvcHRpb25zLm1heCwgaW50ZXJhY3Rpb24pKSB8fCBub01heDtcclxuXHJcbiAgICBhcmcub3B0aW9ucyA9IHtcclxuICAgICAgZW5hYmxlZDogb3B0aW9ucy5lbmFibGVkLFxyXG4gICAgICBlbmRPbmx5OiBvcHRpb25zLmVuZE9ubHksXHJcbiAgICAgIGlubmVyOiB1dGlscy5leHRlbmQoe30sIHJlc3RyaWN0RWRnZXMubm9Jbm5lciksXHJcbiAgICAgIG91dGVyOiB1dGlscy5leHRlbmQoe30sIHJlc3RyaWN0RWRnZXMubm9PdXRlcilcclxuICAgIH07XHJcblxyXG4gICAgaWYgKGVkZ2VzLnRvcCkge1xyXG4gICAgICBhcmcub3B0aW9ucy5pbm5lci50b3AgPSByZWN0LmJvdHRvbSAtIG1pblNpemUuaGVpZ2h0O1xyXG4gICAgICBhcmcub3B0aW9ucy5vdXRlci50b3AgPSByZWN0LmJvdHRvbSAtIG1heFNpemUuaGVpZ2h0O1xyXG4gICAgfSBlbHNlIGlmIChlZGdlcy5ib3R0b20pIHtcclxuICAgICAgYXJnLm9wdGlvbnMuaW5uZXIuYm90dG9tID0gcmVjdC50b3AgKyBtaW5TaXplLmhlaWdodDtcclxuICAgICAgYXJnLm9wdGlvbnMub3V0ZXIuYm90dG9tID0gcmVjdC50b3AgKyBtYXhTaXplLmhlaWdodDtcclxuICAgIH1cclxuICAgIGlmIChlZGdlcy5sZWZ0KSB7XHJcbiAgICAgIGFyZy5vcHRpb25zLmlubmVyLmxlZnQgPSByZWN0LnJpZ2h0IC0gbWluU2l6ZS53aWR0aDtcclxuICAgICAgYXJnLm9wdGlvbnMub3V0ZXIubGVmdCA9IHJlY3QucmlnaHQgLSBtYXhTaXplLndpZHRoO1xyXG4gICAgfSBlbHNlIGlmIChlZGdlcy5yaWdodCkge1xyXG4gICAgICBhcmcub3B0aW9ucy5pbm5lci5yaWdodCA9IHJlY3QubGVmdCArIG1pblNpemUud2lkdGg7XHJcbiAgICAgIGFyZy5vcHRpb25zLm91dGVyLnJpZ2h0ID0gcmVjdC5sZWZ0ICsgbWF4U2l6ZS53aWR0aDtcclxuICAgIH1cclxuXHJcbiAgICByZXN0cmljdEVkZ2VzLnNldChhcmcpO1xyXG4gIH0sXHJcblxyXG4gIG1vZGlmeUNvb3JkczogcmVzdHJpY3RFZGdlcy5tb2RpZnlDb29yZHNcclxufTtcclxuXHJcbm1vZGlmaWVycy5yZXN0cmljdFNpemUgPSByZXN0cmljdFNpemU7XHJcbm1vZGlmaWVycy5uYW1lcy5wdXNoKCdyZXN0cmljdFNpemUnKTtcclxuXHJcbmRlZmF1bHRPcHRpb25zLnBlckFjdGlvbi5yZXN0cmljdFNpemUgPSByZXN0cmljdFNpemUuZGVmYXVsdHM7XHJcbnJlc2l6ZS5kZWZhdWx0cy5yZXN0cmljdFNpemUgPSByZXN0cmljdFNpemUuZGVmYXVsdHM7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHJlc3RyaWN0U2l6ZTtcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvcmVjdFwiOjUxLFwiLi9pbmRleFwiOjI0LFwiLi9yZXN0cmljdEVkZ2VzXCI6MjZ9XSwyODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBtb2RpZmllcnMgPSByZXF1aXJlKCcuL2luZGV4Jyk7XHJcbnZhciBpbnRlcmFjdCA9IHJlcXVpcmUoJy4uL2ludGVyYWN0Jyk7XHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XHJcbnZhciBkZWZhdWx0T3B0aW9ucyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRPcHRpb25zJyk7XHJcblxyXG52YXIgc25hcCA9IHtcclxuICBkZWZhdWx0czoge1xyXG4gICAgZW5hYmxlZDogZmFsc2UsXHJcbiAgICBlbmRPbmx5OiBmYWxzZSxcclxuICAgIHJhbmdlOiBJbmZpbml0eSxcclxuICAgIHRhcmdldHM6IG51bGwsXHJcbiAgICBvZmZzZXRzOiBudWxsLFxyXG5cclxuICAgIHJlbGF0aXZlUG9pbnRzOiBudWxsXHJcbiAgfSxcclxuXHJcbiAgc2V0T2Zmc2V0OiBmdW5jdGlvbiBzZXRPZmZzZXQoX3JlZikge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gX3JlZi5pbnRlcmFjdGlvbixcclxuICAgICAgICBpbnRlcmFjdGFibGUgPSBfcmVmLmludGVyYWN0YWJsZSxcclxuICAgICAgICBlbGVtZW50ID0gX3JlZi5lbGVtZW50LFxyXG4gICAgICAgIHJlY3QgPSBfcmVmLnJlY3QsXHJcbiAgICAgICAgc3RhcnRPZmZzZXQgPSBfcmVmLnN0YXJ0T2Zmc2V0LFxyXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XHJcblxyXG4gICAgdmFyIG9mZnNldHMgPSBbXTtcclxuICAgIHZhciBvcHRpb25zT3JpZ2luID0gdXRpbHMucmVjdFRvWFkodXRpbHMucmVzb2x2ZVJlY3RMaWtlKG9wdGlvbnMub3JpZ2luKSk7XHJcbiAgICB2YXIgb3JpZ2luID0gb3B0aW9uc09yaWdpbiB8fCB1dGlscy5nZXRPcmlnaW5YWShpbnRlcmFjdGFibGUsIGVsZW1lbnQsIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUpO1xyXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwgaW50ZXJhY3RhYmxlLm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uc25hcCB8fCB7fTtcclxuXHJcbiAgICB2YXIgc25hcE9mZnNldCA9IHZvaWQgMDtcclxuXHJcbiAgICBpZiAob3B0aW9ucy5vZmZzZXQgPT09ICdzdGFydENvb3JkcycpIHtcclxuICAgICAgc25hcE9mZnNldCA9IHtcclxuICAgICAgICB4OiBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnggLSBvcmlnaW4ueCxcclxuICAgICAgICB5OiBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnkgLSBvcmlnaW4ueVxyXG4gICAgICB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdmFyIG9mZnNldFJlY3QgPSB1dGlscy5yZXNvbHZlUmVjdExpa2Uob3B0aW9ucy5vZmZzZXQsIGludGVyYWN0YWJsZSwgZWxlbWVudCwgW2ludGVyYWN0aW9uXSk7XHJcblxyXG4gICAgICBzbmFwT2Zmc2V0ID0gdXRpbHMucmVjdFRvWFkob2Zmc2V0UmVjdCkgfHwgeyB4OiAwLCB5OiAwIH07XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHJlY3QgJiYgb3B0aW9ucy5yZWxhdGl2ZVBvaW50cyAmJiBvcHRpb25zLnJlbGF0aXZlUG9pbnRzLmxlbmd0aCkge1xyXG4gICAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBvcHRpb25zLnJlbGF0aXZlUG9pbnRzLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICAgIHZhciBfcmVmMjtcclxuXHJcbiAgICAgICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgICBfcmVmMiA9IF9pdGVyYXRvcltfaSsrXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgX2kgPSBfaXRlcmF0b3IubmV4dCgpO1xyXG4gICAgICAgICAgaWYgKF9pLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgICAgX3JlZjIgPSBfaS52YWx1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBfcmVmMyA9IF9yZWYyLFxyXG4gICAgICAgICAgICByZWxhdGl2ZVggPSBfcmVmMy54LFxyXG4gICAgICAgICAgICByZWxhdGl2ZVkgPSBfcmVmMy55O1xyXG5cclxuICAgICAgICBvZmZzZXRzLnB1c2goe1xyXG4gICAgICAgICAgeDogc3RhcnRPZmZzZXQubGVmdCAtIHJlY3Qud2lkdGggKiByZWxhdGl2ZVggKyBzbmFwT2Zmc2V0LngsXHJcbiAgICAgICAgICB5OiBzdGFydE9mZnNldC50b3AgLSByZWN0LmhlaWdodCAqIHJlbGF0aXZlWSArIHNuYXBPZmZzZXQueVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBvZmZzZXRzLnB1c2goc25hcE9mZnNldCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG9mZnNldHM7XHJcbiAgfSxcclxuXHJcbiAgc2V0OiBmdW5jdGlvbiBzZXQoX3JlZjQpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY0LmludGVyYWN0aW9uLFxyXG4gICAgICAgIHBhZ2VDb29yZHMgPSBfcmVmNC5wYWdlQ29vcmRzLFxyXG4gICAgICAgIHN0YXR1cyA9IF9yZWY0LnN0YXR1cyxcclxuICAgICAgICBvcHRpb25zID0gX3JlZjQub3B0aW9ucyxcclxuICAgICAgICBvZmZzZXRzID0gX3JlZjQub2Zmc2V0O1xyXG5cclxuICAgIHZhciB0YXJnZXRzID0gW107XHJcbiAgICB2YXIgdGFyZ2V0ID0gdm9pZCAwO1xyXG4gICAgdmFyIHBhZ2UgPSB2b2lkIDA7XHJcbiAgICB2YXIgaSA9IHZvaWQgMDtcclxuXHJcbiAgICBpZiAoc3RhdHVzLnVzZVN0YXR1c1hZKSB7XHJcbiAgICAgIHBhZ2UgPSB7IHg6IHN0YXR1cy54LCB5OiBzdGF0dXMueSB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdmFyIG9yaWdpbiA9IHV0aWxzLmdldE9yaWdpblhZKGludGVyYWN0aW9uLnRhcmdldCwgaW50ZXJhY3Rpb24uZWxlbWVudCwgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSk7XHJcblxyXG4gICAgICBwYWdlID0gdXRpbHMuZXh0ZW5kKHt9LCBwYWdlQ29vcmRzKTtcclxuXHJcbiAgICAgIHBhZ2UueCAtPSBvcmlnaW4ueDtcclxuICAgICAgcGFnZS55IC09IG9yaWdpbi55O1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXR1cy5yZWFsWCA9IHBhZ2UueDtcclxuICAgIHN0YXR1cy5yZWFsWSA9IHBhZ2UueTtcclxuXHJcbiAgICB2YXIgbGVuID0gb3B0aW9ucy50YXJnZXRzID8gb3B0aW9ucy50YXJnZXRzLmxlbmd0aCA6IDA7XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IG9mZnNldHMsIF9pc0FycmF5MiA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yMiksIF9pMiA9IDAsIF9pdGVyYXRvcjIgPSBfaXNBcnJheTIgPyBfaXRlcmF0b3IyIDogX2l0ZXJhdG9yMltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICB2YXIgX3JlZjU7XHJcblxyXG4gICAgICBpZiAoX2lzQXJyYXkyKSB7XHJcbiAgICAgICAgaWYgKF9pMiA+PSBfaXRlcmF0b3IyLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjUgPSBfaXRlcmF0b3IyW19pMisrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaTIgPSBfaXRlcmF0b3IyLm5leHQoKTtcclxuICAgICAgICBpZiAoX2kyLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgIF9yZWY1ID0gX2kyLnZhbHVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgX3JlZjYgPSBfcmVmNSxcclxuICAgICAgICAgIG9mZnNldFggPSBfcmVmNi54LFxyXG4gICAgICAgICAgb2Zmc2V0WSA9IF9yZWY2Lnk7XHJcblxyXG4gICAgICB2YXIgcmVsYXRpdmVYID0gcGFnZS54IC0gb2Zmc2V0WDtcclxuICAgICAgdmFyIHJlbGF0aXZlWSA9IHBhZ2UueSAtIG9mZnNldFk7XHJcblxyXG4gICAgICBmb3IgKHZhciBfaXRlcmF0b3IzID0gb3B0aW9ucy50YXJnZXRzLCBfaXNBcnJheTMgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjMpLCBfaTMgPSAwLCBfaXRlcmF0b3IzID0gX2lzQXJyYXkzID8gX2l0ZXJhdG9yMyA6IF9pdGVyYXRvcjNbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgICB2YXIgX3JlZjc7XHJcblxyXG4gICAgICAgIGlmIChfaXNBcnJheTMpIHtcclxuICAgICAgICAgIGlmIChfaTMgPj0gX2l0ZXJhdG9yMy5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgICAgX3JlZjcgPSBfaXRlcmF0b3IzW19pMysrXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgX2kzID0gX2l0ZXJhdG9yMy5uZXh0KCk7XHJcbiAgICAgICAgICBpZiAoX2kzLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgICAgX3JlZjcgPSBfaTMudmFsdWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgc25hcFRhcmdldCA9IF9yZWY3O1xyXG5cclxuICAgICAgICBpZiAodXRpbHMuaXMuZnVuY3Rpb24oc25hcFRhcmdldCkpIHtcclxuICAgICAgICAgIHRhcmdldCA9IHNuYXBUYXJnZXQocmVsYXRpdmVYLCByZWxhdGl2ZVksIGludGVyYWN0aW9uKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGFyZ2V0ID0gc25hcFRhcmdldDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGFyZ2V0KSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRhcmdldHMucHVzaCh7XHJcbiAgICAgICAgICB4OiB1dGlscy5pcy5udW1iZXIodGFyZ2V0LngpID8gdGFyZ2V0LnggKyBvZmZzZXRYIDogcmVsYXRpdmVYLFxyXG4gICAgICAgICAgeTogdXRpbHMuaXMubnVtYmVyKHRhcmdldC55KSA/IHRhcmdldC55ICsgb2Zmc2V0WSA6IHJlbGF0aXZlWSxcclxuXHJcbiAgICAgICAgICByYW5nZTogdXRpbHMuaXMubnVtYmVyKHRhcmdldC5yYW5nZSkgPyB0YXJnZXQucmFuZ2UgOiBvcHRpb25zLnJhbmdlXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB2YXIgY2xvc2VzdCA9IHtcclxuICAgICAgdGFyZ2V0OiBudWxsLFxyXG4gICAgICBpblJhbmdlOiBmYWxzZSxcclxuICAgICAgZGlzdGFuY2U6IDAsXHJcbiAgICAgIHJhbmdlOiAwLFxyXG4gICAgICBkeDogMCxcclxuICAgICAgZHk6IDBcclxuICAgIH07XHJcblxyXG4gICAgZm9yIChpID0gMCwgbGVuID0gdGFyZ2V0cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICB0YXJnZXQgPSB0YXJnZXRzW2ldO1xyXG5cclxuICAgICAgdmFyIHJhbmdlID0gdGFyZ2V0LnJhbmdlO1xyXG4gICAgICB2YXIgZHggPSB0YXJnZXQueCAtIHBhZ2UueDtcclxuICAgICAgdmFyIGR5ID0gdGFyZ2V0LnkgLSBwYWdlLnk7XHJcbiAgICAgIHZhciBkaXN0YW5jZSA9IHV0aWxzLmh5cG90KGR4LCBkeSk7XHJcbiAgICAgIHZhciBpblJhbmdlID0gZGlzdGFuY2UgPD0gcmFuZ2U7XHJcblxyXG4gICAgICAvLyBJbmZpbml0ZSB0YXJnZXRzIGNvdW50IGFzIGJlaW5nIG91dCBvZiByYW5nZVxyXG4gICAgICAvLyBjb21wYXJlZCB0byBub24gaW5maW5pdGUgb25lcyB0aGF0IGFyZSBpbiByYW5nZVxyXG4gICAgICBpZiAocmFuZ2UgPT09IEluZmluaXR5ICYmIGNsb3Nlc3QuaW5SYW5nZSAmJiBjbG9zZXN0LnJhbmdlICE9PSBJbmZpbml0eSkge1xyXG4gICAgICAgIGluUmFuZ2UgPSBmYWxzZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFjbG9zZXN0LnRhcmdldCB8fCAoaW5SYW5nZVxyXG4gICAgICAvLyBpcyB0aGUgY2xvc2VzdCB0YXJnZXQgaW4gcmFuZ2U/XHJcbiAgICAgID8gY2xvc2VzdC5pblJhbmdlICYmIHJhbmdlICE9PSBJbmZpbml0eVxyXG4gICAgICAvLyB0aGUgcG9pbnRlciBpcyByZWxhdGl2ZWx5IGRlZXBlciBpbiB0aGlzIHRhcmdldFxyXG4gICAgICA/IGRpc3RhbmNlIC8gcmFuZ2UgPCBjbG9zZXN0LmRpc3RhbmNlIC8gY2xvc2VzdC5yYW5nZVxyXG4gICAgICAvLyB0aGlzIHRhcmdldCBoYXMgSW5maW5pdGUgcmFuZ2UgYW5kIHRoZSBjbG9zZXN0IGRvZXNuJ3RcclxuICAgICAgOiByYW5nZSA9PT0gSW5maW5pdHkgJiYgY2xvc2VzdC5yYW5nZSAhPT0gSW5maW5pdHkgfHxcclxuICAgICAgLy8gT1IgdGhpcyB0YXJnZXQgaXMgY2xvc2VyIHRoYXQgdGhlIHByZXZpb3VzIGNsb3Nlc3RcclxuICAgICAgZGlzdGFuY2UgPCBjbG9zZXN0LmRpc3RhbmNlIDpcclxuICAgICAgLy8gVGhlIG90aGVyIGlzIG5vdCBpbiByYW5nZSBhbmQgdGhlIHBvaW50ZXIgaXMgY2xvc2VyIHRvIHRoaXMgdGFyZ2V0XHJcbiAgICAgICFjbG9zZXN0LmluUmFuZ2UgJiYgZGlzdGFuY2UgPCBjbG9zZXN0LmRpc3RhbmNlKSkge1xyXG5cclxuICAgICAgICBjbG9zZXN0LnRhcmdldCA9IHRhcmdldDtcclxuICAgICAgICBjbG9zZXN0LmRpc3RhbmNlID0gZGlzdGFuY2U7XHJcbiAgICAgICAgY2xvc2VzdC5yYW5nZSA9IHJhbmdlO1xyXG4gICAgICAgIGNsb3Nlc3QuaW5SYW5nZSA9IGluUmFuZ2U7XHJcbiAgICAgICAgY2xvc2VzdC5keCA9IGR4O1xyXG4gICAgICAgIGNsb3Nlc3QuZHkgPSBkeTtcclxuXHJcbiAgICAgICAgc3RhdHVzLnJhbmdlID0gcmFuZ2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB2YXIgc25hcENoYW5nZWQgPSB2b2lkIDA7XHJcblxyXG4gICAgaWYgKGNsb3Nlc3QudGFyZ2V0KSB7XHJcbiAgICAgIHNuYXBDaGFuZ2VkID0gc3RhdHVzLm1vZGlmaWVkWCAhPT0gY2xvc2VzdC50YXJnZXQueCB8fCBzdGF0dXMubW9kaWZpZWRZICE9PSBjbG9zZXN0LnRhcmdldC55O1xyXG5cclxuICAgICAgc3RhdHVzLm1vZGlmaWVkWCA9IGNsb3Nlc3QudGFyZ2V0Lng7XHJcbiAgICAgIHN0YXR1cy5tb2RpZmllZFkgPSBjbG9zZXN0LnRhcmdldC55O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc25hcENoYW5nZWQgPSB0cnVlO1xyXG5cclxuICAgICAgc3RhdHVzLm1vZGlmaWVkWCA9IE5hTjtcclxuICAgICAgc3RhdHVzLm1vZGlmaWVkWSA9IE5hTjtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0dXMuZHggPSBjbG9zZXN0LmR4O1xyXG4gICAgc3RhdHVzLmR5ID0gY2xvc2VzdC5keTtcclxuXHJcbiAgICBzdGF0dXMuY2hhbmdlZCA9IHNuYXBDaGFuZ2VkIHx8IGNsb3Nlc3QuaW5SYW5nZSAmJiAhc3RhdHVzLmxvY2tlZDtcclxuICAgIHN0YXR1cy5sb2NrZWQgPSBjbG9zZXN0LmluUmFuZ2U7XHJcbiAgfSxcclxuXHJcbiAgbW9kaWZ5Q29vcmRzOiBmdW5jdGlvbiBtb2RpZnlDb29yZHMoX3JlZjgpIHtcclxuICAgIHZhciBwYWdlID0gX3JlZjgucGFnZSxcclxuICAgICAgICBjbGllbnQgPSBfcmVmOC5jbGllbnQsXHJcbiAgICAgICAgc3RhdHVzID0gX3JlZjguc3RhdHVzLFxyXG4gICAgICAgIHBoYXNlID0gX3JlZjgucGhhc2UsXHJcbiAgICAgICAgb3B0aW9ucyA9IF9yZWY4Lm9wdGlvbnM7XHJcblxyXG4gICAgdmFyIHJlbGF0aXZlUG9pbnRzID0gb3B0aW9ucyAmJiBvcHRpb25zLnJlbGF0aXZlUG9pbnRzO1xyXG5cclxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZW5hYmxlZCAmJiAhKHBoYXNlID09PSAnc3RhcnQnICYmIHJlbGF0aXZlUG9pbnRzICYmIHJlbGF0aXZlUG9pbnRzLmxlbmd0aCkpIHtcclxuXHJcbiAgICAgIGlmIChzdGF0dXMubG9ja2VkKSB7XHJcbiAgICAgICAgcGFnZS54ICs9IHN0YXR1cy5keDtcclxuICAgICAgICBwYWdlLnkgKz0gc3RhdHVzLmR5O1xyXG4gICAgICAgIGNsaWVudC54ICs9IHN0YXR1cy5keDtcclxuICAgICAgICBjbGllbnQueSArPSBzdGF0dXMuZHk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgcmFuZ2U6IHN0YXR1cy5yYW5nZSxcclxuICAgICAgICBsb2NrZWQ6IHN0YXR1cy5sb2NrZWQsXHJcbiAgICAgICAgeDogc3RhdHVzLm1vZGlmaWVkWCxcclxuICAgICAgICB5OiBzdGF0dXMubW9kaWZpZWRZLFxyXG4gICAgICAgIHJlYWxYOiBzdGF0dXMucmVhbFgsXHJcbiAgICAgICAgcmVhbFk6IHN0YXR1cy5yZWFsWSxcclxuICAgICAgICBkeDogc3RhdHVzLmR4LFxyXG4gICAgICAgIGR5OiBzdGF0dXMuZHlcclxuICAgICAgfTtcclxuICAgIH1cclxuICB9XHJcbn07XHJcblxyXG5pbnRlcmFjdC5jcmVhdGVTbmFwR3JpZCA9IGZ1bmN0aW9uIChncmlkKSB7XHJcbiAgcmV0dXJuIGZ1bmN0aW9uICh4LCB5KSB7XHJcbiAgICB2YXIgbGltaXRzID0gZ3JpZC5saW1pdHMgfHwge1xyXG4gICAgICBsZWZ0OiAtSW5maW5pdHksXHJcbiAgICAgIHJpZ2h0OiBJbmZpbml0eSxcclxuICAgICAgdG9wOiAtSW5maW5pdHksXHJcbiAgICAgIGJvdHRvbTogSW5maW5pdHlcclxuICAgIH07XHJcbiAgICB2YXIgb2Zmc2V0WCA9IDA7XHJcbiAgICB2YXIgb2Zmc2V0WSA9IDA7XHJcblxyXG4gICAgaWYgKHV0aWxzLmlzLm9iamVjdChncmlkLm9mZnNldCkpIHtcclxuICAgICAgb2Zmc2V0WCA9IGdyaWQub2Zmc2V0Lng7XHJcbiAgICAgIG9mZnNldFkgPSBncmlkLm9mZnNldC55O1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBncmlkeCA9IE1hdGgucm91bmQoKHggLSBvZmZzZXRYKSAvIGdyaWQueCk7XHJcbiAgICB2YXIgZ3JpZHkgPSBNYXRoLnJvdW5kKCh5IC0gb2Zmc2V0WSkgLyBncmlkLnkpO1xyXG5cclxuICAgIHZhciBuZXdYID0gTWF0aC5tYXgobGltaXRzLmxlZnQsIE1hdGgubWluKGxpbWl0cy5yaWdodCwgZ3JpZHggKiBncmlkLnggKyBvZmZzZXRYKSk7XHJcbiAgICB2YXIgbmV3WSA9IE1hdGgubWF4KGxpbWl0cy50b3AsIE1hdGgubWluKGxpbWl0cy5ib3R0b20sIGdyaWR5ICogZ3JpZC55ICsgb2Zmc2V0WSkpO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIHg6IG5ld1gsXHJcbiAgICAgIHk6IG5ld1ksXHJcbiAgICAgIHJhbmdlOiBncmlkLnJhbmdlXHJcbiAgICB9O1xyXG4gIH07XHJcbn07XHJcblxyXG5tb2RpZmllcnMuc25hcCA9IHNuYXA7XHJcbm1vZGlmaWVycy5uYW1lcy5wdXNoKCdzbmFwJyk7XHJcblxyXG5kZWZhdWx0T3B0aW9ucy5wZXJBY3Rpb24uc25hcCA9IHNuYXAuZGVmYXVsdHM7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNuYXA7XHJcblxyXG59LHtcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi9pbnRlcmFjdFwiOjIxLFwiLi4vdXRpbHNcIjo0NCxcIi4vaW5kZXhcIjoyNH1dLDI5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuLy8gVGhpcyBtb2R1bGUgYWxsb3dzIHNuYXBwaW5nIG9mIHRoZSBzaXplIG9mIHRhcmdldHMgZHVyaW5nIHJlc2l6ZVxyXG4vLyBpbnRlcmFjdGlvbnMuXHJcblxyXG52YXIgbW9kaWZpZXJzID0gcmVxdWlyZSgnLi9pbmRleCcpO1xyXG52YXIgc25hcCA9IHJlcXVpcmUoJy4vc25hcCcpO1xyXG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xyXG52YXIgcmVzaXplID0gcmVxdWlyZSgnLi4vYWN0aW9ucy9yZXNpemUnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvJyk7XHJcblxyXG52YXIgc25hcFNpemUgPSB7XHJcbiAgZGVmYXVsdHM6IHtcclxuICAgIGVuYWJsZWQ6IGZhbHNlLFxyXG4gICAgZW5kT25seTogZmFsc2UsXHJcbiAgICByYW5nZTogSW5maW5pdHksXHJcbiAgICB0YXJnZXRzOiBudWxsLFxyXG4gICAgb2Zmc2V0czogbnVsbFxyXG4gIH0sXHJcblxyXG4gIHNldE9mZnNldDogZnVuY3Rpb24gc2V0T2Zmc2V0KGFyZykge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICAgIG9wdGlvbnMgPSBhcmcub3B0aW9ucztcclxuXHJcbiAgICB2YXIgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcztcclxuXHJcbiAgICBpZiAoIWVkZ2VzKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBhcmcub3B0aW9ucyA9IHtcclxuICAgICAgcmVsYXRpdmVQb2ludHM6IFt7XHJcbiAgICAgICAgeDogZWRnZXMubGVmdCA/IDAgOiAxLFxyXG4gICAgICAgIHk6IGVkZ2VzLnRvcCA/IDAgOiAxXHJcbiAgICAgIH1dLFxyXG4gICAgICBvcmlnaW46IHsgeDogMCwgeTogMCB9LFxyXG4gICAgICBvZmZzZXQ6ICdzZWxmJyxcclxuICAgICAgcmFuZ2U6IG9wdGlvbnMucmFuZ2VcclxuICAgIH07XHJcblxyXG4gICAgdmFyIG9mZnNldHMgPSBzbmFwLnNldE9mZnNldChhcmcpO1xyXG4gICAgYXJnLm9wdGlvbnMgPSBvcHRpb25zO1xyXG5cclxuICAgIHJldHVybiBvZmZzZXRzO1xyXG4gIH0sXHJcblxyXG4gIHNldDogZnVuY3Rpb24gc2V0KGFyZykge1xyXG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxyXG4gICAgICAgIG9wdGlvbnMgPSBhcmcub3B0aW9ucyxcclxuICAgICAgICBvZmZzZXQgPSBhcmcub2Zmc2V0LFxyXG4gICAgICAgIHBhZ2VDb29yZHMgPSBhcmcucGFnZUNvb3JkcztcclxuXHJcbiAgICB2YXIgcGFnZSA9IHV0aWxzLmV4dGVuZCh7fSwgcGFnZUNvb3Jkcyk7XHJcbiAgICB2YXIgcmVsYXRpdmVYID0gcGFnZS54IC0gb2Zmc2V0WzBdLng7XHJcbiAgICB2YXIgcmVsYXRpdmVZID0gcGFnZS55IC0gb2Zmc2V0WzBdLnk7XHJcblxyXG4gICAgYXJnLm9wdGlvbnMgPSB1dGlscy5leHRlbmQoe30sIG9wdGlvbnMpO1xyXG4gICAgYXJnLm9wdGlvbnMudGFyZ2V0cyA9IFtdO1xyXG5cclxuICAgIGZvciAodmFyIF9pdGVyYXRvciA9IG9wdGlvbnMudGFyZ2V0cywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWY7XHJcblxyXG4gICAgICBpZiAoX2lzQXJyYXkpIHtcclxuICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XHJcbiAgICAgICAgX3JlZiA9IF9pdGVyYXRvcltfaSsrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pLmRvbmUpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYgPSBfaS52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHNuYXBUYXJnZXQgPSBfcmVmO1xyXG5cclxuICAgICAgdmFyIHRhcmdldCA9IHZvaWQgMDtcclxuXHJcbiAgICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihzbmFwVGFyZ2V0KSkge1xyXG4gICAgICAgIHRhcmdldCA9IHNuYXBUYXJnZXQocmVsYXRpdmVYLCByZWxhdGl2ZVksIGludGVyYWN0aW9uKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0YXJnZXQgPSBzbmFwVGFyZ2V0O1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoIXRhcmdldCkge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoJ3dpZHRoJyBpbiB0YXJnZXQgJiYgJ2hlaWdodCcgaW4gdGFyZ2V0KSB7XHJcbiAgICAgICAgdGFyZ2V0LnggPSB0YXJnZXQud2lkdGg7XHJcbiAgICAgICAgdGFyZ2V0LnkgPSB0YXJnZXQuaGVpZ2h0O1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhcmcub3B0aW9ucy50YXJnZXRzLnB1c2godGFyZ2V0KTtcclxuICAgIH1cclxuXHJcbiAgICBzbmFwLnNldChhcmcpO1xyXG4gIH0sXHJcblxyXG4gIG1vZGlmeUNvb3JkczogZnVuY3Rpb24gbW9kaWZ5Q29vcmRzKGFyZykge1xyXG4gICAgdmFyIG9wdGlvbnMgPSBhcmcub3B0aW9ucztcclxuXHJcblxyXG4gICAgYXJnLm9wdGlvbnMgPSB1dGlscy5leHRlbmQoe30sIG9wdGlvbnMpO1xyXG4gICAgYXJnLm9wdGlvbnMuZW5hYmxlZCA9IG9wdGlvbnMuZW5hYmxlZDtcclxuICAgIGFyZy5vcHRpb25zLnJlbGF0aXZlUG9pbnRzID0gW251bGxdO1xyXG5cclxuICAgIHNuYXAubW9kaWZ5Q29vcmRzKGFyZyk7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kaWZpZXJzLnNuYXBTaXplID0gc25hcFNpemU7XHJcbm1vZGlmaWVycy5uYW1lcy5wdXNoKCdzbmFwU2l6ZScpO1xyXG5cclxuZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uLnNuYXBTaXplID0gc25hcFNpemUuZGVmYXVsdHM7XHJcbnJlc2l6ZS5kZWZhdWx0cy5zbmFwU2l6ZSA9IHNuYXBTaXplLmRlZmF1bHRzO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzbmFwU2l6ZTtcclxuXHJcbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlscy9cIjo0NCxcIi4vaW5kZXhcIjoyNCxcIi4vc25hcFwiOjI4fV0sMzA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxyXG5cclxudmFyIHBvaW50ZXJVdGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzL3BvaW50ZXJVdGlscycpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgZnVuY3Rpb24gUG9pbnRlckV2ZW50KHR5cGUsIHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgaW50ZXJhY3Rpb24pIHtcclxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQb2ludGVyRXZlbnQpO1xyXG5cclxuICAgIHBvaW50ZXJVdGlscy5wb2ludGVyRXh0ZW5kKHRoaXMsIGV2ZW50KTtcclxuXHJcbiAgICBpZiAoZXZlbnQgIT09IHBvaW50ZXIpIHtcclxuICAgICAgcG9pbnRlclV0aWxzLnBvaW50ZXJFeHRlbmQodGhpcywgcG9pbnRlcik7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5pbnRlcmFjdGlvbiA9IGludGVyYWN0aW9uO1xyXG5cclxuICAgIHRoaXMudGltZVN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICB0aGlzLm9yaWdpbmFsRXZlbnQgPSBldmVudDtcclxuICAgIHRoaXMudHlwZSA9IHR5cGU7XHJcbiAgICB0aGlzLnBvaW50ZXJJZCA9IHBvaW50ZXJVdGlscy5nZXRQb2ludGVySWQocG9pbnRlcik7XHJcbiAgICB0aGlzLnBvaW50ZXJUeXBlID0gcG9pbnRlclV0aWxzLmdldFBvaW50ZXJUeXBlKHBvaW50ZXIpO1xyXG4gICAgdGhpcy50YXJnZXQgPSBldmVudFRhcmdldDtcclxuICAgIHRoaXMuY3VycmVudFRhcmdldCA9IG51bGw7XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICd0YXAnKSB7XHJcbiAgICAgIHZhciBwb2ludGVySW5kZXggPSBpbnRlcmFjdGlvbi5nZXRQb2ludGVySW5kZXgocG9pbnRlcik7XHJcbiAgICAgIHRoaXMuZHQgPSB0aGlzLnRpbWVTdGFtcCAtIGludGVyYWN0aW9uLmRvd25UaW1lc1twb2ludGVySW5kZXhdO1xyXG5cclxuICAgICAgdmFyIGludGVydmFsID0gdGhpcy50aW1lU3RhbXAgLSBpbnRlcmFjdGlvbi50YXBUaW1lO1xyXG5cclxuICAgICAgdGhpcy5kb3VibGUgPSAhIShpbnRlcmFjdGlvbi5wcmV2VGFwICYmIGludGVyYWN0aW9uLnByZXZUYXAudHlwZSAhPT0gJ2RvdWJsZXRhcCcgJiYgaW50ZXJhY3Rpb24ucHJldlRhcC50YXJnZXQgPT09IHRoaXMudGFyZ2V0ICYmIGludGVydmFsIDwgNTAwKTtcclxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2RvdWJsZXRhcCcpIHtcclxuICAgICAgdGhpcy5kdCA9IHBvaW50ZXIudGltZVN0YW1wIC0gaW50ZXJhY3Rpb24udGFwVGltZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIFBvaW50ZXJFdmVudC5wcm90b3R5cGUuc3VidHJhY3RPcmlnaW4gPSBmdW5jdGlvbiBzdWJ0cmFjdE9yaWdpbihfcmVmKSB7XHJcbiAgICB2YXIgb3JpZ2luWCA9IF9yZWYueCxcclxuICAgICAgICBvcmlnaW5ZID0gX3JlZi55O1xyXG5cclxuICAgIHRoaXMucGFnZVggLT0gb3JpZ2luWDtcclxuICAgIHRoaXMucGFnZVkgLT0gb3JpZ2luWTtcclxuICAgIHRoaXMuY2xpZW50WCAtPSBvcmlnaW5YO1xyXG4gICAgdGhpcy5jbGllbnRZIC09IG9yaWdpblk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfTtcclxuXHJcbiAgUG9pbnRlckV2ZW50LnByb3RvdHlwZS5hZGRPcmlnaW4gPSBmdW5jdGlvbiBhZGRPcmlnaW4oX3JlZjIpIHtcclxuICAgIHZhciBvcmlnaW5YID0gX3JlZjIueCxcclxuICAgICAgICBvcmlnaW5ZID0gX3JlZjIueTtcclxuXHJcbiAgICB0aGlzLnBhZ2VYICs9IG9yaWdpblg7XHJcbiAgICB0aGlzLnBhZ2VZICs9IG9yaWdpblk7XHJcbiAgICB0aGlzLmNsaWVudFggKz0gb3JpZ2luWDtcclxuICAgIHRoaXMuY2xpZW50WSArPSBvcmlnaW5ZO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIFBvaW50ZXJFdmVudC5wcm90b3R5cGUucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbiBwcmV2ZW50RGVmYXVsdCgpIHtcclxuICAgIHRoaXMub3JpZ2luYWxFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIH07XHJcblxyXG4gIFBvaW50ZXJFdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKCkge1xyXG4gICAgdGhpcy5wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xyXG4gIH07XHJcblxyXG4gIFBvaW50ZXJFdmVudC5wcm90b3R5cGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkge1xyXG4gICAgdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIFBvaW50ZXJFdmVudDtcclxufSgpO1xyXG5cclxufSx7XCIuLi91dGlscy9wb2ludGVyVXRpbHNcIjo0OX1dLDMxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIFBvaW50ZXJFdmVudCA9IHJlcXVpcmUoJy4vUG9pbnRlckV2ZW50Jyk7XHJcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi4vdXRpbHMvYnJvd3NlcicpO1xyXG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xyXG52YXIgc2lnbmFscyA9IHJlcXVpcmUoJy4uL3V0aWxzL1NpZ25hbHMnKS5uZXcoKTtcclxuXHJcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4uL3V0aWxzL2FycicpLFxyXG4gICAgZmlsdGVyID0gX3JlcXVpcmUuZmlsdGVyO1xyXG5cclxudmFyIHNpbXBsZVNpZ25hbHMgPSBbJ2Rvd24nLCAndXAnLCAnY2FuY2VsJ107XHJcbnZhciBzaW1wbGVFdmVudHMgPSBbJ2Rvd24nLCAndXAnLCAnY2FuY2VsJ107XHJcblxyXG52YXIgcG9pbnRlckV2ZW50cyA9IHtcclxuICBQb2ludGVyRXZlbnQ6IFBvaW50ZXJFdmVudCxcclxuICBmaXJlOiBmaXJlLFxyXG4gIGNvbGxlY3RFdmVudFRhcmdldHM6IGNvbGxlY3RFdmVudFRhcmdldHMsXHJcbiAgc2lnbmFsczogc2lnbmFscyxcclxuICBkZWZhdWx0czoge1xyXG4gICAgaG9sZER1cmF0aW9uOiA2MDAsXHJcbiAgICBpZ25vcmVGcm9tOiBudWxsLFxyXG4gICAgYWxsb3dGcm9tOiBudWxsLFxyXG4gICAgb3JpZ2luOiB7IHg6IDAsIHk6IDAgfVxyXG4gIH0sXHJcbiAgdHlwZXM6IFsnZG93bicsICdtb3ZlJywgJ3VwJywgJ2NhbmNlbCcsICd0YXAnLCAnZG91YmxldGFwJywgJ2hvbGQnXVxyXG59O1xyXG5cclxuZnVuY3Rpb24gZmlyZShhcmcpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBhcmcuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXIgPSBhcmcucG9pbnRlcixcclxuICAgICAgZXZlbnQgPSBhcmcuZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gYXJnLmV2ZW50VGFyZ2V0LFxyXG4gICAgICBfYXJnJHR5cGUgPSBhcmcudHlwZSxcclxuICAgICAgdHlwZSA9IF9hcmckdHlwZSA9PT0gdW5kZWZpbmVkID8gYXJnLnBvaW50ZXJFdmVudC50eXBlIDogX2FyZyR0eXBlLFxyXG4gICAgICBfYXJnJHRhcmdldHMgPSBhcmcudGFyZ2V0cyxcclxuICAgICAgdGFyZ2V0cyA9IF9hcmckdGFyZ2V0cyA9PT0gdW5kZWZpbmVkID8gY29sbGVjdEV2ZW50VGFyZ2V0cyhhcmcpIDogX2FyZyR0YXJnZXRzLFxyXG4gICAgICBfYXJnJHBvaW50ZXJFdmVudCA9IGFyZy5wb2ludGVyRXZlbnQsXHJcbiAgICAgIHBvaW50ZXJFdmVudCA9IF9hcmckcG9pbnRlckV2ZW50ID09PSB1bmRlZmluZWQgPyBuZXcgUG9pbnRlckV2ZW50KHR5cGUsIHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgaW50ZXJhY3Rpb24pIDogX2FyZyRwb2ludGVyRXZlbnQ7XHJcblxyXG5cclxuICB2YXIgc2lnbmFsQXJnID0ge1xyXG4gICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgcG9pbnRlcjogcG9pbnRlcixcclxuICAgIGV2ZW50OiBldmVudCxcclxuICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcclxuICAgIHRhcmdldHM6IHRhcmdldHMsXHJcbiAgICB0eXBlOiB0eXBlLFxyXG4gICAgcG9pbnRlckV2ZW50OiBwb2ludGVyRXZlbnRcclxuICB9O1xyXG5cclxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRhcmdldHMubGVuZ3RoOyBpKyspIHtcclxuICAgIHZhciB0YXJnZXQgPSB0YXJnZXRzW2ldO1xyXG5cclxuICAgIGZvciAodmFyIHByb3AgaW4gdGFyZ2V0LnByb3BzIHx8IHt9KSB7XHJcbiAgICAgIHBvaW50ZXJFdmVudFtwcm9wXSA9IHRhcmdldC5wcm9wc1twcm9wXTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgb3JpZ2luID0gdXRpbHMuZ2V0T3JpZ2luWFkodGFyZ2V0LmV2ZW50YWJsZSwgdGFyZ2V0LmVsZW1lbnQpO1xyXG5cclxuICAgIHBvaW50ZXJFdmVudC5zdWJ0cmFjdE9yaWdpbihvcmlnaW4pO1xyXG4gICAgcG9pbnRlckV2ZW50LmV2ZW50YWJsZSA9IHRhcmdldC5ldmVudGFibGU7XHJcbiAgICBwb2ludGVyRXZlbnQuY3VycmVudFRhcmdldCA9IHRhcmdldC5lbGVtZW50O1xyXG5cclxuICAgIHRhcmdldC5ldmVudGFibGUuZmlyZShwb2ludGVyRXZlbnQpO1xyXG5cclxuICAgIHBvaW50ZXJFdmVudC5hZGRPcmlnaW4ob3JpZ2luKTtcclxuXHJcbiAgICBpZiAocG9pbnRlckV2ZW50LmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCB8fCBwb2ludGVyRXZlbnQucHJvcGFnYXRpb25TdG9wcGVkICYmIGkgKyAxIDwgdGFyZ2V0cy5sZW5ndGggJiYgdGFyZ2V0c1tpICsgMV0uZWxlbWVudCAhPT0gcG9pbnRlckV2ZW50LmN1cnJlbnRUYXJnZXQpIHtcclxuICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzaWduYWxzLmZpcmUoJ2ZpcmVkJywgc2lnbmFsQXJnKTtcclxuXHJcbiAgaWYgKHR5cGUgPT09ICd0YXAnKSB7XHJcbiAgICAvLyBpZiBwb2ludGVyRXZlbnQgc2hvdWxkIG1ha2UgYSBkb3VibGUgdGFwLCBjcmVhdGUgYW5kIGZpcmUgYSBkb3VibGV0YXBcclxuICAgIC8vIFBvaW50ZXJFdmVudCBhbmQgdXNlIHRoYXQgYXMgdGhlIHByZXZUYXBcclxuICAgIHZhciBwcmV2VGFwID0gcG9pbnRlckV2ZW50LmRvdWJsZSA/IGZpcmUoe1xyXG4gICAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sIHBvaW50ZXI6IHBvaW50ZXIsIGV2ZW50OiBldmVudCwgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxyXG4gICAgICB0eXBlOiAnZG91YmxldGFwJ1xyXG4gICAgfSkgOiBwb2ludGVyRXZlbnQ7XHJcblxyXG4gICAgaW50ZXJhY3Rpb24ucHJldlRhcCA9IHByZXZUYXA7XHJcbiAgICBpbnRlcmFjdGlvbi50YXBUaW1lID0gcHJldlRhcC50aW1lU3RhbXA7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcG9pbnRlckV2ZW50O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb2xsZWN0RXZlbnRUYXJnZXRzKF9yZWYpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxyXG4gICAgICBwb2ludGVyID0gX3JlZi5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQsXHJcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZi5ldmVudFRhcmdldCxcclxuICAgICAgdHlwZSA9IF9yZWYudHlwZTtcclxuXHJcbiAgdmFyIHBvaW50ZXJJbmRleCA9IGludGVyYWN0aW9uLmdldFBvaW50ZXJJbmRleChwb2ludGVyKTtcclxuXHJcbiAgLy8gZG8gbm90IGZpcmUgYSB0YXAgZXZlbnQgaWYgdGhlIHBvaW50ZXIgd2FzIG1vdmVkIGJlZm9yZSBiZWluZyBsaWZ0ZWRcclxuICBpZiAodHlwZSA9PT0gJ3RhcCcgJiYgKGludGVyYWN0aW9uLnBvaW50ZXJXYXNNb3ZlZFxyXG4gIC8vIG9yIGlmIHRoZSBwb2ludGVydXAgdGFyZ2V0IGlzIGRpZmZlcmVudCB0byB0aGUgcG9pbnRlcmRvd24gdGFyZ2V0XHJcbiAgfHwgIShpbnRlcmFjdGlvbi5kb3duVGFyZ2V0c1twb2ludGVySW5kZXhdICYmIGludGVyYWN0aW9uLmRvd25UYXJnZXRzW3BvaW50ZXJJbmRleF0gPT09IGV2ZW50VGFyZ2V0KSkpIHtcclxuICAgIHJldHVybiBbXTtcclxuICB9XHJcblxyXG4gIHZhciBwYXRoID0gdXRpbHMuZ2V0UGF0aChldmVudFRhcmdldCk7XHJcbiAgdmFyIHNpZ25hbEFyZyA9IHtcclxuICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcclxuICAgIHBvaW50ZXI6IHBvaW50ZXIsXHJcbiAgICBldmVudDogZXZlbnQsXHJcbiAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXHJcbiAgICB0eXBlOiB0eXBlLFxyXG4gICAgcGF0aDogcGF0aCxcclxuICAgIHRhcmdldHM6IFtdLFxyXG4gICAgZWxlbWVudDogbnVsbFxyXG4gIH07XHJcblxyXG4gIGZvciAodmFyIF9pdGVyYXRvciA9IHBhdGgsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICB2YXIgX3JlZjI7XHJcblxyXG4gICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgX3JlZjIgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgX3JlZjIgPSBfaS52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZWxlbWVudCA9IF9yZWYyO1xyXG5cclxuICAgIHNpZ25hbEFyZy5lbGVtZW50ID0gZWxlbWVudDtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ2NvbGxlY3QtdGFyZ2V0cycsIHNpZ25hbEFyZyk7XHJcbiAgfVxyXG5cclxuICBpZiAodHlwZSA9PT0gJ2hvbGQnKSB7XHJcbiAgICBzaWduYWxBcmcudGFyZ2V0cyA9IGZpbHRlcihzaWduYWxBcmcudGFyZ2V0cywgZnVuY3Rpb24gKHRhcmdldCkge1xyXG4gICAgICByZXR1cm4gdGFyZ2V0LmV2ZW50YWJsZS5vcHRpb25zLmhvbGREdXJhdGlvbiA9PT0gaW50ZXJhY3Rpb24uaG9sZFRpbWVyc1twb2ludGVySW5kZXhdLmR1cmF0aW9uO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gc2lnbmFsQXJnLnRhcmdldHM7XHJcbn1cclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3VwZGF0ZS1wb2ludGVyLWRvd24nLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbixcclxuICAgICAgcG9pbnRlckluZGV4ID0gX3JlZjMucG9pbnRlckluZGV4O1xyXG5cclxuICBpbnRlcmFjdGlvbi5ob2xkVGltZXJzW3BvaW50ZXJJbmRleF0gPSB7IGR1cmF0aW9uOiBJbmZpbml0eSwgdGltZW91dDogbnVsbCB9O1xyXG59KTtcclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3JlbW92ZS1wb2ludGVyJywgZnVuY3Rpb24gKF9yZWY0KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjQuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXJJbmRleCA9IF9yZWY0LnBvaW50ZXJJbmRleDtcclxuXHJcbiAgaW50ZXJhY3Rpb24uaG9sZFRpbWVycy5zcGxpY2UocG9pbnRlckluZGV4LCAxKTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdtb3ZlJywgZnVuY3Rpb24gKF9yZWY1KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjUuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXIgPSBfcmVmNS5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWY1LmV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWY1LmV2ZW50VGFyZ2V0LFxyXG4gICAgICBkdXBsaWNhdGVNb3ZlID0gX3JlZjUuZHVwbGljYXRlTW92ZTtcclxuXHJcbiAgdmFyIHBvaW50ZXJJbmRleCA9IGludGVyYWN0aW9uLmdldFBvaW50ZXJJbmRleChwb2ludGVyKTtcclxuXHJcbiAgaWYgKCFkdXBsaWNhdGVNb3ZlICYmICghaW50ZXJhY3Rpb24ucG9pbnRlcklzRG93biB8fCBpbnRlcmFjdGlvbi5wb2ludGVyV2FzTW92ZWQpKSB7XHJcbiAgICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlcklzRG93bikge1xyXG4gICAgICBjbGVhclRpbWVvdXQoaW50ZXJhY3Rpb24uaG9sZFRpbWVyc1twb2ludGVySW5kZXhdLnRpbWVvdXQpO1xyXG4gICAgfVxyXG5cclxuICAgIGZpcmUoe1xyXG4gICAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sIHBvaW50ZXI6IHBvaW50ZXIsIGV2ZW50OiBldmVudCwgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxyXG4gICAgICB0eXBlOiAnbW92ZSdcclxuICAgIH0pO1xyXG4gIH1cclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdkb3duJywgZnVuY3Rpb24gKF9yZWY2KSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjYuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXIgPSBfcmVmNi5wb2ludGVyLFxyXG4gICAgICBldmVudCA9IF9yZWY2LmV2ZW50LFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWY2LmV2ZW50VGFyZ2V0LFxyXG4gICAgICBwb2ludGVySW5kZXggPSBfcmVmNi5wb2ludGVySW5kZXg7XHJcblxyXG4gIC8vIGNvcHkgZXZlbnQgdG8gYmUgdXNlZCBpbiB0aW1lb3V0IGZvciBJRThcclxuICB2YXIgZXZlbnRDb3B5ID0gYnJvd3Nlci5pc0lFOCA/IHV0aWxzLmV4dGVuZCh7fSwgZXZlbnQpIDogZXZlbnQ7XHJcblxyXG4gIHZhciB0aW1lciA9IGludGVyYWN0aW9uLmhvbGRUaW1lcnNbcG9pbnRlckluZGV4XTtcclxuICB2YXIgcGF0aCA9IHV0aWxzLmdldFBhdGgoZXZlbnRUYXJnZXQpO1xyXG4gIHZhciBzaWduYWxBcmcgPSB7XHJcbiAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXHJcbiAgICBwb2ludGVyOiBwb2ludGVyLFxyXG4gICAgZXZlbnQ6IGV2ZW50LFxyXG4gICAgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxyXG4gICAgdHlwZTogJ2hvbGQnLFxyXG4gICAgdGFyZ2V0czogW10sXHJcbiAgICBwYXRoOiBwYXRoLFxyXG4gICAgZWxlbWVudDogbnVsbFxyXG4gIH07XHJcblxyXG4gIGZvciAodmFyIF9pdGVyYXRvcjIgPSBwYXRoLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgIHZhciBfcmVmNztcclxuXHJcbiAgICBpZiAoX2lzQXJyYXkyKSB7XHJcbiAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yMi5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICBfcmVmNyA9IF9pdGVyYXRvcjJbX2kyKytdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgX2kyID0gX2l0ZXJhdG9yMi5uZXh0KCk7XHJcbiAgICAgIGlmIChfaTIuZG9uZSkgYnJlYWs7XHJcbiAgICAgIF9yZWY3ID0gX2kyLnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBlbGVtZW50ID0gX3JlZjc7XHJcblxyXG4gICAgc2lnbmFsQXJnLmVsZW1lbnQgPSBlbGVtZW50O1xyXG5cclxuICAgIHNpZ25hbHMuZmlyZSgnY29sbGVjdC10YXJnZXRzJywgc2lnbmFsQXJnKTtcclxuICB9XHJcblxyXG4gIGlmICghc2lnbmFsQXJnLnRhcmdldHMubGVuZ3RoKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgbWluRHVyYXRpb24gPSBJbmZpbml0eTtcclxuXHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWduYWxBcmcudGFyZ2V0cy5sZW5ndGg7IGkrKykge1xyXG4gICAgdmFyIHRhcmdldCA9IHNpZ25hbEFyZy50YXJnZXRzW2ldO1xyXG4gICAgdmFyIGhvbGREdXJhdGlvbiA9IHRhcmdldC5ldmVudGFibGUub3B0aW9ucy5ob2xkRHVyYXRpb247XHJcblxyXG4gICAgaWYgKGhvbGREdXJhdGlvbiA8IG1pbkR1cmF0aW9uKSB7XHJcbiAgICAgIG1pbkR1cmF0aW9uID0gaG9sZER1cmF0aW9uO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdGltZXIuZHVyYXRpb24gPSBtaW5EdXJhdGlvbjtcclxuICB0aW1lci50aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICBmaXJlKHtcclxuICAgICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXHJcbiAgICAgIHBvaW50ZXI6IGJyb3dzZXIuaXNJRTggPyBldmVudENvcHkgOiBwb2ludGVyLFxyXG4gICAgICBldmVudDogZXZlbnRDb3B5LFxyXG4gICAgICB0eXBlOiAnaG9sZCdcclxuICAgIH0pO1xyXG4gIH0sIG1pbkR1cmF0aW9uKTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCd1cCcsIGZ1bmN0aW9uIChfcmVmOCkge1xyXG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY4LmludGVyYWN0aW9uLFxyXG4gICAgICBwb2ludGVyID0gX3JlZjgucG9pbnRlcixcclxuICAgICAgZXZlbnQgPSBfcmVmOC5ldmVudCxcclxuICAgICAgZXZlbnRUYXJnZXQgPSBfcmVmOC5ldmVudFRhcmdldDtcclxuXHJcbiAgaWYgKCFpbnRlcmFjdGlvbi5wb2ludGVyV2FzTW92ZWQpIHtcclxuICAgIGZpcmUoeyBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCwgcG9pbnRlcjogcG9pbnRlciwgZXZlbnQ6IGV2ZW50LCB0eXBlOiAndGFwJyB9KTtcclxuICB9XHJcbn0pO1xyXG5cclxuWyd1cCcsICdjYW5jZWwnXS5mb3JFYWNoKGZ1bmN0aW9uIChzaWduYWxOYW1lKSB7XHJcbiAgSW50ZXJhY3Rpb24uc2lnbmFscy5vbihzaWduYWxOYW1lLCBmdW5jdGlvbiAoX3JlZjkpIHtcclxuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY5LmludGVyYWN0aW9uLFxyXG4gICAgICAgIHBvaW50ZXJJbmRleCA9IF9yZWY5LnBvaW50ZXJJbmRleDtcclxuXHJcbiAgICBpZiAoaW50ZXJhY3Rpb24uaG9sZFRpbWVyc1twb2ludGVySW5kZXhdKSB7XHJcbiAgICAgIGNsZWFyVGltZW91dChpbnRlcmFjdGlvbi5ob2xkVGltZXJzW3BvaW50ZXJJbmRleF0udGltZW91dCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbn0pO1xyXG5cclxuZnVuY3Rpb24gY3JlYXRlU2lnbmFsTGlzdGVuZXIodHlwZSkge1xyXG4gIHJldHVybiBmdW5jdGlvbiAoX3JlZjEwKSB7XHJcbiAgICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMTAuaW50ZXJhY3Rpb24sXHJcbiAgICAgICAgcG9pbnRlciA9IF9yZWYxMC5wb2ludGVyLFxyXG4gICAgICAgIGV2ZW50ID0gX3JlZjEwLmV2ZW50LFxyXG4gICAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZjEwLmV2ZW50VGFyZ2V0O1xyXG5cclxuICAgIGZpcmUoeyBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCwgcG9pbnRlcjogcG9pbnRlciwgZXZlbnQ6IGV2ZW50LCB0eXBlOiB0eXBlIH0pO1xyXG4gIH07XHJcbn1cclxuXHJcbmZvciAodmFyIGkgPSAwOyBpIDwgc2ltcGxlU2lnbmFscy5sZW5ndGg7IGkrKykge1xyXG4gIEludGVyYWN0aW9uLnNpZ25hbHMub24oc2ltcGxlU2lnbmFsc1tpXSwgY3JlYXRlU2lnbmFsTGlzdGVuZXIoc2ltcGxlRXZlbnRzW2ldKSk7XHJcbn1cclxuXHJcbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xyXG4gIGludGVyYWN0aW9uLnByZXZUYXAgPSBudWxsOyAvLyB0aGUgbW9zdCByZWNlbnQgdGFwIGV2ZW50IG9uIHRoaXMgaW50ZXJhY3Rpb25cclxuICBpbnRlcmFjdGlvbi50YXBUaW1lID0gMDsgLy8gdGltZSBvZiB0aGUgbW9zdCByZWNlbnQgdGFwIGV2ZW50XHJcbiAgaW50ZXJhY3Rpb24uaG9sZFRpbWVycyA9IFtdOyAvLyBbeyBkdXJhdGlvbiwgdGltZW91dCB9XVxyXG59KTtcclxuXHJcbmRlZmF1bHRzLnBvaW50ZXJFdmVudHMgPSBwb2ludGVyRXZlbnRzLmRlZmF1bHRzO1xyXG5tb2R1bGUuZXhwb3J0cyA9IHBvaW50ZXJFdmVudHM7XHJcblxyXG59LHtcIi4uL0ludGVyYWN0aW9uXCI6NSxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvU2lnbmFsc1wiOjM1LFwiLi4vdXRpbHMvYXJyXCI6MzYsXCIuLi91dGlscy9icm93c2VyXCI6MzcsXCIuL1BvaW50ZXJFdmVudFwiOjMwfV0sMzI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgcG9pbnRlckV2ZW50cyA9IHJlcXVpcmUoJy4vYmFzZScpO1xyXG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuLi9JbnRlcmFjdGlvbicpO1xyXG5cclxucG9pbnRlckV2ZW50cy5zaWduYWxzLm9uKCduZXcnLCBvbk5ldyk7XHJcbnBvaW50ZXJFdmVudHMuc2lnbmFscy5vbignZmlyZWQnLCBvbkZpcmVkKTtcclxuXHJcbnZhciBfYXJyID0gWydtb3ZlJywgJ3VwJywgJ2NhbmNlbCcsICdlbmRhbGwnXTtcclxuZm9yICh2YXIgX2kgPSAwOyBfaSA8IF9hcnIubGVuZ3RoOyBfaSsrKSB7XHJcbiAgdmFyIHNpZ25hbCA9IF9hcnJbX2ldO1xyXG4gIEludGVyYWN0aW9uLnNpZ25hbHMub24oc2lnbmFsLCBlbmRIb2xkUmVwZWF0KTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25OZXcoX3JlZikge1xyXG4gIHZhciBwb2ludGVyRXZlbnQgPSBfcmVmLnBvaW50ZXJFdmVudDtcclxuXHJcbiAgaWYgKHBvaW50ZXJFdmVudC50eXBlICE9PSAnaG9sZCcpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHBvaW50ZXJFdmVudC5jb3VudCA9IChwb2ludGVyRXZlbnQuY291bnQgfHwgMCkgKyAxO1xyXG59XHJcblxyXG5mdW5jdGlvbiBvbkZpcmVkKF9yZWYyKSB7XHJcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjIuaW50ZXJhY3Rpb24sXHJcbiAgICAgIHBvaW50ZXJFdmVudCA9IF9yZWYyLnBvaW50ZXJFdmVudCxcclxuICAgICAgZXZlbnRUYXJnZXQgPSBfcmVmMi5ldmVudFRhcmdldCxcclxuICAgICAgdGFyZ2V0cyA9IF9yZWYyLnRhcmdldHM7XHJcblxyXG4gIGlmIChwb2ludGVyRXZlbnQudHlwZSAhPT0gJ2hvbGQnIHx8ICF0YXJnZXRzLmxlbmd0aCkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgLy8gZ2V0IHRoZSByZXBlYXQgaW50ZXJ2YWwgZnJvbSB0aGUgZmlyc3QgZXZlbnRhYmxlXHJcbiAgdmFyIGludGVydmFsID0gdGFyZ2V0c1swXS5ldmVudGFibGUub3B0aW9ucy5ob2xkUmVwZWF0SW50ZXJ2YWw7XHJcblxyXG4gIC8vIGRvbid0IHJlcGVhdCBpZiB0aGUgaW50ZXJ2YWwgaXMgMCBvciBsZXNzXHJcbiAgaWYgKGludGVydmFsIDw9IDApIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIHNldCBhIHRpbWVvdXQgdG8gZmlyZSB0aGUgaG9sZHJlcGVhdCBldmVudFxyXG4gIGludGVyYWN0aW9uLmhvbGRJbnRlcnZhbEhhbmRsZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgcG9pbnRlckV2ZW50cy5maXJlKHtcclxuICAgICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxyXG4gICAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXHJcbiAgICAgIHR5cGU6ICdob2xkJyxcclxuICAgICAgcG9pbnRlcjogcG9pbnRlckV2ZW50LFxyXG4gICAgICBldmVudDogcG9pbnRlckV2ZW50XHJcbiAgICB9KTtcclxuICB9LCBpbnRlcnZhbCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGVuZEhvbGRSZXBlYXQoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbjtcclxuXHJcbiAgLy8gc2V0IHRoZSBpbnRlcmFjdGlvbidzIGhvbGRTdG9wVGltZSBwcm9wZXJ0eVxyXG4gIC8vIHRvIHN0b3AgZnVydGhlciBob2xkUmVwZWF0IGV2ZW50c1xyXG4gIGlmIChpbnRlcmFjdGlvbi5ob2xkSW50ZXJ2YWxIYW5kbGUpIHtcclxuICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJhY3Rpb24uaG9sZEludGVydmFsSGFuZGxlKTtcclxuICAgIGludGVyYWN0aW9uLmhvbGRJbnRlcnZhbEhhbmRsZSA9IG51bGw7XHJcbiAgfVxyXG59XHJcblxyXG4vLyBkb24ndCByZXBlYXQgYnkgZGVmYXVsdFxyXG5wb2ludGVyRXZlbnRzLmRlZmF1bHRzLmhvbGRSZXBlYXRJbnRlcnZhbCA9IDA7XHJcbnBvaW50ZXJFdmVudHMudHlwZXMucHVzaCgnaG9sZHJlcGVhdCcpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgb25OZXc6IG9uTmV3LFxyXG4gIG9uRmlyZWQ6IG9uRmlyZWQsXHJcbiAgZW5kSG9sZFJlcGVhdDogZW5kSG9sZFJlcGVhdFxyXG59O1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuL2Jhc2VcIjozMX1dLDMzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHBvaW50ZXJFdmVudHMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcclxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4uL0ludGVyYWN0YWJsZScpO1xyXG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcclxudmFyIGlzID0gcmVxdWlyZSgnLi4vdXRpbHMvaXMnKTtcclxudmFyIGRvbVV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvZG9tVXRpbHMnKTtcclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcclxudmFyIGV4dGVuZCA9IHJlcXVpcmUoJy4uL3V0aWxzL2V4dGVuZCcpO1xyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi4vdXRpbHMvYXJyJyksXHJcbiAgICBtZXJnZSA9IF9yZXF1aXJlLm1lcmdlO1xyXG5cclxucG9pbnRlckV2ZW50cy5zaWduYWxzLm9uKCdjb2xsZWN0LXRhcmdldHMnLCBmdW5jdGlvbiAoX3JlZikge1xyXG4gIHZhciB0YXJnZXRzID0gX3JlZi50YXJnZXRzLFxyXG4gICAgICBlbGVtZW50ID0gX3JlZi5lbGVtZW50LFxyXG4gICAgICB0eXBlID0gX3JlZi50eXBlLFxyXG4gICAgICBldmVudFRhcmdldCA9IF9yZWYuZXZlbnRUYXJnZXQ7XHJcblxyXG4gIGZ1bmN0aW9uIGNvbGxlY3RTZWxlY3RvcnMoaW50ZXJhY3RhYmxlLCBzZWxlY3RvciwgY29udGV4dCkge1xyXG4gICAgdmFyIGVscyA9IGJyb3dzZXIudXNlTWF0Y2hlc1NlbGVjdG9yUG9seWZpbGwgPyBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpIDogdW5kZWZpbmVkO1xyXG5cclxuICAgIHZhciBldmVudGFibGUgPSBpbnRlcmFjdGFibGUuZXZlbnRzO1xyXG4gICAgdmFyIG9wdGlvbnMgPSBldmVudGFibGUub3B0aW9ucztcclxuXHJcbiAgICBpZiAoZXZlbnRhYmxlW3R5cGVdICYmIGlzLmVsZW1lbnQoZWxlbWVudCkgJiYgZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yLCBlbHMpICYmIGludGVyYWN0YWJsZS50ZXN0SWdub3JlQWxsb3cob3B0aW9ucywgZWxlbWVudCwgZXZlbnRUYXJnZXQpKSB7XHJcblxyXG4gICAgICB0YXJnZXRzLnB1c2goe1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgZXZlbnRhYmxlOiBldmVudGFibGUsXHJcbiAgICAgICAgcHJvcHM6IHsgaW50ZXJhY3RhYmxlOiBpbnRlcmFjdGFibGUgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHZhciBpbnRlcmFjdGFibGUgPSBzY29wZS5pbnRlcmFjdGFibGVzLmdldChlbGVtZW50KTtcclxuXHJcbiAgaWYgKGludGVyYWN0YWJsZSkge1xyXG4gICAgdmFyIGV2ZW50YWJsZSA9IGludGVyYWN0YWJsZS5ldmVudHM7XHJcbiAgICB2YXIgb3B0aW9ucyA9IGV2ZW50YWJsZS5vcHRpb25zO1xyXG5cclxuICAgIGlmIChldmVudGFibGVbdHlwZV0gJiYgaW50ZXJhY3RhYmxlLnRlc3RJZ25vcmVBbGxvdyhvcHRpb25zLCBlbGVtZW50LCBldmVudFRhcmdldCkpIHtcclxuICAgICAgdGFyZ2V0cy5wdXNoKHtcclxuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICAgIGV2ZW50YWJsZTogZXZlbnRhYmxlLFxyXG4gICAgICAgIHByb3BzOiB7IGludGVyYWN0YWJsZTogaW50ZXJhY3RhYmxlIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzY29wZS5pbnRlcmFjdGFibGVzLmZvckVhY2hTZWxlY3Rvcihjb2xsZWN0U2VsZWN0b3JzLCBlbGVtZW50KTtcclxufSk7XHJcblxyXG5JbnRlcmFjdGFibGUuc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKF9yZWYyKSB7XHJcbiAgdmFyIGludGVyYWN0YWJsZSA9IF9yZWYyLmludGVyYWN0YWJsZTtcclxuXHJcbiAgaW50ZXJhY3RhYmxlLmV2ZW50cy5nZXRSZWN0ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBpbnRlcmFjdGFibGUuZ2V0UmVjdChlbGVtZW50KTtcclxuICB9O1xyXG59KTtcclxuXHJcbkludGVyYWN0YWJsZS5zaWduYWxzLm9uKCdzZXQnLCBmdW5jdGlvbiAoX3JlZjMpIHtcclxuICB2YXIgaW50ZXJhY3RhYmxlID0gX3JlZjMuaW50ZXJhY3RhYmxlLFxyXG4gICAgICBvcHRpb25zID0gX3JlZjMub3B0aW9ucztcclxuXHJcbiAgZXh0ZW5kKGludGVyYWN0YWJsZS5ldmVudHMub3B0aW9ucywgcG9pbnRlckV2ZW50cy5kZWZhdWx0cyk7XHJcbiAgZXh0ZW5kKGludGVyYWN0YWJsZS5ldmVudHMub3B0aW9ucywgb3B0aW9ucyk7XHJcbn0pO1xyXG5cclxubWVyZ2UoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIHBvaW50ZXJFdmVudHMudHlwZXMpO1xyXG5cclxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5wb2ludGVyRXZlbnRzID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICBleHRlbmQodGhpcy5ldmVudHMub3B0aW9ucywgb3B0aW9ucyk7XHJcblxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxudmFyIF9fYmFja0NvbXBhdE9wdGlvbiA9IEludGVyYWN0YWJsZS5wcm90b3R5cGUuX2JhY2tDb21wYXRPcHRpb247XHJcblxyXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLl9iYWNrQ29tcGF0T3B0aW9uID0gZnVuY3Rpb24gKG9wdGlvbk5hbWUsIG5ld1ZhbHVlKSB7XHJcbiAgdmFyIHJldCA9IF9fYmFja0NvbXBhdE9wdGlvbi5jYWxsKHRoaXMsIG9wdGlvbk5hbWUsIG5ld1ZhbHVlKTtcclxuXHJcbiAgaWYgKHJldCA9PT0gdGhpcykge1xyXG4gICAgdGhpcy5ldmVudHMub3B0aW9uc1tvcHRpb25OYW1lXSA9IG5ld1ZhbHVlO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHJldDtcclxufTtcclxuXHJcbkludGVyYWN0YWJsZS5zZXR0aW5nc01ldGhvZHMucHVzaCgncG9pbnRlckV2ZW50cycpO1xyXG5cclxufSx7XCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vc2NvcGVcIjozNCxcIi4uL3V0aWxzL2FyclwiOjM2LFwiLi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi4vdXRpbHMvZG9tVXRpbHNcIjozOSxcIi4uL3V0aWxzL2V4dGVuZFwiOjQxLFwiLi4vdXRpbHMvaXNcIjo0NixcIi4vYmFzZVwiOjMxfV0sMzQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XHJcbnZhciBldmVudHMgPSByZXF1aXJlKCcuL3V0aWxzL2V2ZW50cycpO1xyXG52YXIgc2lnbmFscyA9IHJlcXVpcmUoJy4vdXRpbHMvU2lnbmFscycpLm5ldygpO1xyXG5cclxudmFyIHNjb3BlID0ge1xyXG4gIHNpZ25hbHM6IHNpZ25hbHMsXHJcbiAgZXZlbnRzOiBldmVudHMsXHJcbiAgdXRpbHM6IHV0aWxzLFxyXG5cclxuICAvLyBtYWluIGRvY3VtZW50XHJcbiAgZG9jdW1lbnQ6IHJlcXVpcmUoJy4vdXRpbHMvZG9tT2JqZWN0cycpLmRvY3VtZW50LFxyXG4gIC8vIGFsbCBkb2N1bWVudHMgYmVpbmcgbGlzdGVuZWQgdG9cclxuICBkb2N1bWVudHM6IFtdLFxyXG5cclxuICBhZGREb2N1bWVudDogZnVuY3Rpb24gYWRkRG9jdW1lbnQoZG9jLCB3aW4pIHtcclxuICAgIC8vIGRvIG5vdGhpbmcgaWYgZG9jdW1lbnQgaXMgYWxyZWFkeSBrbm93blxyXG4gICAgaWYgKHV0aWxzLmNvbnRhaW5zKHNjb3BlLmRvY3VtZW50cywgZG9jKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgd2luID0gd2luIHx8IHNjb3BlLmdldFdpbmRvdyhkb2MpO1xyXG5cclxuICAgIHNjb3BlLmRvY3VtZW50cy5wdXNoKGRvYyk7XHJcbiAgICBldmVudHMuZG9jdW1lbnRzLnB1c2goZG9jKTtcclxuXHJcbiAgICAvLyBkb24ndCBhZGQgYW4gdW5sb2FkIGV2ZW50IGZvciB0aGUgbWFpbiBkb2N1bWVudFxyXG4gICAgLy8gc28gdGhhdCB0aGUgcGFnZSBtYXkgYmUgY2FjaGVkIGluIGJyb3dzZXIgaGlzdG9yeVxyXG4gICAgaWYgKGRvYyAhPT0gc2NvcGUuZG9jdW1lbnQpIHtcclxuICAgICAgZXZlbnRzLmFkZCh3aW4sICd1bmxvYWQnLCBzY29wZS5vbldpbmRvd1VubG9hZCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmFscy5maXJlKCdhZGQtZG9jdW1lbnQnLCB7IGRvYzogZG9jLCB3aW46IHdpbiB9KTtcclxuICB9LFxyXG5cclxuICByZW1vdmVEb2N1bWVudDogZnVuY3Rpb24gcmVtb3ZlRG9jdW1lbnQoZG9jLCB3aW4pIHtcclxuICAgIHZhciBpbmRleCA9IHV0aWxzLmluZGV4T2Yoc2NvcGUuZG9jdW1lbnRzLCBkb2MpO1xyXG5cclxuICAgIHdpbiA9IHdpbiB8fCBzY29wZS5nZXRXaW5kb3coZG9jKTtcclxuXHJcbiAgICBldmVudHMucmVtb3ZlKHdpbiwgJ3VubG9hZCcsIHNjb3BlLm9uV2luZG93VW5sb2FkKTtcclxuXHJcbiAgICBzY29wZS5kb2N1bWVudHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIGV2ZW50cy5kb2N1bWVudHMuc3BsaWNlKGluZGV4LCAxKTtcclxuXHJcbiAgICBzaWduYWxzLmZpcmUoJ3JlbW92ZS1kb2N1bWVudCcsIHsgd2luOiB3aW4sIGRvYzogZG9jIH0pO1xyXG4gIH0sXHJcblxyXG4gIG9uV2luZG93VW5sb2FkOiBmdW5jdGlvbiBvbldpbmRvd1VubG9hZCgpIHtcclxuICAgIHNjb3BlLnJlbW92ZURvY3VtZW50KHRoaXMuZG9jdW1lbnQsIHRoaXMpO1xyXG4gIH1cclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2NvcGU7XHJcblxyXG59LHtcIi4vdXRpbHNcIjo0NCxcIi4vdXRpbHMvU2lnbmFsc1wiOjM1LFwiLi91dGlscy9kb21PYmplY3RzXCI6MzgsXCIuL3V0aWxzL2V2ZW50c1wiOjQwfV0sMzU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi9hcnInKSxcclxuICAgIGluZGV4T2YgPSBfcmVxdWlyZS5pbmRleE9mO1xyXG5cclxudmFyIFNpZ25hbHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgZnVuY3Rpb24gU2lnbmFscygpIHtcclxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTaWduYWxzKTtcclxuXHJcbiAgICB0aGlzLmxpc3RlbmVycyA9IHtcclxuICAgICAgLy8gc2lnbmFsTmFtZTogW2xpc3RlbmVyc10sXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgU2lnbmFscy5wcm90b3R5cGUub24gPSBmdW5jdGlvbiBvbihuYW1lLCBsaXN0ZW5lcikge1xyXG4gICAgaWYgKCF0aGlzLmxpc3RlbmVyc1tuYW1lXSkge1xyXG4gICAgICB0aGlzLmxpc3RlbmVyc1tuYW1lXSA9IFtsaXN0ZW5lcl07XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmxpc3RlbmVyc1tuYW1lXS5wdXNoKGxpc3RlbmVyKTtcclxuICB9O1xyXG5cclxuICBTaWduYWxzLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiBvZmYobmFtZSwgbGlzdGVuZXIpIHtcclxuICAgIGlmICghdGhpcy5saXN0ZW5lcnNbbmFtZV0pIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBpbmRleCA9IGluZGV4T2YodGhpcy5saXN0ZW5lcnNbbmFtZV0sIGxpc3RlbmVyKTtcclxuXHJcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XHJcbiAgICAgIHRoaXMubGlzdGVuZXJzW25hbWVdLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgU2lnbmFscy5wcm90b3R5cGUuZmlyZSA9IGZ1bmN0aW9uIGZpcmUobmFtZSwgYXJnKSB7XHJcbiAgICB2YXIgdGFyZ2V0TGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnNbbmFtZV07XHJcblxyXG4gICAgaWYgKCF0YXJnZXRMaXN0ZW5lcnMpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFyZ2V0TGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGlmICh0YXJnZXRMaXN0ZW5lcnNbaV0oYXJnLCBuYW1lKSA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9O1xyXG5cclxuICByZXR1cm4gU2lnbmFscztcclxufSgpO1xyXG5cclxuU2lnbmFscy5uZXcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgcmV0dXJuIG5ldyBTaWduYWxzKCk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFNpZ25hbHM7XHJcblxyXG59LHtcIi4vYXJyXCI6MzZ9XSwzNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxuZnVuY3Rpb24gaW5kZXhPZihhcnJheSwgdGFyZ2V0KSB7XHJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFycmF5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBpZiAoYXJyYXlbaV0gPT09IHRhcmdldCkge1xyXG4gICAgICByZXR1cm4gaTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiAtMTtcclxufVxyXG5cclxuZnVuY3Rpb24gY29udGFpbnMoYXJyYXksIHRhcmdldCkge1xyXG4gIHJldHVybiBpbmRleE9mKGFycmF5LCB0YXJnZXQpICE9PSAtMTtcclxufVxyXG5cclxuZnVuY3Rpb24gbWVyZ2UodGFyZ2V0LCBzb3VyY2UpIHtcclxuICBmb3IgKHZhciBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGg7IGkrKykge1xyXG4gICAgdGFyZ2V0LnB1c2goc291cmNlW2ldKTtcclxuICB9XHJcblxyXG4gIHJldHVybiB0YXJnZXQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGZpbHRlcihhcnJheSwgdGVzdCkge1xyXG4gIHZhciByZXN1bHQgPSBbXTtcclxuXHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xyXG4gICAgaWYgKHRlc3QoYXJyYXlbaV0pKSB7XHJcbiAgICAgIHJlc3VsdC5wdXNoKGFycmF5W2ldKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0ge1xyXG4gIGluZGV4T2Y6IGluZGV4T2YsXHJcbiAgY29udGFpbnM6IGNvbnRhaW5zLFxyXG4gIG1lcmdlOiBtZXJnZSxcclxuICBmaWx0ZXI6IGZpbHRlclxyXG59O1xyXG5cclxufSx7fV0sMzc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL3dpbmRvdycpLFxyXG4gICAgd2luZG93ID0gX3JlcXVpcmUud2luZG93O1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnLi9pcycpO1xyXG52YXIgZG9tT2JqZWN0cyA9IHJlcXVpcmUoJy4vZG9tT2JqZWN0cycpO1xyXG5cclxudmFyIEVsZW1lbnQgPSBkb21PYmplY3RzLkVsZW1lbnQ7XHJcbnZhciBuYXZpZ2F0b3IgPSB3aW5kb3cubmF2aWdhdG9yO1xyXG5cclxudmFyIGJyb3dzZXIgPSB7XHJcbiAgLy8gRG9lcyB0aGUgYnJvd3NlciBzdXBwb3J0IHRvdWNoIGlucHV0P1xyXG4gIHN1cHBvcnRzVG91Y2g6ICEhKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyB8fCBpcy5mdW5jdGlvbih3aW5kb3cuRG9jdW1lbnRUb3VjaCkgJiYgZG9tT2JqZWN0cy5kb2N1bWVudCBpbnN0YW5jZW9mIHdpbmRvdy5Eb2N1bWVudFRvdWNoKSxcclxuXHJcbiAgLy8gRG9lcyB0aGUgYnJvd3NlciBzdXBwb3J0IFBvaW50ZXJFdmVudHNcclxuICBzdXBwb3J0c1BvaW50ZXJFdmVudDogISFkb21PYmplY3RzLlBvaW50ZXJFdmVudCxcclxuXHJcbiAgaXNJRTg6ICdhdHRhY2hFdmVudCcgaW4gd2luZG93ICYmICEoJ2FkZEV2ZW50TGlzdGVuZXInIGluIHdpbmRvdyksXHJcblxyXG4gIC8vIE9wZXJhIE1vYmlsZSBtdXN0IGJlIGhhbmRsZWQgZGlmZmVyZW50bHlcclxuICBpc09wZXJhTW9iaWxlOiBuYXZpZ2F0b3IuYXBwTmFtZSA9PT0gJ09wZXJhJyAmJiBicm93c2VyLnN1cHBvcnRzVG91Y2ggJiYgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgnUHJlc3RvJyksXHJcblxyXG4gIC8vIHNjcm9sbGluZyBkb2Vzbid0IGNoYW5nZSB0aGUgcmVzdWx0IG9mIGdldENsaWVudFJlY3RzIG9uIGlPUyA3XHJcbiAgaXNJT1M3OiAvaVAoaG9uZXxvZHxhZCkvLnRlc3QobmF2aWdhdG9yLnBsYXRmb3JtKSAmJiAvT1MgN1teXFxkXS8udGVzdChuYXZpZ2F0b3IuYXBwVmVyc2lvbiksXHJcblxyXG4gIGlzSWU5T3JPbGRlcjogL01TSUUgKDh8OSkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCksXHJcblxyXG4gIC8vIHByZWZpeCBtYXRjaGVzU2VsZWN0b3JcclxuICBwcmVmaXhlZE1hdGNoZXNTZWxlY3RvcjogJ21hdGNoZXMnIGluIEVsZW1lbnQucHJvdG90eXBlID8gJ21hdGNoZXMnIDogJ3dlYmtpdE1hdGNoZXNTZWxlY3RvcicgaW4gRWxlbWVudC5wcm90b3R5cGUgPyAnd2Via2l0TWF0Y2hlc1NlbGVjdG9yJyA6ICdtb3pNYXRjaGVzU2VsZWN0b3InIGluIEVsZW1lbnQucHJvdG90eXBlID8gJ21vek1hdGNoZXNTZWxlY3RvcicgOiAnb01hdGNoZXNTZWxlY3RvcicgaW4gRWxlbWVudC5wcm90b3R5cGUgPyAnb01hdGNoZXNTZWxlY3RvcicgOiAnbXNNYXRjaGVzU2VsZWN0b3InLFxyXG5cclxuICB1c2VNYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbDogZmFsc2UsXHJcblxyXG4gIHBFdmVudFR5cGVzOiBkb21PYmplY3RzLlBvaW50ZXJFdmVudCA/IGRvbU9iamVjdHMuUG9pbnRlckV2ZW50ID09PSB3aW5kb3cuTVNQb2ludGVyRXZlbnQgPyB7XHJcbiAgICB1cDogJ01TUG9pbnRlclVwJyxcclxuICAgIGRvd246ICdNU1BvaW50ZXJEb3duJyxcclxuICAgIG92ZXI6ICdtb3VzZW92ZXInLFxyXG4gICAgb3V0OiAnbW91c2VvdXQnLFxyXG4gICAgbW92ZTogJ01TUG9pbnRlck1vdmUnLFxyXG4gICAgY2FuY2VsOiAnTVNQb2ludGVyQ2FuY2VsJ1xyXG4gIH0gOiB7XHJcbiAgICB1cDogJ3BvaW50ZXJ1cCcsXHJcbiAgICBkb3duOiAncG9pbnRlcmRvd24nLFxyXG4gICAgb3ZlcjogJ3BvaW50ZXJvdmVyJyxcclxuICAgIG91dDogJ3BvaW50ZXJvdXQnLFxyXG4gICAgbW92ZTogJ3BvaW50ZXJtb3ZlJyxcclxuICAgIGNhbmNlbDogJ3BvaW50ZXJjYW5jZWwnXHJcbiAgfSA6IG51bGwsXHJcblxyXG4gIC8vIGJlY2F1c2UgV2Via2l0IGFuZCBPcGVyYSBzdGlsbCB1c2UgJ21vdXNld2hlZWwnIGV2ZW50IHR5cGVcclxuICB3aGVlbEV2ZW50OiAnb25tb3VzZXdoZWVsJyBpbiBkb21PYmplY3RzLmRvY3VtZW50ID8gJ21vdXNld2hlZWwnIDogJ3doZWVsJ1xyXG5cclxufTtcclxuXHJcbmJyb3dzZXIudXNlTWF0Y2hlc1NlbGVjdG9yUG9seWZpbGwgPSAhaXMuZnVuY3Rpb24oRWxlbWVudC5wcm90b3R5cGVbYnJvd3Nlci5wcmVmaXhlZE1hdGNoZXNTZWxlY3Rvcl0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBicm93c2VyO1xyXG5cclxufSx7XCIuL2RvbU9iamVjdHNcIjozOCxcIi4vaXNcIjo0NixcIi4vd2luZG93XCI6NTJ9XSwzODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBkb21PYmplY3RzID0ge307XHJcbnZhciB3aW4gPSByZXF1aXJlKCcuL3dpbmRvdycpLndpbmRvdztcclxuXHJcbmZ1bmN0aW9uIGJsYW5rKCkge31cclxuXHJcbmRvbU9iamVjdHMuZG9jdW1lbnQgPSB3aW4uZG9jdW1lbnQ7XHJcbmRvbU9iamVjdHMuRG9jdW1lbnRGcmFnbWVudCA9IHdpbi5Eb2N1bWVudEZyYWdtZW50IHx8IGJsYW5rO1xyXG5kb21PYmplY3RzLlNWR0VsZW1lbnQgPSB3aW4uU1ZHRWxlbWVudCB8fCBibGFuaztcclxuZG9tT2JqZWN0cy5TVkdTVkdFbGVtZW50ID0gd2luLlNWR1NWR0VsZW1lbnQgfHwgYmxhbms7XHJcbmRvbU9iamVjdHMuU1ZHRWxlbWVudEluc3RhbmNlID0gd2luLlNWR0VsZW1lbnRJbnN0YW5jZSB8fCBibGFuaztcclxuZG9tT2JqZWN0cy5FbGVtZW50ID0gd2luLkVsZW1lbnQgfHwgYmxhbms7XHJcbmRvbU9iamVjdHMuSFRNTEVsZW1lbnQgPSB3aW4uSFRNTEVsZW1lbnQgfHwgZG9tT2JqZWN0cy5FbGVtZW50O1xyXG5cclxuZG9tT2JqZWN0cy5FdmVudCA9IHdpbi5FdmVudDtcclxuZG9tT2JqZWN0cy5Ub3VjaCA9IHdpbi5Ub3VjaCB8fCBibGFuaztcclxuZG9tT2JqZWN0cy5Qb2ludGVyRXZlbnQgPSB3aW4uUG9pbnRlckV2ZW50IHx8IHdpbi5NU1BvaW50ZXJFdmVudDtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZG9tT2JqZWN0cztcclxuXHJcbn0se1wiLi93aW5kb3dcIjo1Mn1dLDM5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHdpbiA9IHJlcXVpcmUoJy4vd2luZG93Jyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi9icm93c2VyJyk7XHJcbnZhciBpcyA9IHJlcXVpcmUoJy4vaXMnKTtcclxudmFyIGRvbU9iamVjdHMgPSByZXF1aXJlKCcuL2RvbU9iamVjdHMnKTtcclxuXHJcbnZhciBkb21VdGlscyA9IHtcclxuICBub2RlQ29udGFpbnM6IGZ1bmN0aW9uIG5vZGVDb250YWlucyhwYXJlbnQsIGNoaWxkKSB7XHJcbiAgICB3aGlsZSAoY2hpbGQpIHtcclxuICAgICAgaWYgKGNoaWxkID09PSBwYXJlbnQpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY2hpbGQgPSBjaGlsZC5wYXJlbnROb2RlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9LFxyXG5cclxuICBjbG9zZXN0OiBmdW5jdGlvbiBjbG9zZXN0KGVsZW1lbnQsIHNlbGVjdG9yKSB7XHJcbiAgICB3aGlsZSAoaXMuZWxlbWVudChlbGVtZW50KSkge1xyXG4gICAgICBpZiAoZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yKSkge1xyXG4gICAgICAgIHJldHVybiBlbGVtZW50O1xyXG4gICAgICB9XHJcblxyXG4gICAgICBlbGVtZW50ID0gZG9tVXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9LFxyXG5cclxuICBwYXJlbnROb2RlOiBmdW5jdGlvbiBwYXJlbnROb2RlKG5vZGUpIHtcclxuICAgIHZhciBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7XHJcblxyXG4gICAgaWYgKGlzLmRvY0ZyYWcocGFyZW50KSkge1xyXG4gICAgICAvLyBza2lwIHBhc3QgI3NoYWRvLXJvb3QgZnJhZ21lbnRzXHJcbiAgICAgIHdoaWxlICgocGFyZW50ID0gcGFyZW50Lmhvc3QpICYmIGlzLmRvY0ZyYWcocGFyZW50KSkge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gcGFyZW50O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwYXJlbnQ7XHJcbiAgfSxcclxuXHJcbiAgLy8gdGFrZW4gZnJvbSBodHRwOi8vdGFuYWxpbi5jb20vZW4vYmxvZy8yMDEyLzEyL21hdGNoZXMtc2VsZWN0b3ItaWU4LyBhbmQgbW9kaWZpZWRcclxuICBtYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbDogYnJvd3Nlci51c2VNYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbCA/IGZ1bmN0aW9uIChlbGVtZW50LCBzZWxlY3RvciwgZWxlbXMpIHtcclxuICAgIGVsZW1zID0gZWxlbXMgfHwgZWxlbWVudC5wYXJlbnROb2RlLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xyXG5cclxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBlbGVtcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICBpZiAoZWxlbXNbaV0gPT09IGVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9IDogbnVsbCxcclxuXHJcbiAgbWF0Y2hlc1NlbGVjdG9yOiBmdW5jdGlvbiBtYXRjaGVzU2VsZWN0b3IoZWxlbWVudCwgc2VsZWN0b3IsIG5vZGVMaXN0KSB7XHJcbiAgICBpZiAoYnJvd3Nlci51c2VNYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbCkge1xyXG4gICAgICByZXR1cm4gZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yUG9seWZpbGwoZWxlbWVudCwgc2VsZWN0b3IsIG5vZGVMaXN0KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyByZW1vdmUgL2RlZXAvIGZyb20gc2VsZWN0b3JzIGlmIHNoYWRvd0RPTSBwb2x5ZmlsbCBpcyB1c2VkXHJcbiAgICBpZiAod2luLndpbmRvdyAhPT0gd2luLnJlYWxXaW5kb3cpIHtcclxuICAgICAgc2VsZWN0b3IgPSBzZWxlY3Rvci5yZXBsYWNlKC9cXC9kZWVwXFwvL2csICcgJyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVsZW1lbnRbYnJvd3Nlci5wcmVmaXhlZE1hdGNoZXNTZWxlY3Rvcl0oc2VsZWN0b3IpO1xyXG4gIH0sXHJcblxyXG4gIC8vIFRlc3QgZm9yIHRoZSBlbGVtZW50IHRoYXQncyBcImFib3ZlXCIgYWxsIG90aGVyIHF1YWxpZmllcnNcclxuICBpbmRleE9mRGVlcGVzdEVsZW1lbnQ6IGZ1bmN0aW9uIGluZGV4T2ZEZWVwZXN0RWxlbWVudChlbGVtZW50cykge1xyXG4gICAgdmFyIGRlZXBlc3Rab25lUGFyZW50cyA9IFtdO1xyXG4gICAgdmFyIGRyb3B6b25lUGFyZW50cyA9IFtdO1xyXG4gICAgdmFyIGRyb3B6b25lID0gdm9pZCAwO1xyXG4gICAgdmFyIGRlZXBlc3Rab25lID0gZWxlbWVudHNbMF07XHJcbiAgICB2YXIgaW5kZXggPSBkZWVwZXN0Wm9uZSA/IDAgOiAtMTtcclxuICAgIHZhciBwYXJlbnQgPSB2b2lkIDA7XHJcbiAgICB2YXIgY2hpbGQgPSB2b2lkIDA7XHJcbiAgICB2YXIgaSA9IHZvaWQgMDtcclxuICAgIHZhciBuID0gdm9pZCAwO1xyXG5cclxuICAgIGZvciAoaSA9IDE7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBkcm9wem9uZSA9IGVsZW1lbnRzW2ldO1xyXG5cclxuICAgICAgLy8gYW4gZWxlbWVudCBtaWdodCBiZWxvbmcgdG8gbXVsdGlwbGUgc2VsZWN0b3IgZHJvcHpvbmVzXHJcbiAgICAgIGlmICghZHJvcHpvbmUgfHwgZHJvcHpvbmUgPT09IGRlZXBlc3Rab25lKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghZGVlcGVzdFpvbmUpIHtcclxuICAgICAgICBkZWVwZXN0Wm9uZSA9IGRyb3B6b25lO1xyXG4gICAgICAgIGluZGV4ID0gaTtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gY2hlY2sgaWYgdGhlIGRlZXBlc3Qgb3IgY3VycmVudCBhcmUgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IG9yIGRvY3VtZW50LnJvb3RFbGVtZW50XHJcbiAgICAgIC8vIC0gaWYgdGhlIGN1cnJlbnQgZHJvcHpvbmUgaXMsIGRvIG5vdGhpbmcgYW5kIGNvbnRpbnVlXHJcbiAgICAgIGlmIChkcm9wem9uZS5wYXJlbnROb2RlID09PSBkcm9wem9uZS5vd25lckRvY3VtZW50KSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgLy8gLSBpZiBkZWVwZXN0IGlzLCB1cGRhdGUgd2l0aCB0aGUgY3VycmVudCBkcm9wem9uZSBhbmQgY29udGludWUgdG8gbmV4dFxyXG4gICAgICBlbHNlIGlmIChkZWVwZXN0Wm9uZS5wYXJlbnROb2RlID09PSBkcm9wem9uZS5vd25lckRvY3VtZW50KSB7XHJcbiAgICAgICAgICBkZWVwZXN0Wm9uZSA9IGRyb3B6b25lO1xyXG4gICAgICAgICAgaW5kZXggPSBpO1xyXG4gICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFkZWVwZXN0Wm9uZVBhcmVudHMubGVuZ3RoKSB7XHJcbiAgICAgICAgcGFyZW50ID0gZGVlcGVzdFpvbmU7XHJcbiAgICAgICAgd2hpbGUgKHBhcmVudC5wYXJlbnROb2RlICYmIHBhcmVudC5wYXJlbnROb2RlICE9PSBwYXJlbnQub3duZXJEb2N1bWVudCkge1xyXG4gICAgICAgICAgZGVlcGVzdFpvbmVQYXJlbnRzLnVuc2hpZnQocGFyZW50KTtcclxuICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gaWYgdGhpcyBlbGVtZW50IGlzIGFuIHN2ZyBlbGVtZW50IGFuZCB0aGUgY3VycmVudCBkZWVwZXN0IGlzXHJcbiAgICAgIC8vIGFuIEhUTUxFbGVtZW50XHJcbiAgICAgIGlmIChkZWVwZXN0Wm9uZSBpbnN0YW5jZW9mIGRvbU9iamVjdHMuSFRNTEVsZW1lbnQgJiYgZHJvcHpvbmUgaW5zdGFuY2VvZiBkb21PYmplY3RzLlNWR0VsZW1lbnQgJiYgIShkcm9wem9uZSBpbnN0YW5jZW9mIGRvbU9iamVjdHMuU1ZHU1ZHRWxlbWVudCkpIHtcclxuXHJcbiAgICAgICAgaWYgKGRyb3B6b25lID09PSBkZWVwZXN0Wm9uZS5wYXJlbnROb2RlKSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHBhcmVudCA9IGRyb3B6b25lLm93bmVyU1ZHRWxlbWVudDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBwYXJlbnQgPSBkcm9wem9uZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZHJvcHpvbmVQYXJlbnRzID0gW107XHJcblxyXG4gICAgICB3aGlsZSAocGFyZW50LnBhcmVudE5vZGUgIT09IHBhcmVudC5vd25lckRvY3VtZW50KSB7XHJcbiAgICAgICAgZHJvcHpvbmVQYXJlbnRzLnVuc2hpZnQocGFyZW50KTtcclxuICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgbiA9IDA7XHJcblxyXG4gICAgICAvLyBnZXQgKHBvc2l0aW9uIG9mIGxhc3QgY29tbW9uIGFuY2VzdG9yKSArIDFcclxuICAgICAgd2hpbGUgKGRyb3B6b25lUGFyZW50c1tuXSAmJiBkcm9wem9uZVBhcmVudHNbbl0gPT09IGRlZXBlc3Rab25lUGFyZW50c1tuXSkge1xyXG4gICAgICAgIG4rKztcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHBhcmVudHMgPSBbZHJvcHpvbmVQYXJlbnRzW24gLSAxXSwgZHJvcHpvbmVQYXJlbnRzW25dLCBkZWVwZXN0Wm9uZVBhcmVudHNbbl1dO1xyXG5cclxuICAgICAgY2hpbGQgPSBwYXJlbnRzWzBdLmxhc3RDaGlsZDtcclxuXHJcbiAgICAgIHdoaWxlIChjaGlsZCkge1xyXG4gICAgICAgIGlmIChjaGlsZCA9PT0gcGFyZW50c1sxXSkge1xyXG4gICAgICAgICAgZGVlcGVzdFpvbmUgPSBkcm9wem9uZTtcclxuICAgICAgICAgIGluZGV4ID0gaTtcclxuICAgICAgICAgIGRlZXBlc3Rab25lUGFyZW50cyA9IFtdO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoY2hpbGQgPT09IHBhcmVudHNbMl0pIHtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY2hpbGQgPSBjaGlsZC5wcmV2aW91c1NpYmxpbmc7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gaW5kZXg7XHJcbiAgfSxcclxuXHJcbiAgbWF0Y2hlc1VwVG86IGZ1bmN0aW9uIG1hdGNoZXNVcFRvKGVsZW1lbnQsIHNlbGVjdG9yLCBsaW1pdCkge1xyXG4gICAgd2hpbGUgKGlzLmVsZW1lbnQoZWxlbWVudCkpIHtcclxuICAgICAgaWYgKGRvbVV0aWxzLm1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvcikpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZWxlbWVudCA9IGRvbVV0aWxzLnBhcmVudE5vZGUoZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAoZWxlbWVudCA9PT0gbGltaXQpIHtcclxuICAgICAgICByZXR1cm4gZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9LFxyXG5cclxuICBnZXRBY3R1YWxFbGVtZW50OiBmdW5jdGlvbiBnZXRBY3R1YWxFbGVtZW50KGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBlbGVtZW50IGluc3RhbmNlb2YgZG9tT2JqZWN0cy5TVkdFbGVtZW50SW5zdGFuY2UgPyBlbGVtZW50LmNvcnJlc3BvbmRpbmdVc2VFbGVtZW50IDogZWxlbWVudDtcclxuICB9LFxyXG5cclxuICBnZXRTY3JvbGxYWTogZnVuY3Rpb24gZ2V0U2Nyb2xsWFkocmVsZXZhbnRXaW5kb3cpIHtcclxuICAgIHJlbGV2YW50V2luZG93ID0gcmVsZXZhbnRXaW5kb3cgfHwgd2luLndpbmRvdztcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHg6IHJlbGV2YW50V2luZG93LnNjcm9sbFggfHwgcmVsZXZhbnRXaW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQsXHJcbiAgICAgIHk6IHJlbGV2YW50V2luZG93LnNjcm9sbFkgfHwgcmVsZXZhbnRXaW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcFxyXG4gICAgfTtcclxuICB9LFxyXG5cclxuICBnZXRFbGVtZW50Q2xpZW50UmVjdDogZnVuY3Rpb24gZ2V0RWxlbWVudENsaWVudFJlY3QoZWxlbWVudCkge1xyXG4gICAgdmFyIGNsaWVudFJlY3QgPSBlbGVtZW50IGluc3RhbmNlb2YgZG9tT2JqZWN0cy5TVkdFbGVtZW50ID8gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSA6IGVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKVswXTtcclxuXHJcbiAgICByZXR1cm4gY2xpZW50UmVjdCAmJiB7XHJcbiAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCxcclxuICAgICAgcmlnaHQ6IGNsaWVudFJlY3QucmlnaHQsXHJcbiAgICAgIHRvcDogY2xpZW50UmVjdC50b3AsXHJcbiAgICAgIGJvdHRvbTogY2xpZW50UmVjdC5ib3R0b20sXHJcbiAgICAgIHdpZHRoOiBjbGllbnRSZWN0LndpZHRoIHx8IGNsaWVudFJlY3QucmlnaHQgLSBjbGllbnRSZWN0LmxlZnQsXHJcbiAgICAgIGhlaWdodDogY2xpZW50UmVjdC5oZWlnaHQgfHwgY2xpZW50UmVjdC5ib3R0b20gLSBjbGllbnRSZWN0LnRvcFxyXG4gICAgfTtcclxuICB9LFxyXG5cclxuICBnZXRFbGVtZW50UmVjdDogZnVuY3Rpb24gZ2V0RWxlbWVudFJlY3QoZWxlbWVudCkge1xyXG4gICAgdmFyIGNsaWVudFJlY3QgPSBkb21VdGlscy5nZXRFbGVtZW50Q2xpZW50UmVjdChlbGVtZW50KTtcclxuXHJcbiAgICBpZiAoIWJyb3dzZXIuaXNJT1M3ICYmIGNsaWVudFJlY3QpIHtcclxuICAgICAgdmFyIHNjcm9sbCA9IGRvbVV0aWxzLmdldFNjcm9sbFhZKHdpbi5nZXRXaW5kb3coZWxlbWVudCkpO1xyXG5cclxuICAgICAgY2xpZW50UmVjdC5sZWZ0ICs9IHNjcm9sbC54O1xyXG4gICAgICBjbGllbnRSZWN0LnJpZ2h0ICs9IHNjcm9sbC54O1xyXG4gICAgICBjbGllbnRSZWN0LnRvcCArPSBzY3JvbGwueTtcclxuICAgICAgY2xpZW50UmVjdC5ib3R0b20gKz0gc2Nyb2xsLnk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGNsaWVudFJlY3Q7XHJcbiAgfSxcclxuXHJcbiAgZ2V0UGF0aDogZnVuY3Rpb24gZ2V0UGF0aChlbGVtZW50KSB7XHJcbiAgICB2YXIgcGF0aCA9IFtdO1xyXG5cclxuICAgIHdoaWxlIChlbGVtZW50KSB7XHJcbiAgICAgIHBhdGgucHVzaChlbGVtZW50KTtcclxuICAgICAgZWxlbWVudCA9IGRvbVV0aWxzLnBhcmVudE5vZGUoZWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBhdGg7XHJcbiAgfSxcclxuXHJcbiAgdHJ5U2VsZWN0b3I6IGZ1bmN0aW9uIHRyeVNlbGVjdG9yKHZhbHVlKSB7XHJcbiAgICBpZiAoIWlzLnN0cmluZyh2YWx1ZSkpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHJhaXNlZCBpZiBpdCBpcyBpbnZhbGlkXHJcbiAgICBkb21PYmplY3RzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodmFsdWUpO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBkb21VdGlscztcclxuXHJcbn0se1wiLi9icm93c2VyXCI6MzcsXCIuL2RvbU9iamVjdHNcIjozOCxcIi4vaXNcIjo0NixcIi4vd2luZG93XCI6NTJ9XSw0MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJy4vaXMnKTtcclxudmFyIGRvbVV0aWxzID0gcmVxdWlyZSgnLi9kb21VdGlscycpO1xyXG52YXIgcEV4dGVuZCA9IHJlcXVpcmUoJy4vcG9pbnRlckV4dGVuZCcpO1xyXG5cclxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi93aW5kb3cnKSxcclxuICAgIHdpbmRvdyA9IF9yZXF1aXJlLndpbmRvdyxcclxuICAgIGdldFdpbmRvdyA9IF9yZXF1aXJlLmdldFdpbmRvdztcclxuXHJcbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCcuL2FycicpLFxyXG4gICAgaW5kZXhPZiA9IF9yZXF1aXJlMi5pbmRleE9mLFxyXG4gICAgY29udGFpbnMgPSBfcmVxdWlyZTIuY29udGFpbnM7XHJcblxyXG52YXIgdXNlQXR0YWNoRXZlbnQgPSAnYXR0YWNoRXZlbnQnIGluIHdpbmRvdyAmJiAhKCdhZGRFdmVudExpc3RlbmVyJyBpbiB3aW5kb3cpO1xyXG52YXIgYWRkRXZlbnQgPSB1c2VBdHRhY2hFdmVudCA/ICdhdHRhY2hFdmVudCcgOiAnYWRkRXZlbnRMaXN0ZW5lcic7XHJcbnZhciByZW1vdmVFdmVudCA9IHVzZUF0dGFjaEV2ZW50ID8gJ2RldGFjaEV2ZW50JyA6ICdyZW1vdmVFdmVudExpc3RlbmVyJztcclxudmFyIG9uID0gdXNlQXR0YWNoRXZlbnQgPyAnb24nIDogJyc7XHJcblxyXG52YXIgZWxlbWVudHMgPSBbXTtcclxudmFyIHRhcmdldHMgPSBbXTtcclxudmFyIGF0dGFjaGVkTGlzdGVuZXJzID0gW107XHJcblxyXG4vLyB7XHJcbi8vICAgdHlwZToge1xyXG4vLyAgICAgc2VsZWN0b3JzOiBbJ3NlbGVjdG9yJywgLi4uXSxcclxuLy8gICAgIGNvbnRleHRzIDogW2RvY3VtZW50LCAuLi5dLFxyXG4vLyAgICAgbGlzdGVuZXJzOiBbW2xpc3RlbmVyLCBjYXB0dXJlLCBwYXNzaXZlXSwgLi4uXVxyXG4vLyAgIH1cclxuLy8gIH1cclxudmFyIGRlbGVnYXRlZEV2ZW50cyA9IHt9O1xyXG5cclxudmFyIGRvY3VtZW50cyA9IFtdO1xyXG5cclxudmFyIHN1cHBvcnRzT3B0aW9ucyA9ICF1c2VBdHRhY2hFdmVudCAmJiBmdW5jdGlvbiAoKSB7XHJcbiAgdmFyIHN1cHBvcnRlZCA9IGZhbHNlO1xyXG5cclxuICB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykuYWRkRXZlbnRMaXN0ZW5lcigndGVzdCcsIG51bGwsIHtcclxuICAgIGdldCBjYXB0dXJlKCkge1xyXG4gICAgICBzdXBwb3J0ZWQgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gc3VwcG9ydGVkO1xyXG59KCk7XHJcblxyXG5mdW5jdGlvbiBhZGQoZWxlbWVudCwgdHlwZSwgbGlzdGVuZXIsIG9wdGlvbmFsQXJnKSB7XHJcbiAgdmFyIG9wdGlvbnMgPSBnZXRPcHRpb25zKG9wdGlvbmFsQXJnKTtcclxuICB2YXIgZWxlbWVudEluZGV4ID0gaW5kZXhPZihlbGVtZW50cywgZWxlbWVudCk7XHJcbiAgdmFyIHRhcmdldCA9IHRhcmdldHNbZWxlbWVudEluZGV4XTtcclxuXHJcbiAgaWYgKCF0YXJnZXQpIHtcclxuICAgIHRhcmdldCA9IHtcclxuICAgICAgZXZlbnRzOiB7fSxcclxuICAgICAgdHlwZUNvdW50OiAwXHJcbiAgICB9O1xyXG5cclxuICAgIGVsZW1lbnRJbmRleCA9IGVsZW1lbnRzLnB1c2goZWxlbWVudCkgLSAxO1xyXG4gICAgdGFyZ2V0cy5wdXNoKHRhcmdldCk7XHJcblxyXG4gICAgYXR0YWNoZWRMaXN0ZW5lcnMucHVzaCh1c2VBdHRhY2hFdmVudCA/IHtcclxuICAgICAgc3VwcGxpZWQ6IFtdLFxyXG4gICAgICB3cmFwcGVkOiBbXSxcclxuICAgICAgdXNlQ291bnQ6IFtdXHJcbiAgICB9IDogbnVsbCk7XHJcbiAgfVxyXG5cclxuICBpZiAoIXRhcmdldC5ldmVudHNbdHlwZV0pIHtcclxuICAgIHRhcmdldC5ldmVudHNbdHlwZV0gPSBbXTtcclxuICAgIHRhcmdldC50eXBlQ291bnQrKztcclxuICB9XHJcblxyXG4gIGlmICghY29udGFpbnModGFyZ2V0LmV2ZW50c1t0eXBlXSwgbGlzdGVuZXIpKSB7XHJcbiAgICB2YXIgcmV0ID0gdm9pZCAwO1xyXG5cclxuICAgIGlmICh1c2VBdHRhY2hFdmVudCkge1xyXG4gICAgICB2YXIgX2F0dGFjaGVkTGlzdGVuZXJzJGVsID0gYXR0YWNoZWRMaXN0ZW5lcnNbZWxlbWVudEluZGV4XSxcclxuICAgICAgICAgIHN1cHBsaWVkID0gX2F0dGFjaGVkTGlzdGVuZXJzJGVsLnN1cHBsaWVkLFxyXG4gICAgICAgICAgd3JhcHBlZCA9IF9hdHRhY2hlZExpc3RlbmVycyRlbC53cmFwcGVkLFxyXG4gICAgICAgICAgdXNlQ291bnQgPSBfYXR0YWNoZWRMaXN0ZW5lcnMkZWwudXNlQ291bnQ7XHJcblxyXG4gICAgICB2YXIgbGlzdGVuZXJJbmRleCA9IGluZGV4T2Yoc3VwcGxpZWQsIGxpc3RlbmVyKTtcclxuXHJcbiAgICAgIHZhciB3cmFwcGVkTGlzdGVuZXIgPSB3cmFwcGVkW2xpc3RlbmVySW5kZXhdIHx8IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIGlmICghZXZlbnQuaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKSB7XHJcbiAgICAgICAgICBldmVudC50YXJnZXQgPSBldmVudC5zcmNFbGVtZW50O1xyXG4gICAgICAgICAgZXZlbnQuY3VycmVudFRhcmdldCA9IGVsZW1lbnQ7XHJcblxyXG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQgPSBldmVudC5wcmV2ZW50RGVmYXVsdCB8fCBwcmV2ZW50RGVmO1xyXG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uID0gZXZlbnQuc3RvcFByb3BhZ2F0aW9uIHx8IHN0b3BQcm9wO1xyXG4gICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uIHx8IHN0b3BJbW1Qcm9wO1xyXG5cclxuICAgICAgICAgIGlmICgvbW91c2V8Y2xpY2svLnRlc3QoZXZlbnQudHlwZSkpIHtcclxuICAgICAgICAgICAgZXZlbnQucGFnZVggPSBldmVudC5jbGllbnRYICsgZ2V0V2luZG93KGVsZW1lbnQpLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0O1xyXG4gICAgICAgICAgICBldmVudC5wYWdlWSA9IGV2ZW50LmNsaWVudFkgKyBnZXRXaW5kb3coZWxlbWVudCkuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcDtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBsaXN0ZW5lcihldmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgcmV0ID0gZWxlbWVudFthZGRFdmVudF0ob24gKyB0eXBlLCB3cmFwcGVkTGlzdGVuZXIsICEhb3B0aW9ucy5jYXB0dXJlKTtcclxuXHJcbiAgICAgIGlmIChsaXN0ZW5lckluZGV4ID09PSAtMSkge1xyXG4gICAgICAgIHN1cHBsaWVkLnB1c2gobGlzdGVuZXIpO1xyXG4gICAgICAgIHdyYXBwZWQucHVzaCh3cmFwcGVkTGlzdGVuZXIpO1xyXG4gICAgICAgIHVzZUNvdW50LnB1c2goMSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdXNlQ291bnRbbGlzdGVuZXJJbmRleF0rKztcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0ID0gZWxlbWVudFthZGRFdmVudF0odHlwZSwgbGlzdGVuZXIsIHN1cHBvcnRzT3B0aW9ucyA/IG9wdGlvbnMgOiAhIW9wdGlvbnMuY2FwdHVyZSk7XHJcbiAgICB9XHJcbiAgICB0YXJnZXQuZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xyXG5cclxuICAgIHJldHVybiByZXQ7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiByZW1vdmUoZWxlbWVudCwgdHlwZSwgbGlzdGVuZXIsIG9wdGlvbmFsQXJnKSB7XHJcbiAgdmFyIG9wdGlvbnMgPSBnZXRPcHRpb25zKG9wdGlvbmFsQXJnKTtcclxuICB2YXIgZWxlbWVudEluZGV4ID0gaW5kZXhPZihlbGVtZW50cywgZWxlbWVudCk7XHJcbiAgdmFyIHRhcmdldCA9IHRhcmdldHNbZWxlbWVudEluZGV4XTtcclxuXHJcbiAgaWYgKCF0YXJnZXQgfHwgIXRhcmdldC5ldmVudHMpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciB3cmFwcGVkTGlzdGVuZXIgPSBsaXN0ZW5lcjtcclxuICB2YXIgbGlzdGVuZXJzID0gdm9pZCAwO1xyXG4gIHZhciBsaXN0ZW5lckluZGV4ID0gdm9pZCAwO1xyXG5cclxuICBpZiAodXNlQXR0YWNoRXZlbnQpIHtcclxuICAgIGxpc3RlbmVycyA9IGF0dGFjaGVkTGlzdGVuZXJzW2VsZW1lbnRJbmRleF07XHJcbiAgICBsaXN0ZW5lckluZGV4ID0gaW5kZXhPZihsaXN0ZW5lcnMuc3VwcGxpZWQsIGxpc3RlbmVyKTtcclxuICAgIHdyYXBwZWRMaXN0ZW5lciA9IGxpc3RlbmVycy53cmFwcGVkW2xpc3RlbmVySW5kZXhdO1xyXG4gIH1cclxuXHJcbiAgaWYgKHR5cGUgPT09ICdhbGwnKSB7XHJcbiAgICBmb3IgKHR5cGUgaW4gdGFyZ2V0LmV2ZW50cykge1xyXG4gICAgICBpZiAodGFyZ2V0LmV2ZW50cy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkge1xyXG4gICAgICAgIHJlbW92ZShlbGVtZW50LCB0eXBlLCAnYWxsJyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGlmICh0YXJnZXQuZXZlbnRzW3R5cGVdKSB7XHJcbiAgICB2YXIgbGVuID0gdGFyZ2V0LmV2ZW50c1t0eXBlXS5sZW5ndGg7XHJcblxyXG4gICAgaWYgKGxpc3RlbmVyID09PSAnYWxsJykge1xyXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgcmVtb3ZlKGVsZW1lbnQsIHR5cGUsIHRhcmdldC5ldmVudHNbdHlwZV1baV0sIG9wdGlvbnMpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBsZW47IF9pKyspIHtcclxuICAgICAgICBpZiAodGFyZ2V0LmV2ZW50c1t0eXBlXVtfaV0gPT09IGxpc3RlbmVyKSB7XHJcbiAgICAgICAgICBlbGVtZW50W3JlbW92ZUV2ZW50XShvbiArIHR5cGUsIHdyYXBwZWRMaXN0ZW5lciwgc3VwcG9ydHNPcHRpb25zID8gb3B0aW9ucyA6ICEhb3B0aW9ucy5jYXB0dXJlKTtcclxuICAgICAgICAgIHRhcmdldC5ldmVudHNbdHlwZV0uc3BsaWNlKF9pLCAxKTtcclxuXHJcbiAgICAgICAgICBpZiAodXNlQXR0YWNoRXZlbnQgJiYgbGlzdGVuZXJzKSB7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycy51c2VDb3VudFtsaXN0ZW5lckluZGV4XS0tO1xyXG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLnVzZUNvdW50W2xpc3RlbmVySW5kZXhdID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgbGlzdGVuZXJzLnN1cHBsaWVkLnNwbGljZShsaXN0ZW5lckluZGV4LCAxKTtcclxuICAgICAgICAgICAgICBsaXN0ZW5lcnMud3JhcHBlZC5zcGxpY2UobGlzdGVuZXJJbmRleCwgMSk7XHJcbiAgICAgICAgICAgICAgbGlzdGVuZXJzLnVzZUNvdW50LnNwbGljZShsaXN0ZW5lckluZGV4LCAxKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0YXJnZXQuZXZlbnRzW3R5cGVdICYmIHRhcmdldC5ldmVudHNbdHlwZV0ubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHRhcmdldC5ldmVudHNbdHlwZV0gPSBudWxsO1xyXG4gICAgICB0YXJnZXQudHlwZUNvdW50LS07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZiAoIXRhcmdldC50eXBlQ291bnQpIHtcclxuICAgIHRhcmdldHMuc3BsaWNlKGVsZW1lbnRJbmRleCwgMSk7XHJcbiAgICBlbGVtZW50cy5zcGxpY2UoZWxlbWVudEluZGV4LCAxKTtcclxuICAgIGF0dGFjaGVkTGlzdGVuZXJzLnNwbGljZShlbGVtZW50SW5kZXgsIDEpO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gYWRkRGVsZWdhdGUoc2VsZWN0b3IsIGNvbnRleHQsIHR5cGUsIGxpc3RlbmVyLCBvcHRpb25hbEFyZykge1xyXG4gIHZhciBvcHRpb25zID0gZ2V0T3B0aW9ucyhvcHRpb25hbEFyZyk7XHJcbiAgaWYgKCFkZWxlZ2F0ZWRFdmVudHNbdHlwZV0pIHtcclxuICAgIGRlbGVnYXRlZEV2ZW50c1t0eXBlXSA9IHtcclxuICAgICAgc2VsZWN0b3JzOiBbXSxcclxuICAgICAgY29udGV4dHM6IFtdLFxyXG4gICAgICBsaXN0ZW5lcnM6IFtdXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIGFkZCBkZWxlZ2F0ZSBsaXN0ZW5lciBmdW5jdGlvbnNcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZG9jdW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIGFkZChkb2N1bWVudHNbaV0sIHR5cGUsIGRlbGVnYXRlTGlzdGVuZXIpO1xyXG4gICAgICBhZGQoZG9jdW1lbnRzW2ldLCB0eXBlLCBkZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdmFyIGRlbGVnYXRlZCA9IGRlbGVnYXRlZEV2ZW50c1t0eXBlXTtcclxuICB2YXIgaW5kZXggPSB2b2lkIDA7XHJcblxyXG4gIGZvciAoaW5kZXggPSBkZWxlZ2F0ZWQuc2VsZWN0b3JzLmxlbmd0aCAtIDE7IGluZGV4ID49IDA7IGluZGV4LS0pIHtcclxuICAgIGlmIChkZWxlZ2F0ZWQuc2VsZWN0b3JzW2luZGV4XSA9PT0gc2VsZWN0b3IgJiYgZGVsZWdhdGVkLmNvbnRleHRzW2luZGV4XSA9PT0gY29udGV4dCkge1xyXG4gICAgICBicmVhaztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChpbmRleCA9PT0gLTEpIHtcclxuICAgIGluZGV4ID0gZGVsZWdhdGVkLnNlbGVjdG9ycy5sZW5ndGg7XHJcblxyXG4gICAgZGVsZWdhdGVkLnNlbGVjdG9ycy5wdXNoKHNlbGVjdG9yKTtcclxuICAgIGRlbGVnYXRlZC5jb250ZXh0cy5wdXNoKGNvbnRleHQpO1xyXG4gICAgZGVsZWdhdGVkLmxpc3RlbmVycy5wdXNoKFtdKTtcclxuICB9XHJcblxyXG4gIC8vIGtlZXAgbGlzdGVuZXIgYW5kIGNhcHR1cmUgYW5kIHBhc3NpdmUgZmxhZ3NcclxuICBkZWxlZ2F0ZWQubGlzdGVuZXJzW2luZGV4XS5wdXNoKFtsaXN0ZW5lciwgISFvcHRpb25zLmNhcHR1cmUsIG9wdGlvbnMucGFzc2l2ZV0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZW1vdmVEZWxlZ2F0ZShzZWxlY3RvciwgY29udGV4dCwgdHlwZSwgbGlzdGVuZXIsIG9wdGlvbmFsQXJnKSB7XHJcbiAgdmFyIG9wdGlvbnMgPSBnZXRPcHRpb25zKG9wdGlvbmFsQXJnKTtcclxuICB2YXIgZGVsZWdhdGVkID0gZGVsZWdhdGVkRXZlbnRzW3R5cGVdO1xyXG4gIHZhciBtYXRjaEZvdW5kID0gZmFsc2U7XHJcbiAgdmFyIGluZGV4ID0gdm9pZCAwO1xyXG5cclxuICBpZiAoIWRlbGVnYXRlZCkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgLy8gY291bnQgZnJvbSBsYXN0IGluZGV4IG9mIGRlbGVnYXRlZCB0byAwXHJcbiAgZm9yIChpbmRleCA9IGRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXgtLSkge1xyXG4gICAgLy8gbG9vayBmb3IgbWF0Y2hpbmcgc2VsZWN0b3IgYW5kIGNvbnRleHQgTm9kZVxyXG4gICAgaWYgKGRlbGVnYXRlZC5zZWxlY3RvcnNbaW5kZXhdID09PSBzZWxlY3RvciAmJiBkZWxlZ2F0ZWQuY29udGV4dHNbaW5kZXhdID09PSBjb250ZXh0KSB7XHJcblxyXG4gICAgICB2YXIgbGlzdGVuZXJzID0gZGVsZWdhdGVkLmxpc3RlbmVyc1tpbmRleF07XHJcblxyXG4gICAgICAvLyBlYWNoIGl0ZW0gb2YgdGhlIGxpc3RlbmVycyBhcnJheSBpcyBhbiBhcnJheTogW2Z1bmN0aW9uLCBjYXB0dXJlLCBwYXNzaXZlXVxyXG4gICAgICBmb3IgKHZhciBpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIF9saXN0ZW5lcnMkaSA9IGxpc3RlbmVyc1tpXSxcclxuICAgICAgICAgICAgZm4gPSBfbGlzdGVuZXJzJGlbMF0sXHJcbiAgICAgICAgICAgIGNhcHR1cmUgPSBfbGlzdGVuZXJzJGlbMV0sXHJcbiAgICAgICAgICAgIHBhc3NpdmUgPSBfbGlzdGVuZXJzJGlbMl07XHJcblxyXG4gICAgICAgIC8vIGNoZWNrIGlmIHRoZSBsaXN0ZW5lciBmdW5jdGlvbnMgYW5kIGNhcHR1cmUgYW5kIHBhc3NpdmUgZmxhZ3MgbWF0Y2hcclxuXHJcbiAgICAgICAgaWYgKGZuID09PSBsaXN0ZW5lciAmJiBjYXB0dXJlID09PSAhIW9wdGlvbnMuY2FwdHVyZSAmJiBwYXNzaXZlID09PSBvcHRpb25zLnBhc3NpdmUpIHtcclxuICAgICAgICAgIC8vIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzXHJcbiAgICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xyXG5cclxuICAgICAgICAgIC8vIGlmIGFsbCBsaXN0ZW5lcnMgZm9yIHRoaXMgaW50ZXJhY3RhYmxlIGhhdmUgYmVlbiByZW1vdmVkXHJcbiAgICAgICAgICAvLyByZW1vdmUgdGhlIGludGVyYWN0YWJsZSBmcm9tIHRoZSBkZWxlZ2F0ZWQgYXJyYXlzXHJcbiAgICAgICAgICBpZiAoIWxpc3RlbmVycy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgZGVsZWdhdGVkLnNlbGVjdG9ycy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICBkZWxlZ2F0ZWQuY29udGV4dHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgZGVsZWdhdGVkLmxpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xyXG5cclxuICAgICAgICAgICAgLy8gcmVtb3ZlIGRlbGVnYXRlIGZ1bmN0aW9uIGZyb20gY29udGV4dFxyXG4gICAgICAgICAgICByZW1vdmUoY29udGV4dCwgdHlwZSwgZGVsZWdhdGVMaXN0ZW5lcik7XHJcbiAgICAgICAgICAgIHJlbW92ZShjb250ZXh0LCB0eXBlLCBkZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBhcnJheXMgaWYgdGhleSBhcmUgZW1wdHlcclxuICAgICAgICAgICAgaWYgKCFkZWxlZ2F0ZWQuc2VsZWN0b3JzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgIGRlbGVnYXRlZEV2ZW50c1t0eXBlXSA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvLyBvbmx5IHJlbW92ZSBvbmUgbGlzdGVuZXJcclxuICAgICAgICAgIG1hdGNoRm91bmQgPSB0cnVlO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAobWF0Y2hGb3VuZCkge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG4vLyBib3VuZCB0byB0aGUgaW50ZXJhY3RhYmxlIGNvbnRleHQgd2hlbiBhIERPTSBldmVudFxyXG4vLyBsaXN0ZW5lciBpcyBhZGRlZCB0byBhIHNlbGVjdG9yIGludGVyYWN0YWJsZVxyXG5mdW5jdGlvbiBkZWxlZ2F0ZUxpc3RlbmVyKGV2ZW50LCBvcHRpb25hbEFyZykge1xyXG4gIHZhciBvcHRpb25zID0gZ2V0T3B0aW9ucyhvcHRpb25hbEFyZyk7XHJcbiAgdmFyIGZha2VFdmVudCA9IHt9O1xyXG4gIHZhciBkZWxlZ2F0ZWQgPSBkZWxlZ2F0ZWRFdmVudHNbZXZlbnQudHlwZV07XHJcbiAgdmFyIGV2ZW50VGFyZ2V0ID0gZG9tVXRpbHMuZ2V0QWN0dWFsRWxlbWVudChldmVudC5wYXRoID8gZXZlbnQucGF0aFswXSA6IGV2ZW50LnRhcmdldCk7XHJcbiAgdmFyIGVsZW1lbnQgPSBldmVudFRhcmdldDtcclxuXHJcbiAgLy8gZHVwbGljYXRlIHRoZSBldmVudCBzbyB0aGF0IGN1cnJlbnRUYXJnZXQgY2FuIGJlIGNoYW5nZWRcclxuICBwRXh0ZW5kKGZha2VFdmVudCwgZXZlbnQpO1xyXG5cclxuICBmYWtlRXZlbnQub3JpZ2luYWxFdmVudCA9IGV2ZW50O1xyXG4gIGZha2VFdmVudC5wcmV2ZW50RGVmYXVsdCA9IHByZXZlbnRPcmlnaW5hbERlZmF1bHQ7XHJcblxyXG4gIC8vIGNsaW1iIHVwIGRvY3VtZW50IHRyZWUgbG9va2luZyBmb3Igc2VsZWN0b3IgbWF0Y2hlc1xyXG4gIHdoaWxlIChpcy5lbGVtZW50KGVsZW1lbnQpKSB7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgdmFyIHNlbGVjdG9yID0gZGVsZWdhdGVkLnNlbGVjdG9yc1tpXTtcclxuICAgICAgdmFyIGNvbnRleHQgPSBkZWxlZ2F0ZWQuY29udGV4dHNbaV07XHJcblxyXG4gICAgICBpZiAoZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yKSAmJiBkb21VdGlscy5ub2RlQ29udGFpbnMoY29udGV4dCwgZXZlbnRUYXJnZXQpICYmIGRvbVV0aWxzLm5vZGVDb250YWlucyhjb250ZXh0LCBlbGVtZW50KSkge1xyXG5cclxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gZGVsZWdhdGVkLmxpc3RlbmVyc1tpXTtcclxuXHJcbiAgICAgICAgZmFrZUV2ZW50LmN1cnJlbnRUYXJnZXQgPSBlbGVtZW50O1xyXG5cclxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxpc3RlbmVycy5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgdmFyIF9saXN0ZW5lcnMkaiA9IGxpc3RlbmVyc1tqXSxcclxuICAgICAgICAgICAgICBmbiA9IF9saXN0ZW5lcnMkalswXSxcclxuICAgICAgICAgICAgICBjYXB0dXJlID0gX2xpc3RlbmVycyRqWzFdLFxyXG4gICAgICAgICAgICAgIHBhc3NpdmUgPSBfbGlzdGVuZXJzJGpbMl07XHJcblxyXG5cclxuICAgICAgICAgIGlmIChjYXB0dXJlID09PSAhIW9wdGlvbnMuY2FwdHVyZSAmJiBwYXNzaXZlID09PSBvcHRpb25zLnBhc3NpdmUpIHtcclxuICAgICAgICAgICAgZm4oZmFrZUV2ZW50KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBlbGVtZW50ID0gZG9tVXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRlbGVnYXRlVXNlQ2FwdHVyZShldmVudCkge1xyXG4gIHJldHVybiBkZWxlZ2F0ZUxpc3RlbmVyLmNhbGwodGhpcywgZXZlbnQsIHRydWUpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBwcmV2ZW50RGVmKCkge1xyXG4gIHRoaXMucmV0dXJuVmFsdWUgPSBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gcHJldmVudE9yaWdpbmFsRGVmYXVsdCgpIHtcclxuICB0aGlzLm9yaWdpbmFsRXZlbnQucHJldmVudERlZmF1bHQoKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc3RvcFByb3AoKSB7XHJcbiAgdGhpcy5jYW5jZWxCdWJibGUgPSB0cnVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzdG9wSW1tUHJvcCgpIHtcclxuICB0aGlzLmNhbmNlbEJ1YmJsZSA9IHRydWU7XHJcbiAgdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRPcHRpb25zKHBhcmFtKSB7XHJcbiAgcmV0dXJuIGlzLm9iamVjdChwYXJhbSkgPyBwYXJhbSA6IHsgY2FwdHVyZTogcGFyYW0gfTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgYWRkOiBhZGQsXHJcbiAgcmVtb3ZlOiByZW1vdmUsXHJcblxyXG4gIGFkZERlbGVnYXRlOiBhZGREZWxlZ2F0ZSxcclxuICByZW1vdmVEZWxlZ2F0ZTogcmVtb3ZlRGVsZWdhdGUsXHJcblxyXG4gIGRlbGVnYXRlTGlzdGVuZXI6IGRlbGVnYXRlTGlzdGVuZXIsXHJcbiAgZGVsZWdhdGVVc2VDYXB0dXJlOiBkZWxlZ2F0ZVVzZUNhcHR1cmUsXHJcbiAgZGVsZWdhdGVkRXZlbnRzOiBkZWxlZ2F0ZWRFdmVudHMsXHJcbiAgZG9jdW1lbnRzOiBkb2N1bWVudHMsXHJcblxyXG4gIHVzZUF0dGFjaEV2ZW50OiB1c2VBdHRhY2hFdmVudCxcclxuICBzdXBwb3J0c09wdGlvbnM6IHN1cHBvcnRzT3B0aW9ucyxcclxuXHJcbiAgX2VsZW1lbnRzOiBlbGVtZW50cyxcclxuICBfdGFyZ2V0czogdGFyZ2V0cyxcclxuICBfYXR0YWNoZWRMaXN0ZW5lcnM6IGF0dGFjaGVkTGlzdGVuZXJzXHJcbn07XHJcblxyXG59LHtcIi4vYXJyXCI6MzYsXCIuL2RvbVV0aWxzXCI6MzksXCIuL2lzXCI6NDYsXCIuL3BvaW50ZXJFeHRlbmRcIjo0OCxcIi4vd2luZG93XCI6NTJ9XSw0MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBleHRlbmQoZGVzdCwgc291cmNlKSB7XHJcbiAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcclxuICAgIGRlc3RbcHJvcF0gPSBzb3VyY2VbcHJvcF07XHJcbiAgfVxyXG4gIHJldHVybiBkZXN0O1xyXG59O1xyXG5cclxufSx7fV0sNDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL3JlY3QnKSxcclxuICAgIHJlc29sdmVSZWN0TGlrZSA9IF9yZXF1aXJlLnJlc29sdmVSZWN0TGlrZSxcclxuICAgIHJlY3RUb1hZID0gX3JlcXVpcmUucmVjdFRvWFk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIGVsZW1lbnQsIGFjdGlvbikge1xyXG4gIHZhciBhY3Rpb25PcHRpb25zID0gdGFyZ2V0Lm9wdGlvbnNbYWN0aW9uXTtcclxuICB2YXIgYWN0aW9uT3JpZ2luID0gYWN0aW9uT3B0aW9ucyAmJiBhY3Rpb25PcHRpb25zLm9yaWdpbjtcclxuICB2YXIgb3JpZ2luID0gYWN0aW9uT3JpZ2luIHx8IHRhcmdldC5vcHRpb25zLm9yaWdpbjtcclxuXHJcbiAgdmFyIG9yaWdpblJlY3QgPSByZXNvbHZlUmVjdExpa2Uob3JpZ2luLCB0YXJnZXQsIGVsZW1lbnQsIFt0YXJnZXQgJiYgZWxlbWVudF0pO1xyXG5cclxuICByZXR1cm4gcmVjdFRvWFkob3JpZ2luUmVjdCkgfHwgeyB4OiAwLCB5OiAwIH07XHJcbn07XHJcblxyXG59LHtcIi4vcmVjdFwiOjUxfV0sNDM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG5cInVzZSBzdHJpY3RcIjtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHgsIHkpIHtcclxuICByZXR1cm4gTWF0aC5zcXJ0KHggKiB4ICsgeSAqIHkpO1xyXG59O1xyXG5cclxufSx7fV0sNDQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi9leHRlbmQnKTtcclxudmFyIHdpbiA9IHJlcXVpcmUoJy4vd2luZG93Jyk7XHJcblxyXG52YXIgdXRpbHMgPSB7XHJcbiAgd2Fybk9uY2U6IGZ1bmN0aW9uIHdhcm5PbmNlKG1ldGhvZCwgbWVzc2FnZSkge1xyXG4gICAgdmFyIHdhcm5lZCA9IGZhbHNlO1xyXG5cclxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGlmICghd2FybmVkKSB7XHJcbiAgICAgICAgd2luLndpbmRvdy5jb25zb2xlLndhcm4obWVzc2FnZSk7XHJcbiAgICAgICAgd2FybmVkID0gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIG1ldGhvZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9LFxyXG5cclxuICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS81NjM0NTI4LzIyODA4ODhcclxuICBfZ2V0UUJlemllclZhbHVlOiBmdW5jdGlvbiBfZ2V0UUJlemllclZhbHVlKHQsIHAxLCBwMiwgcDMpIHtcclxuICAgIHZhciBpVCA9IDEgLSB0O1xyXG4gICAgcmV0dXJuIGlUICogaVQgKiBwMSArIDIgKiBpVCAqIHQgKiBwMiArIHQgKiB0ICogcDM7XHJcbiAgfSxcclxuXHJcbiAgZ2V0UXVhZHJhdGljQ3VydmVQb2ludDogZnVuY3Rpb24gZ2V0UXVhZHJhdGljQ3VydmVQb2ludChzdGFydFgsIHN0YXJ0WSwgY3BYLCBjcFksIGVuZFgsIGVuZFksIHBvc2l0aW9uKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICB4OiB1dGlscy5fZ2V0UUJlemllclZhbHVlKHBvc2l0aW9uLCBzdGFydFgsIGNwWCwgZW5kWCksXHJcbiAgICAgIHk6IHV0aWxzLl9nZXRRQmV6aWVyVmFsdWUocG9zaXRpb24sIHN0YXJ0WSwgY3BZLCBlbmRZKVxyXG4gICAgfTtcclxuICB9LFxyXG5cclxuICAvLyBodHRwOi8vZ2l6bWEuY29tL2Vhc2luZy9cclxuICBlYXNlT3V0UXVhZDogZnVuY3Rpb24gZWFzZU91dFF1YWQodCwgYiwgYywgZCkge1xyXG4gICAgdCAvPSBkO1xyXG4gICAgcmV0dXJuIC1jICogdCAqICh0IC0gMikgKyBiO1xyXG4gIH0sXHJcblxyXG4gIGNvcHlBY3Rpb246IGZ1bmN0aW9uIGNvcHlBY3Rpb24oZGVzdCwgc3JjKSB7XHJcbiAgICBkZXN0Lm5hbWUgPSBzcmMubmFtZTtcclxuICAgIGRlc3QuYXhpcyA9IHNyYy5heGlzO1xyXG4gICAgZGVzdC5lZGdlcyA9IHNyYy5lZGdlcztcclxuXHJcbiAgICByZXR1cm4gZGVzdDtcclxuICB9LFxyXG5cclxuICBpczogcmVxdWlyZSgnLi9pcycpLFxyXG4gIGV4dGVuZDogZXh0ZW5kLFxyXG4gIGh5cG90OiByZXF1aXJlKCcuL2h5cG90JyksXHJcbiAgZ2V0T3JpZ2luWFk6IHJlcXVpcmUoJy4vZ2V0T3JpZ2luWFknKVxyXG59O1xyXG5cclxuZXh0ZW5kKHV0aWxzLCByZXF1aXJlKCcuL2FycicpKTtcclxuZXh0ZW5kKHV0aWxzLCByZXF1aXJlKCcuL2RvbVV0aWxzJykpO1xyXG5leHRlbmQodXRpbHMsIHJlcXVpcmUoJy4vcG9pbnRlclV0aWxzJykpO1xyXG5leHRlbmQodXRpbHMsIHJlcXVpcmUoJy4vcmVjdCcpKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdXRpbHM7XHJcblxyXG59LHtcIi4vYXJyXCI6MzYsXCIuL2RvbVV0aWxzXCI6MzksXCIuL2V4dGVuZFwiOjQxLFwiLi9nZXRPcmlnaW5YWVwiOjQyLFwiLi9oeXBvdFwiOjQzLFwiLi9pc1wiOjQ2LFwiLi9wb2ludGVyVXRpbHNcIjo0OSxcIi4vcmVjdFwiOjUxLFwiLi93aW5kb3dcIjo1Mn1dLDQ1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcclxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi9pbmRleCcpO1xyXG5cclxudmFyIGZpbmRlciA9IHtcclxuICBtZXRob2RPcmRlcjogWydzaW11bGF0aW9uUmVzdW1lJywgJ21vdXNlT3JQZW4nLCAnaGFzUG9pbnRlcicsICdpZGxlJ10sXHJcblxyXG4gIHNlYXJjaDogZnVuY3Rpb24gc2VhcmNoKHBvaW50ZXIsIGV2ZW50VHlwZSwgZXZlbnRUYXJnZXQpIHtcclxuICAgIHZhciBwb2ludGVyVHlwZSA9IHV0aWxzLmdldFBvaW50ZXJUeXBlKHBvaW50ZXIpO1xyXG4gICAgdmFyIHBvaW50ZXJJZCA9IHV0aWxzLmdldFBvaW50ZXJJZChwb2ludGVyKTtcclxuICAgIHZhciBkZXRhaWxzID0geyBwb2ludGVyOiBwb2ludGVyLCBwb2ludGVySWQ6IHBvaW50ZXJJZCwgcG9pbnRlclR5cGU6IHBvaW50ZXJUeXBlLCBldmVudFR5cGU6IGV2ZW50VHlwZSwgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0IH07XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gZmluZGVyLm1ldGhvZE9yZGVyLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xyXG4gICAgICB2YXIgX3JlZjtcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheSkge1xyXG4gICAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmID0gX2l0ZXJhdG9yW19pKytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcclxuICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZiA9IF9pLnZhbHVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgbWV0aG9kID0gX3JlZjtcclxuXHJcbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IGZpbmRlclttZXRob2RdKGRldGFpbHMpO1xyXG5cclxuICAgICAgaWYgKGludGVyYWN0aW9uKSB7XHJcbiAgICAgICAgcmV0dXJuIGludGVyYWN0aW9uO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgLy8gdHJ5IHRvIHJlc3VtZSBzaW11bGF0aW9uIHdpdGggYSBuZXcgcG9pbnRlclxyXG4gIHNpbXVsYXRpb25SZXN1bWU6IGZ1bmN0aW9uIHNpbXVsYXRpb25SZXN1bWUoX3JlZjIpIHtcclxuICAgIHZhciBwb2ludGVyVHlwZSA9IF9yZWYyLnBvaW50ZXJUeXBlLFxyXG4gICAgICAgIGV2ZW50VHlwZSA9IF9yZWYyLmV2ZW50VHlwZSxcclxuICAgICAgICBldmVudFRhcmdldCA9IF9yZWYyLmV2ZW50VGFyZ2V0O1xyXG5cclxuICAgIGlmICghL2Rvd258c3RhcnQvaS50ZXN0KGV2ZW50VHlwZSkpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IHNjb3BlLmludGVyYWN0aW9ucywgX2lzQXJyYXkyID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IyKSwgX2kyID0gMCwgX2l0ZXJhdG9yMiA9IF9pc0FycmF5MiA/IF9pdGVyYXRvcjIgOiBfaXRlcmF0b3IyW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmMztcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheTIpIHtcclxuICAgICAgICBpZiAoX2kyID49IF9pdGVyYXRvcjIubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmMyA9IF9pdGVyYXRvcjJbX2kyKytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pMiA9IF9pdGVyYXRvcjIubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaTIuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjMgPSBfaTIudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzO1xyXG5cclxuICAgICAgdmFyIGVsZW1lbnQgPSBldmVudFRhcmdldDtcclxuXHJcbiAgICAgIGlmIChpbnRlcmFjdGlvbi5zaW11bGF0aW9uICYmIGludGVyYWN0aW9uLnNpbXVsYXRpb24uYWxsb3dSZXN1bWUgJiYgaW50ZXJhY3Rpb24ucG9pbnRlclR5cGUgPT09IHBvaW50ZXJUeXBlKSB7XHJcbiAgICAgICAgd2hpbGUgKGVsZW1lbnQpIHtcclxuICAgICAgICAgIC8vIGlmIHRoZSBlbGVtZW50IGlzIHRoZSBpbnRlcmFjdGlvbiBlbGVtZW50XHJcbiAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gaW50ZXJhY3Rpb24uZWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb247XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBlbGVtZW50ID0gdXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9LFxyXG5cclxuICAvLyBpZiBpdCdzIGEgbW91c2Ugb3IgcGVuIGludGVyYWN0aW9uXHJcbiAgbW91c2VPclBlbjogZnVuY3Rpb24gbW91c2VPclBlbihfcmVmNCkge1xyXG4gICAgdmFyIHBvaW50ZXJJZCA9IF9yZWY0LnBvaW50ZXJJZCxcclxuICAgICAgICBwb2ludGVyVHlwZSA9IF9yZWY0LnBvaW50ZXJUeXBlLFxyXG4gICAgICAgIGV2ZW50VHlwZSA9IF9yZWY0LmV2ZW50VHlwZTtcclxuXHJcbiAgICBpZiAocG9pbnRlclR5cGUgIT09ICdtb3VzZScgJiYgcG9pbnRlclR5cGUgIT09ICdwZW4nKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBmaXJzdE5vbkFjdGl2ZSA9IHZvaWQgMDtcclxuXHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3IzID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheTMgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjMpLCBfaTMgPSAwLCBfaXRlcmF0b3IzID0gX2lzQXJyYXkzID8gX2l0ZXJhdG9yMyA6IF9pdGVyYXRvcjNbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWY1O1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5Mykge1xyXG4gICAgICAgIGlmIChfaTMgPj0gX2l0ZXJhdG9yMy5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWY1ID0gX2l0ZXJhdG9yM1tfaTMrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kzID0gX2l0ZXJhdG9yMy5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pMy5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmNSA9IF9pMy52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGludGVyYWN0aW9uID0gX3JlZjU7XHJcblxyXG4gICAgICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlclR5cGUgPT09IHBvaW50ZXJUeXBlKSB7XHJcbiAgICAgICAgLy8gaWYgaXQncyBhIGRvd24gZXZlbnQsIHNraXAgaW50ZXJhY3Rpb25zIHdpdGggcnVubmluZyBzaW11bGF0aW9uc1xyXG4gICAgICAgIGlmIChpbnRlcmFjdGlvbi5zaW11bGF0aW9uICYmICF1dGlscy5jb250YWlucyhpbnRlcmFjdGlvbi5wb2ludGVySWRzLCBwb2ludGVySWQpKSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGlmIHRoZSBpbnRlcmFjdGlvbiBpcyBhY3RpdmUsIHJldHVybiBpdCBpbW1lZGlhdGVseVxyXG4gICAgICAgIGlmIChpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpKSB7XHJcbiAgICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb247XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIG90aGVyd2lzZSBzYXZlIGl0IGFuZCBsb29rIGZvciBhbm90aGVyIGFjdGl2ZSBpbnRlcmFjdGlvblxyXG4gICAgICAgIGVsc2UgaWYgKCFmaXJzdE5vbkFjdGl2ZSkge1xyXG4gICAgICAgICAgICBmaXJzdE5vbkFjdGl2ZSA9IGludGVyYWN0aW9uO1xyXG4gICAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaWYgbm8gYWN0aXZlIG1vdXNlIGludGVyYWN0aW9uIHdhcyBmb3VuZCB1c2UgdGhlIGZpcnN0IGluYWN0aXZlIG1vdXNlXHJcbiAgICAvLyBpbnRlcmFjdGlvblxyXG4gICAgaWYgKGZpcnN0Tm9uQWN0aXZlKSB7XHJcbiAgICAgIHJldHVybiBmaXJzdE5vbkFjdGl2ZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBmaW5kIGFueSBtb3VzZSBvciBwZW4gaW50ZXJhY3Rpb24uXHJcbiAgICAvLyBpZ25vcmUgdGhlIGludGVyYWN0aW9uIGlmIHRoZSBldmVudFR5cGUgaXMgYSAqZG93biwgYW5kIGEgc2ltdWxhdGlvblxyXG4gICAgLy8gaXMgYWN0aXZlXHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3I0ID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheTQgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjQpLCBfaTQgPSAwLCBfaXRlcmF0b3I0ID0gX2lzQXJyYXk0ID8gX2l0ZXJhdG9yNCA6IF9pdGVyYXRvcjRbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWY2O1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5NCkge1xyXG4gICAgICAgIGlmIChfaTQgPj0gX2l0ZXJhdG9yNC5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWY2ID0gX2l0ZXJhdG9yNFtfaTQrK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2k0ID0gX2l0ZXJhdG9yNC5uZXh0KCk7XHJcbiAgICAgICAgaWYgKF9pNC5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmNiA9IF9pNC52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIF9pbnRlcmFjdGlvbiA9IF9yZWY2O1xyXG5cclxuICAgICAgaWYgKF9pbnRlcmFjdGlvbi5wb2ludGVyVHlwZSA9PT0gcG9pbnRlclR5cGUgJiYgISgvZG93bi9pLnRlc3QoZXZlbnRUeXBlKSAmJiBfaW50ZXJhY3Rpb24uc2ltdWxhdGlvbikpIHtcclxuICAgICAgICByZXR1cm4gX2ludGVyYWN0aW9uO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfSxcclxuXHJcbiAgLy8gZ2V0IGludGVyYWN0aW9uIHRoYXQgaGFzIHRoaXMgcG9pbnRlclxyXG4gIGhhc1BvaW50ZXI6IGZ1bmN0aW9uIGhhc1BvaW50ZXIoX3JlZjcpIHtcclxuICAgIHZhciBwb2ludGVySWQgPSBfcmVmNy5wb2ludGVySWQ7XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yNSA9IHNjb3BlLmludGVyYWN0aW9ucywgX2lzQXJyYXk1ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3I1KSwgX2k1ID0gMCwgX2l0ZXJhdG9yNSA9IF9pc0FycmF5NSA/IF9pdGVyYXRvcjUgOiBfaXRlcmF0b3I1W1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmODtcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheTUpIHtcclxuICAgICAgICBpZiAoX2k1ID49IF9pdGVyYXRvcjUubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmOCA9IF9pdGVyYXRvcjVbX2k1KytdO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIF9pNSA9IF9pdGVyYXRvcjUubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaTUuZG9uZSkgYnJlYWs7XHJcbiAgICAgICAgX3JlZjggPSBfaTUudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY4O1xyXG5cclxuICAgICAgaWYgKHV0aWxzLmNvbnRhaW5zKGludGVyYWN0aW9uLnBvaW50ZXJJZHMsIHBvaW50ZXJJZCkpIHtcclxuICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb247XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9LFxyXG5cclxuICAvLyBnZXQgZmlyc3QgaWRsZSBpbnRlcmFjdGlvbiB3aXRoIGEgbWF0Y2hpbmcgcG9pbnRlclR5cGVcclxuICBpZGxlOiBmdW5jdGlvbiBpZGxlKF9yZWY5KSB7XHJcbiAgICB2YXIgcG9pbnRlclR5cGUgPSBfcmVmOS5wb2ludGVyVHlwZTtcclxuXHJcbiAgICBmb3IgKHZhciBfaXRlcmF0b3I2ID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheTYgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjYpLCBfaTYgPSAwLCBfaXRlcmF0b3I2ID0gX2lzQXJyYXk2ID8gX2l0ZXJhdG9yNiA6IF9pdGVyYXRvcjZbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcclxuICAgICAgdmFyIF9yZWYxMDtcclxuXHJcbiAgICAgIGlmIChfaXNBcnJheTYpIHtcclxuICAgICAgICBpZiAoX2k2ID49IF9pdGVyYXRvcjYubGVuZ3RoKSBicmVhaztcclxuICAgICAgICBfcmVmMTAgPSBfaXRlcmF0b3I2W19pNisrXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfaTYgPSBfaXRlcmF0b3I2Lm5leHQoKTtcclxuICAgICAgICBpZiAoX2k2LmRvbmUpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYxMCA9IF9pNi52YWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGludGVyYWN0aW9uID0gX3JlZjEwO1xyXG5cclxuICAgICAgLy8gaWYgdGhlcmUncyBhbHJlYWR5IGEgcG9pbnRlciBoZWxkIGRvd25cclxuICAgICAgaWYgKGludGVyYWN0aW9uLnBvaW50ZXJJZHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgdmFyIHRhcmdldCA9IGludGVyYWN0aW9uLnRhcmdldDtcclxuICAgICAgICAvLyBkb24ndCBhZGQgdGhpcyBwb2ludGVyIGlmIHRoZXJlIGlzIGEgdGFyZ2V0IGludGVyYWN0YWJsZSBhbmQgaXRcclxuICAgICAgICAvLyBpc24ndCBnZXN0dXJhYmxlXHJcbiAgICAgICAgaWYgKHRhcmdldCAmJiAhdGFyZ2V0Lm9wdGlvbnMuZ2VzdHVyZS5lbmFibGVkKSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgLy8gbWF4aW11bSBvZiAyIHBvaW50ZXJzIHBlciBpbnRlcmFjdGlvblxyXG4gICAgICBlbHNlIGlmIChpbnRlcmFjdGlvbi5wb2ludGVySWRzLmxlbmd0aCA+PSAyKSB7XHJcbiAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICBpZiAoIWludGVyYWN0aW9uLmludGVyYWN0aW5nKCkgJiYgcG9pbnRlclR5cGUgPT09IGludGVyYWN0aW9uLnBvaW50ZXJUeXBlKSB7XHJcbiAgICAgICAgcmV0dXJuIGludGVyYWN0aW9uO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaW5kZXI7XHJcblxyXG59LHtcIi4uL3Njb3BlXCI6MzQsXCIuL2luZGV4XCI6NDR9XSw0NjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcclxuXHJcbnZhciB3aW4gPSByZXF1aXJlKCcuL3dpbmRvdycpO1xyXG52YXIgaXNXaW5kb3cgPSByZXF1aXJlKCcuL2lzV2luZG93Jyk7XHJcblxyXG52YXIgaXMgPSB7XHJcbiAgYXJyYXk6IGZ1bmN0aW9uIGFycmF5KCkge30sXHJcblxyXG4gIHdpbmRvdzogZnVuY3Rpb24gd2luZG93KHRoaW5nKSB7XHJcbiAgICByZXR1cm4gdGhpbmcgPT09IHdpbi53aW5kb3cgfHwgaXNXaW5kb3codGhpbmcpO1xyXG4gIH0sXHJcblxyXG4gIGRvY0ZyYWc6IGZ1bmN0aW9uIGRvY0ZyYWcodGhpbmcpIHtcclxuICAgIHJldHVybiBpcy5vYmplY3QodGhpbmcpICYmIHRoaW5nLm5vZGVUeXBlID09PSAxMTtcclxuICB9LFxyXG5cclxuICBvYmplY3Q6IGZ1bmN0aW9uIG9iamVjdCh0aGluZykge1xyXG4gICAgcmV0dXJuICEhdGhpbmcgJiYgKHR5cGVvZiB0aGluZyA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YodGhpbmcpKSA9PT0gJ29iamVjdCc7XHJcbiAgfSxcclxuXHJcbiAgZnVuY3Rpb246IGZ1bmN0aW9uIF9mdW5jdGlvbih0aGluZykge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gJ2Z1bmN0aW9uJztcclxuICB9LFxyXG5cclxuICBudW1iZXI6IGZ1bmN0aW9uIG51bWJlcih0aGluZykge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gJ251bWJlcic7XHJcbiAgfSxcclxuXHJcbiAgYm9vbDogZnVuY3Rpb24gYm9vbCh0aGluZykge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gJ2Jvb2xlYW4nO1xyXG4gIH0sXHJcblxyXG4gIHN0cmluZzogZnVuY3Rpb24gc3RyaW5nKHRoaW5nKSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHRoaW5nID09PSAnc3RyaW5nJztcclxuICB9LFxyXG5cclxuICBlbGVtZW50OiBmdW5jdGlvbiBlbGVtZW50KHRoaW5nKSB7XHJcbiAgICBpZiAoIXRoaW5nIHx8ICh0eXBlb2YgdGhpbmcgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHRoaW5nKSkgIT09ICdvYmplY3QnKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgX3dpbmRvdyA9IHdpbi5nZXRXaW5kb3codGhpbmcpIHx8IHdpbi53aW5kb3c7XHJcblxyXG4gICAgcmV0dXJuICgvb2JqZWN0fGZ1bmN0aW9uLy50ZXN0KF90eXBlb2YoX3dpbmRvdy5FbGVtZW50KSkgPyB0aGluZyBpbnN0YW5jZW9mIF93aW5kb3cuRWxlbWVudCAvL0RPTTJcclxuICAgICAgOiB0aGluZy5ub2RlVHlwZSA9PT0gMSAmJiB0eXBlb2YgdGhpbmcubm9kZU5hbWUgPT09ICdzdHJpbmcnXHJcbiAgICApO1xyXG4gIH1cclxufTtcclxuXHJcbmlzLmFycmF5ID0gZnVuY3Rpb24gKHRoaW5nKSB7XHJcbiAgcmV0dXJuIGlzLm9iamVjdCh0aGluZykgJiYgdHlwZW9mIHRoaW5nLmxlbmd0aCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXMuZnVuY3Rpb24odGhpbmcuc3BsaWNlKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gaXM7XHJcblxyXG59LHtcIi4vaXNXaW5kb3dcIjo0NyxcIi4vd2luZG93XCI6NTJ9XSw0NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcblwidXNlIHN0cmljdFwiO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhpbmcpIHtcclxuICByZXR1cm4gISEodGhpbmcgJiYgdGhpbmcuV2luZG93KSAmJiB0aGluZyBpbnN0YW5jZW9mIHRoaW5nLldpbmRvdztcclxufTtcclxuXHJcbn0se31dLDQ4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuZnVuY3Rpb24gcG9pbnRlckV4dGVuZChkZXN0LCBzb3VyY2UpIHtcclxuICBmb3IgKHZhciBwcm9wIGluIHNvdXJjZSkge1xyXG4gICAgdmFyIHByZWZpeGVkUHJvcFJFcyA9IG1vZHVsZS5leHBvcnRzLnByZWZpeGVkUHJvcFJFcztcclxuICAgIHZhciBkZXByZWNhdGVkID0gZmFsc2U7XHJcblxyXG4gICAgLy8gc2tpcCBkZXByZWNhdGVkIHByZWZpeGVkIHByb3BlcnRpZXNcclxuICAgIGZvciAodmFyIHZlbmRvciBpbiBwcmVmaXhlZFByb3BSRXMpIHtcclxuICAgICAgaWYgKHByb3AuaW5kZXhPZih2ZW5kb3IpID09PSAwICYmIHByZWZpeGVkUHJvcFJFc1t2ZW5kb3JdLnRlc3QocHJvcCkpIHtcclxuICAgICAgICBkZXByZWNhdGVkID0gdHJ1ZTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghZGVwcmVjYXRlZCAmJiB0eXBlb2Ygc291cmNlW3Byb3BdICE9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGRlc3RbcHJvcF0gPSBzb3VyY2VbcHJvcF07XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBkZXN0O1xyXG59XHJcblxyXG5wb2ludGVyRXh0ZW5kLnByZWZpeGVkUHJvcFJFcyA9IHtcclxuICB3ZWJraXQ6IC8oTW92ZW1lbnRbWFldfFJhZGl1c1tYWV18Um90YXRpb25BbmdsZXxGb3JjZSkkL1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwb2ludGVyRXh0ZW5kO1xyXG5cclxufSx7fV0sNDk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xyXG4ndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaHlwb3QgPSByZXF1aXJlKCcuL2h5cG90Jyk7XHJcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi9icm93c2VyJyk7XHJcbnZhciBkb20gPSByZXF1aXJlKCcuL2RvbU9iamVjdHMnKTtcclxudmFyIGRvbVV0aWxzID0gcmVxdWlyZSgnLi9kb21VdGlscycpO1xyXG52YXIgZG9tT2JqZWN0cyA9IHJlcXVpcmUoJy4vZG9tT2JqZWN0cycpO1xyXG52YXIgaXMgPSByZXF1aXJlKCcuL2lzJyk7XHJcbnZhciBwb2ludGVyRXh0ZW5kID0gcmVxdWlyZSgnLi9wb2ludGVyRXh0ZW5kJyk7XHJcblxyXG52YXIgcG9pbnRlclV0aWxzID0ge1xyXG4gIGNvcHlDb29yZHM6IGZ1bmN0aW9uIGNvcHlDb29yZHMoZGVzdCwgc3JjKSB7XHJcbiAgICBkZXN0LnBhZ2UgPSBkZXN0LnBhZ2UgfHwge307XHJcbiAgICBkZXN0LnBhZ2UueCA9IHNyYy5wYWdlLng7XHJcbiAgICBkZXN0LnBhZ2UueSA9IHNyYy5wYWdlLnk7XHJcblxyXG4gICAgZGVzdC5jbGllbnQgPSBkZXN0LmNsaWVudCB8fCB7fTtcclxuICAgIGRlc3QuY2xpZW50LnggPSBzcmMuY2xpZW50Lng7XHJcbiAgICBkZXN0LmNsaWVudC55ID0gc3JjLmNsaWVudC55O1xyXG5cclxuICAgIGRlc3QudGltZVN0YW1wID0gc3JjLnRpbWVTdGFtcDtcclxuICB9LFxyXG5cclxuICBzZXRDb29yZERlbHRhczogZnVuY3Rpb24gc2V0Q29vcmREZWx0YXModGFyZ2V0T2JqLCBwcmV2LCBjdXIpIHtcclxuICAgIHRhcmdldE9iai5wYWdlLnggPSBjdXIucGFnZS54IC0gcHJldi5wYWdlLng7XHJcbiAgICB0YXJnZXRPYmoucGFnZS55ID0gY3VyLnBhZ2UueSAtIHByZXYucGFnZS55O1xyXG4gICAgdGFyZ2V0T2JqLmNsaWVudC54ID0gY3VyLmNsaWVudC54IC0gcHJldi5jbGllbnQueDtcclxuICAgIHRhcmdldE9iai5jbGllbnQueSA9IGN1ci5jbGllbnQueSAtIHByZXYuY2xpZW50Lnk7XHJcbiAgICB0YXJnZXRPYmoudGltZVN0YW1wID0gY3VyLnRpbWVTdGFtcCAtIHByZXYudGltZVN0YW1wO1xyXG5cclxuICAgIC8vIHNldCBwb2ludGVyIHZlbG9jaXR5XHJcbiAgICB2YXIgZHQgPSBNYXRoLm1heCh0YXJnZXRPYmoudGltZVN0YW1wIC8gMTAwMCwgMC4wMDEpO1xyXG5cclxuICAgIHRhcmdldE9iai5wYWdlLnNwZWVkID0gaHlwb3QodGFyZ2V0T2JqLnBhZ2UueCwgdGFyZ2V0T2JqLnBhZ2UueSkgLyBkdDtcclxuICAgIHRhcmdldE9iai5wYWdlLnZ4ID0gdGFyZ2V0T2JqLnBhZ2UueCAvIGR0O1xyXG4gICAgdGFyZ2V0T2JqLnBhZ2UudnkgPSB0YXJnZXRPYmoucGFnZS55IC8gZHQ7XHJcblxyXG4gICAgdGFyZ2V0T2JqLmNsaWVudC5zcGVlZCA9IGh5cG90KHRhcmdldE9iai5jbGllbnQueCwgdGFyZ2V0T2JqLnBhZ2UueSkgLyBkdDtcclxuICAgIHRhcmdldE9iai5jbGllbnQudnggPSB0YXJnZXRPYmouY2xpZW50LnggLyBkdDtcclxuICAgIHRhcmdldE9iai5jbGllbnQudnkgPSB0YXJnZXRPYmouY2xpZW50LnkgLyBkdDtcclxuICB9LFxyXG5cclxuICBpc05hdGl2ZVBvaW50ZXI6IGZ1bmN0aW9uIGlzTmF0aXZlUG9pbnRlcihwb2ludGVyKSB7XHJcbiAgICByZXR1cm4gcG9pbnRlciBpbnN0YW5jZW9mIGRvbS5FdmVudCB8fCBwb2ludGVyIGluc3RhbmNlb2YgZG9tLlRvdWNoO1xyXG4gIH0sXHJcblxyXG4gIC8vIEdldCBzcGVjaWZpZWQgWC9ZIGNvb3JkcyBmb3IgbW91c2Ugb3IgZXZlbnQudG91Y2hlc1swXVxyXG4gIGdldFhZOiBmdW5jdGlvbiBnZXRYWSh0eXBlLCBwb2ludGVyLCB4eSkge1xyXG4gICAgeHkgPSB4eSB8fCB7fTtcclxuICAgIHR5cGUgPSB0eXBlIHx8ICdwYWdlJztcclxuXHJcbiAgICB4eS54ID0gcG9pbnRlclt0eXBlICsgJ1gnXTtcclxuICAgIHh5LnkgPSBwb2ludGVyW3R5cGUgKyAnWSddO1xyXG5cclxuICAgIHJldHVybiB4eTtcclxuICB9LFxyXG5cclxuICBnZXRQYWdlWFk6IGZ1bmN0aW9uIGdldFBhZ2VYWShwb2ludGVyLCBwYWdlKSB7XHJcbiAgICBwYWdlID0gcGFnZSB8fCB7fTtcclxuXHJcbiAgICAvLyBPcGVyYSBNb2JpbGUgaGFuZGxlcyB0aGUgdmlld3BvcnQgYW5kIHNjcm9sbGluZyBvZGRseVxyXG4gICAgaWYgKGJyb3dzZXIuaXNPcGVyYU1vYmlsZSAmJiBwb2ludGVyVXRpbHMuaXNOYXRpdmVQb2ludGVyKHBvaW50ZXIpKSB7XHJcbiAgICAgIHBvaW50ZXJVdGlscy5nZXRYWSgnc2NyZWVuJywgcG9pbnRlciwgcGFnZSk7XHJcblxyXG4gICAgICBwYWdlLnggKz0gd2luZG93LnNjcm9sbFg7XHJcbiAgICAgIHBhZ2UueSArPSB3aW5kb3cuc2Nyb2xsWTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHBvaW50ZXJVdGlscy5nZXRYWSgncGFnZScsIHBvaW50ZXIsIHBhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwYWdlO1xyXG4gIH0sXHJcblxyXG4gIGdldENsaWVudFhZOiBmdW5jdGlvbiBnZXRDbGllbnRYWShwb2ludGVyLCBjbGllbnQpIHtcclxuICAgIGNsaWVudCA9IGNsaWVudCB8fCB7fTtcclxuXHJcbiAgICBpZiAoYnJvd3Nlci5pc09wZXJhTW9iaWxlICYmIHBvaW50ZXJVdGlscy5pc05hdGl2ZVBvaW50ZXIocG9pbnRlcikpIHtcclxuICAgICAgLy8gT3BlcmEgTW9iaWxlIGhhbmRsZXMgdGhlIHZpZXdwb3J0IGFuZCBzY3JvbGxpbmcgb2RkbHlcclxuICAgICAgcG9pbnRlclV0aWxzLmdldFhZKCdzY3JlZW4nLCBwb2ludGVyLCBjbGllbnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcG9pbnRlclV0aWxzLmdldFhZKCdjbGllbnQnLCBwb2ludGVyLCBjbGllbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjbGllbnQ7XHJcbiAgfSxcclxuXHJcbiAgZ2V0UG9pbnRlcklkOiBmdW5jdGlvbiBnZXRQb2ludGVySWQocG9pbnRlcikge1xyXG4gICAgcmV0dXJuIGlzLm51bWJlcihwb2ludGVyLnBvaW50ZXJJZCkgPyBwb2ludGVyLnBvaW50ZXJJZCA6IHBvaW50ZXIuaWRlbnRpZmllcjtcclxuICB9LFxyXG5cclxuICBzZXRDb29yZHM6IGZ1bmN0aW9uIHNldENvb3Jkcyh0YXJnZXRPYmosIHBvaW50ZXJzLCB0aW1lU3RhbXApIHtcclxuICAgIHZhciBwb2ludGVyID0gcG9pbnRlcnMubGVuZ3RoID4gMSA/IHBvaW50ZXJVdGlscy5wb2ludGVyQXZlcmFnZShwb2ludGVycykgOiBwb2ludGVyc1swXTtcclxuXHJcbiAgICB2YXIgdG1wWFkgPSB7fTtcclxuXHJcbiAgICBwb2ludGVyVXRpbHMuZ2V0UGFnZVhZKHBvaW50ZXIsIHRtcFhZKTtcclxuICAgIHRhcmdldE9iai5wYWdlLnggPSB0bXBYWS54O1xyXG4gICAgdGFyZ2V0T2JqLnBhZ2UueSA9IHRtcFhZLnk7XHJcblxyXG4gICAgcG9pbnRlclV0aWxzLmdldENsaWVudFhZKHBvaW50ZXIsIHRtcFhZKTtcclxuICAgIHRhcmdldE9iai5jbGllbnQueCA9IHRtcFhZLng7XHJcbiAgICB0YXJnZXRPYmouY2xpZW50LnkgPSB0bXBYWS55O1xyXG5cclxuICAgIHRhcmdldE9iai50aW1lU3RhbXAgPSBpcy5udW1iZXIodGltZVN0YW1wKSA/IHRpbWVTdGFtcCA6IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gIH0sXHJcblxyXG4gIHBvaW50ZXJFeHRlbmQ6IHBvaW50ZXJFeHRlbmQsXHJcblxyXG4gIGdldFRvdWNoUGFpcjogZnVuY3Rpb24gZ2V0VG91Y2hQYWlyKGV2ZW50KSB7XHJcbiAgICB2YXIgdG91Y2hlcyA9IFtdO1xyXG5cclxuICAgIC8vIGFycmF5IG9mIHRvdWNoZXMgaXMgc3VwcGxpZWRcclxuICAgIGlmIChpcy5hcnJheShldmVudCkpIHtcclxuICAgICAgdG91Y2hlc1swXSA9IGV2ZW50WzBdO1xyXG4gICAgICB0b3VjaGVzWzFdID0gZXZlbnRbMV07XHJcbiAgICB9XHJcbiAgICAvLyBhbiBldmVudFxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICd0b3VjaGVuZCcpIHtcclxuICAgICAgICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgICAgICB0b3VjaGVzWzBdID0gZXZlbnQudG91Y2hlc1swXTtcclxuICAgICAgICAgICAgdG91Y2hlc1sxXSA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICB0b3VjaGVzWzBdID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XHJcbiAgICAgICAgICAgIHRvdWNoZXNbMV0gPSBldmVudC5jaGFuZ2VkVG91Y2hlc1sxXTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdG91Y2hlc1swXSA9IGV2ZW50LnRvdWNoZXNbMF07XHJcbiAgICAgICAgICB0b3VjaGVzWzFdID0gZXZlbnQudG91Y2hlc1sxXTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICByZXR1cm4gdG91Y2hlcztcclxuICB9LFxyXG5cclxuICBwb2ludGVyQXZlcmFnZTogZnVuY3Rpb24gcG9pbnRlckF2ZXJhZ2UocG9pbnRlcnMpIHtcclxuICAgIHZhciBhdmVyYWdlID0ge1xyXG4gICAgICBwYWdlWDogMCxcclxuICAgICAgcGFnZVk6IDAsXHJcbiAgICAgIGNsaWVudFg6IDAsXHJcbiAgICAgIGNsaWVudFk6IDAsXHJcbiAgICAgIHNjcmVlblg6IDAsXHJcbiAgICAgIHNjcmVlblk6IDBcclxuICAgIH07XHJcblxyXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gcG9pbnRlcnMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XHJcbiAgICAgIHZhciBfcmVmO1xyXG5cclxuICAgICAgaWYgKF9pc0FycmF5KSB7XHJcbiAgICAgICAgaWYgKF9pID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xyXG4gICAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgX2kgPSBfaXRlcmF0b3IubmV4dCgpO1xyXG4gICAgICAgIGlmIChfaS5kb25lKSBicmVhaztcclxuICAgICAgICBfcmVmID0gX2kudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBwb2ludGVyID0gX3JlZjtcclxuXHJcbiAgICAgIGZvciAodmFyIF9wcm9wIGluIGF2ZXJhZ2UpIHtcclxuICAgICAgICBhdmVyYWdlW19wcm9wXSArPSBwb2ludGVyW19wcm9wXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgZm9yICh2YXIgcHJvcCBpbiBhdmVyYWdlKSB7XHJcbiAgICAgIGF2ZXJhZ2VbcHJvcF0gLz0gcG9pbnRlcnMubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBhdmVyYWdlO1xyXG4gIH0sXHJcblxyXG4gIHRvdWNoQkJveDogZnVuY3Rpb24gdG91Y2hCQm94KGV2ZW50KSB7XHJcbiAgICBpZiAoIWV2ZW50Lmxlbmd0aCAmJiAhKGV2ZW50LnRvdWNoZXMgJiYgZXZlbnQudG91Y2hlcy5sZW5ndGggPiAxKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHRvdWNoZXMgPSBwb2ludGVyVXRpbHMuZ2V0VG91Y2hQYWlyKGV2ZW50KTtcclxuICAgIHZhciBtaW5YID0gTWF0aC5taW4odG91Y2hlc1swXS5wYWdlWCwgdG91Y2hlc1sxXS5wYWdlWCk7XHJcbiAgICB2YXIgbWluWSA9IE1hdGgubWluKHRvdWNoZXNbMF0ucGFnZVksIHRvdWNoZXNbMV0ucGFnZVkpO1xyXG4gICAgdmFyIG1heFggPSBNYXRoLm1heCh0b3VjaGVzWzBdLnBhZ2VYLCB0b3VjaGVzWzFdLnBhZ2VYKTtcclxuICAgIHZhciBtYXhZID0gTWF0aC5tYXgodG91Y2hlc1swXS5wYWdlWSwgdG91Y2hlc1sxXS5wYWdlWSk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgeDogbWluWCxcclxuICAgICAgeTogbWluWSxcclxuICAgICAgbGVmdDogbWluWCxcclxuICAgICAgdG9wOiBtaW5ZLFxyXG4gICAgICB3aWR0aDogbWF4WCAtIG1pblgsXHJcbiAgICAgIGhlaWdodDogbWF4WSAtIG1pbllcclxuICAgIH07XHJcbiAgfSxcclxuXHJcbiAgdG91Y2hEaXN0YW5jZTogZnVuY3Rpb24gdG91Y2hEaXN0YW5jZShldmVudCwgZGVsdGFTb3VyY2UpIHtcclxuICAgIHZhciBzb3VyY2VYID0gZGVsdGFTb3VyY2UgKyAnWCc7XHJcbiAgICB2YXIgc291cmNlWSA9IGRlbHRhU291cmNlICsgJ1knO1xyXG4gICAgdmFyIHRvdWNoZXMgPSBwb2ludGVyVXRpbHMuZ2V0VG91Y2hQYWlyKGV2ZW50KTtcclxuXHJcbiAgICB2YXIgZHggPSB0b3VjaGVzWzBdW3NvdXJjZVhdIC0gdG91Y2hlc1sxXVtzb3VyY2VYXTtcclxuICAgIHZhciBkeSA9IHRvdWNoZXNbMF1bc291cmNlWV0gLSB0b3VjaGVzWzFdW3NvdXJjZVldO1xyXG5cclxuICAgIHJldHVybiBoeXBvdChkeCwgZHkpO1xyXG4gIH0sXHJcblxyXG4gIHRvdWNoQW5nbGU6IGZ1bmN0aW9uIHRvdWNoQW5nbGUoZXZlbnQsIHByZXZBbmdsZSwgZGVsdGFTb3VyY2UpIHtcclxuICAgIHZhciBzb3VyY2VYID0gZGVsdGFTb3VyY2UgKyAnWCc7XHJcbiAgICB2YXIgc291cmNlWSA9IGRlbHRhU291cmNlICsgJ1knO1xyXG4gICAgdmFyIHRvdWNoZXMgPSBwb2ludGVyVXRpbHMuZ2V0VG91Y2hQYWlyKGV2ZW50KTtcclxuICAgIHZhciBkeCA9IHRvdWNoZXNbMV1bc291cmNlWF0gLSB0b3VjaGVzWzBdW3NvdXJjZVhdO1xyXG4gICAgdmFyIGR5ID0gdG91Y2hlc1sxXVtzb3VyY2VZXSAtIHRvdWNoZXNbMF1bc291cmNlWV07XHJcbiAgICB2YXIgYW5nbGUgPSAxODAgKiBNYXRoLmF0YW4yKGR5LCBkeCkgLyBNYXRoLlBJO1xyXG5cclxuICAgIHJldHVybiBhbmdsZTtcclxuICB9LFxyXG5cclxuICBnZXRQb2ludGVyVHlwZTogZnVuY3Rpb24gZ2V0UG9pbnRlclR5cGUocG9pbnRlcikge1xyXG4gICAgcmV0dXJuIGlzLnN0cmluZyhwb2ludGVyLnBvaW50ZXJUeXBlKSA/IHBvaW50ZXIucG9pbnRlclR5cGUgOiBpcy5udW1iZXIocG9pbnRlci5wb2ludGVyVHlwZSkgPyBbdW5kZWZpbmVkLCB1bmRlZmluZWQsICd0b3VjaCcsICdwZW4nLCAnbW91c2UnXVtwb2ludGVyLnBvaW50ZXJUeXBlXVxyXG4gICAgLy8gaWYgdGhlIFBvaW50ZXJFdmVudCBBUEkgaXNuJ3QgYXZhaWxhYmxlLCB0aGVuIHRoZSBcInBvaW50ZXJcIiBtdXN0XHJcbiAgICAvLyBiZSBlaXRoZXIgYSBNb3VzZUV2ZW50LCBUb3VjaEV2ZW50LCBvciBUb3VjaCBvYmplY3RcclxuICAgIDogL3RvdWNoLy50ZXN0KHBvaW50ZXIudHlwZSkgfHwgcG9pbnRlciBpbnN0YW5jZW9mIGRvbU9iamVjdHMuVG91Y2ggPyAndG91Y2gnIDogJ21vdXNlJztcclxuICB9LFxyXG5cclxuICAvLyBbIGV2ZW50LnRhcmdldCwgZXZlbnQuY3VycmVudFRhcmdldCBdXHJcbiAgZ2V0RXZlbnRUYXJnZXRzOiBmdW5jdGlvbiBnZXRFdmVudFRhcmdldHMoZXZlbnQpIHtcclxuICAgIHJldHVybiBbZG9tVXRpbHMuZ2V0QWN0dWFsRWxlbWVudChldmVudC5wYXRoID8gZXZlbnQucGF0aFswXSA6IGV2ZW50LnRhcmdldCksIGRvbVV0aWxzLmdldEFjdHVhbEVsZW1lbnQoZXZlbnQuY3VycmVudFRhcmdldCldO1xyXG4gIH1cclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcG9pbnRlclV0aWxzO1xyXG5cclxufSx7XCIuL2Jyb3dzZXJcIjozNyxcIi4vZG9tT2JqZWN0c1wiOjM4LFwiLi9kb21VdGlsc1wiOjM5LFwiLi9oeXBvdFwiOjQzLFwiLi9pc1wiOjQ2LFwiLi9wb2ludGVyRXh0ZW5kXCI6NDh9XSw1MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4vd2luZG93JyksXHJcbiAgICB3aW5kb3cgPSBfcmVxdWlyZS53aW5kb3c7XHJcblxyXG52YXIgdmVuZG9ycyA9IFsnbXMnLCAnbW96JywgJ3dlYmtpdCcsICdvJ107XHJcbnZhciBsYXN0VGltZSA9IDA7XHJcbnZhciByZXF1ZXN0ID0gdm9pZCAwO1xyXG52YXIgY2FuY2VsID0gdm9pZCAwO1xyXG5cclxuZm9yICh2YXIgeCA9IDA7IHggPCB2ZW5kb3JzLmxlbmd0aCAmJiAhd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZTsgeCsrKSB7XHJcbiAgcmVxdWVzdCA9IHdpbmRvd1t2ZW5kb3JzW3hdICsgJ1JlcXVlc3RBbmltYXRpb25GcmFtZSddO1xyXG4gIGNhbmNlbCA9IHdpbmRvd1t2ZW5kb3JzW3hdICsgJ0NhbmNlbEFuaW1hdGlvbkZyYW1lJ10gfHwgd2luZG93W3ZlbmRvcnNbeF0gKyAnQ2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lJ107XHJcbn1cclxuXHJcbmlmICghcmVxdWVzdCkge1xyXG4gIHJlcXVlc3QgPSBmdW5jdGlvbiByZXF1ZXN0KGNhbGxiYWNrKSB7XHJcbiAgICB2YXIgY3VyclRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgIHZhciB0aW1lVG9DYWxsID0gTWF0aC5tYXgoMCwgMTYgLSAoY3VyclRpbWUgLSBsYXN0VGltZSkpO1xyXG4gICAgdmFyIGlkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGNhbGxiYWNrKGN1cnJUaW1lICsgdGltZVRvQ2FsbCk7XHJcbiAgICB9LCB0aW1lVG9DYWxsKTtcclxuXHJcbiAgICBsYXN0VGltZSA9IGN1cnJUaW1lICsgdGltZVRvQ2FsbDtcclxuICAgIHJldHVybiBpZDtcclxuICB9O1xyXG59XHJcblxyXG5pZiAoIWNhbmNlbCkge1xyXG4gIGNhbmNlbCA9IGZ1bmN0aW9uIGNhbmNlbChpZCkge1xyXG4gICAgY2xlYXJUaW1lb3V0KGlkKTtcclxuICB9O1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHtcclxuICByZXF1ZXN0OiByZXF1ZXN0LFxyXG4gIGNhbmNlbDogY2FuY2VsXHJcbn07XHJcblxyXG59LHtcIi4vd2luZG93XCI6NTJ9XSw1MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBleHRlbmQgPSByZXF1aXJlKCcuL2V4dGVuZCcpO1xyXG52YXIgaXMgPSByZXF1aXJlKCcuL2lzJyk7XHJcblxyXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL2RvbVV0aWxzJyksXHJcbiAgICBjbG9zZXN0ID0gX3JlcXVpcmUuY2xvc2VzdCxcclxuICAgIHBhcmVudE5vZGUgPSBfcmVxdWlyZS5wYXJlbnROb2RlLFxyXG4gICAgZ2V0RWxlbWVudFJlY3QgPSBfcmVxdWlyZS5nZXRFbGVtZW50UmVjdDtcclxuXHJcbnZhciByZWN0VXRpbHMgPSB7XHJcbiAgZ2V0U3RyaW5nT3B0aW9uUmVzdWx0OiBmdW5jdGlvbiBnZXRTdHJpbmdPcHRpb25SZXN1bHQodmFsdWUsIGludGVyYWN0YWJsZSwgZWxlbWVudCkge1xyXG4gICAgaWYgKCFpcy5zdHJpbmcodmFsdWUpKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh2YWx1ZSA9PT0gJ3BhcmVudCcpIHtcclxuICAgICAgdmFsdWUgPSBwYXJlbnROb2RlKGVsZW1lbnQpO1xyXG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJ3NlbGYnKSB7XHJcbiAgICAgIHZhbHVlID0gaW50ZXJhY3RhYmxlLmdldFJlY3QoZWxlbWVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YWx1ZSA9IGNsb3Nlc3QoZWxlbWVudCwgdmFsdWUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB2YWx1ZTtcclxuICB9LFxyXG5cclxuICByZXNvbHZlUmVjdExpa2U6IGZ1bmN0aW9uIHJlc29sdmVSZWN0TGlrZSh2YWx1ZSwgaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBmdW5jdGlvbkFyZ3MpIHtcclxuICAgIHZhbHVlID0gcmVjdFV0aWxzLmdldFN0cmluZ09wdGlvblJlc3VsdCh2YWx1ZSwgaW50ZXJhY3RhYmxlLCBlbGVtZW50KSB8fCB2YWx1ZTtcclxuXHJcbiAgICBpZiAoaXMuZnVuY3Rpb24odmFsdWUpKSB7XHJcbiAgICAgIHZhbHVlID0gdmFsdWUuYXBwbHkobnVsbCwgZnVuY3Rpb25BcmdzKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaXMuZWxlbWVudCh2YWx1ZSkpIHtcclxuICAgICAgdmFsdWUgPSBnZXRFbGVtZW50UmVjdCh2YWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG4gIH0sXHJcblxyXG4gIHJlY3RUb1hZOiBmdW5jdGlvbiByZWN0VG9YWShyZWN0KSB7XHJcbiAgICByZXR1cm4gcmVjdCAmJiB7XHJcbiAgICAgIHg6ICd4JyBpbiByZWN0ID8gcmVjdC54IDogcmVjdC5sZWZ0LFxyXG4gICAgICB5OiAneScgaW4gcmVjdCA/IHJlY3QueSA6IHJlY3QudG9wXHJcbiAgICB9O1xyXG4gIH0sXHJcblxyXG4gIHh5d2hUb1RsYnI6IGZ1bmN0aW9uIHh5d2hUb1RsYnIocmVjdCkge1xyXG4gICAgaWYgKHJlY3QgJiYgISgnbGVmdCcgaW4gcmVjdCAmJiAndG9wJyBpbiByZWN0KSkge1xyXG4gICAgICByZWN0ID0gZXh0ZW5kKHt9LCByZWN0KTtcclxuXHJcbiAgICAgIHJlY3QubGVmdCA9IHJlY3QueCB8fCAwO1xyXG4gICAgICByZWN0LnRvcCA9IHJlY3QueSB8fCAwO1xyXG4gICAgICByZWN0LnJpZ2h0ID0gcmVjdC5yaWdodCB8fCByZWN0LmxlZnQgKyByZWN0LndpZHRoO1xyXG4gICAgICByZWN0LmJvdHRvbSA9IHJlY3QuYm90dG9tIHx8IHJlY3QudG9wICsgcmVjdC5oZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlY3Q7XHJcbiAgfSxcclxuXHJcbiAgdGxiclRvWHl3aDogZnVuY3Rpb24gdGxiclRvWHl3aChyZWN0KSB7XHJcbiAgICBpZiAocmVjdCAmJiAhKCd4JyBpbiByZWN0ICYmICd5JyBpbiByZWN0KSkge1xyXG4gICAgICByZWN0ID0gZXh0ZW5kKHt9LCByZWN0KTtcclxuXHJcbiAgICAgIHJlY3QueCA9IHJlY3QubGVmdCB8fCAwO1xyXG4gICAgICByZWN0LnRvcCA9IHJlY3QudG9wIHx8IDA7XHJcbiAgICAgIHJlY3Qud2lkdGggPSByZWN0LndpZHRoIHx8IHJlY3QucmlnaHQgLSByZWN0Lng7XHJcbiAgICAgIHJlY3QuaGVpZ2h0ID0gcmVjdC5oZWlnaHQgfHwgcmVjdC5ib3R0b20gLSByZWN0Lnk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlY3Q7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZWN0VXRpbHM7XHJcblxyXG59LHtcIi4vZG9tVXRpbHNcIjozOSxcIi4vZXh0ZW5kXCI6NDEsXCIuL2lzXCI6NDZ9XSw1MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XHJcbid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciB3aW4gPSBtb2R1bGUuZXhwb3J0cztcclxudmFyIGlzV2luZG93ID0gcmVxdWlyZSgnLi9pc1dpbmRvdycpO1xyXG5cclxuZnVuY3Rpb24gaW5pdCh3aW5kb3cpIHtcclxuICAvLyBnZXQgd3JhcHBlZCB3aW5kb3cgaWYgdXNpbmcgU2hhZG93IERPTSBwb2x5ZmlsbFxyXG5cclxuICB3aW4ucmVhbFdpbmRvdyA9IHdpbmRvdztcclxuXHJcbiAgLy8gY3JlYXRlIGEgVGV4dE5vZGVcclxuICB2YXIgZWwgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xyXG5cclxuICAvLyBjaGVjayBpZiBpdCdzIHdyYXBwZWQgYnkgYSBwb2x5ZmlsbFxyXG4gIGlmIChlbC5vd25lckRvY3VtZW50ICE9PSB3aW5kb3cuZG9jdW1lbnQgJiYgdHlwZW9mIHdpbmRvdy53cmFwID09PSAnZnVuY3Rpb24nICYmIHdpbmRvdy53cmFwKGVsKSA9PT0gZWwpIHtcclxuICAgIC8vIHVzZSB3cmFwcGVkIHdpbmRvd1xyXG4gICAgd2luZG93ID0gd2luZG93LndyYXAod2luZG93KTtcclxuICB9XHJcblxyXG4gIHdpbi53aW5kb3cgPSB3aW5kb3c7XHJcbn1cclxuXHJcbmlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xyXG4gIHdpbi53aW5kb3cgPSB1bmRlZmluZWQ7XHJcbiAgd2luLnJlYWxXaW5kb3cgPSB1bmRlZmluZWQ7XHJcbn0gZWxzZSB7XHJcbiAgaW5pdCh3aW5kb3cpO1xyXG59XHJcblxyXG53aW4uZ2V0V2luZG93ID0gZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHtcclxuICBpZiAoaXNXaW5kb3cobm9kZSkpIHtcclxuICAgIHJldHVybiBub2RlO1xyXG4gIH1cclxuXHJcbiAgdmFyIHJvb3ROb2RlID0gbm9kZS5vd25lckRvY3VtZW50IHx8IG5vZGU7XHJcblxyXG4gIHJldHVybiByb290Tm9kZS5kZWZhdWx0VmlldyB8fCByb290Tm9kZS5wYXJlbnRXaW5kb3cgfHwgd2luLndpbmRvdztcclxufTtcclxuXHJcbndpbi5pbml0ID0gaW5pdDtcclxuXHJcbn0se1wiLi9pc1dpbmRvd1wiOjQ3fV19LHt9LFsxXSkoMSlcclxufSk7XHJcblxyXG5cclxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW50ZXJhY3QuanMubWFwXHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2ludGVyYWN0anMvZGlzdC9pbnRlcmFjdC5qc1xuLy8gbW9kdWxlIGlkID0gMTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///15\n"); /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { -eval("var require;var require;/**\n * interact.js v1.3.0-alpha.4+sha.7970416-dirty\n *\n * Copyright (c) 2012-2017 Taye Adeyemi \n * Open source under the MIT License.\n * https://raw.github.com/taye/interact.js/master/LICENSE\n */\n(function(f){if(true){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.interact = f()}})(function(){var define,module,exports;return (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 require(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 6 && arguments[6] !== undefined ? arguments[6] : false;\n\n _classCallCheck(this, InteractEvent);\n\n var target = interaction.target;\n var deltaSource = (target && target.options || defaults).deltaSource;\n var origin = getOriginXY(target, element, action);\n var starting = phase === 'start';\n var ending = phase === 'end';\n var coords = starting ? interaction.startCoords : interaction.curCoords;\n var prevEvent = interaction.prevEvent;\n\n element = element || interaction.element;\n\n var page = extend({}, coords.page);\n var client = extend({}, coords.client);\n\n page.x -= origin.x;\n page.y -= origin.y;\n\n client.x -= origin.x;\n client.y -= origin.y;\n\n this.ctrlKey = event.ctrlKey;\n this.altKey = event.altKey;\n this.shiftKey = event.shiftKey;\n this.metaKey = event.metaKey;\n this.button = event.button;\n this.buttons = event.buttons;\n this.target = element;\n this.currentTarget = element;\n this.relatedTarget = related || null;\n this.preEnd = preEnd;\n this.type = action + (phase || '');\n this.interaction = interaction;\n this.interactable = target;\n\n this.t0 = starting ? interaction.downTimes[interaction.downTimes.length - 1] : prevEvent.t0;\n\n var signalArg = {\n interaction: interaction,\n event: event,\n action: action,\n phase: phase,\n element: element,\n related: related,\n page: page,\n client: client,\n coords: coords,\n starting: starting,\n ending: ending,\n deltaSource: deltaSource,\n iEvent: this\n };\n\n signals.fire('set-xy', signalArg);\n\n if (ending) {\n // use previous coords when ending\n this.pageX = prevEvent.pageX;\n this.pageY = prevEvent.pageY;\n this.clientX = prevEvent.clientX;\n this.clientY = prevEvent.clientY;\n } else {\n this.pageX = page.x;\n this.pageY = page.y;\n this.clientX = client.x;\n this.clientY = client.y;\n }\n\n this.x0 = interaction.startCoords.page.x - origin.x;\n this.y0 = interaction.startCoords.page.y - origin.y;\n this.clientX0 = interaction.startCoords.client.x - origin.x;\n this.clientY0 = interaction.startCoords.client.y - origin.y;\n\n signals.fire('set-delta', signalArg);\n\n this.timeStamp = coords.timeStamp;\n this.dt = interaction.pointerDelta.timeStamp;\n this.duration = this.timeStamp - this.t0;\n\n // speed and velocity in pixels per second\n this.speed = interaction.pointerDelta[deltaSource].speed;\n this.velocityX = interaction.pointerDelta[deltaSource].vx;\n this.velocityY = interaction.pointerDelta[deltaSource].vy;\n\n this.swipe = ending || phase === 'inertiastart' ? this.getSwipe() : null;\n\n signals.fire('new', signalArg);\n }\n\n InteractEvent.prototype.getSwipe = function getSwipe() {\n var interaction = this.interaction;\n\n if (interaction.prevEvent.speed < 600 || this.timeStamp - interaction.prevEvent.timeStamp > 150) {\n return null;\n }\n\n var angle = 180 * Math.atan2(interaction.prevEvent.velocityY, interaction.prevEvent.velocityX) / Math.PI;\n var overlap = 22.5;\n\n if (angle < 0) {\n angle += 360;\n }\n\n var left = 135 - overlap <= angle && angle < 225 + overlap;\n var up = 225 - overlap <= angle && angle < 315 + overlap;\n\n var right = !left && (315 - overlap <= angle || angle < 45 + overlap);\n var down = !up && 45 - overlap <= angle && angle < 135 + overlap;\n\n return {\n up: up,\n down: down,\n left: left,\n right: right,\n angle: angle,\n speed: interaction.prevEvent.speed,\n velocity: {\n x: interaction.prevEvent.velocityX,\n y: interaction.prevEvent.velocityY\n }\n };\n };\n\n InteractEvent.prototype.preventDefault = function preventDefault() {};\n\n InteractEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {\n this.immediatePropagationStopped = this.propagationStopped = true;\n };\n\n InteractEvent.prototype.stopPropagation = function stopPropagation() {\n this.propagationStopped = true;\n };\n\n return InteractEvent;\n}();\n\nsignals.on('set-delta', function (_ref) {\n var iEvent = _ref.iEvent,\n interaction = _ref.interaction,\n starting = _ref.starting,\n deltaSource = _ref.deltaSource;\n\n var prevEvent = starting ? iEvent : interaction.prevEvent;\n\n if (deltaSource === 'client') {\n iEvent.dx = iEvent.clientX - prevEvent.clientX;\n iEvent.dy = iEvent.clientY - prevEvent.clientY;\n } else {\n iEvent.dx = iEvent.pageX - prevEvent.pageX;\n iEvent.dy = iEvent.pageY - prevEvent.pageY;\n }\n});\n\nInteractEvent.signals = signals;\n\nmodule.exports = InteractEvent;\n\n},{\"./defaultOptions\":18,\"./utils/Signals\":35,\"./utils/extend\":41,\"./utils/getOriginXY\":42}],4:[function(require,module,exports){\n'use strict';\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar is = require('./utils/is');\nvar events = require('./utils/events');\nvar extend = require('./utils/extend');\nvar actions = require('./actions/base');\nvar scope = require('./scope');\nvar Eventable = require('./Eventable');\nvar defaults = require('./defaultOptions');\nvar signals = require('./utils/Signals').new();\n\nvar _require = require('./utils/domUtils'),\n getElementRect = _require.getElementRect,\n nodeContains = _require.nodeContains,\n trySelector = _require.trySelector;\n\nvar _require2 = require('./utils/window'),\n getWindow = _require2.getWindow;\n\nvar _require3 = require('./utils/arr'),\n indexOf = _require3.indexOf,\n contains = _require3.contains;\n\nvar _require4 = require('./utils/browser'),\n wheelEvent = _require4.wheelEvent;\n\n// all set interactables\n\n\nscope.interactables = [];\n\n/*\\\n * Interactable\n [ property ]\n **\n * Object type returned by @interact\n\\*/\n\nvar Interactable = function () {\n function Interactable(target, options) {\n _classCallCheck(this, Interactable);\n\n options = options || {};\n\n this.target = target;\n this.events = new Eventable();\n this._context = options.context || scope.document;\n this._win = getWindow(trySelector(target) ? this._context : target);\n this._doc = this._win.document;\n\n signals.fire('new', {\n target: target,\n options: options,\n interactable: this,\n win: this._win\n });\n\n scope.addDocument(this._doc, this._win);\n\n scope.interactables.push(this);\n\n this.set(options);\n }\n\n Interactable.prototype.setOnEvents = function setOnEvents(action, phases) {\n var onAction = 'on' + action;\n\n if (is.function(phases.onstart)) {\n this.events[onAction + 'start'] = phases.onstart;\n }\n if (is.function(phases.onmove)) {\n this.events[onAction + 'move'] = phases.onmove;\n }\n if (is.function(phases.onend)) {\n this.events[onAction + 'end'] = phases.onend;\n }\n if (is.function(phases.oninertiastart)) {\n this.events[onAction + 'inertiastart'] = phases.oninertiastart;\n }\n\n return this;\n };\n\n Interactable.prototype.setPerAction = function setPerAction(action, options) {\n // for all the default per-action options\n for (var option in options) {\n // if this option exists for this action\n if (option in defaults[action]) {\n // if the option in the options arg is an object value\n if (is.object(options[option])) {\n // duplicate the object\n this.options[action][option] = extend(this.options[action][option] || {}, options[option]);\n\n if (is.object(defaults.perAction[option]) && 'enabled' in defaults.perAction[option]) {\n this.options[action][option].enabled = options[option].enabled === false ? false : true;\n }\n } else if (is.bool(options[option]) && is.object(defaults.perAction[option])) {\n this.options[action][option].enabled = options[option];\n } else if (options[option] !== undefined) {\n // or if it's not undefined, do a plain assignment\n this.options[action][option] = options[option];\n }\n }\n }\n };\n\n /*\\\n * Interactable.getRect\n [ method ]\n *\n * The default function to get an Interactables bounding rect. Can be\n * overridden using @Interactable.rectChecker.\n *\n - element (Element) #optional The element to measure.\n = (object) The object's bounding rectangle.\n o {\n o top : 0,\n o left : 0,\n o bottom: 0,\n o right : 0,\n o width : 0,\n o height: 0\n o }\n \\*/\n\n\n Interactable.prototype.getRect = function getRect(element) {\n element = element || this.target;\n\n if (is.string(this.target) && !is.element(element)) {\n element = this._context.querySelector(this.target);\n }\n\n return getElementRect(element);\n };\n\n /*\\\n * Interactable.rectChecker\n [ method ]\n *\n * Returns or sets the function used to calculate the interactable's\n * element's rectangle\n *\n - checker (function) #optional A function which returns this Interactable's bounding rectangle. See @Interactable.getRect\n = (function | object) The checker function or this Interactable\n \\*/\n\n\n Interactable.prototype.rectChecker = function rectChecker(checker) {\n if (is.function(checker)) {\n this.getRect = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.getRect;\n\n return this;\n }\n\n return this.getRect;\n };\n\n Interactable.prototype._backCompatOption = function _backCompatOption(optionName, newValue) {\n if (trySelector(newValue) || is.object(newValue)) {\n this.options[optionName] = newValue;\n\n for (var _iterator = actions.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var action = _ref;\n\n this.options[action][optionName] = newValue;\n }\n\n return this;\n }\n\n return this.options[optionName];\n };\n\n /*\\\n * Interactable.origin\n [ method ]\n *\n * Gets or sets the origin of the Interactable's element. The x and y\n * of the origin will be subtracted from action event coordinates.\n *\n - origin (object | string) #optional An object eg. { x: 0, y: 0 } or string 'parent', 'self' or any CSS selector\n * OR\n - origin (Element) #optional An HTML or SVG Element whose rect will be used\n **\n = (object) The current origin or this Interactable\n \\*/\n\n\n Interactable.prototype.origin = function origin(newValue) {\n return this._backCompatOption('origin', newValue);\n };\n\n /*\\\n * Interactable.deltaSource\n [ method ]\n *\n * Returns or sets the mouse coordinate types used to calculate the\n * movement of the pointer.\n *\n - newValue (string) #optional Use 'client' if you will be scrolling while interacting; Use 'page' if you want autoScroll to work\n = (string | object) The current deltaSource or this Interactable\n \\*/\n\n\n Interactable.prototype.deltaSource = function deltaSource(newValue) {\n if (newValue === 'page' || newValue === 'client') {\n this.options.deltaSource = newValue;\n\n return this;\n }\n\n return this.options.deltaSource;\n };\n\n /*\\\n * Interactable.context\n [ method ]\n *\n * Gets the selector context Node of the Interactable. The default is `window.document`.\n *\n = (Node) The context Node of this Interactable\n **\n \\*/\n\n\n Interactable.prototype.context = function context() {\n return this._context;\n };\n\n Interactable.prototype.inContext = function inContext(element) {\n return this._context === element.ownerDocument || nodeContains(this._context, element);\n };\n\n /*\\\n * Interactable.fire\n [ method ]\n *\n * Calls listeners for the given InteractEvent type bound globally\n * and directly to this Interactable\n *\n - iEvent (InteractEvent) The InteractEvent object to be fired on this Interactable\n = (Interactable) this Interactable\n \\*/\n\n\n Interactable.prototype.fire = function fire(iEvent) {\n this.events.fire(iEvent);\n\n return this;\n };\n\n Interactable.prototype._onOffMultiple = function _onOffMultiple(method, eventType, listener, options) {\n if (is.string(eventType) && eventType.search(' ') !== -1) {\n eventType = eventType.trim().split(/ +/);\n }\n\n if (is.array(eventType)) {\n for (var i = 0; i < eventType.length; i++) {\n this[method](eventType[i], listener, options);\n }\n\n return true;\n }\n\n if (is.object(eventType)) {\n for (var prop in eventType) {\n this[method](prop, eventType[prop], listener);\n }\n\n return true;\n }\n };\n\n /*\\\n * Interactable.on\n [ method ]\n *\n * Binds a listener for an InteractEvent, pointerEvent or DOM event.\n *\n - eventType (string | array | object) The types of events to listen for\n - listener (function) The function event (s)\n - options (object | boolean) #optional options object or useCapture flag for addEventListener\n = (object) This Interactable\n \\*/\n\n\n Interactable.prototype.on = function on(eventType, listener, options) {\n if (this._onOffMultiple('on', eventType, listener, options)) {\n return this;\n }\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n if (contains(Interactable.eventTypes, eventType)) {\n this.events.on(eventType, listener);\n }\n // delegated event for selector\n else if (is.string(this.target)) {\n events.addDelegate(this.target, this._context, eventType, listener, options);\n } else {\n events.add(this.target, eventType, listener, options);\n }\n\n return this;\n };\n\n /*\\\n * Interactable.off\n [ method ]\n *\n * Removes an InteractEvent, pointerEvent or DOM event listener\n *\n - eventType (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - options (object | boolean) #optional options object or useCapture flag for removeEventListener\n = (object) This Interactable\n \\*/\n\n\n Interactable.prototype.off = function off(eventType, listener, options) {\n if (this._onOffMultiple('off', eventType, listener, options)) {\n return this;\n }\n\n if (eventType === 'wheel') {\n eventType = wheelEvent;\n }\n\n // if it is an action event type\n if (contains(Interactable.eventTypes, eventType)) {\n this.events.off(eventType, listener);\n }\n // delegated event\n else if (is.string(this.target)) {\n events.removeDelegate(this.target, this._context, eventType, listener, options);\n }\n // remove listener from this Interatable's element\n else {\n events.remove(this.target, eventType, listener, options);\n }\n\n return this;\n };\n\n /*\\\n * Interactable.set\n [ method ]\n *\n * Reset the options of this Interactable\n - options (object) The new settings to apply\n = (object) This Interactable\n \\*/\n\n\n Interactable.prototype.set = function set(options) {\n if (!is.object(options)) {\n options = {};\n }\n\n this.options = extend({}, defaults.base);\n\n var perActions = extend({}, defaults.perAction);\n\n for (var actionName in actions.methodDict) {\n var methodName = actions.methodDict[actionName];\n\n this.options[actionName] = extend({}, defaults[actionName]);\n\n this.setPerAction(actionName, perActions);\n\n this[methodName](options[actionName]);\n }\n\n for (var _iterator2 = Interactable.settingsMethods, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\n var _ref2;\n\n if (_isArray2) {\n if (_i2 >= _iterator2.length) break;\n _ref2 = _iterator2[_i2++];\n } else {\n _i2 = _iterator2.next();\n if (_i2.done) break;\n _ref2 = _i2.value;\n }\n\n var setting = _ref2;\n\n this.options[setting] = defaults.base[setting];\n\n if (setting in options) {\n this[setting](options[setting]);\n }\n }\n\n signals.fire('set', {\n options: options,\n interactable: this\n });\n\n return this;\n };\n\n /*\\\n * Interactable.unset\n [ method ]\n *\n * Remove this interactable from the list of interactables and remove\n * it's action capabilities and event listeners\n *\n = (object) @interact\n \\*/\n\n\n Interactable.prototype.unset = function unset() {\n events.remove(this.target, 'all');\n\n if (is.string(this.target)) {\n // remove delegated events\n for (var type in events.delegatedEvents) {\n var delegated = events.delegatedEvents[type];\n\n if (delegated.selectors[0] === this.target && delegated.contexts[0] === this._context) {\n\n delegated.selectors.splice(0, 1);\n delegated.contexts.splice(0, 1);\n delegated.listeners.splice(0, 1);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegated[type] = null;\n }\n }\n\n events.remove(this._context, type, events.delegateListener);\n events.remove(this._context, type, events.delegateUseCapture, true);\n }\n } else {\n events.remove(this, 'all');\n }\n\n signals.fire('unset', { interactable: this });\n\n scope.interactables.splice(indexOf(scope.interactables, this), 1);\n\n // Stop related interactions when an Interactable is unset\n for (var _iterator3 = scope.interactions || [], _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {\n var _ref3;\n\n if (_isArray3) {\n if (_i3 >= _iterator3.length) break;\n _ref3 = _iterator3[_i3++];\n } else {\n _i3 = _iterator3.next();\n if (_i3.done) break;\n _ref3 = _i3.value;\n }\n\n var interaction = _ref3;\n\n if (interaction.target === this && interaction.interacting()) {\n interaction.stop();\n }\n }\n\n return scope.interact;\n };\n\n return Interactable;\n}();\n\nscope.interactables.indexOfElement = function indexOfElement(target, context) {\n context = context || scope.document;\n\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n if (interactable.target === target && interactable._context === context) {\n return i;\n }\n }\n return -1;\n};\n\nscope.interactables.get = function interactableGet(element, options, dontCheckInContext) {\n var ret = this[this.indexOfElement(element, options && options.context)];\n\n return ret && (is.string(element) || dontCheckInContext || ret.inContext(element)) ? ret : null;\n};\n\nscope.interactables.forEachSelector = function (callback, element) {\n for (var i = 0; i < this.length; i++) {\n var interactable = this[i];\n\n // skip non CSS selector targets and out of context elements\n if (!is.string(interactable.target) || element && !interactable.inContext(element)) {\n continue;\n }\n\n var ret = callback(interactable, interactable.target, interactable._context, i, this);\n\n if (ret !== undefined) {\n return ret;\n }\n }\n};\n\n// all interact.js eventTypes\nInteractable.eventTypes = scope.eventTypes = [];\n\nInteractable.signals = signals;\n\nInteractable.settingsMethods = ['deltaSource', 'origin', 'preventDefault', 'rectChecker'];\n\nmodule.exports = Interactable;\n\n},{\"./Eventable\":2,\"./actions/base\":6,\"./defaultOptions\":18,\"./scope\":34,\"./utils/Signals\":35,\"./utils/arr\":36,\"./utils/browser\":37,\"./utils/domUtils\":39,\"./utils/events\":40,\"./utils/extend\":41,\"./utils/is\":46,\"./utils/window\":52}],5:[function(require,module,exports){\n'use strict';\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar scope = require('./scope');\nvar utils = require('./utils');\nvar events = require('./utils/events');\nvar browser = require('./utils/browser');\nvar domObjects = require('./utils/domObjects');\nvar finder = require('./utils/interactionFinder');\nvar signals = require('./utils/Signals').new();\n\nvar listeners = {};\nvar methodNames = ['pointerDown', 'pointerMove', 'pointerUp', 'updatePointer', 'removePointer'];\n\n// for ignoring browser's simulated mouse events\nvar prevTouchTime = 0;\n\n// all active and idle interactions\nscope.interactions = [];\n\nvar Interaction = function () {\n function Interaction(_ref) {\n var pointerType = _ref.pointerType;\n\n _classCallCheck(this, Interaction);\n\n this.target = null; // current interactable being interacted with\n this.element = null; // the target element of the interactable\n\n this.prepared = { // action that's ready to be fired on next move event\n name: null,\n axis: null,\n edges: null\n };\n\n // keep track of added pointers\n this.pointers = [];\n this.pointerIds = [];\n this.downTargets = [];\n this.downTimes = [];\n\n // Previous native pointer move event coordinates\n this.prevCoords = {\n page: { x: 0, y: 0 },\n client: { x: 0, y: 0 },\n timeStamp: 0\n };\n // current native pointer move event coordinates\n this.curCoords = {\n page: { x: 0, y: 0 },\n client: { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Starting InteractEvent pointer coordinates\n this.startCoords = {\n page: { x: 0, y: 0 },\n client: { x: 0, y: 0 },\n timeStamp: 0\n };\n\n // Change in coordinates and time of the pointer\n this.pointerDelta = {\n page: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n client: { x: 0, y: 0, vx: 0, vy: 0, speed: 0 },\n timeStamp: 0\n };\n\n this.downEvent = null; // pointerdown/mousedown/touchstart event\n this.downPointer = {};\n\n this._eventTarget = null;\n this._curEventTarget = null;\n\n this.prevEvent = null; // previous action event\n\n this.pointerIsDown = false;\n this.pointerWasMoved = false;\n this._interacting = false;\n\n this.pointerType = pointerType;\n\n signals.fire('new', this);\n\n scope.interactions.push(this);\n }\n\n Interaction.prototype.pointerDown = function pointerDown(pointer, event, eventTarget) {\n var pointerIndex = this.updatePointer(pointer, event, true);\n\n signals.fire('down', {\n pointer: pointer,\n event: event,\n eventTarget: eventTarget,\n pointerIndex: pointerIndex,\n interaction: this\n });\n };\n\n /*\\\n * Interaction.start\n [ method ]\n *\n * Start an action with the given Interactable and Element as tartgets. The\n * action must be enabled for the target Interactable and an appropriate number\n * of pointers must be held down - 1 for drag/resize, 2 for gesture.\n *\n * Use it with `interactable.able({ manualStart: false })` to always\n * [start actions manually](https://github.com/taye/interact.js/issues/114)\n *\n - action (object) The action to be performed - drag, resize, etc.\n - target (Interactable) The Interactable to target\n - element (Element) The DOM Element to target\n = (object) interact\n **\n | interact(target)\n | .draggable({\n | // disable the default drag start by down->move\n | manualStart: true\n | })\n | // start dragging after the user holds the pointer down\n | .on('hold', function (event) {\n | var interaction = event.interaction;\n |\n | if (!interaction.interacting()) {\n | interaction.start({ name: 'drag' },\n | event.interactable,\n | event.currentTarget);\n | }\n | });\n \\*/\n\n\n Interaction.prototype.start = function start(action, target, element) {\n if (this.interacting() || !this.pointerIsDown || this.pointerIds.length < (action.name === 'gesture' ? 2 : 1)) {\n return;\n }\n\n // if this interaction had been removed after stopping\n // add it back\n if (utils.indexOf(scope.interactions, this) === -1) {\n scope.interactions.push(this);\n }\n\n utils.copyAction(this.prepared, action);\n this.target = target;\n this.element = element;\n\n signals.fire('action-start', {\n interaction: this,\n event: this.downEvent\n });\n };\n\n Interaction.prototype.pointerMove = function pointerMove(pointer, event, eventTarget) {\n if (!this.simulation) {\n this.updatePointer(pointer);\n utils.setCoords(this.curCoords, this.pointers);\n }\n\n var duplicateMove = this.curCoords.page.x === this.prevCoords.page.x && this.curCoords.page.y === this.prevCoords.page.y && this.curCoords.client.x === this.prevCoords.client.x && this.curCoords.client.y === this.prevCoords.client.y;\n\n var dx = void 0;\n var dy = void 0;\n\n // register movement greater than pointerMoveTolerance\n if (this.pointerIsDown && !this.pointerWasMoved) {\n dx = this.curCoords.client.x - this.startCoords.client.x;\n dy = this.curCoords.client.y - this.startCoords.client.y;\n\n this.pointerWasMoved = utils.hypot(dx, dy) > Interaction.pointerMoveTolerance;\n }\n\n var signalArg = {\n pointer: pointer,\n pointerIndex: this.getPointerIndex(pointer),\n event: event,\n eventTarget: eventTarget,\n dx: dx,\n dy: dy,\n duplicate: duplicateMove,\n interaction: this,\n interactingBeforeMove: this.interacting()\n };\n\n if (!duplicateMove) {\n // set pointer coordinate, time changes and speeds\n utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n }\n\n signals.fire('move', signalArg);\n\n if (!duplicateMove) {\n // if interacting, fire an 'action-move' signal etc\n if (this.interacting()) {\n this.doMove(signalArg);\n }\n\n if (this.pointerWasMoved) {\n utils.copyCoords(this.prevCoords, this.curCoords);\n }\n }\n };\n\n /*\\\n * Interaction.doMove\n [ method ]\n *\n * Force a move of the current action at the same coordinates. Useful if\n * snap/restrict has been changed and you want a movement with the new\n * settings.\n *\n **\n | interact(target)\n | .draggable(true)\n | .on('dragmove', function (event) {\n | if (someCondition) {\n | // change the snap settings\n | event.interactable.draggable({ snap: { targets: [] }});\n | // fire another move event with re-calculated snap\n | event.interaction.doMove();\n | }\n | });\n \\*/\n\n\n Interaction.prototype.doMove = function doMove(signalArg) {\n signalArg = utils.extend({\n pointer: this.pointers[0],\n event: this.prevEvent,\n eventTarget: this._eventTarget,\n interaction: this\n }, signalArg || {});\n\n signals.fire('before-action-move', signalArg);\n\n if (!this._dontFireMove) {\n signals.fire('action-move', signalArg);\n }\n\n this._dontFireMove = false;\n };\n\n // End interact move events and stop auto-scroll unless simulation is running\n\n\n Interaction.prototype.pointerUp = function pointerUp(pointer, event, eventTarget, curEventTarget) {\n var pointerIndex = this.getPointerIndex(pointer);\n\n signals.fire(/cancel$/i.test(event.type) ? 'cancel' : 'up', {\n pointer: pointer,\n pointerIndex: pointerIndex,\n event: event,\n eventTarget: eventTarget,\n curEventTarget: curEventTarget,\n interaction: this\n });\n\n if (!this.simulation) {\n this.end(event);\n }\n\n this.pointerIsDown = false;\n this.removePointer(pointer, event);\n };\n\n /*\\\n * Interaction.end\n [ method ]\n *\n * Stop the current action and fire an end event. Inertial movement does\n * not happen.\n *\n - event (PointerEvent) #optional\n **\n | interact(target)\n | .draggable(true)\n | .on('move', function (event) {\n | if (event.pageX > 1000) {\n | // end the current action\n | event.interaction.end();\n | // stop all further listeners from being called\n | event.stopImmediatePropagation();\n | }\n | });\n \\*/\n\n\n Interaction.prototype.end = function end(event) {\n event = event || this.prevEvent;\n\n if (this.interacting()) {\n signals.fire('action-end', {\n event: event,\n interaction: this\n });\n }\n\n this.stop();\n };\n\n Interaction.prototype.currentAction = function currentAction() {\n return this._interacting ? this.prepared.name : null;\n };\n\n Interaction.prototype.interacting = function interacting() {\n return this._interacting;\n };\n\n Interaction.prototype.stop = function stop() {\n signals.fire('stop', { interaction: this });\n\n if (this._interacting) {\n signals.fire('stop-active', { interaction: this });\n signals.fire('stop-' + this.prepared.name, { interaction: this });\n }\n\n this.target = this.element = null;\n\n this._interacting = false;\n this.prepared.name = this.prevEvent = null;\n };\n\n Interaction.prototype.getPointerIndex = function getPointerIndex(pointer) {\n // mouse and pen interactions may have only one pointer\n if (this.pointerType === 'mouse' || this.pointerType === 'pen') {\n return 0;\n }\n\n return utils.indexOf(this.pointerIds, utils.getPointerId(pointer));\n };\n\n Interaction.prototype.updatePointer = function updatePointer(pointer, event) {\n var down = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : event && /(down|start)$/i.test(event.type);\n\n var id = utils.getPointerId(pointer);\n var index = this.getPointerIndex(pointer);\n\n if (index === -1) {\n index = this.pointerIds.length;\n this.pointerIds[index] = id;\n }\n\n if (down) {\n signals.fire('update-pointer-down', {\n pointer: pointer,\n event: event,\n down: down,\n pointerId: id,\n pointerIndex: index,\n interaction: this\n });\n }\n\n this.pointers[index] = pointer;\n\n return index;\n };\n\n Interaction.prototype.removePointer = function removePointer(pointer, event) {\n var index = this.getPointerIndex(pointer);\n\n if (index === -1) {\n return;\n }\n\n signals.fire('remove-pointer', {\n pointer: pointer,\n event: event,\n pointerIndex: index,\n interaction: this\n });\n\n this.pointers.splice(index, 1);\n this.pointerIds.splice(index, 1);\n this.downTargets.splice(index, 1);\n this.downTimes.splice(index, 1);\n };\n\n Interaction.prototype._updateEventTargets = function _updateEventTargets(target, currentTarget) {\n this._eventTarget = target;\n this._curEventTarget = currentTarget;\n };\n\n return Interaction;\n}();\n\nfor (var i = 0, len = methodNames.length; i < len; i++) {\n var method = methodNames[i];\n\n listeners[method] = doOnInteractions(method);\n}\n\nfunction doOnInteractions(method) {\n return function (event) {\n var pointerType = utils.getPointerType(event);\n\n var _utils$getEventTarget = utils.getEventTargets(event),\n eventTarget = _utils$getEventTarget[0],\n curEventTarget = _utils$getEventTarget[1];\n\n var matches = []; // [ [pointer, interaction], ...]\n\n if (browser.supportsTouch && /touch/.test(event.type)) {\n prevTouchTime = new Date().getTime();\n\n for (var _i = 0; _i < event.changedTouches.length; _i++) {\n var pointer = event.changedTouches[_i];\n var interaction = finder.search(pointer, event.type, eventTarget);\n\n matches.push([pointer, interaction || new Interaction({ pointerType: pointerType })]);\n }\n } else {\n var invalidPointer = false;\n\n if (!browser.supportsPointerEvent && /mouse/.test(event.type)) {\n // ignore mouse events while touch interactions are active\n for (var _i2 = 0; _i2 < scope.interactions.length && !invalidPointer; _i2++) {\n invalidPointer = scope.interactions[_i2].pointerType !== 'mouse' && scope.interactions[_i2].pointerIsDown;\n }\n\n // try to ignore mouse events that are simulated by the browser\n // after a touch event\n invalidPointer = invalidPointer || new Date().getTime() - prevTouchTime < 500\n // on iOS and Firefox Mobile, MouseEvent.timeStamp is zero if simulated\n || event.timeStamp === 0;\n }\n\n if (!invalidPointer) {\n var _interaction = finder.search(event, event.type, eventTarget);\n\n if (!_interaction) {\n _interaction = new Interaction({ pointerType: pointerType });\n }\n\n matches.push([event, _interaction]);\n }\n }\n\n for (var _iterator = matches, _isArray = Array.isArray(_iterator), _i3 = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref2;\n\n if (_isArray) {\n if (_i3 >= _iterator.length) break;\n _ref2 = _iterator[_i3++];\n } else {\n _i3 = _iterator.next();\n if (_i3.done) break;\n _ref2 = _i3.value;\n }\n\n var _ref3 = _ref2,\n _pointer = _ref3[0],\n _interaction2 = _ref3[1];\n\n _interaction2._updateEventTargets(eventTarget, curEventTarget);\n _interaction2[method](_pointer, event, eventTarget, curEventTarget);\n }\n };\n}\n\nfunction endAll(event) {\n for (var _i4 = 0; _i4 < scope.interactions.length; _i4++) {\n var interaction = scope.interactions[_i4];\n\n interaction.end(event);\n signals.fire('endall', { event: event, interaction: interaction });\n }\n}\n\nvar docEvents = {/* 'eventType': listenerFunc */};\nvar pEventTypes = browser.pEventTypes;\n\nif (domObjects.PointerEvent) {\n docEvents[pEventTypes.down] = listeners.pointerDown;\n docEvents[pEventTypes.move] = listeners.pointerMove;\n docEvents[pEventTypes.up] = listeners.pointerUp;\n docEvents[pEventTypes.cancel] = listeners.pointerUp;\n} else {\n docEvents.mousedown = listeners.pointerDown;\n docEvents.mousemove = listeners.pointerMove;\n docEvents.mouseup = listeners.pointerUp;\n\n docEvents.touchstart = listeners.pointerDown;\n docEvents.touchmove = listeners.pointerMove;\n docEvents.touchend = listeners.pointerUp;\n docEvents.touchcancel = listeners.pointerUp;\n}\n\ndocEvents.blur = endAll;\n\nfunction onDocSignal(_ref4, signalName) {\n var doc = _ref4.doc;\n\n var eventMethod = signalName.indexOf('add') === 0 ? events.add : events.remove;\n\n // delegate event listener\n for (var eventType in scope.delegatedEvents) {\n eventMethod(doc, eventType, events.delegateListener);\n eventMethod(doc, eventType, events.delegateUseCapture, true);\n }\n\n for (var _eventType in docEvents) {\n eventMethod(doc, _eventType, docEvents[_eventType]);\n }\n}\n\nsignals.on('update-pointer-down', function (_ref5) {\n var interaction = _ref5.interaction,\n pointer = _ref5.pointer,\n pointerId = _ref5.pointerId,\n pointerIndex = _ref5.pointerIndex,\n event = _ref5.event,\n eventTarget = _ref5.eventTarget,\n down = _ref5.down;\n\n interaction.pointerIds[pointerIndex] = pointerId;\n interaction.pointers[pointerIndex] = pointer;\n\n if (down) {\n interaction.pointerIsDown = true;\n }\n\n if (!interaction.interacting()) {\n utils.setCoords(interaction.startCoords, interaction.pointers);\n\n utils.copyCoords(interaction.curCoords, interaction.startCoords);\n utils.copyCoords(interaction.prevCoords, interaction.startCoords);\n\n interaction.downEvent = event;\n interaction.downTimes[pointerIndex] = interaction.curCoords.timeStamp;\n interaction.downTargets[pointerIndex] = eventTarget || event && utils.getEventTargets(event)[0];\n interaction.pointerWasMoved = false;\n\n utils.pointerExtend(interaction.downPointer, pointer);\n }\n});\n\nscope.signals.on('add-document', onDocSignal);\nscope.signals.on('remove-document', onDocSignal);\n\nInteraction.pointerMoveTolerance = 1;\nInteraction.doOnInteractions = doOnInteractions;\nInteraction.endAll = endAll;\nInteraction.signals = signals;\nInteraction.docEvents = docEvents;\n\nscope.endAllInteractions = endAll;\n\nmodule.exports = Interaction;\n\n},{\"./scope\":34,\"./utils\":44,\"./utils/Signals\":35,\"./utils/browser\":37,\"./utils/domObjects\":38,\"./utils/events\":40,\"./utils/interactionFinder\":45}],6:[function(require,module,exports){\n'use strict';\n\nvar Interaction = require('../Interaction');\nvar InteractEvent = require('../InteractEvent');\n\nvar actions = {\n firePrepared: firePrepared,\n names: [],\n methodDict: {}\n};\n\nInteraction.signals.on('action-start', function (_ref) {\n var interaction = _ref.interaction,\n event = _ref.event;\n\n interaction._interacting = true;\n firePrepared(interaction, event, 'start');\n});\n\nInteraction.signals.on('action-move', function (_ref2) {\n var interaction = _ref2.interaction,\n event = _ref2.event,\n preEnd = _ref2.preEnd;\n\n firePrepared(interaction, event, 'move', preEnd);\n\n // if the action was ended in a listener\n if (!interaction.interacting()) {\n return false;\n }\n});\n\nInteraction.signals.on('action-end', function (_ref3) {\n var interaction = _ref3.interaction,\n event = _ref3.event;\n\n firePrepared(interaction, event, 'end');\n});\n\nfunction firePrepared(interaction, event, phase, preEnd) {\n var actionName = interaction.prepared.name;\n\n var newEvent = new InteractEvent(interaction, event, actionName, phase, interaction.element, null, preEnd);\n\n interaction.target.fire(newEvent);\n interaction.prevEvent = newEvent;\n}\n\nmodule.exports = actions;\n\n},{\"../InteractEvent\":3,\"../Interaction\":5}],7:[function(require,module,exports){\n'use strict';\n\nvar actions = require('./base');\nvar utils = require('../utils');\nvar InteractEvent = require('../InteractEvent');\nvar Interactable = require('../Interactable');\nvar Interaction = require('../Interaction');\nvar defaultOptions = require('../defaultOptions');\n\nvar drag = {\n defaults: {\n enabled: false,\n mouseButtons: null,\n\n origin: null,\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n startAxis: 'xy',\n lockAxis: 'xy'\n },\n\n checker: function checker(pointer, event, interactable) {\n var dragOptions = interactable.options.drag;\n\n return dragOptions.enabled ? { name: 'drag', axis: dragOptions.lockAxis === 'start' ? dragOptions.startAxis : dragOptions.lockAxis } : null;\n },\n\n getCursor: function getCursor() {\n return 'move';\n }\n};\n\nInteraction.signals.on('before-action-move', function (_ref) {\n var interaction = _ref.interaction;\n\n if (interaction.prepared.name !== 'drag') {\n return;\n }\n\n var axis = interaction.prepared.axis;\n\n if (axis === 'x') {\n interaction.curCoords.page.y = interaction.startCoords.page.y;\n interaction.curCoords.client.y = interaction.startCoords.client.y;\n\n interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vx);\n interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vx);\n interaction.pointerDelta.client.vy = 0;\n interaction.pointerDelta.page.vy = 0;\n } else if (axis === 'y') {\n interaction.curCoords.page.x = interaction.startCoords.page.x;\n interaction.curCoords.client.x = interaction.startCoords.client.x;\n\n interaction.pointerDelta.page.speed = Math.abs(interaction.pointerDelta.page.vy);\n interaction.pointerDelta.client.speed = Math.abs(interaction.pointerDelta.client.vy);\n interaction.pointerDelta.client.vx = 0;\n interaction.pointerDelta.page.vx = 0;\n }\n});\n\n// dragmove\nInteractEvent.signals.on('new', function (_ref2) {\n var iEvent = _ref2.iEvent,\n interaction = _ref2.interaction;\n\n if (iEvent.type !== 'dragmove') {\n return;\n }\n\n var axis = interaction.prepared.axis;\n\n if (axis === 'x') {\n iEvent.pageY = interaction.startCoords.page.y;\n iEvent.clientY = interaction.startCoords.client.y;\n iEvent.dy = 0;\n } else if (axis === 'y') {\n iEvent.pageX = interaction.startCoords.page.x;\n iEvent.clientX = interaction.startCoords.client.x;\n iEvent.dx = 0;\n }\n});\n\n/*\\\n * Interactable.draggable\n [ method ]\n *\n * Gets or sets whether drag actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of drag events\n | var isDraggable = interact('ul li').draggable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on drag events (object makes the Interactable draggable)\n = (object) This Interactable\n | interact(element).draggable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // the axis in which the first movement must be\n | // for the drag sequence to start\n | // 'xy' by default - any direction\n | startAxis: 'x' || 'y' || 'xy',\n |\n | // 'xy' by default - don't restrict to one axis (move in any direction)\n | // 'x' or 'y' to restrict movement to either axis\n | // 'start' to restrict movement to the axis the drag started in\n | lockAxis: 'x' || 'y' || 'xy' || 'start',\n |\n | // max number of drags that can happen concurrently\n | // with elements of this Interactable. Infinity by default\n | max: Infinity,\n |\n | // max number of drags that can target the same element+Interactable\n | // 1 by default\n | maxPerElement: 2\n | });\n\\*/\nInteractable.prototype.draggable = function (options) {\n if (utils.is.object(options)) {\n this.options.drag.enabled = options.enabled === false ? false : true;\n this.setPerAction('drag', options);\n this.setOnEvents('drag', options);\n\n if (/^(xy|x|y|start)$/.test(options.lockAxis)) {\n this.options.drag.lockAxis = options.lockAxis;\n }\n if (/^(xy|x|y)$/.test(options.startAxis)) {\n this.options.drag.startAxis = options.startAxis;\n }\n\n return this;\n }\n\n if (utils.is.bool(options)) {\n this.options.drag.enabled = options;\n\n if (!options) {\n this.ondragstart = this.ondragstart = this.ondragend = null;\n }\n\n return this;\n }\n\n return this.options.drag;\n};\n\nactions.drag = drag;\nactions.names.push('drag');\nutils.merge(Interactable.eventTypes, ['dragstart', 'dragmove', 'draginertiastart', 'draginertiaresume', 'dragend']);\nactions.methodDict.drag = 'draggable';\n\ndefaultOptions.drag = drag.defaults;\n\nmodule.exports = drag;\n\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"./base\":6}],8:[function(require,module,exports){\n'use strict';\n\nvar actions = require('./base');\nvar utils = require('../utils');\nvar scope = require('../scope');\nvar interact = require('../interact');\nvar InteractEvent = require('../InteractEvent');\nvar Interactable = require('../Interactable');\nvar Interaction = require('../Interaction');\nvar defaultOptions = require('../defaultOptions');\n\nvar drop = {\n defaults: {\n enabled: false,\n accept: null,\n overlap: 'pointer'\n }\n};\n\nvar dynamicDrop = false;\n\nInteraction.signals.on('action-start', function (_ref) {\n var interaction = _ref.interaction,\n event = _ref.event;\n\n if (interaction.prepared.name !== 'drag') {\n return;\n }\n\n // reset active dropzones\n interaction.activeDrops.dropzones = [];\n interaction.activeDrops.elements = [];\n interaction.activeDrops.rects = [];\n\n interaction.dropEvents = null;\n\n if (!interaction.dynamicDrop) {\n setActiveDrops(interaction, interaction.element);\n }\n\n var dragEvent = interaction.prevEvent;\n var dropEvents = getDropEvents(interaction, event, dragEvent);\n\n if (dropEvents.activate) {\n fireActiveDrops(interaction, dropEvents.activate);\n }\n});\n\nInteractEvent.signals.on('new', function (_ref2) {\n var interaction = _ref2.interaction,\n iEvent = _ref2.iEvent,\n event = _ref2.event;\n\n if (iEvent.type !== 'dragmove' && iEvent.type !== 'dragend') {\n return;\n }\n\n var draggableElement = interaction.element;\n var dragEvent = iEvent;\n var dropResult = getDrop(dragEvent, event, draggableElement);\n\n interaction.dropTarget = dropResult.dropzone;\n interaction.dropElement = dropResult.element;\n\n interaction.dropEvents = getDropEvents(interaction, event, dragEvent);\n});\n\nInteraction.signals.on('action-move', function (_ref3) {\n var interaction = _ref3.interaction;\n\n if (interaction.prepared.name !== 'drag') {\n return;\n }\n\n fireDropEvents(interaction, interaction.dropEvents);\n});\n\nInteraction.signals.on('action-end', function (_ref4) {\n var interaction = _ref4.interaction;\n\n if (interaction.prepared.name === 'drag') {\n fireDropEvents(interaction, interaction.dropEvents);\n }\n});\n\nInteraction.signals.on('stop-drag', function (_ref5) {\n var interaction = _ref5.interaction;\n\n interaction.activeDrops.dropzones = interaction.activeDrops.elements = interaction.activeDrops.rects = interaction.dropEvents = null;\n});\n\nfunction collectDrops(interaction, element) {\n var drops = [];\n var elements = [];\n\n element = element || interaction.element;\n\n // collect all dropzones and their elements which qualify for a drop\n for (var _iterator = scope.interactables, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref6;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref6 = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref6 = _i.value;\n }\n\n var current = _ref6;\n\n if (!current.options.drop.enabled) {\n continue;\n }\n\n var accept = current.options.drop.accept;\n\n // test the draggable element against the dropzone's accept setting\n if (utils.is.element(accept) && accept !== element || utils.is.string(accept) && !utils.matchesSelector(element, accept)) {\n\n continue;\n }\n\n // query for new elements if necessary\n var dropElements = utils.is.string(current.target) ? current._context.querySelectorAll(current.target) : [current.target];\n\n for (var i = 0; i < dropElements.length; i++) {\n var currentElement = dropElements[i];\n\n if (currentElement !== element) {\n drops.push(current);\n elements.push(currentElement);\n }\n }\n }\n\n return {\n elements: elements,\n dropzones: drops\n };\n}\n\nfunction fireActiveDrops(interaction, event) {\n var prevElement = void 0;\n\n // loop through all active dropzones and trigger event\n for (var i = 0; i < interaction.activeDrops.dropzones.length; i++) {\n var current = interaction.activeDrops.dropzones[i];\n var currentElement = interaction.activeDrops.elements[i];\n\n // prevent trigger of duplicate events on same element\n if (currentElement !== prevElement) {\n // set current element as event target\n event.target = currentElement;\n current.fire(event);\n }\n prevElement = currentElement;\n }\n}\n\n// Collect a new set of possible drops and save them in activeDrops.\n// setActiveDrops should always be called when a drag has just started or a\n// drag event happens while dynamicDrop is true\nfunction setActiveDrops(interaction, dragElement) {\n // get dropzones and their elements that could receive the draggable\n var possibleDrops = collectDrops(interaction, dragElement, true);\n\n interaction.activeDrops.dropzones = possibleDrops.dropzones;\n interaction.activeDrops.elements = possibleDrops.elements;\n interaction.activeDrops.rects = [];\n\n for (var i = 0; i < interaction.activeDrops.dropzones.length; i++) {\n interaction.activeDrops.rects[i] = interaction.activeDrops.dropzones[i].getRect(interaction.activeDrops.elements[i]);\n }\n}\n\nfunction getDrop(dragEvent, event, dragElement) {\n var interaction = dragEvent.interaction;\n var validDrops = [];\n\n if (dynamicDrop) {\n setActiveDrops(interaction, dragElement);\n }\n\n // collect all dropzones and their elements which qualify for a drop\n for (var j = 0; j < interaction.activeDrops.dropzones.length; j++) {\n var current = interaction.activeDrops.dropzones[j];\n var currentElement = interaction.activeDrops.elements[j];\n var rect = interaction.activeDrops.rects[j];\n\n validDrops.push(current.dropCheck(dragEvent, event, interaction.target, dragElement, currentElement, rect) ? currentElement : null);\n }\n\n // get the most appropriate dropzone based on DOM depth and order\n var dropIndex = utils.indexOfDeepestElement(validDrops);\n\n return {\n dropzone: interaction.activeDrops.dropzones[dropIndex] || null,\n element: interaction.activeDrops.elements[dropIndex] || null\n };\n}\n\nfunction getDropEvents(interaction, pointerEvent, dragEvent) {\n var dropEvents = {\n enter: null,\n leave: null,\n activate: null,\n deactivate: null,\n move: null,\n drop: null\n };\n\n var tmpl = {\n dragEvent: dragEvent,\n interaction: interaction,\n target: interaction.dropElement,\n dropzone: interaction.dropTarget,\n relatedTarget: dragEvent.target,\n draggable: dragEvent.interactable,\n timeStamp: dragEvent.timeStamp\n };\n\n if (interaction.dropElement !== interaction.prevDropElement) {\n // if there was a prevDropTarget, create a dragleave event\n if (interaction.prevDropTarget) {\n dropEvents.leave = utils.extend({ type: 'dragleave' }, tmpl);\n\n dragEvent.dragLeave = dropEvents.leave.target = interaction.prevDropElement;\n dragEvent.prevDropzone = dropEvents.leave.dropzone = interaction.prevDropTarget;\n }\n // if the dropTarget is not null, create a dragenter event\n if (interaction.dropTarget) {\n dropEvents.enter = {\n dragEvent: dragEvent,\n interaction: interaction,\n target: interaction.dropElement,\n dropzone: interaction.dropTarget,\n relatedTarget: dragEvent.target,\n draggable: dragEvent.interactable,\n timeStamp: dragEvent.timeStamp,\n type: 'dragenter'\n };\n\n dragEvent.dragEnter = interaction.dropElement;\n dragEvent.dropzone = interaction.dropTarget;\n }\n }\n\n if (dragEvent.type === 'dragend' && interaction.dropTarget) {\n dropEvents.drop = utils.extend({ type: 'drop' }, tmpl);\n\n dragEvent.dropzone = interaction.dropTarget;\n dragEvent.relatedTarget = interaction.dropElement;\n }\n if (dragEvent.type === 'dragstart') {\n dropEvents.activate = utils.extend({ type: 'dropactivate' }, tmpl);\n\n dropEvents.activate.target = null;\n dropEvents.activate.dropzone = null;\n }\n if (dragEvent.type === 'dragend') {\n dropEvents.deactivate = utils.extend({ type: 'dropdeactivate' }, tmpl);\n\n dropEvents.deactivate.target = null;\n dropEvents.deactivate.dropzone = null;\n }\n if (dragEvent.type === 'dragmove' && interaction.dropTarget) {\n dropEvents.move = utils.extend({\n dragmove: dragEvent,\n type: 'dropmove'\n }, tmpl);\n\n dragEvent.dropzone = interaction.dropTarget;\n }\n\n return dropEvents;\n}\n\nfunction fireDropEvents(interaction, dropEvents) {\n if (dropEvents.leave) {\n interaction.prevDropTarget.fire(dropEvents.leave);\n }\n if (dropEvents.move) {\n interaction.dropTarget.fire(dropEvents.move);\n }\n if (dropEvents.enter) {\n interaction.dropTarget.fire(dropEvents.enter);\n }\n if (dropEvents.drop) {\n interaction.dropTarget.fire(dropEvents.drop);\n }\n if (dropEvents.deactivate) {\n fireActiveDrops(interaction, dropEvents.deactivate);\n }\n\n interaction.prevDropTarget = interaction.dropTarget;\n interaction.prevDropElement = interaction.dropElement;\n}\n\n/*\\\n * Interactable.dropzone\n [ method ]\n *\n * Returns or sets whether elements can be dropped onto this\n * Interactable to trigger drop events\n *\n * Dropzones can receive the following events:\n * - `dropactivate` and `dropdeactivate` when an acceptable drag starts and ends\n * - `dragenter` and `dragleave` when a draggable enters and leaves the dropzone\n * - `dragmove` when a draggable that has entered the dropzone is moved\n * - `drop` when a draggable is dropped into this dropzone\n *\n * Use the `accept` option to allow only elements that match the given CSS\n * selector or element. The value can be:\n *\n * - **an Element** - only that element can be dropped into this dropzone.\n * - **a string**, - the element being dragged must match it as a CSS selector.\n * - **`null`** - accept options is cleared - it accepts any element.\n *\n * Use the `overlap` option to set how drops are checked for. The allowed\n * values are:\n *\n * - `'pointer'`, the pointer must be over the dropzone (default)\n * - `'center'`, the draggable element's center must be over the dropzone\n * - a number from 0-1 which is the `(intersection area) / (draggable area)`.\n * e.g. `0.5` for drop to happen when half of the area of the draggable is\n * over the dropzone\n *\n * Use the `checker` option to specify a function to check if a dragged\n * element is over this Interactable.\n *\n | interact(target)\n | .dropChecker(function(dragEvent, // related dragmove or dragend event\n | event, // TouchEvent/PointerEvent/MouseEvent\n | dropped, // bool result of the default checker\n | dropzone, // dropzone Interactable\n | dropElement, // dropzone elemnt\n | draggable, // draggable Interactable\n | draggableElement) {// draggable element\n |\n | return dropped && event.target.hasAttribute('allow-drop');\n | }\n *\n *\n - options (boolean | object | null) #optional The new value to be set.\n | interact('.drop').dropzone({\n | accept: '.can-drop' || document.getElementById('single-drop'),\n | overlap: 'pointer' || 'center' || zeroToOne\n | }\n = (boolean | object) The current setting or this Interactable\n\\*/\nInteractable.prototype.dropzone = function (options) {\n if (utils.is.object(options)) {\n this.options.drop.enabled = options.enabled === false ? false : true;\n\n if (utils.is.function(options.ondrop)) {\n this.events.ondrop = options.ondrop;\n }\n if (utils.is.function(options.ondropactivate)) {\n this.events.ondropactivate = options.ondropactivate;\n }\n if (utils.is.function(options.ondropdeactivate)) {\n this.events.ondropdeactivate = options.ondropdeactivate;\n }\n if (utils.is.function(options.ondragenter)) {\n this.events.ondragenter = options.ondragenter;\n }\n if (utils.is.function(options.ondragleave)) {\n this.events.ondragleave = options.ondragleave;\n }\n if (utils.is.function(options.ondropmove)) {\n this.events.ondropmove = options.ondropmove;\n }\n\n if (/^(pointer|center)$/.test(options.overlap)) {\n this.options.drop.overlap = options.overlap;\n } else if (utils.is.number(options.overlap)) {\n this.options.drop.overlap = Math.max(Math.min(1, options.overlap), 0);\n }\n if ('accept' in options) {\n this.options.drop.accept = options.accept;\n }\n if ('checker' in options) {\n this.options.drop.checker = options.checker;\n }\n\n return this;\n }\n\n if (utils.is.bool(options)) {\n this.options.drop.enabled = options;\n\n if (!options) {\n this.ondragenter = this.ondragleave = this.ondrop = this.ondropactivate = this.ondropdeactivate = null;\n }\n\n return this;\n }\n\n return this.options.drop;\n};\n\nInteractable.prototype.dropCheck = function (dragEvent, event, draggable, draggableElement, dropElement, rect) {\n var dropped = false;\n\n // if the dropzone has no rect (eg. display: none)\n // call the custom dropChecker or just return false\n if (!(rect = rect || this.getRect(dropElement))) {\n return this.options.drop.checker ? this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement) : false;\n }\n\n var dropOverlap = this.options.drop.overlap;\n\n if (dropOverlap === 'pointer') {\n var origin = utils.getOriginXY(draggable, draggableElement, 'drag');\n var page = utils.getPageXY(dragEvent);\n\n page.x += origin.x;\n page.y += origin.y;\n\n var horizontal = page.x > rect.left && page.x < rect.right;\n var vertical = page.y > rect.top && page.y < rect.bottom;\n\n dropped = horizontal && vertical;\n }\n\n var dragRect = draggable.getRect(draggableElement);\n\n if (dragRect && dropOverlap === 'center') {\n var cx = dragRect.left + dragRect.width / 2;\n var cy = dragRect.top + dragRect.height / 2;\n\n dropped = cx >= rect.left && cx <= rect.right && cy >= rect.top && cy <= rect.bottom;\n }\n\n if (dragRect && utils.is.number(dropOverlap)) {\n var overlapArea = Math.max(0, Math.min(rect.right, dragRect.right) - Math.max(rect.left, dragRect.left)) * Math.max(0, Math.min(rect.bottom, dragRect.bottom) - Math.max(rect.top, dragRect.top));\n\n var overlapRatio = overlapArea / (dragRect.width * dragRect.height);\n\n dropped = overlapRatio >= dropOverlap;\n }\n\n if (this.options.drop.checker) {\n dropped = this.options.drop.checker(dragEvent, event, dropped, this, dropElement, draggable, draggableElement);\n }\n\n return dropped;\n};\n\nInteractable.signals.on('unset', function (_ref7) {\n var interactable = _ref7.interactable;\n\n interactable.dropzone(false);\n});\n\nInteractable.settingsMethods.push('dropChecker');\n\nInteraction.signals.on('new', function (interaction) {\n interaction.dropTarget = null; // the dropzone a drag target might be dropped into\n interaction.dropElement = null; // the element at the time of checking\n interaction.prevDropTarget = null; // the dropzone that was recently dragged away from\n interaction.prevDropElement = null; // the element at the time of checking\n interaction.dropEvents = null; // the dropEvents related to the current drag event\n\n interaction.activeDrops = {\n dropzones: [], // the dropzones that are mentioned below\n elements: [], // elements of dropzones that accept the target draggable\n rects: [] // the rects of the elements mentioned above\n };\n});\n\nInteraction.signals.on('stop', function (_ref8) {\n var interaction = _ref8.interaction;\n\n interaction.dropTarget = interaction.dropElement = interaction.prevDropTarget = interaction.prevDropElement = null;\n});\n\n/*\\\n * interact.dynamicDrop\n [ method ]\n *\n * Returns or sets whether the dimensions of dropzone elements are\n * calculated on every dragmove or only on dragstart for the default\n * dropChecker\n *\n - newValue (boolean) #optional True to check on each move. False to check only before start\n = (boolean | interact) The current setting or interact\n\\*/\ninteract.dynamicDrop = function (newValue) {\n if (utils.is.bool(newValue)) {\n //if (dragging && dynamicDrop !== newValue && !newValue) {\n //calcRects(dropzones);\n //}\n\n dynamicDrop = newValue;\n\n return interact;\n }\n return dynamicDrop;\n};\n\nutils.merge(Interactable.eventTypes, ['dragenter', 'dragleave', 'dropactivate', 'dropdeactivate', 'dropmove', 'drop']);\nactions.methodDict.drop = 'dropzone';\n\ndefaultOptions.drop = drop.defaults;\n\nmodule.exports = drop;\n\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../interact\":21,\"../scope\":34,\"../utils\":44,\"./base\":6}],9:[function(require,module,exports){\n'use strict';\n\nvar actions = require('./base');\nvar utils = require('../utils');\nvar InteractEvent = require('../InteractEvent');\nvar Interactable = require('../Interactable');\nvar Interaction = require('../Interaction');\nvar defaultOptions = require('../defaultOptions');\n\nvar gesture = {\n defaults: {\n enabled: false,\n origin: null,\n restrict: null\n },\n\n checker: function checker(pointer, event, interactable, element, interaction) {\n if (interaction.pointerIds.length >= 2) {\n return { name: 'gesture' };\n }\n\n return null;\n },\n\n getCursor: function getCursor() {\n return '';\n }\n};\n\nInteractEvent.signals.on('new', function (_ref) {\n var iEvent = _ref.iEvent,\n interaction = _ref.interaction;\n\n if (iEvent.type !== 'gesturestart') {\n return;\n }\n iEvent.ds = 0;\n\n interaction.gesture.startDistance = interaction.gesture.prevDistance = iEvent.distance;\n interaction.gesture.startAngle = interaction.gesture.prevAngle = iEvent.angle;\n interaction.gesture.scale = 1;\n});\n\nInteractEvent.signals.on('new', function (_ref2) {\n var iEvent = _ref2.iEvent,\n interaction = _ref2.interaction;\n\n if (iEvent.type !== 'gesturemove') {\n return;\n }\n\n iEvent.ds = iEvent.scale - interaction.gesture.scale;\n\n interaction.target.fire(iEvent);\n\n interaction.gesture.prevAngle = iEvent.angle;\n interaction.gesture.prevDistance = iEvent.distance;\n\n if (iEvent.scale !== Infinity && iEvent.scale !== null && iEvent.scale !== undefined && !isNaN(iEvent.scale)) {\n\n interaction.gesture.scale = iEvent.scale;\n }\n});\n\n/*\\\n * Interactable.gesturable\n [ method ]\n *\n * Gets or sets whether multitouch gestures can be performed on the\n * Interactable's element\n *\n = (boolean) Indicates if this can be the target of gesture events\n | var isGestureable = interact(element).gesturable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on gesture events (makes the Interactable gesturable)\n = (object) this Interactable\n | interact(element).gesturable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | // limit multiple gestures.\n | // See the explanation in @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n\\*/\nInteractable.prototype.gesturable = function (options) {\n if (utils.is.object(options)) {\n this.options.gesture.enabled = options.enabled === false ? false : true;\n this.setPerAction('gesture', options);\n this.setOnEvents('gesture', options);\n\n return this;\n }\n\n if (utils.is.bool(options)) {\n this.options.gesture.enabled = options;\n\n if (!options) {\n this.ongesturestart = this.ongesturestart = this.ongestureend = null;\n }\n\n return this;\n }\n\n return this.options.gesture;\n};\n\nInteractEvent.signals.on('set-delta', function (_ref3) {\n var interaction = _ref3.interaction,\n iEvent = _ref3.iEvent,\n action = _ref3.action,\n event = _ref3.event,\n starting = _ref3.starting,\n ending = _ref3.ending,\n deltaSource = _ref3.deltaSource;\n\n if (action !== 'gesture') {\n return;\n }\n\n var pointers = interaction.pointers;\n\n iEvent.touches = [pointers[0], pointers[1]];\n\n if (starting) {\n iEvent.distance = utils.touchDistance(pointers, deltaSource);\n iEvent.box = utils.touchBBox(pointers);\n iEvent.scale = 1;\n iEvent.ds = 0;\n iEvent.angle = utils.touchAngle(pointers, undefined, deltaSource);\n iEvent.da = 0;\n } else if (ending || event instanceof InteractEvent) {\n iEvent.distance = interaction.prevEvent.distance;\n iEvent.box = interaction.prevEvent.box;\n iEvent.scale = interaction.prevEvent.scale;\n iEvent.ds = iEvent.scale - 1;\n iEvent.angle = interaction.prevEvent.angle;\n iEvent.da = iEvent.angle - interaction.gesture.startAngle;\n } else {\n iEvent.distance = utils.touchDistance(pointers, deltaSource);\n iEvent.box = utils.touchBBox(pointers);\n iEvent.scale = iEvent.distance / interaction.gesture.startDistance;\n iEvent.angle = utils.touchAngle(pointers, interaction.gesture.prevAngle, deltaSource);\n\n iEvent.ds = iEvent.scale - interaction.gesture.prevScale;\n iEvent.da = iEvent.angle - interaction.gesture.prevAngle;\n }\n});\n\nInteraction.signals.on('new', function (interaction) {\n interaction.gesture = {\n start: { x: 0, y: 0 },\n\n startDistance: 0, // distance between two touches of touchStart\n prevDistance: 0,\n distance: 0,\n\n scale: 1, // gesture.distance / gesture.startDistance\n\n startAngle: 0, // angle of line joining two touches\n prevAngle: 0 // angle of the previous gesture event\n };\n});\n\nactions.gesture = gesture;\nactions.names.push('gesture');\nutils.merge(Interactable.eventTypes, ['gesturestart', 'gesturemove', 'gestureend']);\nactions.methodDict.gesture = 'gesturable';\n\ndefaultOptions.gesture = gesture.defaults;\n\nmodule.exports = gesture;\n\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"./base\":6}],10:[function(require,module,exports){\n'use strict';\n\nvar actions = require('./base');\nvar utils = require('../utils');\nvar browser = require('../utils/browser');\nvar InteractEvent = require('../InteractEvent');\nvar Interactable = require('../Interactable');\nvar Interaction = require('../Interaction');\nvar defaultOptions = require('../defaultOptions');\n\n// Less Precision with touch input\nvar defaultMargin = browser.supportsTouch || browser.supportsPointerEvent ? 20 : 10;\n\nvar resize = {\n defaults: {\n enabled: false,\n mouseButtons: null,\n\n origin: null,\n snap: null,\n restrict: null,\n inertia: null,\n autoScroll: null,\n\n square: false,\n preserveAspectRatio: false,\n axis: 'xy',\n\n // use default margin\n margin: NaN,\n\n // object with props left, right, top, bottom which are\n // true/false values to resize when the pointer is over that edge,\n // CSS selectors to match the handles for each direction\n // or the Elements for each handle\n edges: null,\n\n // a value of 'none' will limit the resize rect to a minimum of 0x0\n // 'negate' will alow the rect to have negative width/height\n // 'reposition' will keep the width/height positive by swapping\n // the top and bottom edges and/or swapping the left and right edges\n invert: 'none'\n },\n\n checker: function checker(pointer, event, interactable, element, interaction, rect) {\n if (!rect) {\n return null;\n }\n\n var page = utils.extend({}, interaction.curCoords.page);\n var options = interactable.options;\n\n if (options.resize.enabled) {\n var resizeOptions = options.resize;\n var resizeEdges = { left: false, right: false, top: false, bottom: false };\n\n // if using resize.edges\n if (utils.is.object(resizeOptions.edges)) {\n for (var edge in resizeEdges) {\n resizeEdges[edge] = checkResizeEdge(edge, resizeOptions.edges[edge], page, interaction._eventTarget, element, rect, resizeOptions.margin || defaultMargin);\n }\n\n resizeEdges.left = resizeEdges.left && !resizeEdges.right;\n resizeEdges.top = resizeEdges.top && !resizeEdges.bottom;\n\n if (resizeEdges.left || resizeEdges.right || resizeEdges.top || resizeEdges.bottom) {\n return {\n name: 'resize',\n edges: resizeEdges\n };\n }\n } else {\n var right = options.resize.axis !== 'y' && page.x > rect.right - defaultMargin;\n var bottom = options.resize.axis !== 'x' && page.y > rect.bottom - defaultMargin;\n\n if (right || bottom) {\n return {\n name: 'resize',\n axes: (right ? 'x' : '') + (bottom ? 'y' : '')\n };\n }\n }\n }\n\n return null;\n },\n\n cursors: browser.isIe9OrOlder ? {\n x: 'e-resize',\n y: 's-resize',\n xy: 'se-resize',\n\n top: 'n-resize',\n left: 'w-resize',\n bottom: 's-resize',\n right: 'e-resize',\n topleft: 'se-resize',\n bottomright: 'se-resize',\n topright: 'ne-resize',\n bottomleft: 'ne-resize'\n } : {\n x: 'ew-resize',\n y: 'ns-resize',\n xy: 'nwse-resize',\n\n top: 'ns-resize',\n left: 'ew-resize',\n bottom: 'ns-resize',\n right: 'ew-resize',\n topleft: 'nwse-resize',\n bottomright: 'nwse-resize',\n topright: 'nesw-resize',\n bottomleft: 'nesw-resize'\n },\n\n getCursor: function getCursor(action) {\n if (action.axis) {\n return resize.cursors[action.name + action.axis];\n } else if (action.edges) {\n var cursorKey = '';\n var edgeNames = ['top', 'bottom', 'left', 'right'];\n\n for (var i = 0; i < 4; i++) {\n if (action.edges[edgeNames[i]]) {\n cursorKey += edgeNames[i];\n }\n }\n\n return resize.cursors[cursorKey];\n }\n }\n};\n\n// resizestart\nInteractEvent.signals.on('new', function (_ref) {\n var iEvent = _ref.iEvent,\n interaction = _ref.interaction;\n\n if (iEvent.type !== 'resizestart' || !interaction.prepared.edges) {\n return;\n }\n\n var startRect = interaction.target.getRect(interaction.element);\n var resizeOptions = interaction.target.options.resize;\n\n /*\n * When using the `resizable.square` or `resizable.preserveAspectRatio` options, resizing from one edge\n * will affect another. E.g. with `resizable.square`, resizing to make the right edge larger will make\n * the bottom edge larger by the same amount. We call these 'linked' edges. Any linked edges will depend\n * on the active edges and the edge being interacted with.\n */\n if (resizeOptions.square || resizeOptions.preserveAspectRatio) {\n var linkedEdges = utils.extend({}, interaction.prepared.edges);\n\n linkedEdges.top = linkedEdges.top || linkedEdges.left && !linkedEdges.bottom;\n linkedEdges.left = linkedEdges.left || linkedEdges.top && !linkedEdges.right;\n linkedEdges.bottom = linkedEdges.bottom || linkedEdges.right && !linkedEdges.top;\n linkedEdges.right = linkedEdges.right || linkedEdges.bottom && !linkedEdges.left;\n\n interaction.prepared._linkedEdges = linkedEdges;\n } else {\n interaction.prepared._linkedEdges = null;\n }\n\n // if using `resizable.preserveAspectRatio` option, record aspect ratio at the start of the resize\n if (resizeOptions.preserveAspectRatio) {\n interaction.resizeStartAspectRatio = startRect.width / startRect.height;\n }\n\n interaction.resizeRects = {\n start: startRect,\n current: utils.extend({}, startRect),\n inverted: utils.extend({}, startRect),\n previous: utils.extend({}, startRect),\n delta: {\n left: 0, right: 0, width: 0,\n top: 0, bottom: 0, height: 0\n }\n };\n\n iEvent.rect = interaction.resizeRects.inverted;\n iEvent.deltaRect = interaction.resizeRects.delta;\n});\n\n// resizemove\nInteractEvent.signals.on('new', function (_ref2) {\n var iEvent = _ref2.iEvent,\n phase = _ref2.phase,\n interaction = _ref2.interaction;\n\n if (phase !== 'move' || !interaction.prepared.edges) {\n return;\n }\n\n var resizeOptions = interaction.target.options.resize;\n var invert = resizeOptions.invert;\n var invertible = invert === 'reposition' || invert === 'negate';\n\n var edges = interaction.prepared.edges;\n\n var start = interaction.resizeRects.start;\n var current = interaction.resizeRects.current;\n var inverted = interaction.resizeRects.inverted;\n var delta = interaction.resizeRects.delta;\n var previous = utils.extend(interaction.resizeRects.previous, inverted);\n var originalEdges = edges;\n\n var dx = iEvent.dx;\n var dy = iEvent.dy;\n\n if (resizeOptions.preserveAspectRatio || resizeOptions.square) {\n // `resize.preserveAspectRatio` takes precedence over `resize.square`\n var startAspectRatio = resizeOptions.preserveAspectRatio ? interaction.resizeStartAspectRatio : 1;\n\n edges = interaction.prepared._linkedEdges;\n\n if (originalEdges.left && originalEdges.bottom || originalEdges.right && originalEdges.top) {\n dy = -dx / startAspectRatio;\n } else if (originalEdges.left || originalEdges.right) {\n dy = dx / startAspectRatio;\n } else if (originalEdges.top || originalEdges.bottom) {\n dx = dy * startAspectRatio;\n }\n }\n\n // update the 'current' rect without modifications\n if (edges.top) {\n current.top += dy;\n }\n if (edges.bottom) {\n current.bottom += dy;\n }\n if (edges.left) {\n current.left += dx;\n }\n if (edges.right) {\n current.right += dx;\n }\n\n if (invertible) {\n // if invertible, copy the current rect\n utils.extend(inverted, current);\n\n if (invert === 'reposition') {\n // swap edge values if necessary to keep width/height positive\n var swap = void 0;\n\n if (inverted.top > inverted.bottom) {\n swap = inverted.top;\n\n inverted.top = inverted.bottom;\n inverted.bottom = swap;\n }\n if (inverted.left > inverted.right) {\n swap = inverted.left;\n\n inverted.left = inverted.right;\n inverted.right = swap;\n }\n }\n } else {\n // if not invertible, restrict to minimum of 0x0 rect\n inverted.top = Math.min(current.top, start.bottom);\n inverted.bottom = Math.max(current.bottom, start.top);\n inverted.left = Math.min(current.left, start.right);\n inverted.right = Math.max(current.right, start.left);\n }\n\n inverted.width = inverted.right - inverted.left;\n inverted.height = inverted.bottom - inverted.top;\n\n for (var edge in inverted) {\n delta[edge] = inverted[edge] - previous[edge];\n }\n\n iEvent.edges = interaction.prepared.edges;\n iEvent.rect = inverted;\n iEvent.deltaRect = delta;\n});\n\n/*\\\n * Interactable.resizable\n [ method ]\n *\n * Gets or sets whether resize actions can be performed on the\n * Interactable\n *\n = (boolean) Indicates if this can be the target of resize elements\n | var isResizeable = interact('input[type=text]').resizable();\n * or\n - options (boolean | object) #optional true/false or An object with event listeners to be fired on resize events (object makes the Interactable resizable)\n = (object) This Interactable\n | interact(element).resizable({\n | onstart: function (event) {},\n | onmove : function (event) {},\n | onend : function (event) {},\n |\n | edges: {\n | top : true, // Use pointer coords to check for resize.\n | left : false, // Disable resizing from left edge.\n | bottom: '.resize-s',// Resize if pointer target matches selector\n | right : handleEl // Resize if pointer target is the given Element\n | },\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height are adjusted at a 1:1 ratio.\n | square: false,\n |\n | // Width and height can be adjusted independently. When `true`, width and\n | // height maintain the aspect ratio they had when resizing started.\n | preserveAspectRatio: false,\n |\n | // a value of 'none' will limit the resize rect to a minimum of 0x0\n | // 'negate' will allow the rect to have negative width/height\n | // 'reposition' will keep the width/height positive by swapping\n | // the top and bottom edges and/or swapping the left and right edges\n | invert: 'none' || 'negate' || 'reposition'\n |\n | // limit multiple resizes.\n | // See the explanation in the @Interactable.draggable example\n | max: Infinity,\n | maxPerElement: 1,\n | });\n \\*/\nInteractable.prototype.resizable = function (options) {\n if (utils.is.object(options)) {\n this.options.resize.enabled = options.enabled === false ? false : true;\n this.setPerAction('resize', options);\n this.setOnEvents('resize', options);\n\n if (/^x$|^y$|^xy$/.test(options.axis)) {\n this.options.resize.axis = options.axis;\n } else if (options.axis === null) {\n this.options.resize.axis = defaultOptions.resize.axis;\n }\n\n if (utils.is.bool(options.preserveAspectRatio)) {\n this.options.resize.preserveAspectRatio = options.preserveAspectRatio;\n } else if (utils.is.bool(options.square)) {\n this.options.resize.square = options.square;\n }\n\n return this;\n }\n if (utils.is.bool(options)) {\n this.options.resize.enabled = options;\n\n if (!options) {\n this.onresizestart = this.onresizestart = this.onresizeend = null;\n }\n\n return this;\n }\n return this.options.resize;\n};\n\nfunction checkResizeEdge(name, value, page, element, interactableElement, rect, margin) {\n // false, '', undefined, null\n if (!value) {\n return false;\n }\n\n // true value, use pointer coords and element rect\n if (value === true) {\n // if dimensions are negative, \"switch\" edges\n var width = utils.is.number(rect.width) ? rect.width : rect.right - rect.left;\n var height = utils.is.number(rect.height) ? rect.height : rect.bottom - rect.top;\n\n if (width < 0) {\n if (name === 'left') {\n name = 'right';\n } else if (name === 'right') {\n name = 'left';\n }\n }\n if (height < 0) {\n if (name === 'top') {\n name = 'bottom';\n } else if (name === 'bottom') {\n name = 'top';\n }\n }\n\n if (name === 'left') {\n return page.x < (width >= 0 ? rect.left : rect.right) + margin;\n }\n if (name === 'top') {\n return page.y < (height >= 0 ? rect.top : rect.bottom) + margin;\n }\n\n if (name === 'right') {\n return page.x > (width >= 0 ? rect.right : rect.left) - margin;\n }\n if (name === 'bottom') {\n return page.y > (height >= 0 ? rect.bottom : rect.top) - margin;\n }\n }\n\n // the remaining checks require an element\n if (!utils.is.element(element)) {\n return false;\n }\n\n return utils.is.element(value)\n // the value is an element to use as a resize handle\n ? value === element\n // otherwise check if element matches value as selector\n : utils.matchesUpTo(element, value, interactableElement);\n}\n\nInteraction.signals.on('new', function (interaction) {\n interaction.resizeAxes = 'xy';\n});\n\nInteractEvent.signals.on('set-delta', function (_ref3) {\n var interaction = _ref3.interaction,\n iEvent = _ref3.iEvent,\n action = _ref3.action;\n\n if (action !== 'resize' || !interaction.resizeAxes) {\n return;\n }\n\n var options = interaction.target.options;\n\n if (options.resize.square) {\n if (interaction.resizeAxes === 'y') {\n iEvent.dx = iEvent.dy;\n } else {\n iEvent.dy = iEvent.dx;\n }\n iEvent.axes = 'xy';\n } else {\n iEvent.axes = interaction.resizeAxes;\n\n if (interaction.resizeAxes === 'x') {\n iEvent.dy = 0;\n } else if (interaction.resizeAxes === 'y') {\n iEvent.dx = 0;\n }\n }\n});\n\nactions.resize = resize;\nactions.names.push('resize');\nutils.merge(Interactable.eventTypes, ['resizestart', 'resizemove', 'resizeinertiastart', 'resizeinertiaresume', 'resizeend']);\nactions.methodDict.resize = 'resizable';\n\ndefaultOptions.resize = resize.defaults;\n\nmodule.exports = resize;\n\n},{\"../InteractEvent\":3,\"../Interactable\":4,\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"../utils/browser\":37,\"./base\":6}],11:[function(require,module,exports){\n'use strict';\n\nvar raf = require('./utils/raf');\nvar getWindow = require('./utils/window').getWindow;\nvar is = require('./utils/is');\nvar domUtils = require('./utils/domUtils');\nvar Interaction = require('./Interaction');\nvar defaultOptions = require('./defaultOptions');\n\nvar autoScroll = {\n defaults: {\n enabled: false,\n container: null, // the item that is scrolled (Window or HTMLElement)\n margin: 60,\n speed: 300 // the scroll speed in pixels per second\n },\n\n interaction: null,\n i: null, // the handle returned by window.setInterval\n x: 0, y: 0, // Direction each pulse is to scroll in\n\n isScrolling: false,\n prevTime: 0,\n\n start: function start(interaction) {\n autoScroll.isScrolling = true;\n raf.cancel(autoScroll.i);\n\n autoScroll.interaction = interaction;\n autoScroll.prevTime = new Date().getTime();\n autoScroll.i = raf.request(autoScroll.scroll);\n },\n\n stop: function stop() {\n autoScroll.isScrolling = false;\n raf.cancel(autoScroll.i);\n },\n\n // scroll the window by the values in scroll.x/y\n scroll: function scroll() {\n var options = autoScroll.interaction.target.options[autoScroll.interaction.prepared.name].autoScroll;\n var container = options.container || getWindow(autoScroll.interaction.element);\n var now = new Date().getTime();\n // change in time in seconds\n var dt = (now - autoScroll.prevTime) / 1000;\n // displacement\n var s = options.speed * dt;\n\n if (s >= 1) {\n if (is.window(container)) {\n container.scrollBy(autoScroll.x * s, autoScroll.y * s);\n } else if (container) {\n container.scrollLeft += autoScroll.x * s;\n container.scrollTop += autoScroll.y * s;\n }\n\n autoScroll.prevTime = now;\n }\n\n if (autoScroll.isScrolling) {\n raf.cancel(autoScroll.i);\n autoScroll.i = raf.request(autoScroll.scroll);\n }\n },\n check: function check(interactable, actionName) {\n var options = interactable.options;\n\n return options[actionName].autoScroll && options[actionName].autoScroll.enabled;\n },\n onInteractionMove: function onInteractionMove(_ref) {\n var interaction = _ref.interaction,\n pointer = _ref.pointer;\n\n if (!(interaction.interacting() && autoScroll.check(interaction.target, interaction.prepared.name))) {\n return;\n }\n\n if (interaction.simulation) {\n autoScroll.x = autoScroll.y = 0;\n return;\n }\n\n var top = void 0;\n var right = void 0;\n var bottom = void 0;\n var left = void 0;\n\n var options = interaction.target.options[interaction.prepared.name].autoScroll;\n var container = options.container || getWindow(interaction.element);\n\n if (is.window(container)) {\n left = pointer.clientX < autoScroll.margin;\n top = pointer.clientY < autoScroll.margin;\n right = pointer.clientX > container.innerWidth - autoScroll.margin;\n bottom = pointer.clientY > container.innerHeight - autoScroll.margin;\n } else {\n var rect = domUtils.getElementClientRect(container);\n\n left = pointer.clientX < rect.left + autoScroll.margin;\n top = pointer.clientY < rect.top + autoScroll.margin;\n right = pointer.clientX > rect.right - autoScroll.margin;\n bottom = pointer.clientY > rect.bottom - autoScroll.margin;\n }\n\n autoScroll.x = right ? 1 : left ? -1 : 0;\n autoScroll.y = bottom ? 1 : top ? -1 : 0;\n\n if (!autoScroll.isScrolling) {\n // set the autoScroll properties to those of the target\n autoScroll.margin = options.margin;\n autoScroll.speed = options.speed;\n\n autoScroll.start(interaction);\n }\n }\n};\n\nInteraction.signals.on('stop-active', function () {\n autoScroll.stop();\n});\n\nInteraction.signals.on('action-move', autoScroll.onInteractionMove);\n\ndefaultOptions.perAction.autoScroll = autoScroll.defaults;\n\nmodule.exports = autoScroll;\n\n},{\"./Interaction\":5,\"./defaultOptions\":18,\"./utils/domUtils\":39,\"./utils/is\":46,\"./utils/raf\":50,\"./utils/window\":52}],12:[function(require,module,exports){\n'use strict';\n\nvar Interactable = require('../Interactable');\nvar actions = require('../actions/base');\nvar is = require('../utils/is');\nvar domUtils = require('../utils/domUtils');\n\nInteractable.prototype.getAction = function (pointer, event, interaction, element) {\n var action = this.defaultActionChecker(pointer, event, interaction, element);\n\n if (this.options.actionChecker) {\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\n }\n\n return action;\n};\n\n/*\\\n * Interactable.ignoreFrom\n [ method ]\n *\n * If the target of the `mousedown`, `pointerdown` or `touchstart`\n * event or any of it's parents match the given CSS selector or\n * Element, no drag/resize/gesture is started.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to not ignore any elements\n = (string | Element | object) The current ignoreFrom value or this Interactable\n **\n | interact(element, { ignoreFrom: document.getElementById('no-action') });\n | // or\n | interact(element).ignoreFrom('input, textarea, a');\n\\*/\nInteractable.prototype.ignoreFrom = function (newValue) {\n return this._backCompatOption('ignoreFrom', newValue);\n};\n\n/*\\\n * Interactable.allowFrom\n [ method ]\n *\n * A drag/resize/gesture is started only If the target of the\n * `mousedown`, `pointerdown` or `touchstart` event or any of it's\n * parents match the given CSS selector or Element.\n *\n - newValue (string | Element | null) #optional a CSS selector string, an Element or `null` to allow from any element\n = (string | Element | object) The current allowFrom value or this Interactable\n **\n | interact(element, { allowFrom: document.getElementById('drag-handle') });\n | // or\n | interact(element).allowFrom('.handle');\n\\*/\nInteractable.prototype.allowFrom = function (newValue) {\n return this._backCompatOption('allowFrom', newValue);\n};\n\nInteractable.prototype.testIgnore = function (ignoreFrom, interactableElement, element) {\n if (!ignoreFrom || !is.element(element)) {\n return false;\n }\n\n if (is.string(ignoreFrom)) {\n return domUtils.matchesUpTo(element, ignoreFrom, interactableElement);\n } else if (is.element(ignoreFrom)) {\n return domUtils.nodeContains(ignoreFrom, element);\n }\n\n return false;\n};\n\nInteractable.prototype.testAllow = function (allowFrom, interactableElement, element) {\n if (!allowFrom) {\n return true;\n }\n\n if (!is.element(element)) {\n return false;\n }\n\n if (is.string(allowFrom)) {\n return domUtils.matchesUpTo(element, allowFrom, interactableElement);\n } else if (is.element(allowFrom)) {\n return domUtils.nodeContains(allowFrom, element);\n }\n\n return false;\n};\n\nInteractable.prototype.testIgnoreAllow = function (options, interactableElement, eventTarget) {\n return !this.testIgnore(options.ignoreFrom, interactableElement, eventTarget) && this.testAllow(options.allowFrom, interactableElement, eventTarget);\n};\n\n/*\\\n * Interactable.actionChecker\n [ method ]\n *\n * Gets or sets the function used to check action to be performed on\n * pointerDown\n *\n - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\n = (Function | Interactable) The checker function or this Interactable\n *\n | interact('.resize-drag')\n | .resizable(true)\n | .draggable(true)\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\n |\n | if (interact.matchesSelector(event.target, '.drag-handle') {\n | // force drag with handle target\n | action.name = drag;\n | }\n | else {\n | // resize from the top and right edges\n | action.name = 'resize';\n | action.edges = { top: true, right: true };\n | }\n |\n | return action;\n | });\n\\*/\nInteractable.prototype.actionChecker = function (checker) {\n if (is.function(checker)) {\n this.options.actionChecker = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.actionChecker;\n\n return this;\n }\n\n return this.options.actionChecker;\n};\n\n/*\\\n * Interactable.styleCursor\n [ method ]\n *\n * Returns or sets whether the the cursor should be changed depending on the\n * action that would be performed if the mouse were pressed and dragged.\n *\n - newValue (boolean) #optional\n = (boolean | Interactable) The current setting or this Interactable\n\\*/\nInteractable.prototype.styleCursor = function (newValue) {\n if (is.bool(newValue)) {\n this.options.styleCursor = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.styleCursor;\n\n return this;\n }\n\n return this.options.styleCursor;\n};\n\nInteractable.prototype.defaultActionChecker = function (pointer, event, interaction, element) {\n var rect = this.getRect(element);\n var action = null;\n\n for (var _iterator = actions.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var actionName = _ref;\n\n // check mouseButton setting if the pointer is down\n if (interaction.pointerIsDown && interaction.mouse && (event.buttons & this.options[actionName].mouseButtons) === 0) {\n continue;\n }\n\n action = actions[actionName].checker(pointer, event, this, element, interaction, rect);\n\n if (action) {\n return action;\n }\n }\n};\n\n},{\"../Interactable\":4,\"../actions/base\":6,\"../utils/domUtils\":39,\"../utils/is\":46}],13:[function(require,module,exports){\n'use strict';\n\nvar interact = require('../interact');\nvar Interactable = require('../Interactable');\nvar Interaction = require('../Interaction');\nvar actions = require('../actions/base');\nvar defaultOptions = require('../defaultOptions');\nvar browser = require('../utils/browser');\nvar scope = require('../scope');\nvar utils = require('../utils');\nvar signals = require('../utils/Signals').new();\n\nrequire('./InteractableMethods');\n\nvar autoStart = {\n signals: signals,\n withinInteractionLimit: withinInteractionLimit,\n // Allow this many interactions to happen simultaneously\n maxInteractions: Infinity,\n defaults: {\n perAction: {\n manualStart: false,\n max: Infinity,\n maxPerElement: 1,\n allowFrom: null,\n ignoreFrom: null\n }\n },\n setActionDefaults: function setActionDefaults(action) {\n utils.extend(action.defaults, autoStart.defaults.perAction);\n }\n};\n\n// set cursor style on mousedown\nInteraction.signals.on('down', function (_ref) {\n var interaction = _ref.interaction,\n pointer = _ref.pointer,\n event = _ref.event,\n eventTarget = _ref.eventTarget;\n\n if (interaction.interacting()) {\n return;\n }\n\n var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);\n prepare(interaction, actionInfo);\n});\n\n// set cursor style on mousemove\nInteraction.signals.on('move', function (_ref2) {\n var interaction = _ref2.interaction,\n pointer = _ref2.pointer,\n event = _ref2.event,\n eventTarget = _ref2.eventTarget;\n\n if (!interaction.mouse || interaction.pointerIsDown || interaction.interacting()) {\n return;\n }\n\n var actionInfo = getActionInfo(interaction, pointer, event, eventTarget);\n prepare(interaction, actionInfo);\n});\n\nInteraction.signals.on('move', function (arg) {\n var interaction = arg.interaction,\n event = arg.event;\n\n\n if (!interaction.pointerIsDown || interaction.interacting() || !interaction.pointerWasMoved || !interaction.prepared.name) {\n return;\n }\n\n signals.fire('before-start', arg);\n\n var target = interaction.target;\n\n if (interaction.prepared.name && target) {\n // check manualStart and interaction limit\n if (target.options[interaction.prepared.name].manualStart || !withinInteractionLimit(target, interaction.element, interaction.prepared)) {\n interaction.stop(event);\n } else {\n interaction.start(interaction.prepared, target, interaction.element);\n }\n }\n});\n\n// Check if the current target supports the action.\n// If so, return the validated action. Otherwise, return null\nfunction validateAction(action, interactable, element, eventTarget) {\n if (utils.is.object(action) && interactable.testIgnoreAllow(interactable.options[action.name], element, eventTarget) && interactable.options[action.name].enabled && withinInteractionLimit(interactable, element, action)) {\n return action;\n }\n\n return null;\n}\n\nfunction validateSelector(interaction, pointer, event, matches, matchElements, eventTarget) {\n for (var i = 0, len = matches.length; i < len; i++) {\n var match = matches[i];\n var matchElement = matchElements[i];\n var action = validateAction(match.getAction(pointer, event, interaction, matchElement), match, matchElement, eventTarget);\n\n if (action) {\n return {\n action: action,\n target: match,\n element: matchElement\n };\n }\n }\n\n return {};\n}\n\nfunction getActionInfo(interaction, pointer, event, eventTarget) {\n var matches = [];\n var matchElements = [];\n\n var element = eventTarget;\n var action = null;\n\n function pushMatches(interactable, selector, context) {\n var elements = browser.useMatchesSelectorPolyfill ? context.querySelectorAll(selector) : undefined;\n\n if (utils.matchesSelector(element, selector, elements)) {\n\n matches.push(interactable);\n matchElements.push(element);\n }\n }\n\n while (utils.is.element(element)) {\n matches = [];\n matchElements = [];\n\n var elementInteractable = scope.interactables.get(element);\n\n if (elementInteractable && (action = validateAction(elementInteractable.getAction(pointer, event, interaction, element, eventTarget), elementInteractable, element, eventTarget)) && !elementInteractable.options[action.name].manualStart) {\n return {\n element: element,\n action: action,\n target: elementInteractable\n };\n } else {\n scope.interactables.forEachSelector(pushMatches, element);\n\n var actionInfo = validateSelector(interaction, pointer, event, matches, matchElements, eventTarget);\n\n if (actionInfo.action && !actionInfo.target.options[actionInfo.action.name].manualStart) {\n return actionInfo;\n }\n }\n\n element = utils.parentNode(element);\n }\n\n return {};\n}\n\nfunction prepare(interaction, _ref3) {\n var action = _ref3.action,\n target = _ref3.target,\n element = _ref3.element;\n\n action = action || {};\n\n if (interaction.target && interaction.target.options.styleCursor) {\n interaction.target._doc.documentElement.style.cursor = '';\n }\n\n interaction.target = target;\n interaction.element = element;\n utils.copyAction(interaction.prepared, action);\n\n if (target && target.options.styleCursor) {\n var cursor = action ? actions[action.name].getCursor(action) : '';\n interaction.target._doc.documentElement.style.cursor = cursor;\n }\n\n signals.fire('prepared', { interaction: interaction });\n}\n\nInteraction.signals.on('stop', function (_ref4) {\n var interaction = _ref4.interaction;\n\n var target = interaction.target;\n\n if (target && target.options.styleCursor) {\n target._doc.documentElement.style.cursor = '';\n }\n});\n\nInteractable.prototype.getAction = function (pointer, event, interaction, element) {\n var action = this.defaultActionChecker(pointer, event, interaction, element);\n\n if (this.options.actionChecker) {\n return this.options.actionChecker(pointer, event, action, this, element, interaction);\n }\n\n return action;\n};\n\n/*\\\n * Interactable.actionChecker\n [ method ]\n *\n * Gets or sets the function used to check action to be performed on\n * pointerDown\n *\n - checker (function | null) #optional A function which takes a pointer event, defaultAction string, interactable, element and interaction as parameters and returns an object with name property 'drag' 'resize' or 'gesture' and optionally an `edges` object with boolean 'top', 'left', 'bottom' and right props.\n = (Function | Interactable) The checker function or this Interactable\n *\n | interact('.resize-drag')\n | .resizable(true)\n | .draggable(true)\n | .actionChecker(function (pointer, event, action, interactable, element, interaction) {\n |\n | if (interact.matchesSelector(event.target, '.drag-handle') {\n | // force drag with handle target\n | action.name = drag;\n | }\n | else {\n | // resize from the top and right edges\n | action.name = 'resize';\n | action.edges = { top: true, right: true };\n | }\n |\n | return action;\n | });\n\\*/\nInteractable.prototype.actionChecker = function (checker) {\n if (utils.is.function(checker)) {\n this.options.actionChecker = checker;\n\n return this;\n }\n\n if (checker === null) {\n delete this.options.actionChecker;\n\n return this;\n }\n\n return this.options.actionChecker;\n};\n\n/*\\\n * Interactable.styleCursor\n [ method ]\n *\n * Returns or sets whether the the cursor should be changed depending on the\n * action that would be performed if the mouse were pressed and dragged.\n *\n - newValue (boolean) #optional\n = (boolean | Interactable) The current setting or this Interactable\n\\*/\nInteractable.prototype.styleCursor = function (newValue) {\n if (utils.is.bool(newValue)) {\n this.options.styleCursor = newValue;\n\n return this;\n }\n\n if (newValue === null) {\n delete this.options.styleCursor;\n\n return this;\n }\n\n return this.options.styleCursor;\n};\n\nInteractable.prototype.defaultActionChecker = function (pointer, event, interaction, element) {\n var rect = this.getRect(element);\n var buttons = event.buttons || {\n 0: 1,\n 1: 4,\n 3: 8,\n 4: 16\n }[event.button];\n var action = null;\n\n for (var _iterator = actions.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref5;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref5 = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref5 = _i.value;\n }\n\n var actionName = _ref5;\n\n // check mouseButton setting if the pointer is down\n if (interaction.pointerIsDown && interaction.mouse && (buttons & this.options[actionName].mouseButtons) === 0) {\n continue;\n }\n\n action = actions[actionName].checker(pointer, event, this, element, interaction, rect);\n\n if (action) {\n return action;\n }\n }\n};\n\nfunction withinInteractionLimit(interactable, element, action) {\n var options = interactable.options;\n var maxActions = options[action.name].max;\n var maxPerElement = options[action.name].maxPerElement;\n var activeInteractions = 0;\n var targetCount = 0;\n var targetElementCount = 0;\n\n // no actions if any of these values == 0\n if (!(maxActions && maxPerElement && autoStart.maxInteractions)) {\n return;\n }\n\n for (var i = 0, len = scope.interactions.length; i < len; i++) {\n var interaction = scope.interactions[i];\n var otherAction = interaction.prepared.name;\n\n if (!interaction.interacting()) {\n continue;\n }\n\n activeInteractions++;\n\n if (activeInteractions >= autoStart.maxInteractions) {\n return false;\n }\n\n if (interaction.target !== interactable) {\n continue;\n }\n\n targetCount += otherAction === action.name | 0;\n\n if (targetCount >= maxActions) {\n return false;\n }\n\n if (interaction.element === element) {\n targetElementCount++;\n\n if (otherAction !== action.name || targetElementCount >= maxPerElement) {\n return false;\n }\n }\n }\n\n return autoStart.maxInteractions > 0;\n}\n\n/*\\\n * interact.maxInteractions\n [ method ]\n **\n * Returns or sets the maximum number of concurrent interactions allowed.\n * By default only 1 interaction is allowed at a time (for backwards\n * compatibility). To allow multiple interactions on the same Interactables\n * and elements, you need to enable it in the draggable, resizable and\n * gesturable `'max'` and `'maxPerElement'` options.\n **\n - newValue (number) #optional Any number. newValue <= 0 means no interactions.\n\\*/\ninteract.maxInteractions = function (newValue) {\n if (utils.is.number(newValue)) {\n autoStart.maxInteractions = newValue;\n\n return this;\n }\n\n return autoStart.maxInteractions;\n};\n\nInteractable.settingsMethods.push('styleCursor');\nInteractable.settingsMethods.push('actionChecker');\nInteractable.settingsMethods.push('ignoreFrom');\nInteractable.settingsMethods.push('allowFrom');\n\ndefaultOptions.base.actionChecker = null;\ndefaultOptions.base.styleCursor = true;\n\nutils.extend(defaultOptions.perAction, autoStart.defaults.perAction);\n\nmodule.exports = autoStart;\n\n},{\"../Interactable\":4,\"../Interaction\":5,\"../actions/base\":6,\"../defaultOptions\":18,\"../interact\":21,\"../scope\":34,\"../utils\":44,\"../utils/Signals\":35,\"../utils/browser\":37,\"./InteractableMethods\":12}],14:[function(require,module,exports){\n'use strict';\n\nvar autoStart = require('./base');\nvar Interaction = require('../Interaction');\n\nInteraction.signals.on('new', function (interaction) {\n interaction.delayTimer = null;\n});\n\nautoStart.signals.on('prepared', function (_ref) {\n var interaction = _ref.interaction;\n\n var actionName = interaction.prepared.name;\n\n if (!actionName) {\n return;\n }\n\n var delay = interaction.target.options[actionName].delay;\n\n if (delay > 0) {\n interaction.delayTimer = setTimeout(function () {\n interaction.start(interaction.prepared, interaction.target, interaction.element);\n }, delay);\n }\n});\n\nInteraction.signals.on('move', function (_ref2) {\n var interaction = _ref2.interaction,\n duplicate = _ref2.duplicate;\n\n if (interaction.pointerWasMoved && !duplicate) {\n clearTimeout(interaction.delayTimer);\n }\n});\n\n// prevent regular down->move autoStart\nautoStart.signals.on('before-start', function (_ref3) {\n var interaction = _ref3.interaction;\n\n var actionName = interaction.prepared.name;\n\n if (!actionName) {\n return;\n }\n\n var delay = interaction.target.options[actionName].delay;\n\n if (delay > 0) {\n interaction.prepared.name = null;\n }\n});\n\n},{\"../Interaction\":5,\"./base\":13}],15:[function(require,module,exports){\n'use strict';\n\nvar autoStart = require('./base');\nvar scope = require('../scope');\nvar browser = require('../utils/browser');\nvar is = require('../utils/is');\n\nvar _require = require('../utils/domUtils'),\n matchesSelector = _require.matchesSelector,\n parentNode = _require.parentNode;\n\nautoStart.setActionDefaults(require('../actions/drag'));\n\nautoStart.signals.on('before-start', function (_ref) {\n var interaction = _ref.interaction,\n eventTarget = _ref.eventTarget,\n dx = _ref.dx,\n dy = _ref.dy;\n\n if (interaction.prepared.name !== 'drag') {\n return;\n }\n\n // check if a drag is in the correct axis\n var absX = Math.abs(dx);\n var absY = Math.abs(dy);\n var options = interaction.target.options.drag;\n var startAxis = options.startAxis;\n var currentAxis = absX > absY ? 'x' : absX < absY ? 'y' : 'xy';\n\n interaction.prepared.axis = options.lockAxis === 'start' ? currentAxis[0] // always lock to one axis even if currentAxis === 'xy'\n : options.lockAxis;\n\n // if the movement isn't in the startAxis of the interactable\n if (currentAxis !== 'xy' && startAxis !== 'xy' && startAxis !== currentAxis) {\n // cancel the prepared action\n interaction.prepared.name = null;\n\n // then try to get a drag from another ineractable\n\n if (!interaction.prepared.name) {\n\n var element = eventTarget;\n\n var getDraggable = function getDraggable(interactable, selector, context) {\n var elements = browser.useMatchesSelectorPolyfill ? context.querySelectorAll(selector) : undefined;\n\n if (interactable === interaction.target) {\n return;\n }\n\n if (!options.manualStart && !interactable.testIgnoreAllow(options, element, eventTarget) && matchesSelector(element, selector, elements)) {\n\n var _action = interactable.getAction(interaction.downPointer, interaction.downEvent, interaction, element);\n\n if (_action && _action.name === 'drag' && checkStartAxis(currentAxis, interactable) && autoStart.validateAction(_action, interactable, element, eventTarget)) {\n\n return interactable;\n }\n }\n };\n\n var action = null;\n\n // check all interactables\n while (is.element(element)) {\n var elementInteractable = scope.interactables.get(element);\n\n if (elementInteractable && elementInteractable !== interaction.target && !elementInteractable.options.drag.manualStart) {\n\n action = elementInteractable.getAction(interaction.downPointer, interaction.downEvent, interaction, element);\n }\n if (action && action.name === 'drag' && checkStartAxis(currentAxis, elementInteractable)) {\n\n interaction.prepared.name = 'drag';\n interaction.target = elementInteractable;\n interaction.element = element;\n break;\n }\n\n var selectorInteractable = scope.interactables.forEachSelector(getDraggable, element);\n\n if (selectorInteractable) {\n interaction.prepared.name = 'drag';\n interaction.target = selectorInteractable;\n interaction.element = element;\n break;\n }\n\n element = parentNode(element);\n }\n }\n }\n});\n\nfunction checkStartAxis(startAxis, interactable) {\n if (!interactable) {\n return false;\n }\n\n var thisAxis = interactable.options.drag.startAxis;\n\n return startAxis === 'xy' || thisAxis === 'xy' || thisAxis === startAxis;\n}\n\n},{\"../actions/drag\":7,\"../scope\":34,\"../utils/browser\":37,\"../utils/domUtils\":39,\"../utils/is\":46,\"./base\":13}],16:[function(require,module,exports){\n'use strict';\n\nrequire('./base').setActionDefaults(require('../actions/gesture'));\n\n},{\"../actions/gesture\":9,\"./base\":13}],17:[function(require,module,exports){\n'use strict';\n\nrequire('./base').setActionDefaults(require('../actions/resize'));\n\n},{\"../actions/resize\":10,\"./base\":13}],18:[function(require,module,exports){\n'use strict';\n\nmodule.exports = {\n base: {\n accept: null,\n preventDefault: 'auto',\n deltaSource: 'page'\n },\n\n perAction: {\n origin: { x: 0, y: 0 },\n\n // only allow left button by default\n // see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#Return_value\n mouseButtons: 1,\n\n inertia: {\n enabled: false,\n resistance: 10, // the lambda in exponential decay\n minSpeed: 100, // target speed must be above this for inertia to start\n endSpeed: 10, // the speed at which inertia is slow enough to stop\n allowResume: true, // allow resuming an action in inertia phase\n smoothEndDuration: 300 // animate to snap/restrict endOnly if there's no inertia\n }\n }\n};\n\n},{}],19:[function(require,module,exports){\n'use strict';\n\n/* browser entry point */\n\n// Legacy browser support\nrequire('./legacyBrowsers');\n\n// inertia\nrequire('./inertia');\n\n// modifiers\nrequire('./modifiers/snap');\nrequire('./modifiers/restrict');\n\n// pointerEvents\nrequire('./pointerEvents/base');\nrequire('./pointerEvents/holdRepeat');\nrequire('./pointerEvents/interactableTargets');\n\n// delay\nrequire('./autoStart/delay');\n\n// actions\nrequire('./actions/gesture');\nrequire('./actions/resize');\nrequire('./actions/drag');\nrequire('./actions/drop');\n\n// load these modifiers after resize is loaded\nrequire('./modifiers/snapSize');\nrequire('./modifiers/restrictEdges');\nrequire('./modifiers/restrictSize');\n\n// autoStart actions\nrequire('./autoStart/gesture');\nrequire('./autoStart/resize');\nrequire('./autoStart/drag');\n\n// Interactable preventDefault setting\nrequire('./interactablePreventDefault.js');\n\n// autoScroll\nrequire('./autoScroll');\n\n// export interact\nmodule.exports = require('./interact');\n\n},{\"./actions/drag\":7,\"./actions/drop\":8,\"./actions/gesture\":9,\"./actions/resize\":10,\"./autoScroll\":11,\"./autoStart/delay\":14,\"./autoStart/drag\":15,\"./autoStart/gesture\":16,\"./autoStart/resize\":17,\"./inertia\":20,\"./interact\":21,\"./interactablePreventDefault.js\":22,\"./legacyBrowsers\":23,\"./modifiers/restrict\":25,\"./modifiers/restrictEdges\":26,\"./modifiers/restrictSize\":27,\"./modifiers/snap\":28,\"./modifiers/snapSize\":29,\"./pointerEvents/base\":31,\"./pointerEvents/holdRepeat\":32,\"./pointerEvents/interactableTargets\":33}],20:[function(require,module,exports){\n'use strict';\n\nvar InteractEvent = require('./InteractEvent');\nvar Interaction = require('./Interaction');\nvar modifiers = require('./modifiers');\nvar utils = require('./utils');\nvar animationFrame = require('./utils/raf');\n\nInteraction.signals.on('new', function (interaction) {\n interaction.inertiaStatus = {\n active: false,\n smoothEnd: false,\n allowResume: false,\n\n startEvent: null,\n upCoords: {},\n\n xe: 0, ye: 0,\n sx: 0, sy: 0,\n\n t0: 0,\n vx0: 0, vys: 0,\n duration: 0,\n\n lambda_v0: 0,\n one_ve_v0: 0,\n i: null\n };\n\n interaction.boundInertiaFrame = function () {\n return inertiaFrame.apply(interaction);\n };\n interaction.boundSmoothEndFrame = function () {\n return smoothEndFrame.apply(interaction);\n };\n});\n\nInteraction.signals.on('down', function (_ref) {\n var interaction = _ref.interaction,\n event = _ref.event,\n pointer = _ref.pointer,\n eventTarget = _ref.eventTarget;\n\n var status = interaction.inertiaStatus;\n\n // Check if the down event hits the current inertia target\n if (status.active) {\n var element = eventTarget;\n\n // climb up the DOM tree from the event target\n while (utils.is.element(element)) {\n\n // if interaction element is the current inertia target element\n if (element === interaction.element) {\n // stop inertia\n animationFrame.cancel(status.i);\n status.active = false;\n interaction.simulation = null;\n\n // update pointers to the down event's coordinates\n interaction.updatePointer(pointer);\n utils.setCoords(interaction.curCoords, interaction.pointers);\n\n // fire appropriate signals\n var signalArg = { interaction: interaction };\n Interaction.signals.fire('before-action-move', signalArg);\n Interaction.signals.fire('action-resume', signalArg);\n\n // fire a reume event\n var resumeEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiaresume', interaction.element);\n\n interaction.target.fire(resumeEvent);\n interaction.prevEvent = resumeEvent;\n modifiers.resetStatuses(interaction.modifierStatuses);\n\n utils.copyCoords(interaction.prevCoords, interaction.curCoords);\n break;\n }\n\n element = utils.parentNode(element);\n }\n }\n});\n\nInteraction.signals.on('up', function (_ref2) {\n var interaction = _ref2.interaction,\n event = _ref2.event;\n\n var status = interaction.inertiaStatus;\n\n if (!interaction.interacting() || status.active) {\n return;\n }\n\n var target = interaction.target;\n var options = target && target.options;\n var inertiaOptions = options && interaction.prepared.name && options[interaction.prepared.name].inertia;\n\n var now = new Date().getTime();\n var statuses = {};\n var page = utils.extend({}, interaction.curCoords.page);\n var pointerSpeed = interaction.pointerDelta.client.speed;\n\n var smoothEnd = false;\n var modifierResult = void 0;\n\n // check if inertia should be started\n var inertiaPossible = inertiaOptions && inertiaOptions.enabled && interaction.prepared.name !== 'gesture' && event !== status.startEvent;\n\n var inertia = inertiaPossible && now - interaction.curCoords.timeStamp < 50 && pointerSpeed > inertiaOptions.minSpeed && pointerSpeed > inertiaOptions.endSpeed;\n\n var modifierArg = {\n interaction: interaction,\n pageCoords: page,\n statuses: statuses,\n preEnd: true,\n requireEndOnly: true\n };\n\n // smoothEnd\n if (inertiaPossible && !inertia) {\n modifiers.resetStatuses(statuses);\n\n modifierResult = modifiers.setAll(modifierArg);\n\n if (modifierResult.shouldMove && modifierResult.locked) {\n smoothEnd = true;\n }\n }\n\n if (!(inertia || smoothEnd)) {\n return;\n }\n\n utils.copyCoords(status.upCoords, interaction.curCoords);\n\n interaction.pointers[0] = status.startEvent = new InteractEvent(interaction, event, interaction.prepared.name, 'inertiastart', interaction.element);\n\n status.t0 = now;\n\n status.active = true;\n status.allowResume = inertiaOptions.allowResume;\n interaction.simulation = status;\n\n target.fire(status.startEvent);\n\n if (inertia) {\n status.vx0 = interaction.pointerDelta.client.vx;\n status.vy0 = interaction.pointerDelta.client.vy;\n status.v0 = pointerSpeed;\n\n calcInertia(interaction, status);\n\n utils.extend(page, interaction.curCoords.page);\n\n page.x += status.xe;\n page.y += status.ye;\n\n modifiers.resetStatuses(statuses);\n\n modifierResult = modifiers.setAll(modifierArg);\n\n status.modifiedXe += modifierResult.dx;\n status.modifiedYe += modifierResult.dy;\n\n status.i = animationFrame.request(interaction.boundInertiaFrame);\n } else {\n status.smoothEnd = true;\n status.xe = modifierResult.dx;\n status.ye = modifierResult.dy;\n\n status.sx = status.sy = 0;\n\n status.i = animationFrame.request(interaction.boundSmoothEndFrame);\n }\n});\n\nInteraction.signals.on('stop-active', function (_ref3) {\n var interaction = _ref3.interaction;\n\n var status = interaction.inertiaStatus;\n\n if (status.active) {\n animationFrame.cancel(status.i);\n status.active = false;\n interaction.simulation = null;\n }\n});\n\nfunction calcInertia(interaction, status) {\n var inertiaOptions = interaction.target.options[interaction.prepared.name].inertia;\n var lambda = inertiaOptions.resistance;\n var inertiaDur = -Math.log(inertiaOptions.endSpeed / status.v0) / lambda;\n\n status.x0 = interaction.prevEvent.pageX;\n status.y0 = interaction.prevEvent.pageY;\n status.t0 = status.startEvent.timeStamp / 1000;\n status.sx = status.sy = 0;\n\n status.modifiedXe = status.xe = (status.vx0 - inertiaDur) / lambda;\n status.modifiedYe = status.ye = (status.vy0 - inertiaDur) / lambda;\n status.te = inertiaDur;\n\n status.lambda_v0 = lambda / status.v0;\n status.one_ve_v0 = 1 - inertiaOptions.endSpeed / status.v0;\n}\n\nfunction inertiaFrame() {\n updateInertiaCoords(this);\n utils.setCoordDeltas(this.pointerDelta, this.prevCoords, this.curCoords);\n\n var status = this.inertiaStatus;\n var options = this.target.options[this.prepared.name].inertia;\n var lambda = options.resistance;\n var t = new Date().getTime() / 1000 - status.t0;\n\n if (t < status.te) {\n\n var progress = 1 - (Math.exp(-lambda * t) - status.lambda_v0) / status.one_ve_v0;\n\n if (status.modifiedXe === status.xe && status.modifiedYe === status.ye) {\n status.sx = status.xe * progress;\n status.sy = status.ye * progress;\n } else {\n var quadPoint = utils.getQuadraticCurvePoint(0, 0, status.xe, status.ye, status.modifiedXe, status.modifiedYe, progress);\n\n status.sx = quadPoint.x;\n status.sy = quadPoint.y;\n }\n\n this.doMove();\n\n status.i = animationFrame.request(this.boundInertiaFrame);\n } else {\n status.sx = status.modifiedXe;\n status.sy = status.modifiedYe;\n\n this.doMove();\n this.end(status.startEvent);\n status.active = false;\n this.simulation = null;\n }\n\n utils.copyCoords(this.prevCoords, this.curCoords);\n}\n\nfunction smoothEndFrame() {\n updateInertiaCoords(this);\n\n var status = this.inertiaStatus;\n var t = new Date().getTime() - status.t0;\n var duration = this.target.options[this.prepared.name].inertia.smoothEndDuration;\n\n if (t < duration) {\n status.sx = utils.easeOutQuad(t, 0, status.xe, duration);\n status.sy = utils.easeOutQuad(t, 0, status.ye, duration);\n\n this.pointerMove(status.startEvent, status.startEvent);\n\n status.i = animationFrame.request(this.boundSmoothEndFrame);\n } else {\n status.sx = status.xe;\n status.sy = status.ye;\n\n this.pointerMove(status.startEvent, status.startEvent);\n this.end(status.startEvent);\n\n status.smoothEnd = status.active = false;\n this.simulation = null;\n }\n}\n\nfunction updateInertiaCoords(interaction) {\n var status = interaction.inertiaStatus;\n\n // return if inertia isn't running\n if (!status.active) {\n return;\n }\n\n var pageUp = status.upCoords.page;\n var clientUp = status.upCoords.client;\n\n utils.setCoords(interaction.curCoords, [{\n pageX: pageUp.x + status.sx,\n pageY: pageUp.y + status.sy,\n clientX: clientUp.x + status.sx,\n clientY: clientUp.y + status.sy\n }]);\n}\n\n},{\"./InteractEvent\":3,\"./Interaction\":5,\"./modifiers\":24,\"./utils\":44,\"./utils/raf\":50}],21:[function(require,module,exports){\n'use strict';\n\nvar browser = require('./utils/browser');\nvar events = require('./utils/events');\nvar utils = require('./utils');\nvar scope = require('./scope');\nvar Interactable = require('./Interactable');\nvar Interaction = require('./Interaction');\n\nvar globalEvents = {};\n\n/*\\\n * interact\n [ method ]\n *\n * The methods of this variable can be used to set elements as\n * interactables and also to change various default settings.\n *\n * Calling it as a function and passing an element or a valid CSS selector\n * string returns an Interactable object which has various methods to\n * configure it.\n *\n - element (Element | string) The HTML or SVG Element to interact with or CSS selector\n = (object) An @Interactable\n *\n > Usage\n | interact('#draggable').draggable(true);\n |\n | var rectables = interact('rect');\n | rectables\n | .gesturable(true)\n | .on('gesturemove', function (event) {\n | // ...\n | });\n\\*/\nfunction interact(element, options) {\n var interactable = scope.interactables.get(element, options);\n\n if (!interactable) {\n interactable = new Interactable(element, options);\n interactable.events.global = globalEvents;\n }\n\n return interactable;\n}\n\n/*\\\n * interact.isSet\n [ method ]\n *\n * Check if an element has been set\n - element (Element) The Element being searched for\n = (boolean) Indicates if the element or CSS selector was previously passed to interact\n\\*/\ninteract.isSet = function (element, options) {\n return scope.interactables.indexOfElement(element, options && options.context) !== -1;\n};\n\n/*\\\n * interact.on\n [ method ]\n *\n * Adds a global listener for an InteractEvent or adds a DOM event to\n * `document`\n *\n - type (string | array | object) The types of events to listen for\n - listener (function) The function event (s)\n - options (object | boolean) #optional options object or useCapture flag for addEventListener\n = (object) interact\n\\*/\ninteract.on = function (type, listener, options) {\n if (utils.is.string(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (utils.is.array(type)) {\n for (var _iterator = type, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var eventType = _ref;\n\n interact.on(eventType, listener, options);\n }\n\n return interact;\n }\n\n if (utils.is.object(type)) {\n for (var prop in type) {\n interact.on(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n // if it is an InteractEvent type, add listener to globalEvents\n if (utils.contains(Interactable.eventTypes, type)) {\n // if this type of event was never bound\n if (!globalEvents[type]) {\n globalEvents[type] = [listener];\n } else {\n globalEvents[type].push(listener);\n }\n }\n // If non InteractEvent type, addEventListener to document\n else {\n events.add(scope.document, type, listener, { options: options });\n }\n\n return interact;\n};\n\n/*\\\n * interact.off\n [ method ]\n *\n * Removes a global InteractEvent listener or DOM event from `document`\n *\n - type (string | array | object) The types of events that were listened for\n - listener (function) The listener function to be removed\n - options (object | boolean) #optional options object or useCapture flag for removeEventListener\n = (object) interact\n \\*/\ninteract.off = function (type, listener, options) {\n if (utils.is.string(type) && type.search(' ') !== -1) {\n type = type.trim().split(/ +/);\n }\n\n if (utils.is.array(type)) {\n for (var _iterator2 = type, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\n var _ref2;\n\n if (_isArray2) {\n if (_i2 >= _iterator2.length) break;\n _ref2 = _iterator2[_i2++];\n } else {\n _i2 = _iterator2.next();\n if (_i2.done) break;\n _ref2 = _i2.value;\n }\n\n var eventType = _ref2;\n\n interact.off(eventType, listener, options);\n }\n\n return interact;\n }\n\n if (utils.is.object(type)) {\n for (var prop in type) {\n interact.off(prop, type[prop], listener);\n }\n\n return interact;\n }\n\n if (!utils.contains(Interactable.eventTypes, type)) {\n events.remove(scope.document, type, listener, options);\n } else {\n var index = void 0;\n\n if (type in globalEvents && (index = utils.indexOf(globalEvents[type], listener)) !== -1) {\n globalEvents[type].splice(index, 1);\n }\n }\n\n return interact;\n};\n\n/*\\\n * interact.debug\n [ method ]\n *\n * Returns an object which exposes internal data\n = (object) An object with properties that outline the current state and expose internal functions and variables\n\\*/\ninteract.debug = function () {\n return scope;\n};\n\n// expose the functions used to calculate multi-touch properties\ninteract.getPointerAverage = utils.pointerAverage;\ninteract.getTouchBBox = utils.touchBBox;\ninteract.getTouchDistance = utils.touchDistance;\ninteract.getTouchAngle = utils.touchAngle;\n\ninteract.getElementRect = utils.getElementRect;\ninteract.getElementClientRect = utils.getElementClientRect;\ninteract.matchesSelector = utils.matchesSelector;\ninteract.closest = utils.closest;\n\n/*\\\n * interact.supportsTouch\n [ method ]\n *\n = (boolean) Whether or not the browser supports touch input\n\\*/\ninteract.supportsTouch = function () {\n return browser.supportsTouch;\n};\n\n/*\\\n * interact.supportsPointerEvent\n [ method ]\n *\n = (boolean) Whether or not the browser supports PointerEvents\n\\*/\ninteract.supportsPointerEvent = function () {\n return browser.supportsPointerEvent;\n};\n\n/*\\\n * interact.stop\n [ method ]\n *\n * Cancels all interactions (end events are not fired)\n *\n - event (Event) An event on which to call preventDefault()\n = (object) interact\n\\*/\ninteract.stop = function (event) {\n for (var i = scope.interactions.length - 1; i >= 0; i--) {\n scope.interactions[i].stop(event);\n }\n\n return interact;\n};\n\n/*\\\n * interact.pointerMoveTolerance\n [ method ]\n * Returns or sets the distance the pointer must be moved before an action\n * sequence occurs. This also affects tolerance for tap events.\n *\n - newValue (number) #optional The movement from the start position must be greater than this value\n = (number | Interactable) The current setting or interact\n\\*/\ninteract.pointerMoveTolerance = function (newValue) {\n if (utils.is.number(newValue)) {\n Interaction.pointerMoveTolerance = newValue;\n\n return this;\n }\n\n return Interaction.pointerMoveTolerance;\n};\n\ninteract.addDocument = scope.addDocument;\ninteract.removeDocument = scope.removeDocument;\n\nscope.interact = interact;\n\nmodule.exports = interact;\n\n},{\"./Interactable\":4,\"./Interaction\":5,\"./scope\":34,\"./utils\":44,\"./utils/browser\":37,\"./utils/events\":40}],22:[function(require,module,exports){\n'use strict';\n\nvar Interactable = require('./Interactable');\nvar Interaction = require('./Interaction');\nvar scope = require('./scope');\nvar is = require('./utils/is');\nvar events = require('./utils/events');\n\nvar _require = require('./utils/domUtils'),\n nodeContains = _require.nodeContains,\n matchesSelector = _require.matchesSelector;\n\n/*\\\n * Interactable.preventDefault\n [ method ]\n *\n * Returns or sets whether to prevent the browser's default behaviour\n * in response to pointer events. Can be set to:\n * - `'always'` to always prevent\n * - `'never'` to never prevent\n * - `'auto'` to let interact.js try to determine what would be best\n *\n - newValue (string) #optional `true`, `false` or `'auto'`\n = (string | Interactable) The current setting or this Interactable\n\\*/\n\n\nInteractable.prototype.preventDefault = function (newValue) {\n if (/^(always|never|auto)$/.test(newValue)) {\n this.options.preventDefault = newValue;\n return this;\n }\n\n if (is.bool(newValue)) {\n this.options.preventDefault = newValue ? 'always' : 'never';\n return this;\n }\n\n return this.options.preventDefault;\n};\n\nInteractable.prototype.checkAndPreventDefault = function (event) {\n var setting = this.options.preventDefault;\n\n if (setting === 'never') {\n return;\n }\n\n if (setting === 'always') {\n event.preventDefault();\n return;\n }\n\n // setting === 'auto'\n\n // don't preventDefault if the browser supports passiveEvents\n // CSS touch-action and user-selecct should be used instead\n if (events.supportsOptions) {\n return;\n }\n\n // don't preventDefault of pointerdown events\n if (/^(mouse|pointer|touch)*(down|start)/i.test(event.type)) {\n return;\n }\n\n // don't preventDefault on editable elements\n if (is.element(event.target) && matchesSelector(event.target, 'input,select,textarea,[contenteditable=true],[contenteditable=true] *')) {\n return;\n }\n\n event.preventDefault();\n};\n\nfunction onInteractionEvent(_ref) {\n var interaction = _ref.interaction,\n event = _ref.event;\n\n if (interaction.target) {\n interaction.target.checkAndPreventDefault(event);\n }\n}\n\nvar _arr = ['down', 'move', 'up', 'cancel'];\nfor (var _i = 0; _i < _arr.length; _i++) {\n var eventSignal = _arr[_i];\n Interaction.signals.on(eventSignal, onInteractionEvent);\n}\n\n// prevent native HTML5 drag on interact.js target elements\nInteraction.docEvents.dragstart = function preventNativeDrag(event) {\n for (var _iterator = scope.interactions, _isArray = Array.isArray(_iterator), _i2 = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref2;\n\n if (_isArray) {\n if (_i2 >= _iterator.length) break;\n _ref2 = _iterator[_i2++];\n } else {\n _i2 = _iterator.next();\n if (_i2.done) break;\n _ref2 = _i2.value;\n }\n\n var interaction = _ref2;\n\n\n if (interaction.element && (interaction.element === event.target || nodeContains(interaction.element, event.target))) {\n\n interaction.target.checkAndPreventDefault(event);\n return;\n }\n }\n};\n\n},{\"./Interactable\":4,\"./Interaction\":5,\"./scope\":34,\"./utils/domUtils\":39,\"./utils/events\":40,\"./utils/is\":46}],23:[function(require,module,exports){\n'use strict';\n\nvar scope = require('./scope');\nvar events = require('./utils/events');\nvar browser = require('./utils/browser');\nvar iFinder = require('./utils/interactionFinder');\nvar pointerEvents = require('./pointerEvents/base');\n\nvar _require = require('./utils/window'),\n window = _require.window;\n\nvar toString = Object.prototype.toString;\n\nif (!window.Array.isArray) {\n window.Array.isArray = function (obj) {\n return toString.call(obj) === '[object Array]';\n };\n}\n\nif (!String.prototype.trim) {\n String.prototype.trim = function () {\n return this.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n };\n}\n\n// http://www.quirksmode.org/dom/events/click.html\n// >Events leading to dblclick\n//\n// IE8 doesn't fire down event before dblclick.\n// This workaround tries to fire a tap and doubletap after dblclick\nfunction onIE8Dblclick(event) {\n var eventTarget = event.target;\n var interaction = iFinder.search(event, event.type, eventTarget);\n\n if (!interaction) {\n return;\n }\n\n if (interaction.prevTap && event.clientX === interaction.prevTap.clientX && event.clientY === interaction.prevTap.clientY && eventTarget === interaction.prevTap.target) {\n\n interaction.downTargets[0] = eventTarget;\n interaction.downTimes[0] = new Date().getTime();\n\n pointerEvents.fire({\n interaction: interaction,\n event: event,\n eventTarget: eventTarget,\n pointer: event,\n type: 'tap'\n });\n }\n}\n\nif (browser.isIE8) {\n var selectFix = function selectFix(event) {\n for (var _iterator = scope.interactions, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var interaction = _ref;\n\n if (interaction.interacting()) {\n interaction.target.checkAndPreventDefault(event);\n }\n }\n };\n\n var onDocIE8 = function onDocIE8(_ref2, signalName) {\n var doc = _ref2.doc,\n win = _ref2.win;\n\n var eventMethod = signalName.indexOf('listen') === 0 ? events.add : events.remove;\n\n // For IE's lack of Event#preventDefault\n eventMethod(doc, 'selectstart', selectFix);\n\n if (pointerEvents) {\n eventMethod(doc, 'dblclick', onIE8Dblclick);\n }\n };\n\n scope.signals.on('add-document', onDocIE8);\n scope.signals.on('remove-document', onDocIE8);\n}\n\nmodule.exports = null;\n\n},{\"./pointerEvents/base\":31,\"./scope\":34,\"./utils/browser\":37,\"./utils/events\":40,\"./utils/interactionFinder\":45,\"./utils/window\":52}],24:[function(require,module,exports){\n'use strict';\n\nvar InteractEvent = require('../InteractEvent');\nvar Interaction = require('../Interaction');\nvar extend = require('../utils/extend');\n\nvar modifiers = {\n names: [],\n\n setOffsets: function setOffsets(arg) {\n var interaction = arg.interaction,\n page = arg.pageCoords;\n var target = interaction.target,\n element = interaction.element,\n startOffset = interaction.startOffset;\n\n var rect = target.getRect(element);\n\n if (rect) {\n startOffset.left = page.x - rect.left;\n startOffset.top = page.y - rect.top;\n\n startOffset.right = rect.right - page.x;\n startOffset.bottom = rect.bottom - page.y;\n\n if (!('width' in rect)) {\n rect.width = rect.right - rect.left;\n }\n if (!('height' in rect)) {\n rect.height = rect.bottom - rect.top;\n }\n } else {\n startOffset.left = startOffset.top = startOffset.right = startOffset.bottom = 0;\n }\n\n arg.rect = rect;\n arg.interactable = target;\n arg.element = element;\n\n for (var i = 0; i < modifiers.names.length; i++) {\n var modifierName = modifiers.names[i];\n\n arg.options = target.options[interaction.prepared.name][modifierName];\n\n if (!arg.options) {\n continue;\n }\n\n interaction.modifierOffsets[modifierName] = modifiers[modifierName].setOffset(arg);\n }\n },\n\n setAll: function setAll(arg) {\n var interaction = arg.interaction,\n statuses = arg.statuses,\n preEnd = arg.preEnd,\n requireEndOnly = arg.requireEndOnly;\n\n var coords = extend({}, arg.pageCoords);\n var result = {\n dx: 0,\n dy: 0,\n changed: false,\n locked: false,\n shouldMove: true\n };\n\n for (var _iterator = modifiers.names, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var modifierName = _ref;\n\n var modifier = modifiers[modifierName];\n var options = interaction.target.options[interaction.prepared.name][modifierName];\n\n if (!shouldDo(options, preEnd, requireEndOnly)) {\n continue;\n }\n\n arg.status = arg.status = statuses[modifierName];\n arg.options = options;\n arg.offset = arg.interaction.modifierOffsets[modifierName];\n\n modifier.set(arg);\n\n if (arg.status.locked) {\n coords.x += arg.status.dx;\n coords.y += arg.status.dy;\n\n result.dx += arg.status.dx;\n result.dy += arg.status.dy;\n\n result.locked = true;\n }\n }\n\n // a move should be fired if:\n // - there are no modifiers enabled,\n // - no modifiers are \"locked\" i.e. have changed the pointer's coordinates, or\n // - the locked coords have changed since the last pointer move\n result.shouldMove = !arg.status || !result.locked || arg.status.changed;\n\n return result;\n },\n\n resetStatuses: function resetStatuses(statuses) {\n for (var _iterator2 = modifiers.names, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\n var _ref2;\n\n if (_isArray2) {\n if (_i2 >= _iterator2.length) break;\n _ref2 = _iterator2[_i2++];\n } else {\n _i2 = _iterator2.next();\n if (_i2.done) break;\n _ref2 = _i2.value;\n }\n\n var modifierName = _ref2;\n\n var status = statuses[modifierName] || {};\n\n status.dx = status.dy = 0;\n status.modifiedX = status.modifiedY = NaN;\n status.locked = false;\n status.changed = true;\n\n statuses[modifierName] = status;\n }\n\n return statuses;\n },\n\n start: function start(_ref3, signalName) {\n var interaction = _ref3.interaction;\n\n var arg = {\n interaction: interaction,\n pageCoords: (signalName === 'action-resume' ? interaction.curCoords : interaction.startCoords).page,\n startOffset: interaction.startOffset,\n statuses: interaction.modifierStatuses,\n preEnd: false,\n requireEndOnly: false\n };\n\n modifiers.setOffsets(arg);\n modifiers.resetStatuses(arg.statuses);\n\n arg.pageCoords = extend({}, interaction.startCoords.page);\n interaction.modifierResult = modifiers.setAll(arg);\n }\n};\n\nInteraction.signals.on('new', function (interaction) {\n interaction.startOffset = { left: 0, right: 0, top: 0, bottom: 0 };\n interaction.modifierOffsets = {};\n interaction.modifierStatuses = modifiers.resetStatuses({});\n interaction.modifierResult = null;\n});\n\nInteraction.signals.on('action-start', modifiers.start);\nInteraction.signals.on('action-resume', modifiers.start);\n\nInteraction.signals.on('before-action-move', function (_ref4) {\n var interaction = _ref4.interaction,\n preEnd = _ref4.preEnd,\n interactingBeforeMove = _ref4.interactingBeforeMove;\n\n var modifierResult = modifiers.setAll({\n interaction: interaction,\n preEnd: preEnd,\n pageCoords: interaction.curCoords.page,\n statuses: interaction.modifierStatuses,\n requireEndOnly: false\n });\n\n // don't fire an action move if a modifier would keep the event in the same\n // cordinates as before\n if (!modifierResult.shouldMove && interactingBeforeMove) {\n interaction._dontFireMove = true;\n }\n\n interaction.modifierResult = modifierResult;\n});\n\nInteraction.signals.on('action-end', function (_ref5) {\n var interaction = _ref5.interaction,\n event = _ref5.event;\n\n for (var i = 0; i < modifiers.names.length; i++) {\n var options = interaction.target.options[interaction.prepared.name][modifiers.names[i]];\n\n // if the endOnly option is true for any modifier\n if (shouldDo(options, true, true)) {\n // fire a move event at the modified coordinates\n interaction.doMove({ event: event, preEnd: true });\n break;\n }\n }\n});\n\nInteractEvent.signals.on('set-xy', function (arg) {\n var iEvent = arg.iEvent,\n interaction = arg.interaction;\n\n var modifierArg = extend({}, arg);\n\n for (var i = 0; i < modifiers.names.length; i++) {\n var modifierName = modifiers.names[i];\n modifierArg.options = interaction.target.options[interaction.prepared.name][modifierName];\n\n if (!modifierArg.options) {\n continue;\n }\n\n var modifier = modifiers[modifierName];\n\n modifierArg.status = interaction.modifierStatuses[modifierName];\n\n iEvent[modifierName] = modifier.modifyCoords(modifierArg);\n }\n});\n\nfunction shouldDo(options, preEnd, requireEndOnly) {\n return options && options.enabled && (preEnd || !options.endOnly) && (!requireEndOnly || options.endOnly);\n}\n\nmodule.exports = modifiers;\n\n},{\"../InteractEvent\":3,\"../Interaction\":5,\"../utils/extend\":41}],25:[function(require,module,exports){\n'use strict';\n\nvar modifiers = require('./index');\nvar utils = require('../utils');\nvar defaultOptions = require('../defaultOptions');\n\nvar restrict = {\n defaults: {\n enabled: false,\n endOnly: false,\n restriction: null,\n elementRect: null\n },\n\n setOffset: function setOffset(_ref) {\n var rect = _ref.rect,\n startOffset = _ref.startOffset,\n options = _ref.options;\n\n var elementRect = options && options.elementRect;\n var offset = {};\n\n if (rect && elementRect) {\n offset.left = startOffset.left - rect.width * elementRect.left;\n offset.top = startOffset.top - rect.height * elementRect.top;\n\n offset.right = startOffset.right - rect.width * (1 - elementRect.right);\n offset.bottom = startOffset.bottom - rect.height * (1 - elementRect.bottom);\n } else {\n offset.left = offset.top = offset.right = offset.bottom = 0;\n }\n\n return offset;\n },\n\n set: function set(_ref2) {\n var pageCoords = _ref2.pageCoords,\n interaction = _ref2.interaction,\n status = _ref2.status,\n options = _ref2.options;\n\n if (!options) {\n return status;\n }\n\n var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, pageCoords);\n\n var restriction = getRestrictionRect(options.restriction, interaction, page);\n\n if (!restriction) {\n return status;\n }\n\n status.dx = 0;\n status.dy = 0;\n status.locked = false;\n\n var rect = restriction;\n var modifiedX = page.x;\n var modifiedY = page.y;\n\n var offset = interaction.modifierOffsets.restrict;\n\n // object is assumed to have\n // x, y, width, height or\n // left, top, right, bottom\n if ('x' in restriction && 'y' in restriction) {\n modifiedX = Math.max(Math.min(rect.x + rect.width - offset.right, page.x), rect.x + offset.left);\n modifiedY = Math.max(Math.min(rect.y + rect.height - offset.bottom, page.y), rect.y + offset.top);\n } else {\n modifiedX = Math.max(Math.min(rect.right - offset.right, page.x), rect.left + offset.left);\n modifiedY = Math.max(Math.min(rect.bottom - offset.bottom, page.y), rect.top + offset.top);\n }\n\n status.dx = modifiedX - page.x;\n status.dy = modifiedY - page.y;\n\n status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;\n status.locked = !!(status.dx || status.dy);\n\n status.modifiedX = modifiedX;\n status.modifiedY = modifiedY;\n },\n\n modifyCoords: function modifyCoords(_ref3) {\n var page = _ref3.page,\n client = _ref3.client,\n status = _ref3.status,\n phase = _ref3.phase,\n options = _ref3.options;\n\n var elementRect = options && options.elementRect;\n\n if (options && options.enabled && !(phase === 'start' && elementRect && status.locked)) {\n\n if (status.locked) {\n page.x += status.dx;\n page.y += status.dy;\n client.x += status.dx;\n client.y += status.dy;\n\n return {\n dx: status.dx,\n dy: status.dy\n };\n }\n }\n },\n\n getRestrictionRect: getRestrictionRect\n};\n\nfunction getRestrictionRect(value, interaction, page) {\n if (utils.is.function(value)) {\n return utils.resolveRectLike(value, interaction.target, interaction.element, [page.x, page.y, interaction]);\n } else {\n return utils.resolveRectLike(value, interaction.target, interaction.element);\n }\n}\n\nmodifiers.restrict = restrict;\nmodifiers.names.push('restrict');\n\ndefaultOptions.perAction.restrict = restrict.defaults;\n\nmodule.exports = restrict;\n\n},{\"../defaultOptions\":18,\"../utils\":44,\"./index\":24}],26:[function(require,module,exports){\n'use strict';\n\n// This module adds the options.resize.restrictEdges setting which sets min and\n// max for the top, left, bottom and right edges of the target being resized.\n//\n// interact(target).resize({\n// edges: { top: true, left: true },\n// restrictEdges: {\n// inner: { top: 200, left: 200, right: 400, bottom: 400 },\n// outer: { top: 0, left: 0, right: 600, bottom: 600 },\n// },\n// });\n\nvar modifiers = require('./index');\nvar utils = require('../utils');\nvar rectUtils = require('../utils/rect');\nvar defaultOptions = require('../defaultOptions');\nvar resize = require('../actions/resize');\n\nvar _require = require('./restrict'),\n getRestrictionRect = _require.getRestrictionRect;\n\nvar noInner = { top: +Infinity, left: +Infinity, bottom: -Infinity, right: -Infinity };\nvar noOuter = { top: -Infinity, left: -Infinity, bottom: +Infinity, right: +Infinity };\n\nvar restrictEdges = {\n defaults: {\n enabled: false,\n endOnly: false,\n min: null,\n max: null,\n offset: null\n },\n\n setOffset: function setOffset(_ref) {\n var interaction = _ref.interaction,\n startOffset = _ref.startOffset,\n options = _ref.options;\n\n if (!options) {\n return utils.extend({}, startOffset);\n }\n\n var offset = getRestrictionRect(options.offset, interaction, interaction.startCoords.page);\n\n if (offset) {\n return {\n top: startOffset.top + offset.y,\n left: startOffset.left + offset.x,\n bottom: startOffset.bottom + offset.y,\n right: startOffset.right + offset.x\n };\n }\n\n return startOffset;\n },\n\n set: function set(_ref2) {\n var pageCoords = _ref2.pageCoords,\n interaction = _ref2.interaction,\n status = _ref2.status,\n offset = _ref2.offset,\n options = _ref2.options;\n\n var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;\n\n if (!interaction.interacting() || !edges) {\n return;\n }\n\n var page = status.useStatusXY ? { x: status.x, y: status.y } : utils.extend({}, pageCoords);\n var inner = rectUtils.xywhToTlbr(getRestrictionRect(options.inner, interaction, page)) || noInner;\n var outer = rectUtils.xywhToTlbr(getRestrictionRect(options.outer, interaction, page)) || noOuter;\n\n var modifiedX = page.x;\n var modifiedY = page.y;\n\n status.dx = 0;\n status.dy = 0;\n status.locked = false;\n\n if (edges.top) {\n modifiedY = Math.min(Math.max(outer.top + offset.top, page.y), inner.top + offset.top);\n } else if (edges.bottom) {\n modifiedY = Math.max(Math.min(outer.bottom - offset.bottom, page.y), inner.bottom - offset.bottom);\n }\n if (edges.left) {\n modifiedX = Math.min(Math.max(outer.left + offset.left, page.x), inner.left + offset.left);\n } else if (edges.right) {\n modifiedX = Math.max(Math.min(outer.right - offset.right, page.x), inner.right - offset.right);\n }\n\n status.dx = modifiedX - page.x;\n status.dy = modifiedY - page.y;\n\n status.changed = status.modifiedX !== modifiedX || status.modifiedY !== modifiedY;\n status.locked = !!(status.dx || status.dy);\n\n status.modifiedX = modifiedX;\n status.modifiedY = modifiedY;\n },\n\n modifyCoords: function modifyCoords(_ref3) {\n var page = _ref3.page,\n client = _ref3.client,\n status = _ref3.status,\n phase = _ref3.phase,\n options = _ref3.options;\n\n if (options && options.enabled && !(phase === 'start' && status.locked)) {\n\n if (status.locked) {\n page.x += status.dx;\n page.y += status.dy;\n client.x += status.dx;\n client.y += status.dy;\n\n return {\n dx: status.dx,\n dy: status.dy\n };\n }\n }\n },\n\n noInner: noInner,\n noOuter: noOuter,\n getRestrictionRect: getRestrictionRect\n};\n\nmodifiers.restrictEdges = restrictEdges;\nmodifiers.names.push('restrictEdges');\n\ndefaultOptions.perAction.restrictEdges = restrictEdges.defaults;\nresize.defaults.restrictEdges = restrictEdges.defaults;\n\nmodule.exports = restrictEdges;\n\n},{\"../actions/resize\":10,\"../defaultOptions\":18,\"../utils\":44,\"../utils/rect\":51,\"./index\":24,\"./restrict\":25}],27:[function(require,module,exports){\n'use strict';\n\n// This module adds the options.resize.restrictSize setting which sets min and\n// max width and height for the target being resized.\n//\n// interact(target).resize({\n// edges: { top: true, left: true },\n// restrictSize: {\n// min: { width: -600, height: -600 },\n// max: { width: 600, height: 600 },\n// },\n// });\n\nvar modifiers = require('./index');\nvar restrictEdges = require('./restrictEdges');\nvar utils = require('../utils');\nvar rectUtils = require('../utils/rect');\nvar defaultOptions = require('../defaultOptions');\nvar resize = require('../actions/resize');\n\nvar noMin = { width: -Infinity, height: -Infinity };\nvar noMax = { width: +Infinity, height: +Infinity };\n\nvar restrictSize = {\n defaults: {\n enabled: false,\n endOnly: false,\n min: null,\n max: null\n },\n\n setOffset: function setOffset(_ref) {\n var interaction = _ref.interaction;\n\n return interaction.startOffset;\n },\n\n set: function set(arg) {\n var interaction = arg.interaction,\n options = arg.options;\n\n var edges = interaction.prepared.linkedEdges || interaction.prepared.edges;\n\n if (!interaction.interacting() || !edges) {\n return;\n }\n\n var rect = rectUtils.xywhToTlbr(interaction.resizeRects.inverted);\n\n var minSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.min, interaction)) || noMin;\n var maxSize = rectUtils.tlbrToXywh(restrictEdges.getRestrictionRect(options.max, interaction)) || noMax;\n\n arg.options = {\n enabled: options.enabled,\n endOnly: options.endOnly,\n inner: utils.extend({}, restrictEdges.noInner),\n outer: utils.extend({}, restrictEdges.noOuter)\n };\n\n if (edges.top) {\n arg.options.inner.top = rect.bottom - minSize.height;\n arg.options.outer.top = rect.bottom - maxSize.height;\n } else if (edges.bottom) {\n arg.options.inner.bottom = rect.top + minSize.height;\n arg.options.outer.bottom = rect.top + maxSize.height;\n }\n if (edges.left) {\n arg.options.inner.left = rect.right - minSize.width;\n arg.options.outer.left = rect.right - maxSize.width;\n } else if (edges.right) {\n arg.options.inner.right = rect.left + minSize.width;\n arg.options.outer.right = rect.left + maxSize.width;\n }\n\n restrictEdges.set(arg);\n },\n\n modifyCoords: restrictEdges.modifyCoords\n};\n\nmodifiers.restrictSize = restrictSize;\nmodifiers.names.push('restrictSize');\n\ndefaultOptions.perAction.restrictSize = restrictSize.defaults;\nresize.defaults.restrictSize = restrictSize.defaults;\n\nmodule.exports = restrictSize;\n\n},{\"../actions/resize\":10,\"../defaultOptions\":18,\"../utils\":44,\"../utils/rect\":51,\"./index\":24,\"./restrictEdges\":26}],28:[function(require,module,exports){\n'use strict';\n\nvar modifiers = require('./index');\nvar interact = require('../interact');\nvar utils = require('../utils');\nvar defaultOptions = require('../defaultOptions');\n\nvar snap = {\n defaults: {\n enabled: false,\n endOnly: false,\n range: Infinity,\n targets: null,\n offsets: null,\n\n relativePoints: null\n },\n\n setOffset: function setOffset(_ref) {\n var interaction = _ref.interaction,\n interactable = _ref.interactable,\n element = _ref.element,\n rect = _ref.rect,\n startOffset = _ref.startOffset,\n options = _ref.options;\n\n var offsets = [];\n var optionsOrigin = utils.rectToXY(utils.resolveRectLike(options.origin));\n var origin = optionsOrigin || utils.getOriginXY(interactable, element, interaction.prepared.name);\n options = options || interactable.options[interaction.prepared.name].snap || {};\n\n var snapOffset = void 0;\n\n if (options.offset === 'startCoords') {\n snapOffset = {\n x: interaction.startCoords.page.x - origin.x,\n y: interaction.startCoords.page.y - origin.y\n };\n } else {\n var offsetRect = utils.resolveRectLike(options.offset, interactable, element, [interaction]);\n\n snapOffset = utils.rectToXY(offsetRect) || { x: 0, y: 0 };\n }\n\n if (rect && options.relativePoints && options.relativePoints.length) {\n for (var _iterator = options.relativePoints, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref2;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref2 = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref2 = _i.value;\n }\n\n var _ref3 = _ref2,\n relativeX = _ref3.x,\n relativeY = _ref3.y;\n\n offsets.push({\n x: startOffset.left - rect.width * relativeX + snapOffset.x,\n y: startOffset.top - rect.height * relativeY + snapOffset.y\n });\n }\n } else {\n offsets.push(snapOffset);\n }\n\n return offsets;\n },\n\n set: function set(_ref4) {\n var interaction = _ref4.interaction,\n pageCoords = _ref4.pageCoords,\n status = _ref4.status,\n options = _ref4.options,\n offsets = _ref4.offset;\n\n var targets = [];\n var target = void 0;\n var page = void 0;\n var i = void 0;\n\n if (status.useStatusXY) {\n page = { x: status.x, y: status.y };\n } else {\n var origin = utils.getOriginXY(interaction.target, interaction.element, interaction.prepared.name);\n\n page = utils.extend({}, pageCoords);\n\n page.x -= origin.x;\n page.y -= origin.y;\n }\n\n status.realX = page.x;\n status.realY = page.y;\n\n var len = options.targets ? options.targets.length : 0;\n\n for (var _iterator2 = offsets, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\n var _ref5;\n\n if (_isArray2) {\n if (_i2 >= _iterator2.length) break;\n _ref5 = _iterator2[_i2++];\n } else {\n _i2 = _iterator2.next();\n if (_i2.done) break;\n _ref5 = _i2.value;\n }\n\n var _ref6 = _ref5,\n offsetX = _ref6.x,\n offsetY = _ref6.y;\n\n var relativeX = page.x - offsetX;\n var relativeY = page.y - offsetY;\n\n for (var _iterator3 = options.targets, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {\n var _ref7;\n\n if (_isArray3) {\n if (_i3 >= _iterator3.length) break;\n _ref7 = _iterator3[_i3++];\n } else {\n _i3 = _iterator3.next();\n if (_i3.done) break;\n _ref7 = _i3.value;\n }\n\n var snapTarget = _ref7;\n\n if (utils.is.function(snapTarget)) {\n target = snapTarget(relativeX, relativeY, interaction);\n } else {\n target = snapTarget;\n }\n\n if (!target) {\n continue;\n }\n\n targets.push({\n x: utils.is.number(target.x) ? target.x + offsetX : relativeX,\n y: utils.is.number(target.y) ? target.y + offsetY : relativeY,\n\n range: utils.is.number(target.range) ? target.range : options.range\n });\n }\n }\n\n var closest = {\n target: null,\n inRange: false,\n distance: 0,\n range: 0,\n dx: 0,\n dy: 0\n };\n\n for (i = 0, len = targets.length; i < len; i++) {\n target = targets[i];\n\n var range = target.range;\n var dx = target.x - page.x;\n var dy = target.y - page.y;\n var distance = utils.hypot(dx, dy);\n var inRange = distance <= range;\n\n // Infinite targets count as being out of range\n // compared to non infinite ones that are in range\n if (range === Infinity && closest.inRange && closest.range !== Infinity) {\n inRange = false;\n }\n\n if (!closest.target || (inRange\n // is the closest target in range?\n ? closest.inRange && range !== Infinity\n // the pointer is relatively deeper in this target\n ? distance / range < closest.distance / closest.range\n // this target has Infinite range and the closest doesn't\n : range === Infinity && closest.range !== Infinity ||\n // OR this target is closer that the previous closest\n distance < closest.distance :\n // The other is not in range and the pointer is closer to this target\n !closest.inRange && distance < closest.distance)) {\n\n closest.target = target;\n closest.distance = distance;\n closest.range = range;\n closest.inRange = inRange;\n closest.dx = dx;\n closest.dy = dy;\n\n status.range = range;\n }\n }\n\n var snapChanged = void 0;\n\n if (closest.target) {\n snapChanged = status.modifiedX !== closest.target.x || status.modifiedY !== closest.target.y;\n\n status.modifiedX = closest.target.x;\n status.modifiedY = closest.target.y;\n } else {\n snapChanged = true;\n\n status.modifiedX = NaN;\n status.modifiedY = NaN;\n }\n\n status.dx = closest.dx;\n status.dy = closest.dy;\n\n status.changed = snapChanged || closest.inRange && !status.locked;\n status.locked = closest.inRange;\n },\n\n modifyCoords: function modifyCoords(_ref8) {\n var page = _ref8.page,\n client = _ref8.client,\n status = _ref8.status,\n phase = _ref8.phase,\n options = _ref8.options;\n\n var relativePoints = options && options.relativePoints;\n\n if (options && options.enabled && !(phase === 'start' && relativePoints && relativePoints.length)) {\n\n if (status.locked) {\n page.x += status.dx;\n page.y += status.dy;\n client.x += status.dx;\n client.y += status.dy;\n }\n\n return {\n range: status.range,\n locked: status.locked,\n x: status.modifiedX,\n y: status.modifiedY,\n realX: status.realX,\n realY: status.realY,\n dx: status.dx,\n dy: status.dy\n };\n }\n }\n};\n\ninteract.createSnapGrid = function (grid) {\n return function (x, y) {\n var limits = grid.limits || {\n left: -Infinity,\n right: Infinity,\n top: -Infinity,\n bottom: Infinity\n };\n var offsetX = 0;\n var offsetY = 0;\n\n if (utils.is.object(grid.offset)) {\n offsetX = grid.offset.x;\n offsetY = grid.offset.y;\n }\n\n var gridx = Math.round((x - offsetX) / grid.x);\n var gridy = Math.round((y - offsetY) / grid.y);\n\n var newX = Math.max(limits.left, Math.min(limits.right, gridx * grid.x + offsetX));\n var newY = Math.max(limits.top, Math.min(limits.bottom, gridy * grid.y + offsetY));\n\n return {\n x: newX,\n y: newY,\n range: grid.range\n };\n };\n};\n\nmodifiers.snap = snap;\nmodifiers.names.push('snap');\n\ndefaultOptions.perAction.snap = snap.defaults;\n\nmodule.exports = snap;\n\n},{\"../defaultOptions\":18,\"../interact\":21,\"../utils\":44,\"./index\":24}],29:[function(require,module,exports){\n'use strict';\n\n// This module allows snapping of the size of targets during resize\n// interactions.\n\nvar modifiers = require('./index');\nvar snap = require('./snap');\nvar defaultOptions = require('../defaultOptions');\nvar resize = require('../actions/resize');\nvar utils = require('../utils/');\n\nvar snapSize = {\n defaults: {\n enabled: false,\n endOnly: false,\n range: Infinity,\n targets: null,\n offsets: null\n },\n\n setOffset: function setOffset(arg) {\n var interaction = arg.interaction,\n options = arg.options;\n\n var edges = interaction.prepared.edges;\n\n if (!edges) {\n return;\n }\n\n arg.options = {\n relativePoints: [{\n x: edges.left ? 0 : 1,\n y: edges.top ? 0 : 1\n }],\n origin: { x: 0, y: 0 },\n offset: 'self',\n range: options.range\n };\n\n var offsets = snap.setOffset(arg);\n arg.options = options;\n\n return offsets;\n },\n\n set: function set(arg) {\n var interaction = arg.interaction,\n options = arg.options,\n offset = arg.offset,\n pageCoords = arg.pageCoords;\n\n var page = utils.extend({}, pageCoords);\n var relativeX = page.x - offset[0].x;\n var relativeY = page.y - offset[0].y;\n\n arg.options = utils.extend({}, options);\n arg.options.targets = [];\n\n for (var _iterator = options.targets, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var snapTarget = _ref;\n\n var target = void 0;\n\n if (utils.is.function(snapTarget)) {\n target = snapTarget(relativeX, relativeY, interaction);\n } else {\n target = snapTarget;\n }\n\n if (!target) {\n continue;\n }\n\n if ('width' in target && 'height' in target) {\n target.x = target.width;\n target.y = target.height;\n }\n\n arg.options.targets.push(target);\n }\n\n snap.set(arg);\n },\n\n modifyCoords: function modifyCoords(arg) {\n var options = arg.options;\n\n\n arg.options = utils.extend({}, options);\n arg.options.enabled = options.enabled;\n arg.options.relativePoints = [null];\n\n snap.modifyCoords(arg);\n }\n};\n\nmodifiers.snapSize = snapSize;\nmodifiers.names.push('snapSize');\n\ndefaultOptions.perAction.snapSize = snapSize.defaults;\nresize.defaults.snapSize = snapSize.defaults;\n\nmodule.exports = snapSize;\n\n},{\"../actions/resize\":10,\"../defaultOptions\":18,\"../utils/\":44,\"./index\":24,\"./snap\":28}],30:[function(require,module,exports){\n'use strict';\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar pointerUtils = require('../utils/pointerUtils');\n\nmodule.exports = function () {\n function PointerEvent(type, pointer, event, eventTarget, interaction) {\n _classCallCheck(this, PointerEvent);\n\n pointerUtils.pointerExtend(this, event);\n\n if (event !== pointer) {\n pointerUtils.pointerExtend(this, pointer);\n }\n\n this.interaction = interaction;\n\n this.timeStamp = new Date().getTime();\n this.originalEvent = event;\n this.type = type;\n this.pointerId = pointerUtils.getPointerId(pointer);\n this.pointerType = pointerUtils.getPointerType(pointer);\n this.target = eventTarget;\n this.currentTarget = null;\n\n if (type === 'tap') {\n var pointerIndex = interaction.getPointerIndex(pointer);\n this.dt = this.timeStamp - interaction.downTimes[pointerIndex];\n\n var interval = this.timeStamp - interaction.tapTime;\n\n this.double = !!(interaction.prevTap && interaction.prevTap.type !== 'doubletap' && interaction.prevTap.target === this.target && interval < 500);\n } else if (type === 'doubletap') {\n this.dt = pointer.timeStamp - interaction.tapTime;\n }\n }\n\n PointerEvent.prototype.subtractOrigin = function subtractOrigin(_ref) {\n var originX = _ref.x,\n originY = _ref.y;\n\n this.pageX -= originX;\n this.pageY -= originY;\n this.clientX -= originX;\n this.clientY -= originY;\n\n return this;\n };\n\n PointerEvent.prototype.addOrigin = function addOrigin(_ref2) {\n var originX = _ref2.x,\n originY = _ref2.y;\n\n this.pageX += originX;\n this.pageY += originY;\n this.clientX += originX;\n this.clientY += originY;\n\n return this;\n };\n\n PointerEvent.prototype.preventDefault = function preventDefault() {\n this.originalEvent.preventDefault();\n };\n\n PointerEvent.prototype.stopPropagation = function stopPropagation() {\n this.propagationStopped = true;\n };\n\n PointerEvent.prototype.stopImmediatePropagation = function stopImmediatePropagation() {\n this.immediatePropagationStopped = this.propagationStopped = true;\n };\n\n return PointerEvent;\n}();\n\n},{\"../utils/pointerUtils\":49}],31:[function(require,module,exports){\n'use strict';\n\nvar PointerEvent = require('./PointerEvent');\nvar Interaction = require('../Interaction');\nvar utils = require('../utils');\nvar browser = require('../utils/browser');\nvar defaults = require('../defaultOptions');\nvar signals = require('../utils/Signals').new();\n\nvar _require = require('../utils/arr'),\n filter = _require.filter;\n\nvar simpleSignals = ['down', 'up', 'cancel'];\nvar simpleEvents = ['down', 'up', 'cancel'];\n\nvar pointerEvents = {\n PointerEvent: PointerEvent,\n fire: fire,\n collectEventTargets: collectEventTargets,\n signals: signals,\n defaults: {\n holdDuration: 600,\n ignoreFrom: null,\n allowFrom: null,\n origin: { x: 0, y: 0 }\n },\n types: ['down', 'move', 'up', 'cancel', 'tap', 'doubletap', 'hold']\n};\n\nfunction fire(arg) {\n var interaction = arg.interaction,\n pointer = arg.pointer,\n event = arg.event,\n eventTarget = arg.eventTarget,\n _arg$type = arg.type,\n type = _arg$type === undefined ? arg.pointerEvent.type : _arg$type,\n _arg$targets = arg.targets,\n targets = _arg$targets === undefined ? collectEventTargets(arg) : _arg$targets,\n _arg$pointerEvent = arg.pointerEvent,\n pointerEvent = _arg$pointerEvent === undefined ? new PointerEvent(type, pointer, event, eventTarget, interaction) : _arg$pointerEvent;\n\n\n var signalArg = {\n interaction: interaction,\n pointer: pointer,\n event: event,\n eventTarget: eventTarget,\n targets: targets,\n type: type,\n pointerEvent: pointerEvent\n };\n\n for (var i = 0; i < targets.length; i++) {\n var target = targets[i];\n\n for (var prop in target.props || {}) {\n pointerEvent[prop] = target.props[prop];\n }\n\n var origin = utils.getOriginXY(target.eventable, target.element);\n\n pointerEvent.subtractOrigin(origin);\n pointerEvent.eventable = target.eventable;\n pointerEvent.currentTarget = target.element;\n\n target.eventable.fire(pointerEvent);\n\n pointerEvent.addOrigin(origin);\n\n if (pointerEvent.immediatePropagationStopped || pointerEvent.propagationStopped && i + 1 < targets.length && targets[i + 1].element !== pointerEvent.currentTarget) {\n break;\n }\n }\n\n signals.fire('fired', signalArg);\n\n if (type === 'tap') {\n // if pointerEvent should make a double tap, create and fire a doubletap\n // PointerEvent and use that as the prevTap\n var prevTap = pointerEvent.double ? fire({\n interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,\n type: 'doubletap'\n }) : pointerEvent;\n\n interaction.prevTap = prevTap;\n interaction.tapTime = prevTap.timeStamp;\n }\n\n return pointerEvent;\n}\n\nfunction collectEventTargets(_ref) {\n var interaction = _ref.interaction,\n pointer = _ref.pointer,\n event = _ref.event,\n eventTarget = _ref.eventTarget,\n type = _ref.type;\n\n var pointerIndex = interaction.getPointerIndex(pointer);\n\n // do not fire a tap event if the pointer was moved before being lifted\n if (type === 'tap' && (interaction.pointerWasMoved\n // or if the pointerup target is different to the pointerdown target\n || !(interaction.downTargets[pointerIndex] && interaction.downTargets[pointerIndex] === eventTarget))) {\n return [];\n }\n\n var path = utils.getPath(eventTarget);\n var signalArg = {\n interaction: interaction,\n pointer: pointer,\n event: event,\n eventTarget: eventTarget,\n type: type,\n path: path,\n targets: [],\n element: null\n };\n\n for (var _iterator = path, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref2;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref2 = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref2 = _i.value;\n }\n\n var element = _ref2;\n\n signalArg.element = element;\n\n signals.fire('collect-targets', signalArg);\n }\n\n if (type === 'hold') {\n signalArg.targets = filter(signalArg.targets, function (target) {\n return target.eventable.options.holdDuration === interaction.holdTimers[pointerIndex].duration;\n });\n }\n\n return signalArg.targets;\n}\n\nInteraction.signals.on('update-pointer-down', function (_ref3) {\n var interaction = _ref3.interaction,\n pointerIndex = _ref3.pointerIndex;\n\n interaction.holdTimers[pointerIndex] = { duration: Infinity, timeout: null };\n});\n\nInteraction.signals.on('remove-pointer', function (_ref4) {\n var interaction = _ref4.interaction,\n pointerIndex = _ref4.pointerIndex;\n\n interaction.holdTimers.splice(pointerIndex, 1);\n});\n\nInteraction.signals.on('move', function (_ref5) {\n var interaction = _ref5.interaction,\n pointer = _ref5.pointer,\n event = _ref5.event,\n eventTarget = _ref5.eventTarget,\n duplicateMove = _ref5.duplicateMove;\n\n var pointerIndex = interaction.getPointerIndex(pointer);\n\n if (!duplicateMove && (!interaction.pointerIsDown || interaction.pointerWasMoved)) {\n if (interaction.pointerIsDown) {\n clearTimeout(interaction.holdTimers[pointerIndex].timeout);\n }\n\n fire({\n interaction: interaction, pointer: pointer, event: event, eventTarget: eventTarget,\n type: 'move'\n });\n }\n});\n\nInteraction.signals.on('down', function (_ref6) {\n var interaction = _ref6.interaction,\n pointer = _ref6.pointer,\n event = _ref6.event,\n eventTarget = _ref6.eventTarget,\n pointerIndex = _ref6.pointerIndex;\n\n // copy event to be used in timeout for IE8\n var eventCopy = browser.isIE8 ? utils.extend({}, event) : event;\n\n var timer = interaction.holdTimers[pointerIndex];\n var path = utils.getPath(eventTarget);\n var signalArg = {\n interaction: interaction,\n pointer: pointer,\n event: event,\n eventTarget: eventTarget,\n type: 'hold',\n targets: [],\n path: path,\n element: null\n };\n\n for (var _iterator2 = path, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\n var _ref7;\n\n if (_isArray2) {\n if (_i2 >= _iterator2.length) break;\n _ref7 = _iterator2[_i2++];\n } else {\n _i2 = _iterator2.next();\n if (_i2.done) break;\n _ref7 = _i2.value;\n }\n\n var element = _ref7;\n\n signalArg.element = element;\n\n signals.fire('collect-targets', signalArg);\n }\n\n if (!signalArg.targets.length) {\n return;\n }\n\n var minDuration = Infinity;\n\n for (var i = 0; i < signalArg.targets.length; i++) {\n var target = signalArg.targets[i];\n var holdDuration = target.eventable.options.holdDuration;\n\n if (holdDuration < minDuration) {\n minDuration = holdDuration;\n }\n }\n\n timer.duration = minDuration;\n timer.timeout = setTimeout(function () {\n fire({\n interaction: interaction,\n eventTarget: eventTarget,\n pointer: browser.isIE8 ? eventCopy : pointer,\n event: eventCopy,\n type: 'hold'\n });\n }, minDuration);\n});\n\nInteraction.signals.on('up', function (_ref8) {\n var interaction = _ref8.interaction,\n pointer = _ref8.pointer,\n event = _ref8.event,\n eventTarget = _ref8.eventTarget;\n\n if (!interaction.pointerWasMoved) {\n fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: 'tap' });\n }\n});\n\n['up', 'cancel'].forEach(function (signalName) {\n Interaction.signals.on(signalName, function (_ref9) {\n var interaction = _ref9.interaction,\n pointerIndex = _ref9.pointerIndex;\n\n if (interaction.holdTimers[pointerIndex]) {\n clearTimeout(interaction.holdTimers[pointerIndex].timeout);\n }\n });\n});\n\nfunction createSignalListener(type) {\n return function (_ref10) {\n var interaction = _ref10.interaction,\n pointer = _ref10.pointer,\n event = _ref10.event,\n eventTarget = _ref10.eventTarget;\n\n fire({ interaction: interaction, eventTarget: eventTarget, pointer: pointer, event: event, type: type });\n };\n}\n\nfor (var i = 0; i < simpleSignals.length; i++) {\n Interaction.signals.on(simpleSignals[i], createSignalListener(simpleEvents[i]));\n}\n\nInteraction.signals.on('new', function (interaction) {\n interaction.prevTap = null; // the most recent tap event on this interaction\n interaction.tapTime = 0; // time of the most recent tap event\n interaction.holdTimers = []; // [{ duration, timeout }]\n});\n\ndefaults.pointerEvents = pointerEvents.defaults;\nmodule.exports = pointerEvents;\n\n},{\"../Interaction\":5,\"../defaultOptions\":18,\"../utils\":44,\"../utils/Signals\":35,\"../utils/arr\":36,\"../utils/browser\":37,\"./PointerEvent\":30}],32:[function(require,module,exports){\n'use strict';\n\nvar pointerEvents = require('./base');\nvar Interaction = require('../Interaction');\n\npointerEvents.signals.on('new', onNew);\npointerEvents.signals.on('fired', onFired);\n\nvar _arr = ['move', 'up', 'cancel', 'endall'];\nfor (var _i = 0; _i < _arr.length; _i++) {\n var signal = _arr[_i];\n Interaction.signals.on(signal, endHoldRepeat);\n}\n\nfunction onNew(_ref) {\n var pointerEvent = _ref.pointerEvent;\n\n if (pointerEvent.type !== 'hold') {\n return;\n }\n\n pointerEvent.count = (pointerEvent.count || 0) + 1;\n}\n\nfunction onFired(_ref2) {\n var interaction = _ref2.interaction,\n pointerEvent = _ref2.pointerEvent,\n eventTarget = _ref2.eventTarget,\n targets = _ref2.targets;\n\n if (pointerEvent.type !== 'hold' || !targets.length) {\n return;\n }\n\n // get the repeat interval from the first eventable\n var interval = targets[0].eventable.options.holdRepeatInterval;\n\n // don't repeat if the interval is 0 or less\n if (interval <= 0) {\n return;\n }\n\n // set a timeout to fire the holdrepeat event\n interaction.holdIntervalHandle = setTimeout(function () {\n pointerEvents.fire({\n interaction: interaction,\n eventTarget: eventTarget,\n type: 'hold',\n pointer: pointerEvent,\n event: pointerEvent\n });\n }, interval);\n}\n\nfunction endHoldRepeat(_ref3) {\n var interaction = _ref3.interaction;\n\n // set the interaction's holdStopTime property\n // to stop further holdRepeat events\n if (interaction.holdIntervalHandle) {\n clearInterval(interaction.holdIntervalHandle);\n interaction.holdIntervalHandle = null;\n }\n}\n\n// don't repeat by default\npointerEvents.defaults.holdRepeatInterval = 0;\npointerEvents.types.push('holdrepeat');\n\nmodule.exports = {\n onNew: onNew,\n onFired: onFired,\n endHoldRepeat: endHoldRepeat\n};\n\n},{\"../Interaction\":5,\"./base\":31}],33:[function(require,module,exports){\n'use strict';\n\nvar pointerEvents = require('./base');\nvar Interactable = require('../Interactable');\nvar browser = require('../utils/browser');\nvar is = require('../utils/is');\nvar domUtils = require('../utils/domUtils');\nvar scope = require('../scope');\nvar extend = require('../utils/extend');\n\nvar _require = require('../utils/arr'),\n merge = _require.merge;\n\npointerEvents.signals.on('collect-targets', function (_ref) {\n var targets = _ref.targets,\n element = _ref.element,\n type = _ref.type,\n eventTarget = _ref.eventTarget;\n\n function collectSelectors(interactable, selector, context) {\n var els = browser.useMatchesSelectorPolyfill ? context.querySelectorAll(selector) : undefined;\n\n var eventable = interactable.events;\n var options = eventable.options;\n\n if (eventable[type] && is.element(element) && domUtils.matchesSelector(element, selector, els) && interactable.testIgnoreAllow(options, element, eventTarget)) {\n\n targets.push({\n element: element,\n eventable: eventable,\n props: { interactable: interactable }\n });\n }\n }\n\n var interactable = scope.interactables.get(element);\n\n if (interactable) {\n var eventable = interactable.events;\n var options = eventable.options;\n\n if (eventable[type] && interactable.testIgnoreAllow(options, element, eventTarget)) {\n targets.push({\n element: element,\n eventable: eventable,\n props: { interactable: interactable }\n });\n }\n }\n\n scope.interactables.forEachSelector(collectSelectors, element);\n});\n\nInteractable.signals.on('new', function (_ref2) {\n var interactable = _ref2.interactable;\n\n interactable.events.getRect = function (element) {\n return interactable.getRect(element);\n };\n});\n\nInteractable.signals.on('set', function (_ref3) {\n var interactable = _ref3.interactable,\n options = _ref3.options;\n\n extend(interactable.events.options, pointerEvents.defaults);\n extend(interactable.events.options, options);\n});\n\nmerge(Interactable.eventTypes, pointerEvents.types);\n\nInteractable.prototype.pointerEvents = function (options) {\n extend(this.events.options, options);\n\n return this;\n};\n\nvar __backCompatOption = Interactable.prototype._backCompatOption;\n\nInteractable.prototype._backCompatOption = function (optionName, newValue) {\n var ret = __backCompatOption.call(this, optionName, newValue);\n\n if (ret === this) {\n this.events.options[optionName] = newValue;\n }\n\n return ret;\n};\n\nInteractable.settingsMethods.push('pointerEvents');\n\n},{\"../Interactable\":4,\"../scope\":34,\"../utils/arr\":36,\"../utils/browser\":37,\"../utils/domUtils\":39,\"../utils/extend\":41,\"../utils/is\":46,\"./base\":31}],34:[function(require,module,exports){\n'use strict';\n\nvar utils = require('./utils');\nvar events = require('./utils/events');\nvar signals = require('./utils/Signals').new();\n\nvar scope = {\n signals: signals,\n events: events,\n utils: utils,\n\n // main document\n document: require('./utils/domObjects').document,\n // all documents being listened to\n documents: [],\n\n addDocument: function addDocument(doc, win) {\n // do nothing if document is already known\n if (utils.contains(scope.documents, doc)) {\n return false;\n }\n\n win = win || scope.getWindow(doc);\n\n scope.documents.push(doc);\n events.documents.push(doc);\n\n // don't add an unload event for the main document\n // so that the page may be cached in browser history\n if (doc !== scope.document) {\n events.add(win, 'unload', scope.onWindowUnload);\n }\n\n signals.fire('add-document', { doc: doc, win: win });\n },\n\n removeDocument: function removeDocument(doc, win) {\n var index = utils.indexOf(scope.documents, doc);\n\n win = win || scope.getWindow(doc);\n\n events.remove(win, 'unload', scope.onWindowUnload);\n\n scope.documents.splice(index, 1);\n events.documents.splice(index, 1);\n\n signals.fire('remove-document', { win: win, doc: doc });\n },\n\n onWindowUnload: function onWindowUnload() {\n scope.removeDocument(this.document, this);\n }\n};\n\nmodule.exports = scope;\n\n},{\"./utils\":44,\"./utils/Signals\":35,\"./utils/domObjects\":38,\"./utils/events\":40}],35:[function(require,module,exports){\n'use strict';\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar _require = require('./arr'),\n indexOf = _require.indexOf;\n\nvar Signals = function () {\n function Signals() {\n _classCallCheck(this, Signals);\n\n this.listeners = {\n // signalName: [listeners],\n };\n }\n\n Signals.prototype.on = function on(name, listener) {\n if (!this.listeners[name]) {\n this.listeners[name] = [listener];\n return;\n }\n\n this.listeners[name].push(listener);\n };\n\n Signals.prototype.off = function off(name, listener) {\n if (!this.listeners[name]) {\n return;\n }\n\n var index = indexOf(this.listeners[name], listener);\n\n if (index !== -1) {\n this.listeners[name].splice(index, 1);\n }\n };\n\n Signals.prototype.fire = function fire(name, arg) {\n var targetListeners = this.listeners[name];\n\n if (!targetListeners) {\n return;\n }\n\n for (var i = 0; i < targetListeners.length; i++) {\n if (targetListeners[i](arg, name) === false) {\n return;\n }\n }\n };\n\n return Signals;\n}();\n\nSignals.new = function () {\n return new Signals();\n};\n\nmodule.exports = Signals;\n\n},{\"./arr\":36}],36:[function(require,module,exports){\n\"use strict\";\n\nfunction indexOf(array, target) {\n for (var i = 0, len = array.length; i < len; i++) {\n if (array[i] === target) {\n return i;\n }\n }\n\n return -1;\n}\n\nfunction contains(array, target) {\n return indexOf(array, target) !== -1;\n}\n\nfunction merge(target, source) {\n for (var i = 0; i < source.length; i++) {\n target.push(source[i]);\n }\n\n return target;\n}\n\nfunction filter(array, test) {\n var result = [];\n\n for (var i = 0; i < array.length; i++) {\n if (test(array[i])) {\n result.push(array[i]);\n }\n }\n\n return result;\n}\n\nmodule.exports = {\n indexOf: indexOf,\n contains: contains,\n merge: merge,\n filter: filter\n};\n\n},{}],37:[function(require,module,exports){\n'use strict';\n\nvar _require = require('./window'),\n window = _require.window;\n\nvar is = require('./is');\nvar domObjects = require('./domObjects');\n\nvar Element = domObjects.Element;\nvar navigator = window.navigator;\n\nvar browser = {\n // Does the browser support touch input?\n supportsTouch: !!('ontouchstart' in window || is.function(window.DocumentTouch) && domObjects.document instanceof window.DocumentTouch),\n\n // Does the browser support PointerEvents\n supportsPointerEvent: !!domObjects.PointerEvent,\n\n isIE8: 'attachEvent' in window && !('addEventListener' in window),\n\n // Opera Mobile must be handled differently\n isOperaMobile: navigator.appName === 'Opera' && browser.supportsTouch && navigator.userAgent.match('Presto'),\n\n // scrolling doesn't change the result of getClientRects on iOS 7\n isIOS7: /iP(hone|od|ad)/.test(navigator.platform) && /OS 7[^\\d]/.test(navigator.appVersion),\n\n isIe9OrOlder: /MSIE (8|9)/.test(navigator.userAgent),\n\n // prefix matchesSelector\n prefixedMatchesSelector: 'matches' in Element.prototype ? 'matches' : 'webkitMatchesSelector' in Element.prototype ? 'webkitMatchesSelector' : 'mozMatchesSelector' in Element.prototype ? 'mozMatchesSelector' : 'oMatchesSelector' in Element.prototype ? 'oMatchesSelector' : 'msMatchesSelector',\n\n useMatchesSelectorPolyfill: false,\n\n pEventTypes: domObjects.PointerEvent ? domObjects.PointerEvent === window.MSPointerEvent ? {\n up: 'MSPointerUp',\n down: 'MSPointerDown',\n over: 'mouseover',\n out: 'mouseout',\n move: 'MSPointerMove',\n cancel: 'MSPointerCancel'\n } : {\n up: 'pointerup',\n down: 'pointerdown',\n over: 'pointerover',\n out: 'pointerout',\n move: 'pointermove',\n cancel: 'pointercancel'\n } : null,\n\n // because Webkit and Opera still use 'mousewheel' event type\n wheelEvent: 'onmousewheel' in domObjects.document ? 'mousewheel' : 'wheel'\n\n};\n\nbrowser.useMatchesSelectorPolyfill = !is.function(Element.prototype[browser.prefixedMatchesSelector]);\n\nmodule.exports = browser;\n\n},{\"./domObjects\":38,\"./is\":46,\"./window\":52}],38:[function(require,module,exports){\n'use strict';\n\nvar domObjects = {};\nvar win = require('./window').window;\n\nfunction blank() {}\n\ndomObjects.document = win.document;\ndomObjects.DocumentFragment = win.DocumentFragment || blank;\ndomObjects.SVGElement = win.SVGElement || blank;\ndomObjects.SVGSVGElement = win.SVGSVGElement || blank;\ndomObjects.SVGElementInstance = win.SVGElementInstance || blank;\ndomObjects.Element = win.Element || blank;\ndomObjects.HTMLElement = win.HTMLElement || domObjects.Element;\n\ndomObjects.Event = win.Event;\ndomObjects.Touch = win.Touch || blank;\ndomObjects.PointerEvent = win.PointerEvent || win.MSPointerEvent;\n\nmodule.exports = domObjects;\n\n},{\"./window\":52}],39:[function(require,module,exports){\n'use strict';\n\nvar win = require('./window');\nvar browser = require('./browser');\nvar is = require('./is');\nvar domObjects = require('./domObjects');\n\nvar domUtils = {\n nodeContains: function nodeContains(parent, child) {\n while (child) {\n if (child === parent) {\n return true;\n }\n\n child = child.parentNode;\n }\n\n return false;\n },\n\n closest: function closest(element, selector) {\n while (is.element(element)) {\n if (domUtils.matchesSelector(element, selector)) {\n return element;\n }\n\n element = domUtils.parentNode(element);\n }\n\n return null;\n },\n\n parentNode: function parentNode(node) {\n var parent = node.parentNode;\n\n if (is.docFrag(parent)) {\n // skip past #shado-root fragments\n while ((parent = parent.host) && is.docFrag(parent)) {\n continue;\n }\n\n return parent;\n }\n\n return parent;\n },\n\n // taken from http://tanalin.com/en/blog/2012/12/matches-selector-ie8/ and modified\n matchesSelectorPolyfill: browser.useMatchesSelectorPolyfill ? function (element, selector, elems) {\n elems = elems || element.parentNode.querySelectorAll(selector);\n\n for (var i = 0, len = elems.length; i < len; i++) {\n if (elems[i] === element) {\n return true;\n }\n }\n\n return false;\n } : null,\n\n matchesSelector: function matchesSelector(element, selector, nodeList) {\n if (browser.useMatchesSelectorPolyfill) {\n return domUtils.matchesSelectorPolyfill(element, selector, nodeList);\n }\n\n // remove /deep/ from selectors if shadowDOM polyfill is used\n if (win.window !== win.realWindow) {\n selector = selector.replace(/\\/deep\\//g, ' ');\n }\n\n return element[browser.prefixedMatchesSelector](selector);\n },\n\n // Test for the element that's \"above\" all other qualifiers\n indexOfDeepestElement: function indexOfDeepestElement(elements) {\n var deepestZoneParents = [];\n var dropzoneParents = [];\n var dropzone = void 0;\n var deepestZone = elements[0];\n var index = deepestZone ? 0 : -1;\n var parent = void 0;\n var child = void 0;\n var i = void 0;\n var n = void 0;\n\n for (i = 1; i < elements.length; i++) {\n dropzone = elements[i];\n\n // an element might belong to multiple selector dropzones\n if (!dropzone || dropzone === deepestZone) {\n continue;\n }\n\n if (!deepestZone) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n // check if the deepest or current are document.documentElement or document.rootElement\n // - if the current dropzone is, do nothing and continue\n if (dropzone.parentNode === dropzone.ownerDocument) {\n continue;\n }\n // - if deepest is, update with the current dropzone and continue to next\n else if (deepestZone.parentNode === dropzone.ownerDocument) {\n deepestZone = dropzone;\n index = i;\n continue;\n }\n\n if (!deepestZoneParents.length) {\n parent = deepestZone;\n while (parent.parentNode && parent.parentNode !== parent.ownerDocument) {\n deepestZoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n }\n\n // if this element is an svg element and the current deepest is\n // an HTMLElement\n if (deepestZone instanceof domObjects.HTMLElement && dropzone instanceof domObjects.SVGElement && !(dropzone instanceof domObjects.SVGSVGElement)) {\n\n if (dropzone === deepestZone.parentNode) {\n continue;\n }\n\n parent = dropzone.ownerSVGElement;\n } else {\n parent = dropzone;\n }\n\n dropzoneParents = [];\n\n while (parent.parentNode !== parent.ownerDocument) {\n dropzoneParents.unshift(parent);\n parent = parent.parentNode;\n }\n\n n = 0;\n\n // get (position of last common ancestor) + 1\n while (dropzoneParents[n] && dropzoneParents[n] === deepestZoneParents[n]) {\n n++;\n }\n\n var parents = [dropzoneParents[n - 1], dropzoneParents[n], deepestZoneParents[n]];\n\n child = parents[0].lastChild;\n\n while (child) {\n if (child === parents[1]) {\n deepestZone = dropzone;\n index = i;\n deepestZoneParents = [];\n\n break;\n } else if (child === parents[2]) {\n break;\n }\n\n child = child.previousSibling;\n }\n }\n\n return index;\n },\n\n matchesUpTo: function matchesUpTo(element, selector, limit) {\n while (is.element(element)) {\n if (domUtils.matchesSelector(element, selector)) {\n return true;\n }\n\n element = domUtils.parentNode(element);\n\n if (element === limit) {\n return domUtils.matchesSelector(element, selector);\n }\n }\n\n return false;\n },\n\n getActualElement: function getActualElement(element) {\n return element instanceof domObjects.SVGElementInstance ? element.correspondingUseElement : element;\n },\n\n getScrollXY: function getScrollXY(relevantWindow) {\n relevantWindow = relevantWindow || win.window;\n return {\n x: relevantWindow.scrollX || relevantWindow.document.documentElement.scrollLeft,\n y: relevantWindow.scrollY || relevantWindow.document.documentElement.scrollTop\n };\n },\n\n getElementClientRect: function getElementClientRect(element) {\n var clientRect = element instanceof domObjects.SVGElement ? element.getBoundingClientRect() : element.getClientRects()[0];\n\n return clientRect && {\n left: clientRect.left,\n right: clientRect.right,\n top: clientRect.top,\n bottom: clientRect.bottom,\n width: clientRect.width || clientRect.right - clientRect.left,\n height: clientRect.height || clientRect.bottom - clientRect.top\n };\n },\n\n getElementRect: function getElementRect(element) {\n var clientRect = domUtils.getElementClientRect(element);\n\n if (!browser.isIOS7 && clientRect) {\n var scroll = domUtils.getScrollXY(win.getWindow(element));\n\n clientRect.left += scroll.x;\n clientRect.right += scroll.x;\n clientRect.top += scroll.y;\n clientRect.bottom += scroll.y;\n }\n\n return clientRect;\n },\n\n getPath: function getPath(element) {\n var path = [];\n\n while (element) {\n path.push(element);\n element = domUtils.parentNode(element);\n }\n\n return path;\n },\n\n trySelector: function trySelector(value) {\n if (!is.string(value)) {\n return false;\n }\n\n // an exception will be raised if it is invalid\n domObjects.document.querySelector(value);\n return true;\n }\n};\n\nmodule.exports = domUtils;\n\n},{\"./browser\":37,\"./domObjects\":38,\"./is\":46,\"./window\":52}],40:[function(require,module,exports){\n'use strict';\n\nvar is = require('./is');\nvar domUtils = require('./domUtils');\nvar pExtend = require('./pointerExtend');\n\nvar _require = require('./window'),\n window = _require.window,\n getWindow = _require.getWindow;\n\nvar _require2 = require('./arr'),\n indexOf = _require2.indexOf,\n contains = _require2.contains;\n\nvar useAttachEvent = 'attachEvent' in window && !('addEventListener' in window);\nvar addEvent = useAttachEvent ? 'attachEvent' : 'addEventListener';\nvar removeEvent = useAttachEvent ? 'detachEvent' : 'removeEventListener';\nvar on = useAttachEvent ? 'on' : '';\n\nvar elements = [];\nvar targets = [];\nvar attachedListeners = [];\n\n// {\n// type: {\n// selectors: ['selector', ...],\n// contexts : [document, ...],\n// listeners: [[listener, capture, passive], ...]\n// }\n// }\nvar delegatedEvents = {};\n\nvar documents = [];\n\nvar supportsOptions = !useAttachEvent && function () {\n var supported = false;\n\n window.document.createElement('div').addEventListener('test', null, {\n get capture() {\n supported = true;\n }\n });\n\n return supported;\n}();\n\nfunction add(element, type, listener, optionalArg) {\n var options = getOptions(optionalArg);\n var elementIndex = indexOf(elements, element);\n var target = targets[elementIndex];\n\n if (!target) {\n target = {\n events: {},\n typeCount: 0\n };\n\n elementIndex = elements.push(element) - 1;\n targets.push(target);\n\n attachedListeners.push(useAttachEvent ? {\n supplied: [],\n wrapped: [],\n useCount: []\n } : null);\n }\n\n if (!target.events[type]) {\n target.events[type] = [];\n target.typeCount++;\n }\n\n if (!contains(target.events[type], listener)) {\n var ret = void 0;\n\n if (useAttachEvent) {\n var _attachedListeners$el = attachedListeners[elementIndex],\n supplied = _attachedListeners$el.supplied,\n wrapped = _attachedListeners$el.wrapped,\n useCount = _attachedListeners$el.useCount;\n\n var listenerIndex = indexOf(supplied, listener);\n\n var wrappedListener = wrapped[listenerIndex] || function (event) {\n if (!event.immediatePropagationStopped) {\n event.target = event.srcElement;\n event.currentTarget = element;\n\n event.preventDefault = event.preventDefault || preventDef;\n event.stopPropagation = event.stopPropagation || stopProp;\n event.stopImmediatePropagation = event.stopImmediatePropagation || stopImmProp;\n\n if (/mouse|click/.test(event.type)) {\n event.pageX = event.clientX + getWindow(element).document.documentElement.scrollLeft;\n event.pageY = event.clientY + getWindow(element).document.documentElement.scrollTop;\n }\n\n listener(event);\n }\n };\n\n ret = element[addEvent](on + type, wrappedListener, !!options.capture);\n\n if (listenerIndex === -1) {\n supplied.push(listener);\n wrapped.push(wrappedListener);\n useCount.push(1);\n } else {\n useCount[listenerIndex]++;\n }\n } else {\n ret = element[addEvent](type, listener, supportsOptions ? options : !!options.capture);\n }\n target.events[type].push(listener);\n\n return ret;\n }\n}\n\nfunction remove(element, type, listener, optionalArg) {\n var options = getOptions(optionalArg);\n var elementIndex = indexOf(elements, element);\n var target = targets[elementIndex];\n\n if (!target || !target.events) {\n return;\n }\n\n var wrappedListener = listener;\n var listeners = void 0;\n var listenerIndex = void 0;\n\n if (useAttachEvent) {\n listeners = attachedListeners[elementIndex];\n listenerIndex = indexOf(listeners.supplied, listener);\n wrappedListener = listeners.wrapped[listenerIndex];\n }\n\n if (type === 'all') {\n for (type in target.events) {\n if (target.events.hasOwnProperty(type)) {\n remove(element, type, 'all');\n }\n }\n return;\n }\n\n if (target.events[type]) {\n var len = target.events[type].length;\n\n if (listener === 'all') {\n for (var i = 0; i < len; i++) {\n remove(element, type, target.events[type][i], options);\n }\n return;\n } else {\n for (var _i = 0; _i < len; _i++) {\n if (target.events[type][_i] === listener) {\n element[removeEvent](on + type, wrappedListener, supportsOptions ? options : !!options.capture);\n target.events[type].splice(_i, 1);\n\n if (useAttachEvent && listeners) {\n listeners.useCount[listenerIndex]--;\n if (listeners.useCount[listenerIndex] === 0) {\n listeners.supplied.splice(listenerIndex, 1);\n listeners.wrapped.splice(listenerIndex, 1);\n listeners.useCount.splice(listenerIndex, 1);\n }\n }\n\n break;\n }\n }\n }\n\n if (target.events[type] && target.events[type].length === 0) {\n target.events[type] = null;\n target.typeCount--;\n }\n }\n\n if (!target.typeCount) {\n targets.splice(elementIndex, 1);\n elements.splice(elementIndex, 1);\n attachedListeners.splice(elementIndex, 1);\n }\n}\n\nfunction addDelegate(selector, context, type, listener, optionalArg) {\n var options = getOptions(optionalArg);\n if (!delegatedEvents[type]) {\n delegatedEvents[type] = {\n selectors: [],\n contexts: [],\n listeners: []\n };\n\n // add delegate listener functions\n for (var i = 0; i < documents.length; i++) {\n add(documents[i], type, delegateListener);\n add(documents[i], type, delegateUseCapture, true);\n }\n }\n\n var delegated = delegatedEvents[type];\n var index = void 0;\n\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {\n break;\n }\n }\n\n if (index === -1) {\n index = delegated.selectors.length;\n\n delegated.selectors.push(selector);\n delegated.contexts.push(context);\n delegated.listeners.push([]);\n }\n\n // keep listener and capture and passive flags\n delegated.listeners[index].push([listener, !!options.capture, options.passive]);\n}\n\nfunction removeDelegate(selector, context, type, listener, optionalArg) {\n var options = getOptions(optionalArg);\n var delegated = delegatedEvents[type];\n var matchFound = false;\n var index = void 0;\n\n if (!delegated) {\n return;\n }\n\n // count from last index of delegated to 0\n for (index = delegated.selectors.length - 1; index >= 0; index--) {\n // look for matching selector and context Node\n if (delegated.selectors[index] === selector && delegated.contexts[index] === context) {\n\n var listeners = delegated.listeners[index];\n\n // each item of the listeners array is an array: [function, capture, passive]\n for (var i = listeners.length - 1; i >= 0; i--) {\n var _listeners$i = listeners[i],\n fn = _listeners$i[0],\n capture = _listeners$i[1],\n passive = _listeners$i[2];\n\n // check if the listener functions and capture and passive flags match\n\n if (fn === listener && capture === !!options.capture && passive === options.passive) {\n // remove the listener from the array of listeners\n listeners.splice(i, 1);\n\n // if all listeners for this interactable have been removed\n // remove the interactable from the delegated arrays\n if (!listeners.length) {\n delegated.selectors.splice(index, 1);\n delegated.contexts.splice(index, 1);\n delegated.listeners.splice(index, 1);\n\n // remove delegate function from context\n remove(context, type, delegateListener);\n remove(context, type, delegateUseCapture, true);\n\n // remove the arrays if they are empty\n if (!delegated.selectors.length) {\n delegatedEvents[type] = null;\n }\n }\n\n // only remove one listener\n matchFound = true;\n break;\n }\n }\n\n if (matchFound) {\n break;\n }\n }\n }\n}\n\n// bound to the interactable context when a DOM event\n// listener is added to a selector interactable\nfunction delegateListener(event, optionalArg) {\n var options = getOptions(optionalArg);\n var fakeEvent = {};\n var delegated = delegatedEvents[event.type];\n var eventTarget = domUtils.getActualElement(event.path ? event.path[0] : event.target);\n var element = eventTarget;\n\n // duplicate the event so that currentTarget can be changed\n pExtend(fakeEvent, event);\n\n fakeEvent.originalEvent = event;\n fakeEvent.preventDefault = preventOriginalDefault;\n\n // climb up document tree looking for selector matches\n while (is.element(element)) {\n for (var i = 0; i < delegated.selectors.length; i++) {\n var selector = delegated.selectors[i];\n var context = delegated.contexts[i];\n\n if (domUtils.matchesSelector(element, selector) && domUtils.nodeContains(context, eventTarget) && domUtils.nodeContains(context, element)) {\n\n var listeners = delegated.listeners[i];\n\n fakeEvent.currentTarget = element;\n\n for (var j = 0; j < listeners.length; j++) {\n var _listeners$j = listeners[j],\n fn = _listeners$j[0],\n capture = _listeners$j[1],\n passive = _listeners$j[2];\n\n\n if (capture === !!options.capture && passive === options.passive) {\n fn(fakeEvent);\n }\n }\n }\n }\n\n element = domUtils.parentNode(element);\n }\n}\n\nfunction delegateUseCapture(event) {\n return delegateListener.call(this, event, true);\n}\n\nfunction preventDef() {\n this.returnValue = false;\n}\n\nfunction preventOriginalDefault() {\n this.originalEvent.preventDefault();\n}\n\nfunction stopProp() {\n this.cancelBubble = true;\n}\n\nfunction stopImmProp() {\n this.cancelBubble = true;\n this.immediatePropagationStopped = true;\n}\n\nfunction getOptions(param) {\n return is.object(param) ? param : { capture: param };\n}\n\nmodule.exports = {\n add: add,\n remove: remove,\n\n addDelegate: addDelegate,\n removeDelegate: removeDelegate,\n\n delegateListener: delegateListener,\n delegateUseCapture: delegateUseCapture,\n delegatedEvents: delegatedEvents,\n documents: documents,\n\n useAttachEvent: useAttachEvent,\n supportsOptions: supportsOptions,\n\n _elements: elements,\n _targets: targets,\n _attachedListeners: attachedListeners\n};\n\n},{\"./arr\":36,\"./domUtils\":39,\"./is\":46,\"./pointerExtend\":48,\"./window\":52}],41:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function extend(dest, source) {\n for (var prop in source) {\n dest[prop] = source[prop];\n }\n return dest;\n};\n\n},{}],42:[function(require,module,exports){\n'use strict';\n\nvar _require = require('./rect'),\n resolveRectLike = _require.resolveRectLike,\n rectToXY = _require.rectToXY;\n\nmodule.exports = function (target, element, action) {\n var actionOptions = target.options[action];\n var actionOrigin = actionOptions && actionOptions.origin;\n var origin = actionOrigin || target.options.origin;\n\n var originRect = resolveRectLike(origin, target, element, [target && element]);\n\n return rectToXY(originRect) || { x: 0, y: 0 };\n};\n\n},{\"./rect\":51}],43:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function (x, y) {\n return Math.sqrt(x * x + y * y);\n};\n\n},{}],44:[function(require,module,exports){\n'use strict';\n\nvar extend = require('./extend');\nvar win = require('./window');\n\nvar utils = {\n warnOnce: function warnOnce(method, message) {\n var warned = false;\n\n return function () {\n if (!warned) {\n win.window.console.warn(message);\n warned = true;\n }\n\n return method.apply(this, arguments);\n };\n },\n\n // http://stackoverflow.com/a/5634528/2280888\n _getQBezierValue: function _getQBezierValue(t, p1, p2, p3) {\n var iT = 1 - t;\n return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;\n },\n\n getQuadraticCurvePoint: function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {\n return {\n x: utils._getQBezierValue(position, startX, cpX, endX),\n y: utils._getQBezierValue(position, startY, cpY, endY)\n };\n },\n\n // http://gizma.com/easing/\n easeOutQuad: function easeOutQuad(t, b, c, d) {\n t /= d;\n return -c * t * (t - 2) + b;\n },\n\n copyAction: function copyAction(dest, src) {\n dest.name = src.name;\n dest.axis = src.axis;\n dest.edges = src.edges;\n\n return dest;\n },\n\n is: require('./is'),\n extend: extend,\n hypot: require('./hypot'),\n getOriginXY: require('./getOriginXY')\n};\n\nextend(utils, require('./arr'));\nextend(utils, require('./domUtils'));\nextend(utils, require('./pointerUtils'));\nextend(utils, require('./rect'));\n\nmodule.exports = utils;\n\n},{\"./arr\":36,\"./domUtils\":39,\"./extend\":41,\"./getOriginXY\":42,\"./hypot\":43,\"./is\":46,\"./pointerUtils\":49,\"./rect\":51,\"./window\":52}],45:[function(require,module,exports){\n'use strict';\n\nvar scope = require('../scope');\nvar utils = require('./index');\n\nvar finder = {\n methodOrder: ['simulationResume', 'mouseOrPen', 'hasPointer', 'idle'],\n\n search: function search(pointer, eventType, eventTarget) {\n var pointerType = utils.getPointerType(pointer);\n var pointerId = utils.getPointerId(pointer);\n var details = { pointer: pointer, pointerId: pointerId, pointerType: pointerType, eventType: eventType, eventTarget: eventTarget };\n\n for (var _iterator = finder.methodOrder, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var method = _ref;\n\n var interaction = finder[method](details);\n\n if (interaction) {\n return interaction;\n }\n }\n },\n\n // try to resume simulation with a new pointer\n simulationResume: function simulationResume(_ref2) {\n var pointerType = _ref2.pointerType,\n eventType = _ref2.eventType,\n eventTarget = _ref2.eventTarget;\n\n if (!/down|start/i.test(eventType)) {\n return null;\n }\n\n for (var _iterator2 = scope.interactions, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {\n var _ref3;\n\n if (_isArray2) {\n if (_i2 >= _iterator2.length) break;\n _ref3 = _iterator2[_i2++];\n } else {\n _i2 = _iterator2.next();\n if (_i2.done) break;\n _ref3 = _i2.value;\n }\n\n var interaction = _ref3;\n\n var element = eventTarget;\n\n if (interaction.simulation && interaction.simulation.allowResume && interaction.pointerType === pointerType) {\n while (element) {\n // if the element is the interaction element\n if (element === interaction.element) {\n return interaction;\n }\n element = utils.parentNode(element);\n }\n }\n }\n\n return null;\n },\n\n // if it's a mouse or pen interaction\n mouseOrPen: function mouseOrPen(_ref4) {\n var pointerId = _ref4.pointerId,\n pointerType = _ref4.pointerType,\n eventType = _ref4.eventType;\n\n if (pointerType !== 'mouse' && pointerType !== 'pen') {\n return null;\n }\n\n var firstNonActive = void 0;\n\n for (var _iterator3 = scope.interactions, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {\n var _ref5;\n\n if (_isArray3) {\n if (_i3 >= _iterator3.length) break;\n _ref5 = _iterator3[_i3++];\n } else {\n _i3 = _iterator3.next();\n if (_i3.done) break;\n _ref5 = _i3.value;\n }\n\n var interaction = _ref5;\n\n if (interaction.pointerType === pointerType) {\n // if it's a down event, skip interactions with running simulations\n if (interaction.simulation && !utils.contains(interaction.pointerIds, pointerId)) {\n continue;\n }\n\n // if the interaction is active, return it immediately\n if (interaction.interacting()) {\n return interaction;\n }\n // otherwise save it and look for another active interaction\n else if (!firstNonActive) {\n firstNonActive = interaction;\n }\n }\n }\n\n // if no active mouse interaction was found use the first inactive mouse\n // interaction\n if (firstNonActive) {\n return firstNonActive;\n }\n\n // find any mouse or pen interaction.\n // ignore the interaction if the eventType is a *down, and a simulation\n // is active\n for (var _iterator4 = scope.interactions, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {\n var _ref6;\n\n if (_isArray4) {\n if (_i4 >= _iterator4.length) break;\n _ref6 = _iterator4[_i4++];\n } else {\n _i4 = _iterator4.next();\n if (_i4.done) break;\n _ref6 = _i4.value;\n }\n\n var _interaction = _ref6;\n\n if (_interaction.pointerType === pointerType && !(/down/i.test(eventType) && _interaction.simulation)) {\n return _interaction;\n }\n }\n\n return null;\n },\n\n // get interaction that has this pointer\n hasPointer: function hasPointer(_ref7) {\n var pointerId = _ref7.pointerId;\n\n for (var _iterator5 = scope.interactions, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {\n var _ref8;\n\n if (_isArray5) {\n if (_i5 >= _iterator5.length) break;\n _ref8 = _iterator5[_i5++];\n } else {\n _i5 = _iterator5.next();\n if (_i5.done) break;\n _ref8 = _i5.value;\n }\n\n var interaction = _ref8;\n\n if (utils.contains(interaction.pointerIds, pointerId)) {\n return interaction;\n }\n }\n },\n\n // get first idle interaction with a matching pointerType\n idle: function idle(_ref9) {\n var pointerType = _ref9.pointerType;\n\n for (var _iterator6 = scope.interactions, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {\n var _ref10;\n\n if (_isArray6) {\n if (_i6 >= _iterator6.length) break;\n _ref10 = _iterator6[_i6++];\n } else {\n _i6 = _iterator6.next();\n if (_i6.done) break;\n _ref10 = _i6.value;\n }\n\n var interaction = _ref10;\n\n // if there's already a pointer held down\n if (interaction.pointerIds.length === 1) {\n var target = interaction.target;\n // don't add this pointer if there is a target interactable and it\n // isn't gesturable\n if (target && !target.options.gesture.enabled) {\n continue;\n }\n }\n // maximum of 2 pointers per interaction\n else if (interaction.pointerIds.length >= 2) {\n continue;\n }\n\n if (!interaction.interacting() && pointerType === interaction.pointerType) {\n return interaction;\n }\n }\n\n return null;\n }\n};\n\nmodule.exports = finder;\n\n},{\"../scope\":34,\"./index\":44}],46:[function(require,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar win = require('./window');\nvar isWindow = require('./isWindow');\n\nvar is = {\n array: function array() {},\n\n window: function window(thing) {\n return thing === win.window || isWindow(thing);\n },\n\n docFrag: function docFrag(thing) {\n return is.object(thing) && thing.nodeType === 11;\n },\n\n object: function object(thing) {\n return !!thing && (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) === 'object';\n },\n\n function: function _function(thing) {\n return typeof thing === 'function';\n },\n\n number: function number(thing) {\n return typeof thing === 'number';\n },\n\n bool: function bool(thing) {\n return typeof thing === 'boolean';\n },\n\n string: function string(thing) {\n return typeof thing === 'string';\n },\n\n element: function element(thing) {\n if (!thing || (typeof thing === 'undefined' ? 'undefined' : _typeof(thing)) !== 'object') {\n return false;\n }\n\n var _window = win.getWindow(thing) || win.window;\n\n return (/object|function/.test(_typeof(_window.Element)) ? thing instanceof _window.Element //DOM2\n : thing.nodeType === 1 && typeof thing.nodeName === 'string'\n );\n }\n};\n\nis.array = function (thing) {\n return is.object(thing) && typeof thing.length !== 'undefined' && is.function(thing.splice);\n};\n\nmodule.exports = is;\n\n},{\"./isWindow\":47,\"./window\":52}],47:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function (thing) {\n return !!(thing && thing.Window) && thing instanceof thing.Window;\n};\n\n},{}],48:[function(require,module,exports){\n'use strict';\n\nfunction pointerExtend(dest, source) {\n for (var prop in source) {\n var prefixedPropREs = module.exports.prefixedPropREs;\n var deprecated = false;\n\n // skip deprecated prefixed properties\n for (var vendor in prefixedPropREs) {\n if (prop.indexOf(vendor) === 0 && prefixedPropREs[vendor].test(prop)) {\n deprecated = true;\n break;\n }\n }\n\n if (!deprecated && typeof source[prop] !== 'function') {\n dest[prop] = source[prop];\n }\n }\n return dest;\n}\n\npointerExtend.prefixedPropREs = {\n webkit: /(Movement[XY]|Radius[XY]|RotationAngle|Force)$/\n};\n\nmodule.exports = pointerExtend;\n\n},{}],49:[function(require,module,exports){\n'use strict';\n\nvar hypot = require('./hypot');\nvar browser = require('./browser');\nvar dom = require('./domObjects');\nvar domUtils = require('./domUtils');\nvar domObjects = require('./domObjects');\nvar is = require('./is');\nvar pointerExtend = require('./pointerExtend');\n\nvar pointerUtils = {\n copyCoords: function copyCoords(dest, src) {\n dest.page = dest.page || {};\n dest.page.x = src.page.x;\n dest.page.y = src.page.y;\n\n dest.client = dest.client || {};\n dest.client.x = src.client.x;\n dest.client.y = src.client.y;\n\n dest.timeStamp = src.timeStamp;\n },\n\n setCoordDeltas: function setCoordDeltas(targetObj, prev, cur) {\n targetObj.page.x = cur.page.x - prev.page.x;\n targetObj.page.y = cur.page.y - prev.page.y;\n targetObj.client.x = cur.client.x - prev.client.x;\n targetObj.client.y = cur.client.y - prev.client.y;\n targetObj.timeStamp = cur.timeStamp - prev.timeStamp;\n\n // set pointer velocity\n var dt = Math.max(targetObj.timeStamp / 1000, 0.001);\n\n targetObj.page.speed = hypot(targetObj.page.x, targetObj.page.y) / dt;\n targetObj.page.vx = targetObj.page.x / dt;\n targetObj.page.vy = targetObj.page.y / dt;\n\n targetObj.client.speed = hypot(targetObj.client.x, targetObj.page.y) / dt;\n targetObj.client.vx = targetObj.client.x / dt;\n targetObj.client.vy = targetObj.client.y / dt;\n },\n\n isNativePointer: function isNativePointer(pointer) {\n return pointer instanceof dom.Event || pointer instanceof dom.Touch;\n },\n\n // Get specified X/Y coords for mouse or event.touches[0]\n getXY: function getXY(type, pointer, xy) {\n xy = xy || {};\n type = type || 'page';\n\n xy.x = pointer[type + 'X'];\n xy.y = pointer[type + 'Y'];\n\n return xy;\n },\n\n getPageXY: function getPageXY(pointer, page) {\n page = page || {};\n\n // Opera Mobile handles the viewport and scrolling oddly\n if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {\n pointerUtils.getXY('screen', pointer, page);\n\n page.x += window.scrollX;\n page.y += window.scrollY;\n } else {\n pointerUtils.getXY('page', pointer, page);\n }\n\n return page;\n },\n\n getClientXY: function getClientXY(pointer, client) {\n client = client || {};\n\n if (browser.isOperaMobile && pointerUtils.isNativePointer(pointer)) {\n // Opera Mobile handles the viewport and scrolling oddly\n pointerUtils.getXY('screen', pointer, client);\n } else {\n pointerUtils.getXY('client', pointer, client);\n }\n\n return client;\n },\n\n getPointerId: function getPointerId(pointer) {\n return is.number(pointer.pointerId) ? pointer.pointerId : pointer.identifier;\n },\n\n setCoords: function setCoords(targetObj, pointers, timeStamp) {\n var pointer = pointers.length > 1 ? pointerUtils.pointerAverage(pointers) : pointers[0];\n\n var tmpXY = {};\n\n pointerUtils.getPageXY(pointer, tmpXY);\n targetObj.page.x = tmpXY.x;\n targetObj.page.y = tmpXY.y;\n\n pointerUtils.getClientXY(pointer, tmpXY);\n targetObj.client.x = tmpXY.x;\n targetObj.client.y = tmpXY.y;\n\n targetObj.timeStamp = is.number(timeStamp) ? timeStamp : new Date().getTime();\n },\n\n pointerExtend: pointerExtend,\n\n getTouchPair: function getTouchPair(event) {\n var touches = [];\n\n // array of touches is supplied\n if (is.array(event)) {\n touches[0] = event[0];\n touches[1] = event[1];\n }\n // an event\n else {\n if (event.type === 'touchend') {\n if (event.touches.length === 1) {\n touches[0] = event.touches[0];\n touches[1] = event.changedTouches[0];\n } else if (event.touches.length === 0) {\n touches[0] = event.changedTouches[0];\n touches[1] = event.changedTouches[1];\n }\n } else {\n touches[0] = event.touches[0];\n touches[1] = event.touches[1];\n }\n }\n\n return touches;\n },\n\n pointerAverage: function pointerAverage(pointers) {\n var average = {\n pageX: 0,\n pageY: 0,\n clientX: 0,\n clientY: 0,\n screenX: 0,\n screenY: 0\n };\n\n for (var _iterator = pointers, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var pointer = _ref;\n\n for (var _prop in average) {\n average[_prop] += pointer[_prop];\n }\n }\n for (var prop in average) {\n average[prop] /= pointers.length;\n }\n\n return average;\n },\n\n touchBBox: function touchBBox(event) {\n if (!event.length && !(event.touches && event.touches.length > 1)) {\n return;\n }\n\n var touches = pointerUtils.getTouchPair(event);\n var minX = Math.min(touches[0].pageX, touches[1].pageX);\n var minY = Math.min(touches[0].pageY, touches[1].pageY);\n var maxX = Math.max(touches[0].pageX, touches[1].pageX);\n var maxY = Math.max(touches[0].pageY, touches[1].pageY);\n\n return {\n x: minX,\n y: minY,\n left: minX,\n top: minY,\n width: maxX - minX,\n height: maxY - minY\n };\n },\n\n touchDistance: function touchDistance(event, deltaSource) {\n var sourceX = deltaSource + 'X';\n var sourceY = deltaSource + 'Y';\n var touches = pointerUtils.getTouchPair(event);\n\n var dx = touches[0][sourceX] - touches[1][sourceX];\n var dy = touches[0][sourceY] - touches[1][sourceY];\n\n return hypot(dx, dy);\n },\n\n touchAngle: function touchAngle(event, prevAngle, deltaSource) {\n var sourceX = deltaSource + 'X';\n var sourceY = deltaSource + 'Y';\n var touches = pointerUtils.getTouchPair(event);\n var dx = touches[1][sourceX] - touches[0][sourceX];\n var dy = touches[1][sourceY] - touches[0][sourceY];\n var angle = 180 * Math.atan2(dy, dx) / Math.PI;\n\n return angle;\n },\n\n getPointerType: function getPointerType(pointer) {\n return is.string(pointer.pointerType) ? pointer.pointerType : is.number(pointer.pointerType) ? [undefined, undefined, 'touch', 'pen', 'mouse'][pointer.pointerType]\n // if the PointerEvent API isn't available, then the \"pointer\" must\n // be either a MouseEvent, TouchEvent, or Touch object\n : /touch/.test(pointer.type) || pointer instanceof domObjects.Touch ? 'touch' : 'mouse';\n },\n\n // [ event.target, event.currentTarget ]\n getEventTargets: function getEventTargets(event) {\n return [domUtils.getActualElement(event.path ? event.path[0] : event.target), domUtils.getActualElement(event.currentTarget)];\n }\n};\n\nmodule.exports = pointerUtils;\n\n},{\"./browser\":37,\"./domObjects\":38,\"./domUtils\":39,\"./hypot\":43,\"./is\":46,\"./pointerExtend\":48}],50:[function(require,module,exports){\n'use strict';\n\nvar _require = require('./window'),\n window = _require.window;\n\nvar vendors = ['ms', 'moz', 'webkit', 'o'];\nvar lastTime = 0;\nvar request = void 0;\nvar cancel = void 0;\n\nfor (var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) {\n request = window[vendors[x] + 'RequestAnimationFrame'];\n cancel = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];\n}\n\nif (!request) {\n request = function request(callback) {\n var currTime = new Date().getTime();\n var timeToCall = Math.max(0, 16 - (currTime - lastTime));\n var id = setTimeout(function () {\n callback(currTime + timeToCall);\n }, timeToCall);\n\n lastTime = currTime + timeToCall;\n return id;\n };\n}\n\nif (!cancel) {\n cancel = function cancel(id) {\n clearTimeout(id);\n };\n}\n\nmodule.exports = {\n request: request,\n cancel: cancel\n};\n\n},{\"./window\":52}],51:[function(require,module,exports){\n'use strict';\n\nvar extend = require('./extend');\nvar is = require('./is');\n\nvar _require = require('./domUtils'),\n closest = _require.closest,\n parentNode = _require.parentNode,\n getElementRect = _require.getElementRect;\n\nvar rectUtils = {\n getStringOptionResult: function getStringOptionResult(value, interactable, element) {\n if (!is.string(value)) {\n return null;\n }\n\n if (value === 'parent') {\n value = parentNode(element);\n } else if (value === 'self') {\n value = interactable.getRect(element);\n } else {\n value = closest(element, value);\n }\n\n return value;\n },\n\n resolveRectLike: function resolveRectLike(value, interactable, element, functionArgs) {\n value = rectUtils.getStringOptionResult(value, interactable, element) || value;\n\n if (is.function(value)) {\n value = value.apply(null, functionArgs);\n }\n\n if (is.element(value)) {\n value = getElementRect(value);\n }\n\n return value;\n },\n\n rectToXY: function rectToXY(rect) {\n return rect && {\n x: 'x' in rect ? rect.x : rect.left,\n y: 'y' in rect ? rect.y : rect.top\n };\n },\n\n xywhToTlbr: function xywhToTlbr(rect) {\n if (rect && !('left' in rect && 'top' in rect)) {\n rect = extend({}, rect);\n\n rect.left = rect.x || 0;\n rect.top = rect.y || 0;\n rect.right = rect.right || rect.left + rect.width;\n rect.bottom = rect.bottom || rect.top + rect.height;\n }\n\n return rect;\n },\n\n tlbrToXywh: function tlbrToXywh(rect) {\n if (rect && !('x' in rect && 'y' in rect)) {\n rect = extend({}, rect);\n\n rect.x = rect.left || 0;\n rect.top = rect.top || 0;\n rect.width = rect.width || rect.right - rect.x;\n rect.height = rect.height || rect.bottom - rect.y;\n }\n\n return rect;\n }\n};\n\nmodule.exports = rectUtils;\n\n},{\"./domUtils\":39,\"./extend\":41,\"./is\":46}],52:[function(require,module,exports){\n'use strict';\n\nvar win = module.exports;\nvar isWindow = require('./isWindow');\n\nfunction init(window) {\n // get wrapped window if using Shadow DOM polyfill\n\n win.realWindow = window;\n\n // create a TextNode\n var el = window.document.createTextNode('');\n\n // check if it's wrapped by a polyfill\n if (el.ownerDocument !== window.document && typeof window.wrap === 'function' && window.wrap(el) === el) {\n // use wrapped window\n window = window.wrap(window);\n }\n\n win.window = window;\n}\n\nif (typeof window === 'undefined') {\n win.window = undefined;\n win.realWindow = undefined;\n} else {\n init(window);\n}\n\nwin.getWindow = function getWindow(node) {\n if (isWindow(node)) {\n return node;\n }\n\n var rootNode = node.ownerDocument || node;\n\n return rootNode.defaultView || rootNode.parentWindow || win.window;\n};\n\nwin.init = init;\n\n},{\"./isWindow\":47}]},{},[1])(1)\n});\n\n\n//# sourceMappingURL=interact.js.map\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW50ZXJhY3Rqcy9kaXN0L2ludGVyYWN0LmpzP2JiZmUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IllBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFNBQTJELG1CQUFtQixnREFBZ0QsYUFBYSxLQUFLLE1BQU0sZ0NBQWdDLFNBQVMscUNBQXFDLFNBQVMsbUNBQW1DLE9BQU8sS0FBSyxPQUFPLGtCQUFrQixhQUFhLDBCQUEwQiwwQkFBMEIsZ0JBQWdCLFVBQVUsVUFBVSwwQ0FBMEMsOEJBQXdCLG9CQUFvQiw4Q0FBOEMsa0NBQWtDLFlBQVksWUFBWSxtQ0FBbUMsaUJBQWlCLGdCQUFnQixzQkFBc0Isb0JBQW9CLDBDQUEwQyxZQUFZLFdBQVcsWUFBWSxTQUFTLEdBQUc7QUFDNXlCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBLENBQUMsRUFBRSx5Q0FBeUM7QUFDNUM7O0FBRUEsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdko7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHlDQUF5QywrQ0FBK0M7QUFDeEY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBNEIsZUFBZTtBQUMzQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBLENBQUMsRUFBRSx3Q0FBd0M7QUFDM0M7O0FBRUEsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdko7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLHdCQUF3QjtBQUN4QiwwQkFBMEI7O0FBRTFCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHdGQUF3RjtBQUMzRjs7QUFFQSxpREFBaUQsMENBQTBDLDBEQUEwRCxFQUFFOztBQUV2SjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtGQUFrRjs7QUFFbEY7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx3SkFBd0o7QUFDeEo7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXVELGFBQWE7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUZBQXlGO0FBQ3pGO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsc0JBQXNCO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRCQUE0Qjs7QUFFNUIsOEJBQThCOztBQUU5QjtBQUNBOztBQUVBLDBDQUEwQzs7QUFFMUM7O0FBRUE7QUFDQTs7QUFFQSw2S0FBNks7QUFDN0s7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBLGtDQUFrQyxzR0FBc0c7QUFDeEksR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLG1DQUFtQztBQUNuQyxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDRHQUE0RztBQUMvRzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsMEpBQTBKO0FBQzFKOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLHlCQUF5QjtBQUM1Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLDhDQUE4QztBQUMvRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGlCQUFpQiw4Q0FBOEM7QUFDL0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsOENBQThDO0FBQy9EO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QyxvQkFBb0I7O0FBRTNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG9DQUFvQyxlQUFlOztBQUVuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3Qyx1QkFBdUI7O0FBRS9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLHlCQUF5Qjs7QUFFbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0EsZ0NBQWdDO0FBQ2hDLGlDQUFpQztBQUNqQyxvQ0FBb0M7QUFDcEMscUNBQXFDO0FBQ3JDLGdDQUFnQzs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsMklBQTJJO0FBQzlJOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsbUNBQW1DO0FBQ25DLG1DQUFtQztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsWUFBWSxhQUFhOztBQUV6QjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsNEdBQTRHO0FBQy9HOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDhCQUE4QjtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0EseUJBQXlCOztBQUV6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEscUJBQXFCLE9BQU87QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRCQUE0QjtBQUM1Qiw2QkFBNkI7QUFDN0IsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQyxtQ0FBbUM7QUFDbkMsbUNBQW1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSxrSUFBa0k7QUFDckk7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSxtSEFBbUg7QUFDdEg7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLG1EQUFtRDtBQUN6RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixvREFBb0Q7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsb0pBQW9KO0FBQ3BKOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxnRkFBZ0Y7QUFDbkY7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsdUNBQXVDLFNBQVM7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNEJBQTRCLDJCQUEyQjtBQUN2RDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLG9KQUFvSjtBQUNwSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrREFBa0QsU0FBUztBQUMzRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHNNQUFzTTtBQUN6TTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVELENBQUMsRUFBRSwrQkFBK0I7QUFDbEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDRHQUE0RztBQUMvRzs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsbUNBQW1DO0FBQ3RDOztBQUVBOztBQUVBLENBQUMsRUFBRSxtQ0FBbUM7QUFDdEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxhQUFhLGFBQWE7O0FBRTFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEdBQUc7QUFDSjs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxDQUFDLEVBQUUsc2dCQUFzZ0I7QUFDemdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdCQUFnQjs7QUFFaEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLENBQUMsRUFBRSxxRkFBcUY7QUFDeEY7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2SUFBNkk7QUFDN0k7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxtQkFBbUI7QUFDckU7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxSkFBcUo7QUFDcko7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsUUFBUTtBQUNyRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSx3R0FBd0c7QUFDM0c7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0JBQWdCLGtCQUFrQjtBQUNsQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDBKQUEwSjtBQUMxSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDRHQUE0RztBQUMvRzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJKQUEySjtBQUMzSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLG1JQUFtSTtBQUN0STs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG1CQUFtQiw0QkFBNEI7QUFDL0M7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdKQUF3SjtBQUN4Sjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLGdLQUFnSztBQUNoSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsNEJBQTRCO0FBQzdDOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiw2QkFBNkI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUEsNkJBQTZCOztBQUU3QixpQkFBaUIsNEJBQTRCO0FBQzdDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsNkRBQTZEO0FBQ2hFOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEscUNBQXFDLDJCQUEyQixrQkFBa0I7O0FBRWxGOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLGtEQUFrRDtBQUNyRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsd0JBQXdCO0FBQ3JDO0FBQ0EsZUFBZSwrQ0FBK0M7QUFDOUQsZUFBZSwrQ0FBK0M7QUFDOUQsTUFBTTtBQUNOLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGVBQWU7QUFDZixlQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFDQUFxQywyQkFBMkIsa0JBQWtCO0FBQ2xGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsNEdBQTRHO0FBQy9HOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSx3QkFBd0I7QUFDckM7QUFDQSxhQUFhLDRCQUE0QjtBQUN6QyxhQUFhLDRCQUE0QjtBQUN6QyxNQUFNO0FBQ04sSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLGlIQUFpSDtBQUNwSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQSxrREFBa0Q7QUFDbEQ7O0FBRUE7QUFDQSxpS0FBaUs7QUFDaks7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsY0FBYztBQUNkLEtBQUs7QUFDTDs7QUFFQSw0QkFBNEI7O0FBRTVCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLHdKQUF3SjtBQUN4Sjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsa0tBQWtLO0FBQ2xLOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUNBQXFDLFNBQVM7QUFDOUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsbUVBQW1FO0FBQ3RFOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxlQUFlLGFBQWE7QUFDNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsOEJBQThCO0FBQzlCO0FBQ0E7O0FBRUEsaUNBQWlDO0FBQ2pDOztBQUVBLHdKQUF3SjtBQUN4Sjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOzs7QUFHQSxpQ0FBaUM7QUFDakM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSxzRkFBc0Y7QUFDekY7O0FBRUEsaURBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdko7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRCxDQUFDLEVBQUUsMkJBQTJCO0FBQzlCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsb0JBQW9CO0FBQ3JDOztBQUVBLHVDQUF1QztBQUN2QztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwySUFBMkk7QUFDM0k7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDBDQUEwQztBQUMxQyxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaURBQWlEOztBQUVqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUpBQW1KO0FBQ25KOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxpQkFBaUIsOEJBQThCO0FBQy9DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0gsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsVUFBVSxrR0FBa0c7QUFDNUc7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxVQUFVLGlHQUFpRztBQUMzRztBQUNBOztBQUVBLGVBQWUsMEJBQTBCO0FBQ3pDO0FBQ0E7O0FBRUE7QUFDQSw2QkFBNkI7QUFDN0IsMEJBQTBCO0FBQzFCLDhCQUE4QixNQUFNLG9CQUFvQjtBQUN4RCxDQUFDOztBQUVEO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDBJQUEwSTtBQUM3STs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxnQkFBZ0Isa0JBQWtCO0FBQ2xDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsK0JBQStCO0FBQ2xDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLE9BQU87QUFDUDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQixPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsbUpBQW1KO0FBQ3RKOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQ0FBa0MscUJBQXFCO0FBQ3ZELEdBQUc7O0FBRUg7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLHFDQUFxQyxxQkFBcUI7QUFDMUQsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsOEVBQThFO0FBQ2pGOztBQUVBLGlEQUFpRCwwQ0FBMEMsMERBQTBELEVBQUU7O0FBRXZKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsNEJBQTRCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsV0FBVztBQUNkOztBQUVBO0FBQ0EscUNBQXFDLFNBQVM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsbUJBQW1CO0FBQ3BDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlCQUFpQixrQkFBa0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxHQUFHO0FBQ0o7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSwwQ0FBMEM7QUFDN0M7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLGNBQWM7QUFDakI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQSx1Q0FBdUMsU0FBUztBQUNoRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZSxxQkFBcUI7QUFDcEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHlEQUF5RDtBQUM1RDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtB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QUFDQSxtQkFBbUI7O0FBRW5CLDJKQUEySjtBQUMzSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG1LQUFtSztBQUNuSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLG1LQUFtSztBQUNuSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1LQUFtSztBQUNuSzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQSxtS0FBbUs7QUFDbks7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUEsbUtBQW1LO0FBQ25LOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDJCQUEyQjtBQUM5Qjs7QUFFQSxvR0FBb0csbUJBQW1CLEVBQUUsbUJBQW1CLDhIQUE4SDs7QUFFMVE7QUFDQTs7QUFFQTtBQUNBLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDhCQUE4QjtBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxHQUFHO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEdBQUc7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpSkFBaUo7QUFDako7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSw2RkFBNkY7QUFDaEc7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLHFEQUFxRDtBQUNwRTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxjQUFjO0FBQ2pCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLHdDQUF3QztBQUMzQzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRztBQUN4QixDQUFDOzs7QUFHRCIsImZpbGUiOiIxNi5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogaW50ZXJhY3QuanMgdjEuMy4wLWFscGhhLjQrc2hhLjc5NzA0MTYtZGlydHlcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNyBUYXllIEFkZXllbWkgPGRldkB0YXllLm1lPlxuICogT3BlbiBzb3VyY2UgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuICogaHR0cHM6Ly9yYXcuZ2l0aHViLmNvbS90YXllL2ludGVyYWN0LmpzL21hc3Rlci9MSUNFTlNFXG4gKi9cbihmdW5jdGlvbihmKXtpZih0eXBlb2YgZXhwb3J0cz09PVwib2JqZWN0XCImJnR5cGVvZiBtb2R1bGUhPT1cInVuZGVmaW5lZFwiKXttb2R1bGUuZXhwb3J0cz1mKCl9ZWxzZSBpZih0eXBlb2YgZGVmaW5lPT09XCJmdW5jdGlvblwiJiZkZWZpbmUuYW1kKXtkZWZpbmUoW10sZil9ZWxzZXt2YXIgZztpZih0eXBlb2Ygd2luZG93IT09XCJ1bmRlZmluZWRcIil7Zz13aW5kb3d9ZWxzZSBpZih0eXBlb2YgZ2xvYmFsIT09XCJ1bmRlZmluZWRcIil7Zz1nbG9iYWx9ZWxzZSBpZih0eXBlb2Ygc2VsZiE9PVwidW5kZWZpbmVkXCIpe2c9c2VsZn1lbHNle2c9dGhpc31nLmludGVyYWN0ID0gZigpfX0pKGZ1bmN0aW9uKCl7dmFyIGRlZmluZSxtb2R1bGUsZXhwb3J0cztyZXR1cm4gKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkoezE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG4vKlxuICogSW4gYSAod2luZG93bGVzcykgc2VydmVyIGVudmlyb25tZW50IHRoaXMgZmlsZSBleHBvcnRzIGEgZmFjdG9yeSBmdW5jdGlvblxuICogdGhhdCB0YWtlcyB0aGUgd2luZG93IHRvIHVzZS5cbiAqXG4gKiAgICAgdmFyIGludGVyYWN0ID0gcmVxdWlyZSgnaW50ZXJhY3QuanMnKSh3aW5kb3dPYmplY3QpO1xuICpcbiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdGF5ZS9pbnRlcmFjdC5qcy9pc3N1ZXMvMTg3XG4gKi9cbmlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh3aW5kb3cpIHtcbiAgICByZXF1aXJlKCcuL3NyYy91dGlscy93aW5kb3cnKS5pbml0KHdpbmRvdyk7XG5cbiAgICByZXR1cm4gcmVxdWlyZSgnLi9zcmMvaW5kZXgnKTtcbiAgfTtcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9zcmMvaW5kZXgnKTtcbn1cblxufSx7XCIuL3NyYy9pbmRleFwiOjE5LFwiLi9zcmMvdXRpbHMvd2luZG93XCI6NTJ9XSwyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi91dGlscy9hcnInKSxcbiAgICBpbmRleE9mID0gX3JlcXVpcmUuaW5kZXhPZjtcblxudmFyIGV4dGVuZCA9IHJlcXVpcmUoJy4vdXRpbHMvZXh0ZW5kLmpzJyk7XG5cbmZ1bmN0aW9uIGZpcmVVbnRpbEltbWVkaWF0ZVN0b3BwZWQoZXZlbnQsIGxpc3RlbmVycykge1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbiAmJiAhZXZlbnQuaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOyBpKyspIHtcbiAgICBsaXN0ZW5lcnNbaV0oZXZlbnQpO1xuICB9XG59XG5cbnZhciBFdmVudGFibGUgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEV2ZW50YWJsZShvcHRpb25zKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEV2ZW50YWJsZSk7XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBleHRlbmQoe30sIG9wdGlvbnMgfHwge30pO1xuICB9XG5cbiAgRXZlbnRhYmxlLnByb3RvdHlwZS5maXJlID0gZnVuY3Rpb24gZmlyZShldmVudCkge1xuICAgIHZhciBsaXN0ZW5lcnMgPSB2b2lkIDA7XG4gICAgdmFyIG9uRXZlbnQgPSAnb24nICsgZXZlbnQudHlwZTtcbiAgICB2YXIgZ2xvYmFsID0gdGhpcy5nbG9iYWw7XG5cbiAgICAvLyBJbnRlcmFjdGFibGUjb24oKSBsaXN0ZW5lcnNcbiAgICBpZiAobGlzdGVuZXJzID0gdGhpc1tldmVudC50eXBlXSkge1xuICAgICAgZmlyZVVudGlsSW1tZWRpYXRlU3RvcHBlZChldmVudCwgbGlzdGVuZXJzKTtcbiAgICB9XG5cbiAgICAvLyBpbnRlcmFjdGFibGUub25ldmVudCBsaXN0ZW5lclxuICAgIGlmICh0aGlzW29uRXZlbnRdKSB7XG4gICAgICB0aGlzW29uRXZlbnRdKGV2ZW50KTtcbiAgICB9XG5cbiAgICAvLyBpbnRlcmFjdC5vbigpIGxpc3RlbmVyc1xuICAgIGlmICghZXZlbnQucHJvcGFnYXRpb25TdG9wcGVkICYmIGdsb2JhbCAmJiAobGlzdGVuZXJzID0gZ2xvYmFsW2V2ZW50LnR5cGVdKSkge1xuICAgICAgZmlyZVVudGlsSW1tZWRpYXRlU3RvcHBlZChldmVudCwgbGlzdGVuZXJzKTtcbiAgICB9XG4gIH07XG5cbiAgRXZlbnRhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKGV2ZW50VHlwZSwgbGlzdGVuZXIpIHtcbiAgICAvLyBpZiB0aGlzIHR5cGUgb2YgZXZlbnQgd2FzIG5ldmVyIGJvdW5kXG4gICAgaWYgKHRoaXNbZXZlbnRUeXBlXSkge1xuICAgICAgdGhpc1tldmVudFR5cGVdLnB1c2gobGlzdGVuZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzW2V2ZW50VHlwZV0gPSBbbGlzdGVuZXJdO1xuICAgIH1cbiAgfTtcblxuICBFdmVudGFibGUucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIG9mZihldmVudFR5cGUsIGxpc3RlbmVyKSB7XG4gICAgLy8gaWYgaXQgaXMgYW4gYWN0aW9uIGV2ZW50IHR5cGVcbiAgICB2YXIgZXZlbnRMaXN0ID0gdGhpc1tldmVudFR5cGVdO1xuICAgIHZhciBpbmRleCA9IGV2ZW50TGlzdCA/IGluZGV4T2YoZXZlbnRMaXN0LCBsaXN0ZW5lcikgOiAtMTtcblxuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIGV2ZW50TGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cblxuICAgIGlmIChldmVudExpc3QgJiYgZXZlbnRMaXN0Lmxlbmd0aCA9PT0gMCB8fCAhbGlzdGVuZXIpIHtcbiAgICAgIHRoaXNbZXZlbnRUeXBlXSA9IGxpc3RlbmVyO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gRXZlbnRhYmxlO1xufSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50YWJsZTtcblxufSx7XCIuL3V0aWxzL2FyclwiOjM2LFwiLi91dGlscy9leHRlbmQuanNcIjo0MX1dLDM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi91dGlscy9leHRlbmQnKTtcbnZhciBnZXRPcmlnaW5YWSA9IHJlcXVpcmUoJy4vdXRpbHMvZ2V0T3JpZ2luWFknKTtcbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4vZGVmYXVsdE9wdGlvbnMnKTtcbnZhciBzaWduYWxzID0gcmVxdWlyZSgnLi91dGlscy9TaWduYWxzJykubmV3KCk7XG5cbnZhciBJbnRlcmFjdEV2ZW50ID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBJbnRlcmFjdEV2ZW50KGludGVyYWN0aW9uLCBldmVudCwgYWN0aW9uLCBwaGFzZSwgZWxlbWVudCwgcmVsYXRlZCkge1xuICAgIHZhciBwcmVFbmQgPSBhcmd1bWVudHMubGVuZ3RoID4gNiAmJiBhcmd1bWVudHNbNl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1s2XSA6IGZhbHNlO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEludGVyYWN0RXZlbnQpO1xuXG4gICAgdmFyIHRhcmdldCA9IGludGVyYWN0aW9uLnRhcmdldDtcbiAgICB2YXIgZGVsdGFTb3VyY2UgPSAodGFyZ2V0ICYmIHRhcmdldC5vcHRpb25zIHx8IGRlZmF1bHRzKS5kZWx0YVNvdXJjZTtcbiAgICB2YXIgb3JpZ2luID0gZ2V0T3JpZ2luWFkodGFyZ2V0LCBlbGVtZW50LCBhY3Rpb24pO1xuICAgIHZhciBzdGFydGluZyA9IHBoYXNlID09PSAnc3RhcnQnO1xuICAgIHZhciBlbmRpbmcgPSBwaGFzZSA9PT0gJ2VuZCc7XG4gICAgdmFyIGNvb3JkcyA9IHN0YXJ0aW5nID8gaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMgOiBpbnRlcmFjdGlvbi5jdXJDb29yZHM7XG4gICAgdmFyIHByZXZFdmVudCA9IGludGVyYWN0aW9uLnByZXZFdmVudDtcblxuICAgIGVsZW1lbnQgPSBlbGVtZW50IHx8IGludGVyYWN0aW9uLmVsZW1lbnQ7XG5cbiAgICB2YXIgcGFnZSA9IGV4dGVuZCh7fSwgY29vcmRzLnBhZ2UpO1xuICAgIHZhciBjbGllbnQgPSBleHRlbmQoe30sIGNvb3Jkcy5jbGllbnQpO1xuXG4gICAgcGFnZS54IC09IG9yaWdpbi54O1xuICAgIHBhZ2UueSAtPSBvcmlnaW4ueTtcblxuICAgIGNsaWVudC54IC09IG9yaWdpbi54O1xuICAgIGNsaWVudC55IC09IG9yaWdpbi55O1xuXG4gICAgdGhpcy5jdHJsS2V5ID0gZXZlbnQuY3RybEtleTtcbiAgICB0aGlzLmFsdEtleSA9IGV2ZW50LmFsdEtleTtcbiAgICB0aGlzLnNoaWZ0S2V5ID0gZXZlbnQuc2hpZnRLZXk7XG4gICAgdGhpcy5tZXRhS2V5ID0gZXZlbnQubWV0YUtleTtcbiAgICB0aGlzLmJ1dHRvbiA9IGV2ZW50LmJ1dHRvbjtcbiAgICB0aGlzLmJ1dHRvbnMgPSBldmVudC5idXR0b25zO1xuICAgIHRoaXMudGFyZ2V0ID0gZWxlbWVudDtcbiAgICB0aGlzLmN1cnJlbnRUYXJnZXQgPSBlbGVtZW50O1xuICAgIHRoaXMucmVsYXRlZFRhcmdldCA9IHJlbGF0ZWQgfHwgbnVsbDtcbiAgICB0aGlzLnByZUVuZCA9IHByZUVuZDtcbiAgICB0aGlzLnR5cGUgPSBhY3Rpb24gKyAocGhhc2UgfHwgJycpO1xuICAgIHRoaXMuaW50ZXJhY3Rpb24gPSBpbnRlcmFjdGlvbjtcbiAgICB0aGlzLmludGVyYWN0YWJsZSA9IHRhcmdldDtcblxuICAgIHRoaXMudDAgPSBzdGFydGluZyA/IGludGVyYWN0aW9uLmRvd25UaW1lc1tpbnRlcmFjdGlvbi5kb3duVGltZXMubGVuZ3RoIC0gMV0gOiBwcmV2RXZlbnQudDA7XG5cbiAgICB2YXIgc2lnbmFsQXJnID0ge1xuICAgICAgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLFxuICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgYWN0aW9uOiBhY3Rpb24sXG4gICAgICBwaGFzZTogcGhhc2UsXG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgICAgcmVsYXRlZDogcmVsYXRlZCxcbiAgICAgIHBhZ2U6IHBhZ2UsXG4gICAgICBjbGllbnQ6IGNsaWVudCxcbiAgICAgIGNvb3JkczogY29vcmRzLFxuICAgICAgc3RhcnRpbmc6IHN0YXJ0aW5nLFxuICAgICAgZW5kaW5nOiBlbmRpbmcsXG4gICAgICBkZWx0YVNvdXJjZTogZGVsdGFTb3VyY2UsXG4gICAgICBpRXZlbnQ6IHRoaXNcbiAgICB9O1xuXG4gICAgc2lnbmFscy5maXJlKCdzZXQteHknLCBzaWduYWxBcmcpO1xuXG4gICAgaWYgKGVuZGluZykge1xuICAgICAgLy8gdXNlIHByZXZpb3VzIGNvb3JkcyB3aGVuIGVuZGluZ1xuICAgICAgdGhpcy5wYWdlWCA9IHByZXZFdmVudC5wYWdlWDtcbiAgICAgIHRoaXMucGFnZVkgPSBwcmV2RXZlbnQucGFnZVk7XG4gICAgICB0aGlzLmNsaWVudFggPSBwcmV2RXZlbnQuY2xpZW50WDtcbiAgICAgIHRoaXMuY2xpZW50WSA9IHByZXZFdmVudC5jbGllbnRZO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhZ2VYID0gcGFnZS54O1xuICAgICAgdGhpcy5wYWdlWSA9IHBhZ2UueTtcbiAgICAgIHRoaXMuY2xpZW50WCA9IGNsaWVudC54O1xuICAgICAgdGhpcy5jbGllbnRZID0gY2xpZW50Lnk7XG4gICAgfVxuXG4gICAgdGhpcy54MCA9IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLnBhZ2UueCAtIG9yaWdpbi54O1xuICAgIHRoaXMueTAgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnkgLSBvcmlnaW4ueTtcbiAgICB0aGlzLmNsaWVudFgwID0gaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMuY2xpZW50LnggLSBvcmlnaW4ueDtcbiAgICB0aGlzLmNsaWVudFkwID0gaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMuY2xpZW50LnkgLSBvcmlnaW4ueTtcblxuICAgIHNpZ25hbHMuZmlyZSgnc2V0LWRlbHRhJywgc2lnbmFsQXJnKTtcblxuICAgIHRoaXMudGltZVN0YW1wID0gY29vcmRzLnRpbWVTdGFtcDtcbiAgICB0aGlzLmR0ID0gaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLnRpbWVTdGFtcDtcbiAgICB0aGlzLmR1cmF0aW9uID0gdGhpcy50aW1lU3RhbXAgLSB0aGlzLnQwO1xuXG4gICAgLy8gc3BlZWQgYW5kIHZlbG9jaXR5IGluIHBpeGVscyBwZXIgc2Vjb25kXG4gICAgdGhpcy5zcGVlZCA9IGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YVtkZWx0YVNvdXJjZV0uc3BlZWQ7XG4gICAgdGhpcy52ZWxvY2l0eVggPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGFbZGVsdGFTb3VyY2VdLnZ4O1xuICAgIHRoaXMudmVsb2NpdHlZID0gaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhW2RlbHRhU291cmNlXS52eTtcblxuICAgIHRoaXMuc3dpcGUgPSBlbmRpbmcgfHwgcGhhc2UgPT09ICdpbmVydGlhc3RhcnQnID8gdGhpcy5nZXRTd2lwZSgpIDogbnVsbDtcblxuICAgIHNpZ25hbHMuZmlyZSgnbmV3Jywgc2lnbmFsQXJnKTtcbiAgfVxuXG4gIEludGVyYWN0RXZlbnQucHJvdG90eXBlLmdldFN3aXBlID0gZnVuY3Rpb24gZ2V0U3dpcGUoKSB7XG4gICAgdmFyIGludGVyYWN0aW9uID0gdGhpcy5pbnRlcmFjdGlvbjtcblxuICAgIGlmIChpbnRlcmFjdGlvbi5wcmV2RXZlbnQuc3BlZWQgPCA2MDAgfHwgdGhpcy50aW1lU3RhbXAgLSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQudGltZVN0YW1wID4gMTUwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgYW5nbGUgPSAxODAgKiBNYXRoLmF0YW4yKGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVksIGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVgpIC8gTWF0aC5QSTtcbiAgICB2YXIgb3ZlcmxhcCA9IDIyLjU7XG5cbiAgICBpZiAoYW5nbGUgPCAwKSB7XG4gICAgICBhbmdsZSArPSAzNjA7XG4gICAgfVxuXG4gICAgdmFyIGxlZnQgPSAxMzUgLSBvdmVybGFwIDw9IGFuZ2xlICYmIGFuZ2xlIDwgMjI1ICsgb3ZlcmxhcDtcbiAgICB2YXIgdXAgPSAyMjUgLSBvdmVybGFwIDw9IGFuZ2xlICYmIGFuZ2xlIDwgMzE1ICsgb3ZlcmxhcDtcblxuICAgIHZhciByaWdodCA9ICFsZWZ0ICYmICgzMTUgLSBvdmVybGFwIDw9IGFuZ2xlIHx8IGFuZ2xlIDwgNDUgKyBvdmVybGFwKTtcbiAgICB2YXIgZG93biA9ICF1cCAmJiA0NSAtIG92ZXJsYXAgPD0gYW5nbGUgJiYgYW5nbGUgPCAxMzUgKyBvdmVybGFwO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHVwOiB1cCxcbiAgICAgIGRvd246IGRvd24sXG4gICAgICBsZWZ0OiBsZWZ0LFxuICAgICAgcmlnaHQ6IHJpZ2h0LFxuICAgICAgYW5nbGU6IGFuZ2xlLFxuICAgICAgc3BlZWQ6IGludGVyYWN0aW9uLnByZXZFdmVudC5zcGVlZCxcbiAgICAgIHZlbG9jaXR5OiB7XG4gICAgICAgIHg6IGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVgsXG4gICAgICAgIHk6IGludGVyYWN0aW9uLnByZXZFdmVudC52ZWxvY2l0eVlcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4gIEludGVyYWN0RXZlbnQucHJvdG90eXBlLnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gcHJldmVudERlZmF1bHQoKSB7fTtcblxuICBJbnRlcmFjdEV2ZW50LnByb3RvdHlwZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gPSBmdW5jdGlvbiBzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSB7XG4gICAgdGhpcy5pbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XG4gIH07XG5cbiAgSW50ZXJhY3RFdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKCkge1xuICAgIHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTtcbiAgfTtcblxuICByZXR1cm4gSW50ZXJhY3RFdmVudDtcbn0oKTtcblxuc2lnbmFscy5vbignc2V0LWRlbHRhJywgZnVuY3Rpb24gKF9yZWYpIHtcbiAgdmFyIGlFdmVudCA9IF9yZWYuaUV2ZW50LFxuICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxuICAgICAgc3RhcnRpbmcgPSBfcmVmLnN0YXJ0aW5nLFxuICAgICAgZGVsdGFTb3VyY2UgPSBfcmVmLmRlbHRhU291cmNlO1xuXG4gIHZhciBwcmV2RXZlbnQgPSBzdGFydGluZyA/IGlFdmVudCA6IGludGVyYWN0aW9uLnByZXZFdmVudDtcblxuICBpZiAoZGVsdGFTb3VyY2UgPT09ICdjbGllbnQnKSB7XG4gICAgaUV2ZW50LmR4ID0gaUV2ZW50LmNsaWVudFggLSBwcmV2RXZlbnQuY2xpZW50WDtcbiAgICBpRXZlbnQuZHkgPSBpRXZlbnQuY2xpZW50WSAtIHByZXZFdmVudC5jbGllbnRZO1xuICB9IGVsc2Uge1xuICAgIGlFdmVudC5keCA9IGlFdmVudC5wYWdlWCAtIHByZXZFdmVudC5wYWdlWDtcbiAgICBpRXZlbnQuZHkgPSBpRXZlbnQucGFnZVkgLSBwcmV2RXZlbnQucGFnZVk7XG4gIH1cbn0pO1xuXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMgPSBzaWduYWxzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEludGVyYWN0RXZlbnQ7XG5cbn0se1wiLi9kZWZhdWx0T3B0aW9uc1wiOjE4LFwiLi91dGlscy9TaWduYWxzXCI6MzUsXCIuL3V0aWxzL2V4dGVuZFwiOjQxLFwiLi91dGlscy9nZXRPcmlnaW5YWVwiOjQyfV0sNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBpcyA9IHJlcXVpcmUoJy4vdXRpbHMvaXMnKTtcbnZhciBldmVudHMgPSByZXF1aXJlKCcuL3V0aWxzL2V2ZW50cycpO1xudmFyIGV4dGVuZCA9IHJlcXVpcmUoJy4vdXRpbHMvZXh0ZW5kJyk7XG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4vYWN0aW9ucy9iYXNlJyk7XG52YXIgc2NvcGUgPSByZXF1aXJlKCcuL3Njb3BlJyk7XG52YXIgRXZlbnRhYmxlID0gcmVxdWlyZSgnLi9FdmVudGFibGUnKTtcbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4vZGVmYXVsdE9wdGlvbnMnKTtcbnZhciBzaWduYWxzID0gcmVxdWlyZSgnLi91dGlscy9TaWduYWxzJykubmV3KCk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4vdXRpbHMvZG9tVXRpbHMnKSxcbiAgICBnZXRFbGVtZW50UmVjdCA9IF9yZXF1aXJlLmdldEVsZW1lbnRSZWN0LFxuICAgIG5vZGVDb250YWlucyA9IF9yZXF1aXJlLm5vZGVDb250YWlucyxcbiAgICB0cnlTZWxlY3RvciA9IF9yZXF1aXJlLnRyeVNlbGVjdG9yO1xuXG52YXIgX3JlcXVpcmUyID0gcmVxdWlyZSgnLi91dGlscy93aW5kb3cnKSxcbiAgICBnZXRXaW5kb3cgPSBfcmVxdWlyZTIuZ2V0V2luZG93O1xuXG52YXIgX3JlcXVpcmUzID0gcmVxdWlyZSgnLi91dGlscy9hcnInKSxcbiAgICBpbmRleE9mID0gX3JlcXVpcmUzLmluZGV4T2YsXG4gICAgY29udGFpbnMgPSBfcmVxdWlyZTMuY29udGFpbnM7XG5cbnZhciBfcmVxdWlyZTQgPSByZXF1aXJlKCcuL3V0aWxzL2Jyb3dzZXInKSxcbiAgICB3aGVlbEV2ZW50ID0gX3JlcXVpcmU0LndoZWVsRXZlbnQ7XG5cbi8vIGFsbCBzZXQgaW50ZXJhY3RhYmxlc1xuXG5cbnNjb3BlLmludGVyYWN0YWJsZXMgPSBbXTtcblxuLypcXFxuICogSW50ZXJhY3RhYmxlXG4gWyBwcm9wZXJ0eSBdXG4gKipcbiAqIE9iamVjdCB0eXBlIHJldHVybmVkIGJ5IEBpbnRlcmFjdFxuXFwqL1xuXG52YXIgSW50ZXJhY3RhYmxlID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBJbnRlcmFjdGFibGUodGFyZ2V0LCBvcHRpb25zKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEludGVyYWN0YWJsZSk7XG5cbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIHRoaXMuZXZlbnRzID0gbmV3IEV2ZW50YWJsZSgpO1xuICAgIHRoaXMuX2NvbnRleHQgPSBvcHRpb25zLmNvbnRleHQgfHwgc2NvcGUuZG9jdW1lbnQ7XG4gICAgdGhpcy5fd2luID0gZ2V0V2luZG93KHRyeVNlbGVjdG9yKHRhcmdldCkgPyB0aGlzLl9jb250ZXh0IDogdGFyZ2V0KTtcbiAgICB0aGlzLl9kb2MgPSB0aGlzLl93aW4uZG9jdW1lbnQ7XG5cbiAgICBzaWduYWxzLmZpcmUoJ25ldycsIHtcbiAgICAgIHRhcmdldDogdGFyZ2V0LFxuICAgICAgb3B0aW9uczogb3B0aW9ucyxcbiAgICAgIGludGVyYWN0YWJsZTogdGhpcyxcbiAgICAgIHdpbjogdGhpcy5fd2luXG4gICAgfSk7XG5cbiAgICBzY29wZS5hZGREb2N1bWVudCh0aGlzLl9kb2MsIHRoaXMuX3dpbik7XG5cbiAgICBzY29wZS5pbnRlcmFjdGFibGVzLnB1c2godGhpcyk7XG5cbiAgICB0aGlzLnNldChvcHRpb25zKTtcbiAgfVxuXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuc2V0T25FdmVudHMgPSBmdW5jdGlvbiBzZXRPbkV2ZW50cyhhY3Rpb24sIHBoYXNlcykge1xuICAgIHZhciBvbkFjdGlvbiA9ICdvbicgKyBhY3Rpb247XG5cbiAgICBpZiAoaXMuZnVuY3Rpb24ocGhhc2VzLm9uc3RhcnQpKSB7XG4gICAgICB0aGlzLmV2ZW50c1tvbkFjdGlvbiArICdzdGFydCddID0gcGhhc2VzLm9uc3RhcnQ7XG4gICAgfVxuICAgIGlmIChpcy5mdW5jdGlvbihwaGFzZXMub25tb3ZlKSkge1xuICAgICAgdGhpcy5ldmVudHNbb25BY3Rpb24gKyAnbW92ZSddID0gcGhhc2VzLm9ubW92ZTtcbiAgICB9XG4gICAgaWYgKGlzLmZ1bmN0aW9uKHBoYXNlcy5vbmVuZCkpIHtcbiAgICAgIHRoaXMuZXZlbnRzW29uQWN0aW9uICsgJ2VuZCddID0gcGhhc2VzLm9uZW5kO1xuICAgIH1cbiAgICBpZiAoaXMuZnVuY3Rpb24ocGhhc2VzLm9uaW5lcnRpYXN0YXJ0KSkge1xuICAgICAgdGhpcy5ldmVudHNbb25BY3Rpb24gKyAnaW5lcnRpYXN0YXJ0J10gPSBwaGFzZXMub25pbmVydGlhc3RhcnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zZXRQZXJBY3Rpb24gPSBmdW5jdGlvbiBzZXRQZXJBY3Rpb24oYWN0aW9uLCBvcHRpb25zKSB7XG4gICAgLy8gZm9yIGFsbCB0aGUgZGVmYXVsdCBwZXItYWN0aW9uIG9wdGlvbnNcbiAgICBmb3IgKHZhciBvcHRpb24gaW4gb3B0aW9ucykge1xuICAgICAgLy8gaWYgdGhpcyBvcHRpb24gZXhpc3RzIGZvciB0aGlzIGFjdGlvblxuICAgICAgaWYgKG9wdGlvbiBpbiBkZWZhdWx0c1thY3Rpb25dKSB7XG4gICAgICAgIC8vIGlmIHRoZSBvcHRpb24gaW4gdGhlIG9wdGlvbnMgYXJnIGlzIGFuIG9iamVjdCB2YWx1ZVxuICAgICAgICBpZiAoaXMub2JqZWN0KG9wdGlvbnNbb3B0aW9uXSkpIHtcbiAgICAgICAgICAvLyBkdXBsaWNhdGUgdGhlIG9iamVjdFxuICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0gPSBleHRlbmQodGhpcy5vcHRpb25zW2FjdGlvbl1bb3B0aW9uXSB8fCB7fSwgb3B0aW9uc1tvcHRpb25dKTtcblxuICAgICAgICAgIGlmIChpcy5vYmplY3QoZGVmYXVsdHMucGVyQWN0aW9uW29wdGlvbl0pICYmICdlbmFibGVkJyBpbiBkZWZhdWx0cy5wZXJBY3Rpb25bb3B0aW9uXSkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zW2FjdGlvbl1bb3B0aW9uXS5lbmFibGVkID0gb3B0aW9uc1tvcHRpb25dLmVuYWJsZWQgPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpcy5ib29sKG9wdGlvbnNbb3B0aW9uXSkgJiYgaXMub2JqZWN0KGRlZmF1bHRzLnBlckFjdGlvbltvcHRpb25dKSkge1xuICAgICAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25dW29wdGlvbl0uZW5hYmxlZCA9IG9wdGlvbnNbb3B0aW9uXTtcbiAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zW29wdGlvbl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIG9yIGlmIGl0J3Mgbm90IHVuZGVmaW5lZCwgZG8gYSBwbGFpbiBhc3NpZ25tZW50XG4gICAgICAgICAgdGhpcy5vcHRpb25zW2FjdGlvbl1bb3B0aW9uXSA9IG9wdGlvbnNbb3B0aW9uXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKlxcXG4gICAqIEludGVyYWN0YWJsZS5nZXRSZWN0XG4gICBbIG1ldGhvZCBdXG4gICAqXG4gICAqIFRoZSBkZWZhdWx0IGZ1bmN0aW9uIHRvIGdldCBhbiBJbnRlcmFjdGFibGVzIGJvdW5kaW5nIHJlY3QuIENhbiBiZVxuICAgKiBvdmVycmlkZGVuIHVzaW5nIEBJbnRlcmFjdGFibGUucmVjdENoZWNrZXIuXG4gICAqXG4gICAtIGVsZW1lbnQgKEVsZW1lbnQpICNvcHRpb25hbCBUaGUgZWxlbWVudCB0byBtZWFzdXJlLlxuICAgPSAob2JqZWN0KSBUaGUgb2JqZWN0J3MgYm91bmRpbmcgcmVjdGFuZ2xlLlxuICAgbyB7XG4gICBvICAgICB0b3AgICA6IDAsXG4gICBvICAgICBsZWZ0ICA6IDAsXG4gICBvICAgICBib3R0b206IDAsXG4gICBvICAgICByaWdodCA6IDAsXG4gICBvICAgICB3aWR0aCA6IDAsXG4gICBvICAgICBoZWlnaHQ6IDBcbiAgIG8gfVxuICBcXCovXG5cblxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLmdldFJlY3QgPSBmdW5jdGlvbiBnZXRSZWN0KGVsZW1lbnQpIHtcbiAgICBlbGVtZW50ID0gZWxlbWVudCB8fCB0aGlzLnRhcmdldDtcblxuICAgIGlmIChpcy5zdHJpbmcodGhpcy50YXJnZXQpICYmICFpcy5lbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICBlbGVtZW50ID0gdGhpcy5fY29udGV4dC5xdWVyeVNlbGVjdG9yKHRoaXMudGFyZ2V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0RWxlbWVudFJlY3QoZWxlbWVudCk7XG4gIH07XG5cbiAgLypcXFxuICAgKiBJbnRlcmFjdGFibGUucmVjdENoZWNrZXJcbiAgIFsgbWV0aG9kIF1cbiAgICpcbiAgICogUmV0dXJucyBvciBzZXRzIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgaW50ZXJhY3RhYmxlJ3NcbiAgICogZWxlbWVudCdzIHJlY3RhbmdsZVxuICAgKlxuICAgLSBjaGVja2VyIChmdW5jdGlvbikgI29wdGlvbmFsIEEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyB0aGlzIEludGVyYWN0YWJsZSdzIGJvdW5kaW5nIHJlY3RhbmdsZS4gU2VlIEBJbnRlcmFjdGFibGUuZ2V0UmVjdFxuICAgPSAoZnVuY3Rpb24gfCBvYmplY3QpIFRoZSBjaGVja2VyIGZ1bmN0aW9uIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG4gIFxcKi9cblxuXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUucmVjdENoZWNrZXIgPSBmdW5jdGlvbiByZWN0Q2hlY2tlcihjaGVja2VyKSB7XG4gICAgaWYgKGlzLmZ1bmN0aW9uKGNoZWNrZXIpKSB7XG4gICAgICB0aGlzLmdldFJlY3QgPSBjaGVja2VyO1xuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBpZiAoY2hlY2tlciA9PT0gbnVsbCkge1xuICAgICAgZGVsZXRlIHRoaXMub3B0aW9ucy5nZXRSZWN0O1xuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5nZXRSZWN0O1xuICB9O1xuXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuX2JhY2tDb21wYXRPcHRpb24gPSBmdW5jdGlvbiBfYmFja0NvbXBhdE9wdGlvbihvcHRpb25OYW1lLCBuZXdWYWx1ZSkge1xuICAgIGlmICh0cnlTZWxlY3RvcihuZXdWYWx1ZSkgfHwgaXMub2JqZWN0KG5ld1ZhbHVlKSkge1xuICAgICAgdGhpcy5vcHRpb25zW29wdGlvbk5hbWVdID0gbmV3VmFsdWU7XG5cbiAgICAgIGZvciAodmFyIF9pdGVyYXRvciA9IGFjdGlvbnMubmFtZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICAgIHZhciBfcmVmO1xuXG4gICAgICAgIGlmIChfaXNBcnJheSkge1xuICAgICAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcbiAgICAgICAgICBfcmVmID0gX2l0ZXJhdG9yW19pKytdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XG4gICAgICAgICAgX3JlZiA9IF9pLnZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGFjdGlvbiA9IF9yZWY7XG5cbiAgICAgICAgdGhpcy5vcHRpb25zW2FjdGlvbl1bb3B0aW9uTmFtZV0gPSBuZXdWYWx1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMub3B0aW9uc1tvcHRpb25OYW1lXTtcbiAgfTtcblxuICAvKlxcXG4gICAqIEludGVyYWN0YWJsZS5vcmlnaW5cbiAgIFsgbWV0aG9kIF1cbiAgICpcbiAgICogR2V0cyBvciBzZXRzIHRoZSBvcmlnaW4gb2YgdGhlIEludGVyYWN0YWJsZSdzIGVsZW1lbnQuICBUaGUgeCBhbmQgeVxuICAgKiBvZiB0aGUgb3JpZ2luIHdpbGwgYmUgc3VidHJhY3RlZCBmcm9tIGFjdGlvbiBldmVudCBjb29yZGluYXRlcy5cbiAgICpcbiAgIC0gb3JpZ2luIChvYmplY3QgfCBzdHJpbmcpICNvcHRpb25hbCBBbiBvYmplY3QgZWcuIHsgeDogMCwgeTogMCB9IG9yIHN0cmluZyAncGFyZW50JywgJ3NlbGYnIG9yIGFueSBDU1Mgc2VsZWN0b3JcbiAgICogT1JcbiAgIC0gb3JpZ2luIChFbGVtZW50KSAjb3B0aW9uYWwgQW4gSFRNTCBvciBTVkcgRWxlbWVudCB3aG9zZSByZWN0IHdpbGwgYmUgdXNlZFxuICAgKipcbiAgID0gKG9iamVjdCkgVGhlIGN1cnJlbnQgb3JpZ2luIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG4gIFxcKi9cblxuXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUub3JpZ2luID0gZnVuY3Rpb24gb3JpZ2luKG5ld1ZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMuX2JhY2tDb21wYXRPcHRpb24oJ29yaWdpbicsIG5ld1ZhbHVlKTtcbiAgfTtcblxuICAvKlxcXG4gICAqIEludGVyYWN0YWJsZS5kZWx0YVNvdXJjZVxuICAgWyBtZXRob2QgXVxuICAgKlxuICAgKiBSZXR1cm5zIG9yIHNldHMgdGhlIG1vdXNlIGNvb3JkaW5hdGUgdHlwZXMgdXNlZCB0byBjYWxjdWxhdGUgdGhlXG4gICAqIG1vdmVtZW50IG9mIHRoZSBwb2ludGVyLlxuICAgKlxuICAgLSBuZXdWYWx1ZSAoc3RyaW5nKSAjb3B0aW9uYWwgVXNlICdjbGllbnQnIGlmIHlvdSB3aWxsIGJlIHNjcm9sbGluZyB3aGlsZSBpbnRlcmFjdGluZzsgVXNlICdwYWdlJyBpZiB5b3Ugd2FudCBhdXRvU2Nyb2xsIHRvIHdvcmtcbiAgID0gKHN0cmluZyB8IG9iamVjdCkgVGhlIGN1cnJlbnQgZGVsdGFTb3VyY2Ugb3IgdGhpcyBJbnRlcmFjdGFibGVcbiAgXFwqL1xuXG5cbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5kZWx0YVNvdXJjZSA9IGZ1bmN0aW9uIGRlbHRhU291cmNlKG5ld1ZhbHVlKSB7XG4gICAgaWYgKG5ld1ZhbHVlID09PSAncGFnZScgfHwgbmV3VmFsdWUgPT09ICdjbGllbnQnKSB7XG4gICAgICB0aGlzLm9wdGlvbnMuZGVsdGFTb3VyY2UgPSBuZXdWYWx1ZTtcblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5kZWx0YVNvdXJjZTtcbiAgfTtcblxuICAvKlxcXG4gICAqIEludGVyYWN0YWJsZS5jb250ZXh0XG4gICBbIG1ldGhvZCBdXG4gICAqXG4gICAqIEdldHMgdGhlIHNlbGVjdG9yIGNvbnRleHQgTm9kZSBvZiB0aGUgSW50ZXJhY3RhYmxlLiBUaGUgZGVmYXVsdCBpcyBgd2luZG93LmRvY3VtZW50YC5cbiAgICpcbiAgID0gKE5vZGUpIFRoZSBjb250ZXh0IE5vZGUgb2YgdGhpcyBJbnRlcmFjdGFibGVcbiAgICoqXG4gIFxcKi9cblxuXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuY29udGV4dCA9IGZ1bmN0aW9uIGNvbnRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbnRleHQ7XG4gIH07XG5cbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5pbkNvbnRleHQgPSBmdW5jdGlvbiBpbkNvbnRleHQoZWxlbWVudCkge1xuICAgIHJldHVybiB0aGlzLl9jb250ZXh0ID09PSBlbGVtZW50Lm93bmVyRG9jdW1lbnQgfHwgbm9kZUNvbnRhaW5zKHRoaXMuX2NvbnRleHQsIGVsZW1lbnQpO1xuICB9O1xuXG4gIC8qXFxcbiAgICogSW50ZXJhY3RhYmxlLmZpcmVcbiAgIFsgbWV0aG9kIF1cbiAgICpcbiAgICogQ2FsbHMgbGlzdGVuZXJzIGZvciB0aGUgZ2l2ZW4gSW50ZXJhY3RFdmVudCB0eXBlIGJvdW5kIGdsb2JhbGx5XG4gICAqIGFuZCBkaXJlY3RseSB0byB0aGlzIEludGVyYWN0YWJsZVxuICAgKlxuICAgLSBpRXZlbnQgKEludGVyYWN0RXZlbnQpIFRoZSBJbnRlcmFjdEV2ZW50IG9iamVjdCB0byBiZSBmaXJlZCBvbiB0aGlzIEludGVyYWN0YWJsZVxuICAgPSAoSW50ZXJhY3RhYmxlKSB0aGlzIEludGVyYWN0YWJsZVxuICBcXCovXG5cblxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLmZpcmUgPSBmdW5jdGlvbiBmaXJlKGlFdmVudCkge1xuICAgIHRoaXMuZXZlbnRzLmZpcmUoaUV2ZW50KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEludGVyYWN0YWJsZS5wcm90b3R5cGUuX29uT2ZmTXVsdGlwbGUgPSBmdW5jdGlvbiBfb25PZmZNdWx0aXBsZShtZXRob2QsIGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICBpZiAoaXMuc3RyaW5nKGV2ZW50VHlwZSkgJiYgZXZlbnRUeXBlLnNlYXJjaCgnICcpICE9PSAtMSkge1xuICAgICAgZXZlbnRUeXBlID0gZXZlbnRUeXBlLnRyaW0oKS5zcGxpdCgvICsvKTtcbiAgICB9XG5cbiAgICBpZiAoaXMuYXJyYXkoZXZlbnRUeXBlKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldmVudFR5cGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpc1ttZXRob2RdKGV2ZW50VHlwZVtpXSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoaXMub2JqZWN0KGV2ZW50VHlwZSkpIHtcbiAgICAgIGZvciAodmFyIHByb3AgaW4gZXZlbnRUeXBlKSB7XG4gICAgICAgIHRoaXNbbWV0aG9kXShwcm9wLCBldmVudFR5cGVbcHJvcF0sIGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9O1xuXG4gIC8qXFxcbiAgICogSW50ZXJhY3RhYmxlLm9uXG4gICBbIG1ldGhvZCBdXG4gICAqXG4gICAqIEJpbmRzIGEgbGlzdGVuZXIgZm9yIGFuIEludGVyYWN0RXZlbnQsIHBvaW50ZXJFdmVudCBvciBET00gZXZlbnQuXG4gICAqXG4gICAtIGV2ZW50VHlwZSAgKHN0cmluZyB8IGFycmF5IHwgb2JqZWN0KSBUaGUgdHlwZXMgb2YgZXZlbnRzIHRvIGxpc3RlbiBmb3JcbiAgIC0gbGlzdGVuZXIgICAoZnVuY3Rpb24pIFRoZSBmdW5jdGlvbiBldmVudCAocylcbiAgIC0gb3B0aW9ucyAgICAob2JqZWN0IHwgYm9vbGVhbikgI29wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IG9yIHVzZUNhcHR1cmUgZmxhZyBmb3IgYWRkRXZlbnRMaXN0ZW5lclxuICAgPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxuICBcXCovXG5cblxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gb24oZXZlbnRUeXBlLCBsaXN0ZW5lciwgb3B0aW9ucykge1xuICAgIGlmICh0aGlzLl9vbk9mZk11bHRpcGxlKCdvbicsIGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBpZiAoZXZlbnRUeXBlID09PSAnd2hlZWwnKSB7XG4gICAgICBldmVudFR5cGUgPSB3aGVlbEV2ZW50O1xuICAgIH1cblxuICAgIGlmIChjb250YWlucyhJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgZXZlbnRUeXBlKSkge1xuICAgICAgdGhpcy5ldmVudHMub24oZXZlbnRUeXBlLCBsaXN0ZW5lcik7XG4gICAgfVxuICAgIC8vIGRlbGVnYXRlZCBldmVudCBmb3Igc2VsZWN0b3JcbiAgICBlbHNlIGlmIChpcy5zdHJpbmcodGhpcy50YXJnZXQpKSB7XG4gICAgICAgIGV2ZW50cy5hZGREZWxlZ2F0ZSh0aGlzLnRhcmdldCwgdGhpcy5fY29udGV4dCwgZXZlbnRUeXBlLCBsaXN0ZW5lciwgb3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBldmVudHMuYWRkKHRoaXMudGFyZ2V0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcbiAgICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qXFxcbiAgICogSW50ZXJhY3RhYmxlLm9mZlxuICAgWyBtZXRob2QgXVxuICAgKlxuICAgKiBSZW1vdmVzIGFuIEludGVyYWN0RXZlbnQsIHBvaW50ZXJFdmVudCBvciBET00gZXZlbnQgbGlzdGVuZXJcbiAgICpcbiAgIC0gZXZlbnRUeXBlICAoc3RyaW5nIHwgYXJyYXkgfCBvYmplY3QpIFRoZSB0eXBlcyBvZiBldmVudHMgdGhhdCB3ZXJlIGxpc3RlbmVkIGZvclxuICAgLSBsaXN0ZW5lciAgIChmdW5jdGlvbikgVGhlIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIGJlIHJlbW92ZWRcbiAgIC0gb3B0aW9ucyAgICAob2JqZWN0IHwgYm9vbGVhbikgI29wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IG9yIHVzZUNhcHR1cmUgZmxhZyBmb3IgcmVtb3ZlRXZlbnRMaXN0ZW5lclxuICAgPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxuICBcXCovXG5cblxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIG9mZihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgaWYgKHRoaXMuX29uT2ZmTXVsdGlwbGUoJ29mZicsIGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBpZiAoZXZlbnRUeXBlID09PSAnd2hlZWwnKSB7XG4gICAgICBldmVudFR5cGUgPSB3aGVlbEV2ZW50O1xuICAgIH1cblxuICAgIC8vIGlmIGl0IGlzIGFuIGFjdGlvbiBldmVudCB0eXBlXG4gICAgaWYgKGNvbnRhaW5zKEludGVyYWN0YWJsZS5ldmVudFR5cGVzLCBldmVudFR5cGUpKSB7XG4gICAgICB0aGlzLmV2ZW50cy5vZmYoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XG4gICAgfVxuICAgIC8vIGRlbGVnYXRlZCBldmVudFxuICAgIGVsc2UgaWYgKGlzLnN0cmluZyh0aGlzLnRhcmdldCkpIHtcbiAgICAgICAgZXZlbnRzLnJlbW92ZURlbGVnYXRlKHRoaXMudGFyZ2V0LCB0aGlzLl9jb250ZXh0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIC8vIHJlbW92ZSBsaXN0ZW5lciBmcm9tIHRoaXMgSW50ZXJhdGFibGUncyBlbGVtZW50XG4gICAgICBlbHNlIHtcbiAgICAgICAgICBldmVudHMucmVtb3ZlKHRoaXMudGFyZ2V0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLypcXFxuICAgKiBJbnRlcmFjdGFibGUuc2V0XG4gICBbIG1ldGhvZCBdXG4gICAqXG4gICAqIFJlc2V0IHRoZSBvcHRpb25zIG9mIHRoaXMgSW50ZXJhY3RhYmxlXG4gICAtIG9wdGlvbnMgKG9iamVjdCkgVGhlIG5ldyBzZXR0aW5ncyB0byBhcHBseVxuICAgPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxuICBcXCovXG5cblxuICBJbnRlcmFjdGFibGUucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIHNldChvcHRpb25zKSB7XG4gICAgaWYgKCFpcy5vYmplY3Qob3B0aW9ucykpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMgPSBleHRlbmQoe30sIGRlZmF1bHRzLmJhc2UpO1xuXG4gICAgdmFyIHBlckFjdGlvbnMgPSBleHRlbmQoe30sIGRlZmF1bHRzLnBlckFjdGlvbik7XG5cbiAgICBmb3IgKHZhciBhY3Rpb25OYW1lIGluIGFjdGlvbnMubWV0aG9kRGljdCkge1xuICAgICAgdmFyIG1ldGhvZE5hbWUgPSBhY3Rpb25zLm1ldGhvZERpY3RbYWN0aW9uTmFtZV07XG5cbiAgICAgIHRoaXMub3B0aW9uc1thY3Rpb25OYW1lXSA9IGV4dGVuZCh7fSwgZGVmYXVsdHNbYWN0aW9uTmFtZV0pO1xuXG4gICAgICB0aGlzLnNldFBlckFjdGlvbihhY3Rpb25OYW1lLCBwZXJBY3Rpb25zKTtcblxuICAgICAgdGhpc1ttZXRob2ROYW1lXShvcHRpb25zW2FjdGlvbk5hbWVdKTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBfaXRlcmF0b3IyID0gSW50ZXJhY3RhYmxlLnNldHRpbmdzTWV0aG9kcywgX2lzQXJyYXkyID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IyKSwgX2kyID0gMCwgX2l0ZXJhdG9yMiA9IF9pc0FycmF5MiA/IF9pdGVyYXRvcjIgOiBfaXRlcmF0b3IyW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICB2YXIgX3JlZjI7XG5cbiAgICAgIGlmIChfaXNBcnJheTIpIHtcbiAgICAgICAgaWYgKF9pMiA+PSBfaXRlcmF0b3IyLmxlbmd0aCkgYnJlYWs7XG4gICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yMltfaTIrK107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaTIgPSBfaXRlcmF0b3IyLm5leHQoKTtcbiAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcbiAgICAgICAgX3JlZjIgPSBfaTIudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBzZXR0aW5nID0gX3JlZjI7XG5cbiAgICAgIHRoaXMub3B0aW9uc1tzZXR0aW5nXSA9IGRlZmF1bHRzLmJhc2Vbc2V0dGluZ107XG5cbiAgICAgIGlmIChzZXR0aW5nIGluIG9wdGlvbnMpIHtcbiAgICAgICAgdGhpc1tzZXR0aW5nXShvcHRpb25zW3NldHRpbmddKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzaWduYWxzLmZpcmUoJ3NldCcsIHtcbiAgICAgIG9wdGlvbnM6IG9wdGlvbnMsXG4gICAgICBpbnRlcmFjdGFibGU6IHRoaXNcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qXFxcbiAgICogSW50ZXJhY3RhYmxlLnVuc2V0XG4gICBbIG1ldGhvZCBdXG4gICAqXG4gICAqIFJlbW92ZSB0aGlzIGludGVyYWN0YWJsZSBmcm9tIHRoZSBsaXN0IG9mIGludGVyYWN0YWJsZXMgYW5kIHJlbW92ZVxuICAgKiBpdCdzIGFjdGlvbiBjYXBhYmlsaXRpZXMgYW5kIGV2ZW50IGxpc3RlbmVyc1xuICAgKlxuICAgPSAob2JqZWN0KSBAaW50ZXJhY3RcbiAgXFwqL1xuXG5cbiAgSW50ZXJhY3RhYmxlLnByb3RvdHlwZS51bnNldCA9IGZ1bmN0aW9uIHVuc2V0KCkge1xuICAgIGV2ZW50cy5yZW1vdmUodGhpcy50YXJnZXQsICdhbGwnKTtcblxuICAgIGlmIChpcy5zdHJpbmcodGhpcy50YXJnZXQpKSB7XG4gICAgICAvLyByZW1vdmUgZGVsZWdhdGVkIGV2ZW50c1xuICAgICAgZm9yICh2YXIgdHlwZSBpbiBldmVudHMuZGVsZWdhdGVkRXZlbnRzKSB7XG4gICAgICAgIHZhciBkZWxlZ2F0ZWQgPSBldmVudHMuZGVsZWdhdGVkRXZlbnRzW3R5cGVdO1xuXG4gICAgICAgIGlmIChkZWxlZ2F0ZWQuc2VsZWN0b3JzWzBdID09PSB0aGlzLnRhcmdldCAmJiBkZWxlZ2F0ZWQuY29udGV4dHNbMF0gPT09IHRoaXMuX2NvbnRleHQpIHtcblxuICAgICAgICAgIGRlbGVnYXRlZC5zZWxlY3RvcnMuc3BsaWNlKDAsIDEpO1xuICAgICAgICAgIGRlbGVnYXRlZC5jb250ZXh0cy5zcGxpY2UoMCwgMSk7XG4gICAgICAgICAgZGVsZWdhdGVkLmxpc3RlbmVycy5zcGxpY2UoMCwgMSk7XG5cbiAgICAgICAgICAvLyByZW1vdmUgdGhlIGFycmF5cyBpZiB0aGV5IGFyZSBlbXB0eVxuICAgICAgICAgIGlmICghZGVsZWdhdGVkLnNlbGVjdG9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRlbGVnYXRlZFt0eXBlXSA9IG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXZlbnRzLnJlbW92ZSh0aGlzLl9jb250ZXh0LCB0eXBlLCBldmVudHMuZGVsZWdhdGVMaXN0ZW5lcik7XG4gICAgICAgIGV2ZW50cy5yZW1vdmUodGhpcy5fY29udGV4dCwgdHlwZSwgZXZlbnRzLmRlbGVnYXRlVXNlQ2FwdHVyZSwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2ZW50cy5yZW1vdmUodGhpcywgJ2FsbCcpO1xuICAgIH1cblxuICAgIHNpZ25hbHMuZmlyZSgndW5zZXQnLCB7IGludGVyYWN0YWJsZTogdGhpcyB9KTtcblxuICAgIHNjb3BlLmludGVyYWN0YWJsZXMuc3BsaWNlKGluZGV4T2Yoc2NvcGUuaW50ZXJhY3RhYmxlcywgdGhpcyksIDEpO1xuXG4gICAgLy8gU3RvcCByZWxhdGVkIGludGVyYWN0aW9ucyB3aGVuIGFuIEludGVyYWN0YWJsZSBpcyB1bnNldFxuICAgIGZvciAodmFyIF9pdGVyYXRvcjMgPSBzY29wZS5pbnRlcmFjdGlvbnMgfHwgW10sIF9pc0FycmF5MyA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yMyksIF9pMyA9IDAsIF9pdGVyYXRvcjMgPSBfaXNBcnJheTMgPyBfaXRlcmF0b3IzIDogX2l0ZXJhdG9yM1tTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xuICAgICAgdmFyIF9yZWYzO1xuXG4gICAgICBpZiAoX2lzQXJyYXkzKSB7XG4gICAgICAgIGlmIChfaTMgPj0gX2l0ZXJhdG9yMy5sZW5ndGgpIGJyZWFrO1xuICAgICAgICBfcmVmMyA9IF9pdGVyYXRvcjNbX2kzKytdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX2kzID0gX2l0ZXJhdG9yMy5uZXh0KCk7XG4gICAgICAgIGlmIChfaTMuZG9uZSkgYnJlYWs7XG4gICAgICAgIF9yZWYzID0gX2kzLnZhbHVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMztcblxuICAgICAgaWYgKGludGVyYWN0aW9uLnRhcmdldCA9PT0gdGhpcyAmJiBpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpKSB7XG4gICAgICAgIGludGVyYWN0aW9uLnN0b3AoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NvcGUuaW50ZXJhY3Q7XG4gIH07XG5cbiAgcmV0dXJuIEludGVyYWN0YWJsZTtcbn0oKTtcblxuc2NvcGUuaW50ZXJhY3RhYmxlcy5pbmRleE9mRWxlbWVudCA9IGZ1bmN0aW9uIGluZGV4T2ZFbGVtZW50KHRhcmdldCwgY29udGV4dCkge1xuICBjb250ZXh0ID0gY29udGV4dCB8fCBzY29wZS5kb2N1bWVudDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaW50ZXJhY3RhYmxlID0gdGhpc1tpXTtcblxuICAgIGlmIChpbnRlcmFjdGFibGUudGFyZ2V0ID09PSB0YXJnZXQgJiYgaW50ZXJhY3RhYmxlLl9jb250ZXh0ID09PSBjb250ZXh0KSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufTtcblxuc2NvcGUuaW50ZXJhY3RhYmxlcy5nZXQgPSBmdW5jdGlvbiBpbnRlcmFjdGFibGVHZXQoZWxlbWVudCwgb3B0aW9ucywgZG9udENoZWNrSW5Db250ZXh0KSB7XG4gIHZhciByZXQgPSB0aGlzW3RoaXMuaW5kZXhPZkVsZW1lbnQoZWxlbWVudCwgb3B0aW9ucyAmJiBvcHRpb25zLmNvbnRleHQpXTtcblxuICByZXR1cm4gcmV0ICYmIChpcy5zdHJpbmcoZWxlbWVudCkgfHwgZG9udENoZWNrSW5Db250ZXh0IHx8IHJldC5pbkNvbnRleHQoZWxlbWVudCkpID8gcmV0IDogbnVsbDtcbn07XG5cbnNjb3BlLmludGVyYWN0YWJsZXMuZm9yRWFjaFNlbGVjdG9yID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBlbGVtZW50KSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpbnRlcmFjdGFibGUgPSB0aGlzW2ldO1xuXG4gICAgLy8gc2tpcCBub24gQ1NTIHNlbGVjdG9yIHRhcmdldHMgYW5kIG91dCBvZiBjb250ZXh0IGVsZW1lbnRzXG4gICAgaWYgKCFpcy5zdHJpbmcoaW50ZXJhY3RhYmxlLnRhcmdldCkgfHwgZWxlbWVudCAmJiAhaW50ZXJhY3RhYmxlLmluQ29udGV4dChlbGVtZW50KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIHJldCA9IGNhbGxiYWNrKGludGVyYWN0YWJsZSwgaW50ZXJhY3RhYmxlLnRhcmdldCwgaW50ZXJhY3RhYmxlLl9jb250ZXh0LCBpLCB0aGlzKTtcblxuICAgIGlmIChyZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG4gIH1cbn07XG5cbi8vIGFsbCBpbnRlcmFjdC5qcyBldmVudFR5cGVzXG5JbnRlcmFjdGFibGUuZXZlbnRUeXBlcyA9IHNjb3BlLmV2ZW50VHlwZXMgPSBbXTtcblxuSW50ZXJhY3RhYmxlLnNpZ25hbHMgPSBzaWduYWxzO1xuXG5JbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzID0gWydkZWx0YVNvdXJjZScsICdvcmlnaW4nLCAncHJldmVudERlZmF1bHQnLCAncmVjdENoZWNrZXInXTtcblxubW9kdWxlLmV4cG9ydHMgPSBJbnRlcmFjdGFibGU7XG5cbn0se1wiLi9FdmVudGFibGVcIjoyLFwiLi9hY3Rpb25zL2Jhc2VcIjo2LFwiLi9kZWZhdWx0T3B0aW9uc1wiOjE4LFwiLi9zY29wZVwiOjM0LFwiLi91dGlscy9TaWduYWxzXCI6MzUsXCIuL3V0aWxzL2FyclwiOjM2LFwiLi91dGlscy9icm93c2VyXCI6MzcsXCIuL3V0aWxzL2RvbVV0aWxzXCI6MzksXCIuL3V0aWxzL2V2ZW50c1wiOjQwLFwiLi91dGlscy9leHRlbmRcIjo0MSxcIi4vdXRpbHMvaXNcIjo0NixcIi4vdXRpbHMvd2luZG93XCI6NTJ9XSw1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIHNjb3BlID0gcmVxdWlyZSgnLi9zY29wZScpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGV2ZW50cyA9IHJlcXVpcmUoJy4vdXRpbHMvZXZlbnRzJyk7XG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4vdXRpbHMvYnJvd3NlcicpO1xudmFyIGRvbU9iamVjdHMgPSByZXF1aXJlKCcuL3V0aWxzL2RvbU9iamVjdHMnKTtcbnZhciBmaW5kZXIgPSByZXF1aXJlKCcuL3V0aWxzL2ludGVyYWN0aW9uRmluZGVyJyk7XG52YXIgc2lnbmFscyA9IHJlcXVpcmUoJy4vdXRpbHMvU2lnbmFscycpLm5ldygpO1xuXG52YXIgbGlzdGVuZXJzID0ge307XG52YXIgbWV0aG9kTmFtZXMgPSBbJ3BvaW50ZXJEb3duJywgJ3BvaW50ZXJNb3ZlJywgJ3BvaW50ZXJVcCcsICd1cGRhdGVQb2ludGVyJywgJ3JlbW92ZVBvaW50ZXInXTtcblxuLy8gZm9yIGlnbm9yaW5nIGJyb3dzZXIncyBzaW11bGF0ZWQgbW91c2UgZXZlbnRzXG52YXIgcHJldlRvdWNoVGltZSA9IDA7XG5cbi8vIGFsbCBhY3RpdmUgYW5kIGlkbGUgaW50ZXJhY3Rpb25zXG5zY29wZS5pbnRlcmFjdGlvbnMgPSBbXTtcblxudmFyIEludGVyYWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBJbnRlcmFjdGlvbihfcmVmKSB7XG4gICAgdmFyIHBvaW50ZXJUeXBlID0gX3JlZi5wb2ludGVyVHlwZTtcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBJbnRlcmFjdGlvbik7XG5cbiAgICB0aGlzLnRhcmdldCA9IG51bGw7IC8vIGN1cnJlbnQgaW50ZXJhY3RhYmxlIGJlaW5nIGludGVyYWN0ZWQgd2l0aFxuICAgIHRoaXMuZWxlbWVudCA9IG51bGw7IC8vIHRoZSB0YXJnZXQgZWxlbWVudCBvZiB0aGUgaW50ZXJhY3RhYmxlXG5cbiAgICB0aGlzLnByZXBhcmVkID0geyAvLyBhY3Rpb24gdGhhdCdzIHJlYWR5IHRvIGJlIGZpcmVkIG9uIG5leHQgbW92ZSBldmVudFxuICAgICAgbmFtZTogbnVsbCxcbiAgICAgIGF4aXM6IG51bGwsXG4gICAgICBlZGdlczogbnVsbFxuICAgIH07XG5cbiAgICAvLyBrZWVwIHRyYWNrIG9mIGFkZGVkIHBvaW50ZXJzXG4gICAgdGhpcy5wb2ludGVycyA9IFtdO1xuICAgIHRoaXMucG9pbnRlcklkcyA9IFtdO1xuICAgIHRoaXMuZG93blRhcmdldHMgPSBbXTtcbiAgICB0aGlzLmRvd25UaW1lcyA9IFtdO1xuXG4gICAgLy8gUHJldmlvdXMgbmF0aXZlIHBvaW50ZXIgbW92ZSBldmVudCBjb29yZGluYXRlc1xuICAgIHRoaXMucHJldkNvb3JkcyA9IHtcbiAgICAgIHBhZ2U6IHsgeDogMCwgeTogMCB9LFxuICAgICAgY2xpZW50OiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgIHRpbWVTdGFtcDogMFxuICAgIH07XG4gICAgLy8gY3VycmVudCBuYXRpdmUgcG9pbnRlciBtb3ZlIGV2ZW50IGNvb3JkaW5hdGVzXG4gICAgdGhpcy5jdXJDb29yZHMgPSB7XG4gICAgICBwYWdlOiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgIGNsaWVudDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICB0aW1lU3RhbXA6IDBcbiAgICB9O1xuXG4gICAgLy8gU3RhcnRpbmcgSW50ZXJhY3RFdmVudCBwb2ludGVyIGNvb3JkaW5hdGVzXG4gICAgdGhpcy5zdGFydENvb3JkcyA9IHtcbiAgICAgIHBhZ2U6IHsgeDogMCwgeTogMCB9LFxuICAgICAgY2xpZW50OiB7IHg6IDAsIHk6IDAgfSxcbiAgICAgIHRpbWVTdGFtcDogMFxuICAgIH07XG5cbiAgICAvLyBDaGFuZ2UgaW4gY29vcmRpbmF0ZXMgYW5kIHRpbWUgb2YgdGhlIHBvaW50ZXJcbiAgICB0aGlzLnBvaW50ZXJEZWx0YSA9IHtcbiAgICAgIHBhZ2U6IHsgeDogMCwgeTogMCwgdng6IDAsIHZ5OiAwLCBzcGVlZDogMCB9LFxuICAgICAgY2xpZW50OiB7IHg6IDAsIHk6IDAsIHZ4OiAwLCB2eTogMCwgc3BlZWQ6IDAgfSxcbiAgICAgIHRpbWVTdGFtcDogMFxuICAgIH07XG5cbiAgICB0aGlzLmRvd25FdmVudCA9IG51bGw7IC8vIHBvaW50ZXJkb3duL21vdXNlZG93bi90b3VjaHN0YXJ0IGV2ZW50XG4gICAgdGhpcy5kb3duUG9pbnRlciA9IHt9O1xuXG4gICAgdGhpcy5fZXZlbnRUYXJnZXQgPSBudWxsO1xuICAgIHRoaXMuX2N1ckV2ZW50VGFyZ2V0ID0gbnVsbDtcblxuICAgIHRoaXMucHJldkV2ZW50ID0gbnVsbDsgLy8gcHJldmlvdXMgYWN0aW9uIGV2ZW50XG5cbiAgICB0aGlzLnBvaW50ZXJJc0Rvd24gPSBmYWxzZTtcbiAgICB0aGlzLnBvaW50ZXJXYXNNb3ZlZCA9IGZhbHNlO1xuICAgIHRoaXMuX2ludGVyYWN0aW5nID0gZmFsc2U7XG5cbiAgICB0aGlzLnBvaW50ZXJUeXBlID0gcG9pbnRlclR5cGU7XG5cbiAgICBzaWduYWxzLmZpcmUoJ25ldycsIHRoaXMpO1xuXG4gICAgc2NvcGUuaW50ZXJhY3Rpb25zLnB1c2godGhpcyk7XG4gIH1cblxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUucG9pbnRlckRvd24gPSBmdW5jdGlvbiBwb2ludGVyRG93bihwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQpIHtcbiAgICB2YXIgcG9pbnRlckluZGV4ID0gdGhpcy51cGRhdGVQb2ludGVyKHBvaW50ZXIsIGV2ZW50LCB0cnVlKTtcblxuICAgIHNpZ25hbHMuZmlyZSgnZG93bicsIHtcbiAgICAgIHBvaW50ZXI6IHBvaW50ZXIsXG4gICAgICBldmVudDogZXZlbnQsXG4gICAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXG4gICAgICBwb2ludGVySW5kZXg6IHBvaW50ZXJJbmRleCxcbiAgICAgIGludGVyYWN0aW9uOiB0aGlzXG4gICAgfSk7XG4gIH07XG5cbiAgLypcXFxuICAgKiBJbnRlcmFjdGlvbi5zdGFydFxuICAgWyBtZXRob2QgXVxuICAgKlxuICAgKiBTdGFydCBhbiBhY3Rpb24gd2l0aCB0aGUgZ2l2ZW4gSW50ZXJhY3RhYmxlIGFuZCBFbGVtZW50IGFzIHRhcnRnZXRzLiBUaGVcbiAgICogYWN0aW9uIG11c3QgYmUgZW5hYmxlZCBmb3IgdGhlIHRhcmdldCBJbnRlcmFjdGFibGUgYW5kIGFuIGFwcHJvcHJpYXRlIG51bWJlclxuICAgKiBvZiBwb2ludGVycyBtdXN0IGJlIGhlbGQgZG93biAtIDEgZm9yIGRyYWcvcmVzaXplLCAyIGZvciBnZXN0dXJlLlxuICAgKlxuICAgKiBVc2UgaXQgd2l0aCBgaW50ZXJhY3RhYmxlLjxhY3Rpb24+YWJsZSh7IG1hbnVhbFN0YXJ0OiBmYWxzZSB9KWAgdG8gYWx3YXlzXG4gICAqIFtzdGFydCBhY3Rpb25zIG1hbnVhbGx5XShodHRwczovL2dpdGh1Yi5jb20vdGF5ZS9pbnRlcmFjdC5qcy9pc3N1ZXMvMTE0KVxuICAgKlxuICAgLSBhY3Rpb24gIChvYmplY3QpICBUaGUgYWN0aW9uIHRvIGJlIHBlcmZvcm1lZCAtIGRyYWcsIHJlc2l6ZSwgZXRjLlxuICAgLSB0YXJnZXQgIChJbnRlcmFjdGFibGUpIFRoZSBJbnRlcmFjdGFibGUgdG8gdGFyZ2V0XG4gICAtIGVsZW1lbnQgKEVsZW1lbnQpIFRoZSBET00gRWxlbWVudCB0byB0YXJnZXRcbiAgID0gKG9iamVjdCkgaW50ZXJhY3RcbiAgICoqXG4gICB8IGludGVyYWN0KHRhcmdldClcbiAgIHwgICAuZHJhZ2dhYmxlKHtcbiAgIHwgICAgIC8vIGRpc2FibGUgdGhlIGRlZmF1bHQgZHJhZyBzdGFydCBieSBkb3duLT5tb3ZlXG4gICB8ICAgICBtYW51YWxTdGFydDogdHJ1ZVxuICAgfCAgIH0pXG4gICB8ICAgLy8gc3RhcnQgZHJhZ2dpbmcgYWZ0ZXIgdGhlIHVzZXIgaG9sZHMgdGhlIHBvaW50ZXIgZG93blxuICAgfCAgIC5vbignaG9sZCcsIGZ1bmN0aW9uIChldmVudCkge1xuICAgfCAgICAgdmFyIGludGVyYWN0aW9uID0gZXZlbnQuaW50ZXJhY3Rpb247XG4gICB8XG4gICB8ICAgICBpZiAoIWludGVyYWN0aW9uLmludGVyYWN0aW5nKCkpIHtcbiAgIHwgICAgICAgaW50ZXJhY3Rpb24uc3RhcnQoeyBuYW1lOiAnZHJhZycgfSxcbiAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuaW50ZXJhY3RhYmxlLFxuICAgfCAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5jdXJyZW50VGFyZ2V0KTtcbiAgIHwgICAgIH1cbiAgIHwgfSk7XG4gICBcXCovXG5cblxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiBzdGFydChhY3Rpb24sIHRhcmdldCwgZWxlbWVudCkge1xuICAgIGlmICh0aGlzLmludGVyYWN0aW5nKCkgfHwgIXRoaXMucG9pbnRlcklzRG93biB8fCB0aGlzLnBvaW50ZXJJZHMubGVuZ3RoIDwgKGFjdGlvbi5uYW1lID09PSAnZ2VzdHVyZScgPyAyIDogMSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBpZiB0aGlzIGludGVyYWN0aW9uIGhhZCBiZWVuIHJlbW92ZWQgYWZ0ZXIgc3RvcHBpbmdcbiAgICAvLyBhZGQgaXQgYmFja1xuICAgIGlmICh1dGlscy5pbmRleE9mKHNjb3BlLmludGVyYWN0aW9ucywgdGhpcykgPT09IC0xKSB7XG4gICAgICBzY29wZS5pbnRlcmFjdGlvbnMucHVzaCh0aGlzKTtcbiAgICB9XG5cbiAgICB1dGlscy5jb3B5QWN0aW9uKHRoaXMucHJlcGFyZWQsIGFjdGlvbik7XG4gICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIHNpZ25hbHMuZmlyZSgnYWN0aW9uLXN0YXJ0Jywge1xuICAgICAgaW50ZXJhY3Rpb246IHRoaXMsXG4gICAgICBldmVudDogdGhpcy5kb3duRXZlbnRcbiAgICB9KTtcbiAgfTtcblxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUucG9pbnRlck1vdmUgPSBmdW5jdGlvbiBwb2ludGVyTW92ZShwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQpIHtcbiAgICBpZiAoIXRoaXMuc2ltdWxhdGlvbikge1xuICAgICAgdGhpcy51cGRhdGVQb2ludGVyKHBvaW50ZXIpO1xuICAgICAgdXRpbHMuc2V0Q29vcmRzKHRoaXMuY3VyQ29vcmRzLCB0aGlzLnBvaW50ZXJzKTtcbiAgICB9XG5cbiAgICB2YXIgZHVwbGljYXRlTW92ZSA9IHRoaXMuY3VyQ29vcmRzLnBhZ2UueCA9PT0gdGhpcy5wcmV2Q29vcmRzLnBhZ2UueCAmJiB0aGlzLmN1ckNvb3Jkcy5wYWdlLnkgPT09IHRoaXMucHJldkNvb3Jkcy5wYWdlLnkgJiYgdGhpcy5jdXJDb29yZHMuY2xpZW50LnggPT09IHRoaXMucHJldkNvb3Jkcy5jbGllbnQueCAmJiB0aGlzLmN1ckNvb3Jkcy5jbGllbnQueSA9PT0gdGhpcy5wcmV2Q29vcmRzLmNsaWVudC55O1xuXG4gICAgdmFyIGR4ID0gdm9pZCAwO1xuICAgIHZhciBkeSA9IHZvaWQgMDtcblxuICAgIC8vIHJlZ2lzdGVyIG1vdmVtZW50IGdyZWF0ZXIgdGhhbiBwb2ludGVyTW92ZVRvbGVyYW5jZVxuICAgIGlmICh0aGlzLnBvaW50ZXJJc0Rvd24gJiYgIXRoaXMucG9pbnRlcldhc01vdmVkKSB7XG4gICAgICBkeCA9IHRoaXMuY3VyQ29vcmRzLmNsaWVudC54IC0gdGhpcy5zdGFydENvb3Jkcy5jbGllbnQueDtcbiAgICAgIGR5ID0gdGhpcy5jdXJDb29yZHMuY2xpZW50LnkgLSB0aGlzLnN0YXJ0Q29vcmRzLmNsaWVudC55O1xuXG4gICAgICB0aGlzLnBvaW50ZXJXYXNNb3ZlZCA9IHV0aWxzLmh5cG90KGR4LCBkeSkgPiBJbnRlcmFjdGlvbi5wb2ludGVyTW92ZVRvbGVyYW5jZTtcbiAgICB9XG5cbiAgICB2YXIgc2lnbmFsQXJnID0ge1xuICAgICAgcG9pbnRlcjogcG9pbnRlcixcbiAgICAgIHBvaW50ZXJJbmRleDogdGhpcy5nZXRQb2ludGVySW5kZXgocG9pbnRlciksXG4gICAgICBldmVudDogZXZlbnQsXG4gICAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXG4gICAgICBkeDogZHgsXG4gICAgICBkeTogZHksXG4gICAgICBkdXBsaWNhdGU6IGR1cGxpY2F0ZU1vdmUsXG4gICAgICBpbnRlcmFjdGlvbjogdGhpcyxcbiAgICAgIGludGVyYWN0aW5nQmVmb3JlTW92ZTogdGhpcy5pbnRlcmFjdGluZygpXG4gICAgfTtcblxuICAgIGlmICghZHVwbGljYXRlTW92ZSkge1xuICAgICAgLy8gc2V0IHBvaW50ZXIgY29vcmRpbmF0ZSwgdGltZSBjaGFuZ2VzIGFuZCBzcGVlZHNcbiAgICAgIHV0aWxzLnNldENvb3JkRGVsdGFzKHRoaXMucG9pbnRlckRlbHRhLCB0aGlzLnByZXZDb29yZHMsIHRoaXMuY3VyQ29vcmRzKTtcbiAgICB9XG5cbiAgICBzaWduYWxzLmZpcmUoJ21vdmUnLCBzaWduYWxBcmcpO1xuXG4gICAgaWYgKCFkdXBsaWNhdGVNb3ZlKSB7XG4gICAgICAvLyBpZiBpbnRlcmFjdGluZywgZmlyZSBhbiAnYWN0aW9uLW1vdmUnIHNpZ25hbCBldGNcbiAgICAgIGlmICh0aGlzLmludGVyYWN0aW5nKCkpIHtcbiAgICAgICAgdGhpcy5kb01vdmUoc2lnbmFsQXJnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucG9pbnRlcldhc01vdmVkKSB7XG4gICAgICAgIHV0aWxzLmNvcHlDb29yZHModGhpcy5wcmV2Q29vcmRzLCB0aGlzLmN1ckNvb3Jkcyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qXFxcbiAgICogSW50ZXJhY3Rpb24uZG9Nb3ZlXG4gICBbIG1ldGhvZCBdXG4gICAqXG4gICAqIEZvcmNlIGEgbW92ZSBvZiB0aGUgY3VycmVudCBhY3Rpb24gYXQgdGhlIHNhbWUgY29vcmRpbmF0ZXMuIFVzZWZ1bCBpZlxuICAgKiBzbmFwL3Jlc3RyaWN0IGhhcyBiZWVuIGNoYW5nZWQgYW5kIHlvdSB3YW50IGEgbW92ZW1lbnQgd2l0aCB0aGUgbmV3XG4gICAqIHNldHRpbmdzLlxuICAgKlxuICAgKipcbiAgIHwgaW50ZXJhY3QodGFyZ2V0KVxuICAgfCAgIC5kcmFnZ2FibGUodHJ1ZSlcbiAgIHwgICAub24oJ2RyYWdtb3ZlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICB8ICAgICBpZiAoc29tZUNvbmRpdGlvbikge1xuICAgfCAgICAgICAvLyBjaGFuZ2UgdGhlIHNuYXAgc2V0dGluZ3NcbiAgIHwgICAgICAgZXZlbnQuaW50ZXJhY3RhYmxlLmRyYWdnYWJsZSh7IHNuYXA6IHsgdGFyZ2V0czogW10gfX0pO1xuICAgfCAgICAgICAvLyBmaXJlIGFub3RoZXIgbW92ZSBldmVudCB3aXRoIHJlLWNhbGN1bGF0ZWQgc25hcFxuICAgfCAgICAgICBldmVudC5pbnRlcmFjdGlvbi5kb01vdmUoKTtcbiAgIHwgICAgIH1cbiAgIHwgICB9KTtcbiAgIFxcKi9cblxuXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5kb01vdmUgPSBmdW5jdGlvbiBkb01vdmUoc2lnbmFsQXJnKSB7XG4gICAgc2lnbmFsQXJnID0gdXRpbHMuZXh0ZW5kKHtcbiAgICAgIHBvaW50ZXI6IHRoaXMucG9pbnRlcnNbMF0sXG4gICAgICBldmVudDogdGhpcy5wcmV2RXZlbnQsXG4gICAgICBldmVudFRhcmdldDogdGhpcy5fZXZlbnRUYXJnZXQsXG4gICAgICBpbnRlcmFjdGlvbjogdGhpc1xuICAgIH0sIHNpZ25hbEFyZyB8fCB7fSk7XG5cbiAgICBzaWduYWxzLmZpcmUoJ2JlZm9yZS1hY3Rpb24tbW92ZScsIHNpZ25hbEFyZyk7XG5cbiAgICBpZiAoIXRoaXMuX2RvbnRGaXJlTW92ZSkge1xuICAgICAgc2lnbmFscy5maXJlKCdhY3Rpb24tbW92ZScsIHNpZ25hbEFyZyk7XG4gICAgfVxuXG4gICAgdGhpcy5fZG9udEZpcmVNb3ZlID0gZmFsc2U7XG4gIH07XG5cbiAgLy8gRW5kIGludGVyYWN0IG1vdmUgZXZlbnRzIGFuZCBzdG9wIGF1dG8tc2Nyb2xsIHVubGVzcyBzaW11bGF0aW9uIGlzIHJ1bm5pbmdcblxuXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5wb2ludGVyVXAgPSBmdW5jdGlvbiBwb2ludGVyVXAocG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0LCBjdXJFdmVudFRhcmdldCkge1xuICAgIHZhciBwb2ludGVySW5kZXggPSB0aGlzLmdldFBvaW50ZXJJbmRleChwb2ludGVyKTtcblxuICAgIHNpZ25hbHMuZmlyZSgvY2FuY2VsJC9pLnRlc3QoZXZlbnQudHlwZSkgPyAnY2FuY2VsJyA6ICd1cCcsIHtcbiAgICAgIHBvaW50ZXI6IHBvaW50ZXIsXG4gICAgICBwb2ludGVySW5kZXg6IHBvaW50ZXJJbmRleCxcbiAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcbiAgICAgIGN1ckV2ZW50VGFyZ2V0OiBjdXJFdmVudFRhcmdldCxcbiAgICAgIGludGVyYWN0aW9uOiB0aGlzXG4gICAgfSk7XG5cbiAgICBpZiAoIXRoaXMuc2ltdWxhdGlvbikge1xuICAgICAgdGhpcy5lbmQoZXZlbnQpO1xuICAgIH1cblxuICAgIHRoaXMucG9pbnRlcklzRG93biA9IGZhbHNlO1xuICAgIHRoaXMucmVtb3ZlUG9pbnRlcihwb2ludGVyLCBldmVudCk7XG4gIH07XG5cbiAgLypcXFxuICAgKiBJbnRlcmFjdGlvbi5lbmRcbiAgIFsgbWV0aG9kIF1cbiAgICpcbiAgICogU3RvcCB0aGUgY3VycmVudCBhY3Rpb24gYW5kIGZpcmUgYW4gZW5kIGV2ZW50LiBJbmVydGlhbCBtb3ZlbWVudCBkb2VzXG4gICAqIG5vdCBoYXBwZW4uXG4gICAqXG4gICAtIGV2ZW50IChQb2ludGVyRXZlbnQpICNvcHRpb25hbFxuICAgKipcbiAgIHwgaW50ZXJhY3QodGFyZ2V0KVxuICAgfCAgIC5kcmFnZ2FibGUodHJ1ZSlcbiAgIHwgICAub24oJ21vdmUnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgIHwgICAgIGlmIChldmVudC5wYWdlWCA+IDEwMDApIHtcbiAgIHwgICAgICAgLy8gZW5kIHRoZSBjdXJyZW50IGFjdGlvblxuICAgfCAgICAgICBldmVudC5pbnRlcmFjdGlvbi5lbmQoKTtcbiAgIHwgICAgICAgLy8gc3RvcCBhbGwgZnVydGhlciBsaXN0ZW5lcnMgZnJvbSBiZWluZyBjYWxsZWRcbiAgIHwgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICB8ICAgICB9XG4gICB8ICAgfSk7XG4gICBcXCovXG5cblxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gZW5kKGV2ZW50KSB7XG4gICAgZXZlbnQgPSBldmVudCB8fCB0aGlzLnByZXZFdmVudDtcblxuICAgIGlmICh0aGlzLmludGVyYWN0aW5nKCkpIHtcbiAgICAgIHNpZ25hbHMuZmlyZSgnYWN0aW9uLWVuZCcsIHtcbiAgICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgICBpbnRlcmFjdGlvbjogdGhpc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5zdG9wKCk7XG4gIH07XG5cbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLmN1cnJlbnRBY3Rpb24gPSBmdW5jdGlvbiBjdXJyZW50QWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9pbnRlcmFjdGluZyA/IHRoaXMucHJlcGFyZWQubmFtZSA6IG51bGw7XG4gIH07XG5cbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLmludGVyYWN0aW5nID0gZnVuY3Rpb24gaW50ZXJhY3RpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2ludGVyYWN0aW5nO1xuICB9O1xuXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gc3RvcCgpIHtcbiAgICBzaWduYWxzLmZpcmUoJ3N0b3AnLCB7IGludGVyYWN0aW9uOiB0aGlzIH0pO1xuXG4gICAgaWYgKHRoaXMuX2ludGVyYWN0aW5nKSB7XG4gICAgICBzaWduYWxzLmZpcmUoJ3N0b3AtYWN0aXZlJywgeyBpbnRlcmFjdGlvbjogdGhpcyB9KTtcbiAgICAgIHNpZ25hbHMuZmlyZSgnc3RvcC0nICsgdGhpcy5wcmVwYXJlZC5uYW1lLCB7IGludGVyYWN0aW9uOiB0aGlzIH0pO1xuICAgIH1cblxuICAgIHRoaXMudGFyZ2V0ID0gdGhpcy5lbGVtZW50ID0gbnVsbDtcblxuICAgIHRoaXMuX2ludGVyYWN0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5wcmVwYXJlZC5uYW1lID0gdGhpcy5wcmV2RXZlbnQgPSBudWxsO1xuICB9O1xuXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRQb2ludGVySW5kZXggPSBmdW5jdGlvbiBnZXRQb2ludGVySW5kZXgocG9pbnRlcikge1xuICAgIC8vIG1vdXNlIGFuZCBwZW4gaW50ZXJhY3Rpb25zIG1heSBoYXZlIG9ubHkgb25lIHBvaW50ZXJcbiAgICBpZiAodGhpcy5wb2ludGVyVHlwZSA9PT0gJ21vdXNlJyB8fCB0aGlzLnBvaW50ZXJUeXBlID09PSAncGVuJykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHV0aWxzLmluZGV4T2YodGhpcy5wb2ludGVySWRzLCB1dGlscy5nZXRQb2ludGVySWQocG9pbnRlcikpO1xuICB9O1xuXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS51cGRhdGVQb2ludGVyID0gZnVuY3Rpb24gdXBkYXRlUG9pbnRlcihwb2ludGVyLCBldmVudCkge1xuICAgIHZhciBkb3duID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBldmVudCAmJiAvKGRvd258c3RhcnQpJC9pLnRlc3QoZXZlbnQudHlwZSk7XG5cbiAgICB2YXIgaWQgPSB1dGlscy5nZXRQb2ludGVySWQocG9pbnRlcik7XG4gICAgdmFyIGluZGV4ID0gdGhpcy5nZXRQb2ludGVySW5kZXgocG9pbnRlcik7XG5cbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICBpbmRleCA9IHRoaXMucG9pbnRlcklkcy5sZW5ndGg7XG4gICAgICB0aGlzLnBvaW50ZXJJZHNbaW5kZXhdID0gaWQ7XG4gICAgfVxuXG4gICAgaWYgKGRvd24pIHtcbiAgICAgIHNpZ25hbHMuZmlyZSgndXBkYXRlLXBvaW50ZXItZG93bicsIHtcbiAgICAgICAgcG9pbnRlcjogcG9pbnRlcixcbiAgICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgICBkb3duOiBkb3duLFxuICAgICAgICBwb2ludGVySWQ6IGlkLFxuICAgICAgICBwb2ludGVySW5kZXg6IGluZGV4LFxuICAgICAgICBpbnRlcmFjdGlvbjogdGhpc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5wb2ludGVyc1tpbmRleF0gPSBwb2ludGVyO1xuXG4gICAgcmV0dXJuIGluZGV4O1xuICB9O1xuXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5yZW1vdmVQb2ludGVyID0gZnVuY3Rpb24gcmVtb3ZlUG9pbnRlcihwb2ludGVyLCBldmVudCkge1xuICAgIHZhciBpbmRleCA9IHRoaXMuZ2V0UG9pbnRlckluZGV4KHBvaW50ZXIpO1xuXG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNpZ25hbHMuZmlyZSgncmVtb3ZlLXBvaW50ZXInLCB7XG4gICAgICBwb2ludGVyOiBwb2ludGVyLFxuICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgcG9pbnRlckluZGV4OiBpbmRleCxcbiAgICAgIGludGVyYWN0aW9uOiB0aGlzXG4gICAgfSk7XG5cbiAgICB0aGlzLnBvaW50ZXJzLnNwbGljZShpbmRleCwgMSk7XG4gICAgdGhpcy5wb2ludGVySWRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgdGhpcy5kb3duVGFyZ2V0cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMuZG93blRpbWVzLnNwbGljZShpbmRleCwgMSk7XG4gIH07XG5cbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLl91cGRhdGVFdmVudFRhcmdldHMgPSBmdW5jdGlvbiBfdXBkYXRlRXZlbnRUYXJnZXRzKHRhcmdldCwgY3VycmVudFRhcmdldCkge1xuICAgIHRoaXMuX2V2ZW50VGFyZ2V0ID0gdGFyZ2V0O1xuICAgIHRoaXMuX2N1ckV2ZW50VGFyZ2V0ID0gY3VycmVudFRhcmdldDtcbiAgfTtcblxuICByZXR1cm4gSW50ZXJhY3Rpb247XG59KCk7XG5cbmZvciAodmFyIGkgPSAwLCBsZW4gPSBtZXRob2ROYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICB2YXIgbWV0aG9kID0gbWV0aG9kTmFtZXNbaV07XG5cbiAgbGlzdGVuZXJzW21ldGhvZF0gPSBkb09uSW50ZXJhY3Rpb25zKG1ldGhvZCk7XG59XG5cbmZ1bmN0aW9uIGRvT25JbnRlcmFjdGlvbnMobWV0aG9kKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgcG9pbnRlclR5cGUgPSB1dGlscy5nZXRQb2ludGVyVHlwZShldmVudCk7XG5cbiAgICB2YXIgX3V0aWxzJGdldEV2ZW50VGFyZ2V0ID0gdXRpbHMuZ2V0RXZlbnRUYXJnZXRzKGV2ZW50KSxcbiAgICAgICAgZXZlbnRUYXJnZXQgPSBfdXRpbHMkZ2V0RXZlbnRUYXJnZXRbMF0sXG4gICAgICAgIGN1ckV2ZW50VGFyZ2V0ID0gX3V0aWxzJGdldEV2ZW50VGFyZ2V0WzFdO1xuXG4gICAgdmFyIG1hdGNoZXMgPSBbXTsgLy8gWyBbcG9pbnRlciwgaW50ZXJhY3Rpb25dLCAuLi5dXG5cbiAgICBpZiAoYnJvd3Nlci5zdXBwb3J0c1RvdWNoICYmIC90b3VjaC8udGVzdChldmVudC50eXBlKSkge1xuICAgICAgcHJldlRvdWNoVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgZXZlbnQuY2hhbmdlZFRvdWNoZXMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhciBwb2ludGVyID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbX2ldO1xuICAgICAgICB2YXIgaW50ZXJhY3Rpb24gPSBmaW5kZXIuc2VhcmNoKHBvaW50ZXIsIGV2ZW50LnR5cGUsIGV2ZW50VGFyZ2V0KTtcblxuICAgICAgICBtYXRjaGVzLnB1c2goW3BvaW50ZXIsIGludGVyYWN0aW9uIHx8IG5ldyBJbnRlcmFjdGlvbih7IHBvaW50ZXJUeXBlOiBwb2ludGVyVHlwZSB9KV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgaW52YWxpZFBvaW50ZXIgPSBmYWxzZTtcblxuICAgICAgaWYgKCFicm93c2VyLnN1cHBvcnRzUG9pbnRlckV2ZW50ICYmIC9tb3VzZS8udGVzdChldmVudC50eXBlKSkge1xuICAgICAgICAvLyBpZ25vcmUgbW91c2UgZXZlbnRzIHdoaWxlIHRvdWNoIGludGVyYWN0aW9ucyBhcmUgYWN0aXZlXG4gICAgICAgIGZvciAodmFyIF9pMiA9IDA7IF9pMiA8IHNjb3BlLmludGVyYWN0aW9ucy5sZW5ndGggJiYgIWludmFsaWRQb2ludGVyOyBfaTIrKykge1xuICAgICAgICAgIGludmFsaWRQb2ludGVyID0gc2NvcGUuaW50ZXJhY3Rpb25zW19pMl0ucG9pbnRlclR5cGUgIT09ICdtb3VzZScgJiYgc2NvcGUuaW50ZXJhY3Rpb25zW19pMl0ucG9pbnRlcklzRG93bjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHRyeSB0byBpZ25vcmUgbW91c2UgZXZlbnRzIHRoYXQgYXJlIHNpbXVsYXRlZCBieSB0aGUgYnJvd3NlclxuICAgICAgICAvLyBhZnRlciBhIHRvdWNoIGV2ZW50XG4gICAgICAgIGludmFsaWRQb2ludGVyID0gaW52YWxpZFBvaW50ZXIgfHwgbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBwcmV2VG91Y2hUaW1lIDwgNTAwXG4gICAgICAgIC8vIG9uIGlPUyBhbmQgRmlyZWZveCBNb2JpbGUsIE1vdXNlRXZlbnQudGltZVN0YW1wIGlzIHplcm8gaWYgc2ltdWxhdGVkXG4gICAgICAgIHx8IGV2ZW50LnRpbWVTdGFtcCA9PT0gMDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpbnZhbGlkUG9pbnRlcikge1xuICAgICAgICB2YXIgX2ludGVyYWN0aW9uID0gZmluZGVyLnNlYXJjaChldmVudCwgZXZlbnQudHlwZSwgZXZlbnRUYXJnZXQpO1xuXG4gICAgICAgIGlmICghX2ludGVyYWN0aW9uKSB7XG4gICAgICAgICAgX2ludGVyYWN0aW9uID0gbmV3IEludGVyYWN0aW9uKHsgcG9pbnRlclR5cGU6IHBvaW50ZXJUeXBlIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgbWF0Y2hlcy5wdXNoKFtldmVudCwgX2ludGVyYWN0aW9uXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gbWF0Y2hlcywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pMyA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICB2YXIgX3JlZjI7XG5cbiAgICAgIGlmIChfaXNBcnJheSkge1xuICAgICAgICBpZiAoX2kzID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xuICAgICAgICBfcmVmMiA9IF9pdGVyYXRvcltfaTMrK107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaTMgPSBfaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICBpZiAoX2kzLmRvbmUpIGJyZWFrO1xuICAgICAgICBfcmVmMiA9IF9pMy52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIF9yZWYzID0gX3JlZjIsXG4gICAgICAgICAgX3BvaW50ZXIgPSBfcmVmM1swXSxcbiAgICAgICAgICBfaW50ZXJhY3Rpb24yID0gX3JlZjNbMV07XG5cbiAgICAgIF9pbnRlcmFjdGlvbjIuX3VwZGF0ZUV2ZW50VGFyZ2V0cyhldmVudFRhcmdldCwgY3VyRXZlbnRUYXJnZXQpO1xuICAgICAgX2ludGVyYWN0aW9uMlttZXRob2RdKF9wb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsIGN1ckV2ZW50VGFyZ2V0KTtcbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIGVuZEFsbChldmVudCkge1xuICBmb3IgKHZhciBfaTQgPSAwOyBfaTQgPCBzY29wZS5pbnRlcmFjdGlvbnMubGVuZ3RoOyBfaTQrKykge1xuICAgIHZhciBpbnRlcmFjdGlvbiA9IHNjb3BlLmludGVyYWN0aW9uc1tfaTRdO1xuXG4gICAgaW50ZXJhY3Rpb24uZW5kKGV2ZW50KTtcbiAgICBzaWduYWxzLmZpcmUoJ2VuZGFsbCcsIHsgZXZlbnQ6IGV2ZW50LCBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24gfSk7XG4gIH1cbn1cblxudmFyIGRvY0V2ZW50cyA9IHsvKiAnZXZlbnRUeXBlJzogbGlzdGVuZXJGdW5jICovfTtcbnZhciBwRXZlbnRUeXBlcyA9IGJyb3dzZXIucEV2ZW50VHlwZXM7XG5cbmlmIChkb21PYmplY3RzLlBvaW50ZXJFdmVudCkge1xuICBkb2NFdmVudHNbcEV2ZW50VHlwZXMuZG93bl0gPSBsaXN0ZW5lcnMucG9pbnRlckRvd247XG4gIGRvY0V2ZW50c1twRXZlbnRUeXBlcy5tb3ZlXSA9IGxpc3RlbmVycy5wb2ludGVyTW92ZTtcbiAgZG9jRXZlbnRzW3BFdmVudFR5cGVzLnVwXSA9IGxpc3RlbmVycy5wb2ludGVyVXA7XG4gIGRvY0V2ZW50c1twRXZlbnRUeXBlcy5jYW5jZWxdID0gbGlzdGVuZXJzLnBvaW50ZXJVcDtcbn0gZWxzZSB7XG4gIGRvY0V2ZW50cy5tb3VzZWRvd24gPSBsaXN0ZW5lcnMucG9pbnRlckRvd247XG4gIGRvY0V2ZW50cy5tb3VzZW1vdmUgPSBsaXN0ZW5lcnMucG9pbnRlck1vdmU7XG4gIGRvY0V2ZW50cy5tb3VzZXVwID0gbGlzdGVuZXJzLnBvaW50ZXJVcDtcblxuICBkb2NFdmVudHMudG91Y2hzdGFydCA9IGxpc3RlbmVycy5wb2ludGVyRG93bjtcbiAgZG9jRXZlbnRzLnRvdWNobW92ZSA9IGxpc3RlbmVycy5wb2ludGVyTW92ZTtcbiAgZG9jRXZlbnRzLnRvdWNoZW5kID0gbGlzdGVuZXJzLnBvaW50ZXJVcDtcbiAgZG9jRXZlbnRzLnRvdWNoY2FuY2VsID0gbGlzdGVuZXJzLnBvaW50ZXJVcDtcbn1cblxuZG9jRXZlbnRzLmJsdXIgPSBlbmRBbGw7XG5cbmZ1bmN0aW9uIG9uRG9jU2lnbmFsKF9yZWY0LCBzaWduYWxOYW1lKSB7XG4gIHZhciBkb2MgPSBfcmVmNC5kb2M7XG5cbiAgdmFyIGV2ZW50TWV0aG9kID0gc2lnbmFsTmFtZS5pbmRleE9mKCdhZGQnKSA9PT0gMCA/IGV2ZW50cy5hZGQgOiBldmVudHMucmVtb3ZlO1xuXG4gIC8vIGRlbGVnYXRlIGV2ZW50IGxpc3RlbmVyXG4gIGZvciAodmFyIGV2ZW50VHlwZSBpbiBzY29wZS5kZWxlZ2F0ZWRFdmVudHMpIHtcbiAgICBldmVudE1ldGhvZChkb2MsIGV2ZW50VHlwZSwgZXZlbnRzLmRlbGVnYXRlTGlzdGVuZXIpO1xuICAgIGV2ZW50TWV0aG9kKGRvYywgZXZlbnRUeXBlLCBldmVudHMuZGVsZWdhdGVVc2VDYXB0dXJlLCB0cnVlKTtcbiAgfVxuXG4gIGZvciAodmFyIF9ldmVudFR5cGUgaW4gZG9jRXZlbnRzKSB7XG4gICAgZXZlbnRNZXRob2QoZG9jLCBfZXZlbnRUeXBlLCBkb2NFdmVudHNbX2V2ZW50VHlwZV0pO1xuICB9XG59XG5cbnNpZ25hbHMub24oJ3VwZGF0ZS1wb2ludGVyLWRvd24nLCBmdW5jdGlvbiAoX3JlZjUpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjUuaW50ZXJhY3Rpb24sXG4gICAgICBwb2ludGVyID0gX3JlZjUucG9pbnRlcixcbiAgICAgIHBvaW50ZXJJZCA9IF9yZWY1LnBvaW50ZXJJZCxcbiAgICAgIHBvaW50ZXJJbmRleCA9IF9yZWY1LnBvaW50ZXJJbmRleCxcbiAgICAgIGV2ZW50ID0gX3JlZjUuZXZlbnQsXG4gICAgICBldmVudFRhcmdldCA9IF9yZWY1LmV2ZW50VGFyZ2V0LFxuICAgICAgZG93biA9IF9yZWY1LmRvd247XG5cbiAgaW50ZXJhY3Rpb24ucG9pbnRlcklkc1twb2ludGVySW5kZXhdID0gcG9pbnRlcklkO1xuICBpbnRlcmFjdGlvbi5wb2ludGVyc1twb2ludGVySW5kZXhdID0gcG9pbnRlcjtcblxuICBpZiAoZG93bikge1xuICAgIGludGVyYWN0aW9uLnBvaW50ZXJJc0Rvd24gPSB0cnVlO1xuICB9XG5cbiAgaWYgKCFpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpKSB7XG4gICAgdXRpbHMuc2V0Q29vcmRzKGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLCBpbnRlcmFjdGlvbi5wb2ludGVycyk7XG5cbiAgICB1dGlscy5jb3B5Q29vcmRzKGludGVyYWN0aW9uLmN1ckNvb3JkcywgaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMpO1xuICAgIHV0aWxzLmNvcHlDb29yZHMoaW50ZXJhY3Rpb24ucHJldkNvb3JkcywgaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMpO1xuXG4gICAgaW50ZXJhY3Rpb24uZG93bkV2ZW50ID0gZXZlbnQ7XG4gICAgaW50ZXJhY3Rpb24uZG93blRpbWVzW3BvaW50ZXJJbmRleF0gPSBpbnRlcmFjdGlvbi5jdXJDb29yZHMudGltZVN0YW1wO1xuICAgIGludGVyYWN0aW9uLmRvd25UYXJnZXRzW3BvaW50ZXJJbmRleF0gPSBldmVudFRhcmdldCB8fCBldmVudCAmJiB1dGlscy5nZXRFdmVudFRhcmdldHMoZXZlbnQpWzBdO1xuICAgIGludGVyYWN0aW9uLnBvaW50ZXJXYXNNb3ZlZCA9IGZhbHNlO1xuXG4gICAgdXRpbHMucG9pbnRlckV4dGVuZChpbnRlcmFjdGlvbi5kb3duUG9pbnRlciwgcG9pbnRlcik7XG4gIH1cbn0pO1xuXG5zY29wZS5zaWduYWxzLm9uKCdhZGQtZG9jdW1lbnQnLCBvbkRvY1NpZ25hbCk7XG5zY29wZS5zaWduYWxzLm9uKCdyZW1vdmUtZG9jdW1lbnQnLCBvbkRvY1NpZ25hbCk7XG5cbkludGVyYWN0aW9uLnBvaW50ZXJNb3ZlVG9sZXJhbmNlID0gMTtcbkludGVyYWN0aW9uLmRvT25JbnRlcmFjdGlvbnMgPSBkb09uSW50ZXJhY3Rpb25zO1xuSW50ZXJhY3Rpb24uZW5kQWxsID0gZW5kQWxsO1xuSW50ZXJhY3Rpb24uc2lnbmFscyA9IHNpZ25hbHM7XG5JbnRlcmFjdGlvbi5kb2NFdmVudHMgPSBkb2NFdmVudHM7XG5cbnNjb3BlLmVuZEFsbEludGVyYWN0aW9ucyA9IGVuZEFsbDtcblxubW9kdWxlLmV4cG9ydHMgPSBJbnRlcmFjdGlvbjtcblxufSx7XCIuL3Njb3BlXCI6MzQsXCIuL3V0aWxzXCI6NDQsXCIuL3V0aWxzL1NpZ25hbHNcIjozNSxcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9kb21PYmplY3RzXCI6MzgsXCIuL3V0aWxzL2V2ZW50c1wiOjQwLFwiLi91dGlscy9pbnRlcmFjdGlvbkZpbmRlclwiOjQ1fV0sNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XG52YXIgSW50ZXJhY3RFdmVudCA9IHJlcXVpcmUoJy4uL0ludGVyYWN0RXZlbnQnKTtcblxudmFyIGFjdGlvbnMgPSB7XG4gIGZpcmVQcmVwYXJlZDogZmlyZVByZXBhcmVkLFxuICBuYW1lczogW10sXG4gIG1ldGhvZERpY3Q6IHt9XG59O1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tc3RhcnQnLCBmdW5jdGlvbiAoX3JlZikge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxuICAgICAgZXZlbnQgPSBfcmVmLmV2ZW50O1xuXG4gIGludGVyYWN0aW9uLl9pbnRlcmFjdGluZyA9IHRydWU7XG4gIGZpcmVQcmVwYXJlZChpbnRlcmFjdGlvbiwgZXZlbnQsICdzdGFydCcpO1xufSk7XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ2FjdGlvbi1tb3ZlJywgZnVuY3Rpb24gKF9yZWYyKSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxuICAgICAgZXZlbnQgPSBfcmVmMi5ldmVudCxcbiAgICAgIHByZUVuZCA9IF9yZWYyLnByZUVuZDtcblxuICBmaXJlUHJlcGFyZWQoaW50ZXJhY3Rpb24sIGV2ZW50LCAnbW92ZScsIHByZUVuZCk7XG5cbiAgLy8gaWYgdGhlIGFjdGlvbiB3YXMgZW5kZWQgaW4gYSBsaXN0ZW5lclxuICBpZiAoIWludGVyYWN0aW9uLmludGVyYWN0aW5nKCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pO1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tZW5kJywgZnVuY3Rpb24gKF9yZWYzKSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzLmludGVyYWN0aW9uLFxuICAgICAgZXZlbnQgPSBfcmVmMy5ldmVudDtcblxuICBmaXJlUHJlcGFyZWQoaW50ZXJhY3Rpb24sIGV2ZW50LCAnZW5kJyk7XG59KTtcblxuZnVuY3Rpb24gZmlyZVByZXBhcmVkKGludGVyYWN0aW9uLCBldmVudCwgcGhhc2UsIHByZUVuZCkge1xuICB2YXIgYWN0aW9uTmFtZSA9IGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWU7XG5cbiAgdmFyIG5ld0V2ZW50ID0gbmV3IEludGVyYWN0RXZlbnQoaW50ZXJhY3Rpb24sIGV2ZW50LCBhY3Rpb25OYW1lLCBwaGFzZSwgaW50ZXJhY3Rpb24uZWxlbWVudCwgbnVsbCwgcHJlRW5kKTtcblxuICBpbnRlcmFjdGlvbi50YXJnZXQuZmlyZShuZXdFdmVudCk7XG4gIGludGVyYWN0aW9uLnByZXZFdmVudCA9IG5ld0V2ZW50O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFjdGlvbnM7XG5cbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGlvblwiOjV9XSw3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgSW50ZXJhY3RFdmVudCA9IHJlcXVpcmUoJy4uL0ludGVyYWN0RXZlbnQnKTtcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xuXG52YXIgZHJhZyA9IHtcbiAgZGVmYXVsdHM6IHtcbiAgICBlbmFibGVkOiBmYWxzZSxcbiAgICBtb3VzZUJ1dHRvbnM6IG51bGwsXG5cbiAgICBvcmlnaW46IG51bGwsXG4gICAgc25hcDogbnVsbCxcbiAgICByZXN0cmljdDogbnVsbCxcbiAgICBpbmVydGlhOiBudWxsLFxuICAgIGF1dG9TY3JvbGw6IG51bGwsXG5cbiAgICBzdGFydEF4aXM6ICd4eScsXG4gICAgbG9ja0F4aXM6ICd4eSdcbiAgfSxcblxuICBjaGVja2VyOiBmdW5jdGlvbiBjaGVja2VyKHBvaW50ZXIsIGV2ZW50LCBpbnRlcmFjdGFibGUpIHtcbiAgICB2YXIgZHJhZ09wdGlvbnMgPSBpbnRlcmFjdGFibGUub3B0aW9ucy5kcmFnO1xuXG4gICAgcmV0dXJuIGRyYWdPcHRpb25zLmVuYWJsZWQgPyB7IG5hbWU6ICdkcmFnJywgYXhpczogZHJhZ09wdGlvbnMubG9ja0F4aXMgPT09ICdzdGFydCcgPyBkcmFnT3B0aW9ucy5zdGFydEF4aXMgOiBkcmFnT3B0aW9ucy5sb2NrQXhpcyB9IDogbnVsbDtcbiAgfSxcblxuICBnZXRDdXJzb3I6IGZ1bmN0aW9uIGdldEN1cnNvcigpIHtcbiAgICByZXR1cm4gJ21vdmUnO1xuICB9XG59O1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdiZWZvcmUtYWN0aW9uLW1vdmUnLCBmdW5jdGlvbiAoX3JlZikge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uO1xuXG4gIGlmIChpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lICE9PSAnZHJhZycpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgYXhpcyA9IGludGVyYWN0aW9uLnByZXBhcmVkLmF4aXM7XG5cbiAgaWYgKGF4aXMgPT09ICd4Jykge1xuICAgIGludGVyYWN0aW9uLmN1ckNvb3Jkcy5wYWdlLnkgPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnk7XG4gICAgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLmNsaWVudC55ID0gaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMuY2xpZW50Lnk7XG5cbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEucGFnZS5zcGVlZCA9IE1hdGguYWJzKGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5wYWdlLnZ4KTtcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnNwZWVkID0gTWF0aC5hYnMoaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC52eCk7XG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC52eSA9IDA7XG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLnBhZ2UudnkgPSAwO1xuICB9IGVsc2UgaWYgKGF4aXMgPT09ICd5Jykge1xuICAgIGludGVyYWN0aW9uLmN1ckNvb3Jkcy5wYWdlLnggPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLng7XG4gICAgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLmNsaWVudC54ID0gaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMuY2xpZW50Lng7XG5cbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEucGFnZS5zcGVlZCA9IE1hdGguYWJzKGludGVyYWN0aW9uLnBvaW50ZXJEZWx0YS5wYWdlLnZ5KTtcbiAgICBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnNwZWVkID0gTWF0aC5hYnMoaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC52eSk7XG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC52eCA9IDA7XG4gICAgaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLnBhZ2UudnggPSAwO1xuICB9XG59KTtcblxuLy8gZHJhZ21vdmVcbkludGVyYWN0RXZlbnQuc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKF9yZWYyKSB7XG4gIHZhciBpRXZlbnQgPSBfcmVmMi5pRXZlbnQsXG4gICAgICBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uO1xuXG4gIGlmIChpRXZlbnQudHlwZSAhPT0gJ2RyYWdtb3ZlJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBheGlzID0gaW50ZXJhY3Rpb24ucHJlcGFyZWQuYXhpcztcblxuICBpZiAoYXhpcyA9PT0gJ3gnKSB7XG4gICAgaUV2ZW50LnBhZ2VZID0gaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMucGFnZS55O1xuICAgIGlFdmVudC5jbGllbnRZID0gaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMuY2xpZW50Lnk7XG4gICAgaUV2ZW50LmR5ID0gMDtcbiAgfSBlbHNlIGlmIChheGlzID09PSAneScpIHtcbiAgICBpRXZlbnQucGFnZVggPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLng7XG4gICAgaUV2ZW50LmNsaWVudFggPSBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5jbGllbnQueDtcbiAgICBpRXZlbnQuZHggPSAwO1xuICB9XG59KTtcblxuLypcXFxuICogSW50ZXJhY3RhYmxlLmRyYWdnYWJsZVxuIFsgbWV0aG9kIF1cbiAqXG4gKiBHZXRzIG9yIHNldHMgd2hldGhlciBkcmFnIGFjdGlvbnMgY2FuIGJlIHBlcmZvcm1lZCBvbiB0aGVcbiAqIEludGVyYWN0YWJsZVxuICpcbiA9IChib29sZWFuKSBJbmRpY2F0ZXMgaWYgdGhpcyBjYW4gYmUgdGhlIHRhcmdldCBvZiBkcmFnIGV2ZW50c1xuIHwgdmFyIGlzRHJhZ2dhYmxlID0gaW50ZXJhY3QoJ3VsIGxpJykuZHJhZ2dhYmxlKCk7XG4gKiBvclxuIC0gb3B0aW9ucyAoYm9vbGVhbiB8IG9iamVjdCkgI29wdGlvbmFsIHRydWUvZmFsc2Ugb3IgQW4gb2JqZWN0IHdpdGggZXZlbnQgbGlzdGVuZXJzIHRvIGJlIGZpcmVkIG9uIGRyYWcgZXZlbnRzIChvYmplY3QgbWFrZXMgdGhlIEludGVyYWN0YWJsZSBkcmFnZ2FibGUpXG4gPSAob2JqZWN0KSBUaGlzIEludGVyYWN0YWJsZVxuIHwgaW50ZXJhY3QoZWxlbWVudCkuZHJhZ2dhYmxlKHtcbiB8ICAgICBvbnN0YXJ0OiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxuIHwgICAgIG9ubW92ZSA6IGZ1bmN0aW9uIChldmVudCkge30sXG4gfCAgICAgb25lbmQgIDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcbiB8XG4gfCAgICAgLy8gdGhlIGF4aXMgaW4gd2hpY2ggdGhlIGZpcnN0IG1vdmVtZW50IG11c3QgYmVcbiB8ICAgICAvLyBmb3IgdGhlIGRyYWcgc2VxdWVuY2UgdG8gc3RhcnRcbiB8ICAgICAvLyAneHknIGJ5IGRlZmF1bHQgLSBhbnkgZGlyZWN0aW9uXG4gfCAgICAgc3RhcnRBeGlzOiAneCcgfHwgJ3knIHx8ICd4eScsXG4gfFxuIHwgICAgIC8vICd4eScgYnkgZGVmYXVsdCAtIGRvbid0IHJlc3RyaWN0IHRvIG9uZSBheGlzIChtb3ZlIGluIGFueSBkaXJlY3Rpb24pXG4gfCAgICAgLy8gJ3gnIG9yICd5JyB0byByZXN0cmljdCBtb3ZlbWVudCB0byBlaXRoZXIgYXhpc1xuIHwgICAgIC8vICdzdGFydCcgdG8gcmVzdHJpY3QgbW92ZW1lbnQgdG8gdGhlIGF4aXMgdGhlIGRyYWcgc3RhcnRlZCBpblxuIHwgICAgIGxvY2tBeGlzOiAneCcgfHwgJ3knIHx8ICd4eScgfHwgJ3N0YXJ0JyxcbiB8XG4gfCAgICAgLy8gbWF4IG51bWJlciBvZiBkcmFncyB0aGF0IGNhbiBoYXBwZW4gY29uY3VycmVudGx5XG4gfCAgICAgLy8gd2l0aCBlbGVtZW50cyBvZiB0aGlzIEludGVyYWN0YWJsZS4gSW5maW5pdHkgYnkgZGVmYXVsdFxuIHwgICAgIG1heDogSW5maW5pdHksXG4gfFxuIHwgICAgIC8vIG1heCBudW1iZXIgb2YgZHJhZ3MgdGhhdCBjYW4gdGFyZ2V0IHRoZSBzYW1lIGVsZW1lbnQrSW50ZXJhY3RhYmxlXG4gfCAgICAgLy8gMSBieSBkZWZhdWx0XG4gfCAgICAgbWF4UGVyRWxlbWVudDogMlxuIHwgfSk7XG5cXCovXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLmRyYWdnYWJsZSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIGlmICh1dGlscy5pcy5vYmplY3Qob3B0aW9ucykpIHtcbiAgICB0aGlzLm9wdGlvbnMuZHJhZy5lbmFibGVkID0gb3B0aW9ucy5lbmFibGVkID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZTtcbiAgICB0aGlzLnNldFBlckFjdGlvbignZHJhZycsIG9wdGlvbnMpO1xuICAgIHRoaXMuc2V0T25FdmVudHMoJ2RyYWcnLCBvcHRpb25zKTtcblxuICAgIGlmICgvXih4eXx4fHl8c3RhcnQpJC8udGVzdChvcHRpb25zLmxvY2tBeGlzKSkge1xuICAgICAgdGhpcy5vcHRpb25zLmRyYWcubG9ja0F4aXMgPSBvcHRpb25zLmxvY2tBeGlzO1xuICAgIH1cbiAgICBpZiAoL14oeHl8eHx5KSQvLnRlc3Qob3B0aW9ucy5zdGFydEF4aXMpKSB7XG4gICAgICB0aGlzLm9wdGlvbnMuZHJhZy5zdGFydEF4aXMgPSBvcHRpb25zLnN0YXJ0QXhpcztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGlmICh1dGlscy5pcy5ib29sKG9wdGlvbnMpKSB7XG4gICAgdGhpcy5vcHRpb25zLmRyYWcuZW5hYmxlZCA9IG9wdGlvbnM7XG5cbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIHRoaXMub25kcmFnc3RhcnQgPSB0aGlzLm9uZHJhZ3N0YXJ0ID0gdGhpcy5vbmRyYWdlbmQgPSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMub3B0aW9ucy5kcmFnO1xufTtcblxuYWN0aW9ucy5kcmFnID0gZHJhZztcbmFjdGlvbnMubmFtZXMucHVzaCgnZHJhZycpO1xudXRpbHMubWVyZ2UoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIFsnZHJhZ3N0YXJ0JywgJ2RyYWdtb3ZlJywgJ2RyYWdpbmVydGlhc3RhcnQnLCAnZHJhZ2luZXJ0aWFyZXN1bWUnLCAnZHJhZ2VuZCddKTtcbmFjdGlvbnMubWV0aG9kRGljdC5kcmFnID0gJ2RyYWdnYWJsZSc7XG5cbmRlZmF1bHRPcHRpb25zLmRyYWcgPSBkcmFnLmRlZmF1bHRzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRyYWc7XG5cbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vSW50ZXJhY3Rpb25cIjo1LFwiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL3V0aWxzXCI6NDQsXCIuL2Jhc2VcIjo2fV0sODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBhY3Rpb25zID0gcmVxdWlyZSgnLi9iYXNlJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcbnZhciBpbnRlcmFjdCA9IHJlcXVpcmUoJy4uL2ludGVyYWN0Jyk7XG52YXIgSW50ZXJhY3RFdmVudCA9IHJlcXVpcmUoJy4uL0ludGVyYWN0RXZlbnQnKTtcbnZhciBJbnRlcmFjdGFibGUgPSByZXF1aXJlKCcuLi9JbnRlcmFjdGFibGUnKTtcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xuXG52YXIgZHJvcCA9IHtcbiAgZGVmYXVsdHM6IHtcbiAgICBlbmFibGVkOiBmYWxzZSxcbiAgICBhY2NlcHQ6IG51bGwsXG4gICAgb3ZlcmxhcDogJ3BvaW50ZXInXG4gIH1cbn07XG5cbnZhciBkeW5hbWljRHJvcCA9IGZhbHNlO1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tc3RhcnQnLCBmdW5jdGlvbiAoX3JlZikge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uLFxuICAgICAgZXZlbnQgPSBfcmVmLmV2ZW50O1xuXG4gIGlmIChpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lICE9PSAnZHJhZycpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyByZXNldCBhY3RpdmUgZHJvcHpvbmVzXG4gIGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmRyb3B6b25lcyA9IFtdO1xuICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5lbGVtZW50cyA9IFtdO1xuICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5yZWN0cyA9IFtdO1xuXG4gIGludGVyYWN0aW9uLmRyb3BFdmVudHMgPSBudWxsO1xuXG4gIGlmICghaW50ZXJhY3Rpb24uZHluYW1pY0Ryb3ApIHtcbiAgICBzZXRBY3RpdmVEcm9wcyhpbnRlcmFjdGlvbiwgaW50ZXJhY3Rpb24uZWxlbWVudCk7XG4gIH1cblxuICB2YXIgZHJhZ0V2ZW50ID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50O1xuICB2YXIgZHJvcEV2ZW50cyA9IGdldERyb3BFdmVudHMoaW50ZXJhY3Rpb24sIGV2ZW50LCBkcmFnRXZlbnQpO1xuXG4gIGlmIChkcm9wRXZlbnRzLmFjdGl2YXRlKSB7XG4gICAgZmlyZUFjdGl2ZURyb3BzKGludGVyYWN0aW9uLCBkcm9wRXZlbnRzLmFjdGl2YXRlKTtcbiAgfVxufSk7XG5cbkludGVyYWN0RXZlbnQuc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKF9yZWYyKSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxuICAgICAgaUV2ZW50ID0gX3JlZjIuaUV2ZW50LFxuICAgICAgZXZlbnQgPSBfcmVmMi5ldmVudDtcblxuICBpZiAoaUV2ZW50LnR5cGUgIT09ICdkcmFnbW92ZScgJiYgaUV2ZW50LnR5cGUgIT09ICdkcmFnZW5kJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBkcmFnZ2FibGVFbGVtZW50ID0gaW50ZXJhY3Rpb24uZWxlbWVudDtcbiAgdmFyIGRyYWdFdmVudCA9IGlFdmVudDtcbiAgdmFyIGRyb3BSZXN1bHQgPSBnZXREcm9wKGRyYWdFdmVudCwgZXZlbnQsIGRyYWdnYWJsZUVsZW1lbnQpO1xuXG4gIGludGVyYWN0aW9uLmRyb3BUYXJnZXQgPSBkcm9wUmVzdWx0LmRyb3B6b25lO1xuICBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudCA9IGRyb3BSZXN1bHQuZWxlbWVudDtcblxuICBpbnRlcmFjdGlvbi5kcm9wRXZlbnRzID0gZ2V0RHJvcEV2ZW50cyhpbnRlcmFjdGlvbiwgZXZlbnQsIGRyYWdFdmVudCk7XG59KTtcblxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYWN0aW9uLW1vdmUnLCBmdW5jdGlvbiAoX3JlZjMpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjMuaW50ZXJhY3Rpb247XG5cbiAgaWYgKGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgIT09ICdkcmFnJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZpcmVEcm9wRXZlbnRzKGludGVyYWN0aW9uLCBpbnRlcmFjdGlvbi5kcm9wRXZlbnRzKTtcbn0pO1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tZW5kJywgZnVuY3Rpb24gKF9yZWY0KSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY0LmludGVyYWN0aW9uO1xuXG4gIGlmIChpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lID09PSAnZHJhZycpIHtcbiAgICBmaXJlRHJvcEV2ZW50cyhpbnRlcmFjdGlvbiwgaW50ZXJhY3Rpb24uZHJvcEV2ZW50cyk7XG4gIH1cbn0pO1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdzdG9wLWRyYWcnLCBmdW5jdGlvbiAoX3JlZjUpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjUuaW50ZXJhY3Rpb247XG5cbiAgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzID0gaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZWxlbWVudHMgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5yZWN0cyA9IGludGVyYWN0aW9uLmRyb3BFdmVudHMgPSBudWxsO1xufSk7XG5cbmZ1bmN0aW9uIGNvbGxlY3REcm9wcyhpbnRlcmFjdGlvbiwgZWxlbWVudCkge1xuICB2YXIgZHJvcHMgPSBbXTtcbiAgdmFyIGVsZW1lbnRzID0gW107XG5cbiAgZWxlbWVudCA9IGVsZW1lbnQgfHwgaW50ZXJhY3Rpb24uZWxlbWVudDtcblxuICAvLyBjb2xsZWN0IGFsbCBkcm9wem9uZXMgYW5kIHRoZWlyIGVsZW1lbnRzIHdoaWNoIHF1YWxpZnkgZm9yIGEgZHJvcFxuICBmb3IgKHZhciBfaXRlcmF0b3IgPSBzY29wZS5pbnRlcmFjdGFibGVzLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xuICAgIHZhciBfcmVmNjtcblxuICAgIGlmIChfaXNBcnJheSkge1xuICAgICAgaWYgKF9pID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xuICAgICAgX3JlZjYgPSBfaXRlcmF0b3JbX2krK107XG4gICAgfSBlbHNlIHtcbiAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcbiAgICAgIF9yZWY2ID0gX2kudmFsdWU7XG4gICAgfVxuXG4gICAgdmFyIGN1cnJlbnQgPSBfcmVmNjtcblxuICAgIGlmICghY3VycmVudC5vcHRpb25zLmRyb3AuZW5hYmxlZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIGFjY2VwdCA9IGN1cnJlbnQub3B0aW9ucy5kcm9wLmFjY2VwdDtcblxuICAgIC8vIHRlc3QgdGhlIGRyYWdnYWJsZSBlbGVtZW50IGFnYWluc3QgdGhlIGRyb3B6b25lJ3MgYWNjZXB0IHNldHRpbmdcbiAgICBpZiAodXRpbHMuaXMuZWxlbWVudChhY2NlcHQpICYmIGFjY2VwdCAhPT0gZWxlbWVudCB8fCB1dGlscy5pcy5zdHJpbmcoYWNjZXB0KSAmJiAhdXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIGFjY2VwdCkpIHtcblxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gcXVlcnkgZm9yIG5ldyBlbGVtZW50cyBpZiBuZWNlc3NhcnlcbiAgICB2YXIgZHJvcEVsZW1lbnRzID0gdXRpbHMuaXMuc3RyaW5nKGN1cnJlbnQudGFyZ2V0KSA/IGN1cnJlbnQuX2NvbnRleHQucXVlcnlTZWxlY3RvckFsbChjdXJyZW50LnRhcmdldCkgOiBbY3VycmVudC50YXJnZXRdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkcm9wRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjdXJyZW50RWxlbWVudCA9IGRyb3BFbGVtZW50c1tpXTtcblxuICAgICAgaWYgKGN1cnJlbnRFbGVtZW50ICE9PSBlbGVtZW50KSB7XG4gICAgICAgIGRyb3BzLnB1c2goY3VycmVudCk7XG4gICAgICAgIGVsZW1lbnRzLnB1c2goY3VycmVudEVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZWxlbWVudHM6IGVsZW1lbnRzLFxuICAgIGRyb3B6b25lczogZHJvcHNcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmlyZUFjdGl2ZURyb3BzKGludGVyYWN0aW9uLCBldmVudCkge1xuICB2YXIgcHJldkVsZW1lbnQgPSB2b2lkIDA7XG5cbiAgLy8gbG9vcCB0aHJvdWdoIGFsbCBhY3RpdmUgZHJvcHpvbmVzIGFuZCB0cmlnZ2VyIGV2ZW50XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXNbaV07XG4gICAgdmFyIGN1cnJlbnRFbGVtZW50ID0gaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZWxlbWVudHNbaV07XG5cbiAgICAvLyBwcmV2ZW50IHRyaWdnZXIgb2YgZHVwbGljYXRlIGV2ZW50cyBvbiBzYW1lIGVsZW1lbnRcbiAgICBpZiAoY3VycmVudEVsZW1lbnQgIT09IHByZXZFbGVtZW50KSB7XG4gICAgICAvLyBzZXQgY3VycmVudCBlbGVtZW50IGFzIGV2ZW50IHRhcmdldFxuICAgICAgZXZlbnQudGFyZ2V0ID0gY3VycmVudEVsZW1lbnQ7XG4gICAgICBjdXJyZW50LmZpcmUoZXZlbnQpO1xuICAgIH1cbiAgICBwcmV2RWxlbWVudCA9IGN1cnJlbnRFbGVtZW50O1xuICB9XG59XG5cbi8vIENvbGxlY3QgYSBuZXcgc2V0IG9mIHBvc3NpYmxlIGRyb3BzIGFuZCBzYXZlIHRoZW0gaW4gYWN0aXZlRHJvcHMuXG4vLyBzZXRBY3RpdmVEcm9wcyBzaG91bGQgYWx3YXlzIGJlIGNhbGxlZCB3aGVuIGEgZHJhZyBoYXMganVzdCBzdGFydGVkIG9yIGFcbi8vIGRyYWcgZXZlbnQgaGFwcGVucyB3aGlsZSBkeW5hbWljRHJvcCBpcyB0cnVlXG5mdW5jdGlvbiBzZXRBY3RpdmVEcm9wcyhpbnRlcmFjdGlvbiwgZHJhZ0VsZW1lbnQpIHtcbiAgLy8gZ2V0IGRyb3B6b25lcyBhbmQgdGhlaXIgZWxlbWVudHMgdGhhdCBjb3VsZCByZWNlaXZlIHRoZSBkcmFnZ2FibGVcbiAgdmFyIHBvc3NpYmxlRHJvcHMgPSBjb2xsZWN0RHJvcHMoaW50ZXJhY3Rpb24sIGRyYWdFbGVtZW50LCB0cnVlKTtcblxuICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXMgPSBwb3NzaWJsZURyb3BzLmRyb3B6b25lcztcbiAgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZWxlbWVudHMgPSBwb3NzaWJsZURyb3BzLmVsZW1lbnRzO1xuICBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5yZWN0cyA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMucmVjdHNbaV0gPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXNbaV0uZ2V0UmVjdChpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5lbGVtZW50c1tpXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0RHJvcChkcmFnRXZlbnQsIGV2ZW50LCBkcmFnRWxlbWVudCkge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBkcmFnRXZlbnQuaW50ZXJhY3Rpb247XG4gIHZhciB2YWxpZERyb3BzID0gW107XG5cbiAgaWYgKGR5bmFtaWNEcm9wKSB7XG4gICAgc2V0QWN0aXZlRHJvcHMoaW50ZXJhY3Rpb24sIGRyYWdFbGVtZW50KTtcbiAgfVxuXG4gIC8vIGNvbGxlY3QgYWxsIGRyb3B6b25lcyBhbmQgdGhlaXIgZWxlbWVudHMgd2hpY2ggcXVhbGlmeSBmb3IgYSBkcm9wXG4gIGZvciAodmFyIGogPSAwOyBqIDwgaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZHJvcHpvbmVzLmxlbmd0aDsgaisrKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXNbal07XG4gICAgdmFyIGN1cnJlbnRFbGVtZW50ID0gaW50ZXJhY3Rpb24uYWN0aXZlRHJvcHMuZWxlbWVudHNbal07XG4gICAgdmFyIHJlY3QgPSBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5yZWN0c1tqXTtcblxuICAgIHZhbGlkRHJvcHMucHVzaChjdXJyZW50LmRyb3BDaGVjayhkcmFnRXZlbnQsIGV2ZW50LCBpbnRlcmFjdGlvbi50YXJnZXQsIGRyYWdFbGVtZW50LCBjdXJyZW50RWxlbWVudCwgcmVjdCkgPyBjdXJyZW50RWxlbWVudCA6IG51bGwpO1xuICB9XG5cbiAgLy8gZ2V0IHRoZSBtb3N0IGFwcHJvcHJpYXRlIGRyb3B6b25lIGJhc2VkIG9uIERPTSBkZXB0aCBhbmQgb3JkZXJcbiAgdmFyIGRyb3BJbmRleCA9IHV0aWxzLmluZGV4T2ZEZWVwZXN0RWxlbWVudCh2YWxpZERyb3BzKTtcblxuICByZXR1cm4ge1xuICAgIGRyb3B6b25lOiBpbnRlcmFjdGlvbi5hY3RpdmVEcm9wcy5kcm9wem9uZXNbZHJvcEluZGV4XSB8fCBudWxsLFxuICAgIGVsZW1lbnQ6IGludGVyYWN0aW9uLmFjdGl2ZURyb3BzLmVsZW1lbnRzW2Ryb3BJbmRleF0gfHwgbnVsbFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXREcm9wRXZlbnRzKGludGVyYWN0aW9uLCBwb2ludGVyRXZlbnQsIGRyYWdFdmVudCkge1xuICB2YXIgZHJvcEV2ZW50cyA9IHtcbiAgICBlbnRlcjogbnVsbCxcbiAgICBsZWF2ZTogbnVsbCxcbiAgICBhY3RpdmF0ZTogbnVsbCxcbiAgICBkZWFjdGl2YXRlOiBudWxsLFxuICAgIG1vdmU6IG51bGwsXG4gICAgZHJvcDogbnVsbFxuICB9O1xuXG4gIHZhciB0bXBsID0ge1xuICAgIGRyYWdFdmVudDogZHJhZ0V2ZW50LFxuICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcbiAgICB0YXJnZXQ6IGludGVyYWN0aW9uLmRyb3BFbGVtZW50LFxuICAgIGRyb3B6b25lOiBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0LFxuICAgIHJlbGF0ZWRUYXJnZXQ6IGRyYWdFdmVudC50YXJnZXQsXG4gICAgZHJhZ2dhYmxlOiBkcmFnRXZlbnQuaW50ZXJhY3RhYmxlLFxuICAgIHRpbWVTdGFtcDogZHJhZ0V2ZW50LnRpbWVTdGFtcFxuICB9O1xuXG4gIGlmIChpbnRlcmFjdGlvbi5kcm9wRWxlbWVudCAhPT0gaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50KSB7XG4gICAgLy8gaWYgdGhlcmUgd2FzIGEgcHJldkRyb3BUYXJnZXQsIGNyZWF0ZSBhIGRyYWdsZWF2ZSBldmVudFxuICAgIGlmIChpbnRlcmFjdGlvbi5wcmV2RHJvcFRhcmdldCkge1xuICAgICAgZHJvcEV2ZW50cy5sZWF2ZSA9IHV0aWxzLmV4dGVuZCh7IHR5cGU6ICdkcmFnbGVhdmUnIH0sIHRtcGwpO1xuXG4gICAgICBkcmFnRXZlbnQuZHJhZ0xlYXZlID0gZHJvcEV2ZW50cy5sZWF2ZS50YXJnZXQgPSBpbnRlcmFjdGlvbi5wcmV2RHJvcEVsZW1lbnQ7XG4gICAgICBkcmFnRXZlbnQucHJldkRyb3B6b25lID0gZHJvcEV2ZW50cy5sZWF2ZS5kcm9wem9uZSA9IGludGVyYWN0aW9uLnByZXZEcm9wVGFyZ2V0O1xuICAgIH1cbiAgICAvLyBpZiB0aGUgZHJvcFRhcmdldCBpcyBub3QgbnVsbCwgY3JlYXRlIGEgZHJhZ2VudGVyIGV2ZW50XG4gICAgaWYgKGludGVyYWN0aW9uLmRyb3BUYXJnZXQpIHtcbiAgICAgIGRyb3BFdmVudHMuZW50ZXIgPSB7XG4gICAgICAgIGRyYWdFdmVudDogZHJhZ0V2ZW50LFxuICAgICAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXG4gICAgICAgIHRhcmdldDogaW50ZXJhY3Rpb24uZHJvcEVsZW1lbnQsXG4gICAgICAgIGRyb3B6b25lOiBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0LFxuICAgICAgICByZWxhdGVkVGFyZ2V0OiBkcmFnRXZlbnQudGFyZ2V0LFxuICAgICAgICBkcmFnZ2FibGU6IGRyYWdFdmVudC5pbnRlcmFjdGFibGUsXG4gICAgICAgIHRpbWVTdGFtcDogZHJhZ0V2ZW50LnRpbWVTdGFtcCxcbiAgICAgICAgdHlwZTogJ2RyYWdlbnRlcidcbiAgICAgIH07XG5cbiAgICAgIGRyYWdFdmVudC5kcmFnRW50ZXIgPSBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudDtcbiAgICAgIGRyYWdFdmVudC5kcm9wem9uZSA9IGludGVyYWN0aW9uLmRyb3BUYXJnZXQ7XG4gICAgfVxuICB9XG5cbiAgaWYgKGRyYWdFdmVudC50eXBlID09PSAnZHJhZ2VuZCcgJiYgaW50ZXJhY3Rpb24uZHJvcFRhcmdldCkge1xuICAgIGRyb3BFdmVudHMuZHJvcCA9IHV0aWxzLmV4dGVuZCh7IHR5cGU6ICdkcm9wJyB9LCB0bXBsKTtcblxuICAgIGRyYWdFdmVudC5kcm9wem9uZSA9IGludGVyYWN0aW9uLmRyb3BUYXJnZXQ7XG4gICAgZHJhZ0V2ZW50LnJlbGF0ZWRUYXJnZXQgPSBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudDtcbiAgfVxuICBpZiAoZHJhZ0V2ZW50LnR5cGUgPT09ICdkcmFnc3RhcnQnKSB7XG4gICAgZHJvcEV2ZW50cy5hY3RpdmF0ZSA9IHV0aWxzLmV4dGVuZCh7IHR5cGU6ICdkcm9wYWN0aXZhdGUnIH0sIHRtcGwpO1xuXG4gICAgZHJvcEV2ZW50cy5hY3RpdmF0ZS50YXJnZXQgPSBudWxsO1xuICAgIGRyb3BFdmVudHMuYWN0aXZhdGUuZHJvcHpvbmUgPSBudWxsO1xuICB9XG4gIGlmIChkcmFnRXZlbnQudHlwZSA9PT0gJ2RyYWdlbmQnKSB7XG4gICAgZHJvcEV2ZW50cy5kZWFjdGl2YXRlID0gdXRpbHMuZXh0ZW5kKHsgdHlwZTogJ2Ryb3BkZWFjdGl2YXRlJyB9LCB0bXBsKTtcblxuICAgIGRyb3BFdmVudHMuZGVhY3RpdmF0ZS50YXJnZXQgPSBudWxsO1xuICAgIGRyb3BFdmVudHMuZGVhY3RpdmF0ZS5kcm9wem9uZSA9IG51bGw7XG4gIH1cbiAgaWYgKGRyYWdFdmVudC50eXBlID09PSAnZHJhZ21vdmUnICYmIGludGVyYWN0aW9uLmRyb3BUYXJnZXQpIHtcbiAgICBkcm9wRXZlbnRzLm1vdmUgPSB1dGlscy5leHRlbmQoe1xuICAgICAgZHJhZ21vdmU6IGRyYWdFdmVudCxcbiAgICAgIHR5cGU6ICdkcm9wbW92ZSdcbiAgICB9LCB0bXBsKTtcblxuICAgIGRyYWdFdmVudC5kcm9wem9uZSA9IGludGVyYWN0aW9uLmRyb3BUYXJnZXQ7XG4gIH1cblxuICByZXR1cm4gZHJvcEV2ZW50cztcbn1cblxuZnVuY3Rpb24gZmlyZURyb3BFdmVudHMoaW50ZXJhY3Rpb24sIGRyb3BFdmVudHMpIHtcbiAgaWYgKGRyb3BFdmVudHMubGVhdmUpIHtcbiAgICBpbnRlcmFjdGlvbi5wcmV2RHJvcFRhcmdldC5maXJlKGRyb3BFdmVudHMubGVhdmUpO1xuICB9XG4gIGlmIChkcm9wRXZlbnRzLm1vdmUpIHtcbiAgICBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0LmZpcmUoZHJvcEV2ZW50cy5tb3ZlKTtcbiAgfVxuICBpZiAoZHJvcEV2ZW50cy5lbnRlcikge1xuICAgIGludGVyYWN0aW9uLmRyb3BUYXJnZXQuZmlyZShkcm9wRXZlbnRzLmVudGVyKTtcbiAgfVxuICBpZiAoZHJvcEV2ZW50cy5kcm9wKSB7XG4gICAgaW50ZXJhY3Rpb24uZHJvcFRhcmdldC5maXJlKGRyb3BFdmVudHMuZHJvcCk7XG4gIH1cbiAgaWYgKGRyb3BFdmVudHMuZGVhY3RpdmF0ZSkge1xuICAgIGZpcmVBY3RpdmVEcm9wcyhpbnRlcmFjdGlvbiwgZHJvcEV2ZW50cy5kZWFjdGl2YXRlKTtcbiAgfVxuXG4gIGludGVyYWN0aW9uLnByZXZEcm9wVGFyZ2V0ID0gaW50ZXJhY3Rpb24uZHJvcFRhcmdldDtcbiAgaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50ID0gaW50ZXJhY3Rpb24uZHJvcEVsZW1lbnQ7XG59XG5cbi8qXFxcbiAqIEludGVyYWN0YWJsZS5kcm9wem9uZVxuIFsgbWV0aG9kIF1cbiAqXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciBlbGVtZW50cyBjYW4gYmUgZHJvcHBlZCBvbnRvIHRoaXNcbiAqIEludGVyYWN0YWJsZSB0byB0cmlnZ2VyIGRyb3AgZXZlbnRzXG4gKlxuICogRHJvcHpvbmVzIGNhbiByZWNlaXZlIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICogIC0gYGRyb3BhY3RpdmF0ZWAgYW5kIGBkcm9wZGVhY3RpdmF0ZWAgd2hlbiBhbiBhY2NlcHRhYmxlIGRyYWcgc3RhcnRzIGFuZCBlbmRzXG4gKiAgLSBgZHJhZ2VudGVyYCBhbmQgYGRyYWdsZWF2ZWAgd2hlbiBhIGRyYWdnYWJsZSBlbnRlcnMgYW5kIGxlYXZlcyB0aGUgZHJvcHpvbmVcbiAqICAtIGBkcmFnbW92ZWAgd2hlbiBhIGRyYWdnYWJsZSB0aGF0IGhhcyBlbnRlcmVkIHRoZSBkcm9wem9uZSBpcyBtb3ZlZFxuICogIC0gYGRyb3BgIHdoZW4gYSBkcmFnZ2FibGUgaXMgZHJvcHBlZCBpbnRvIHRoaXMgZHJvcHpvbmVcbiAqXG4gKiBVc2UgdGhlIGBhY2NlcHRgIG9wdGlvbiB0byBhbGxvdyBvbmx5IGVsZW1lbnRzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIENTU1xuICogc2VsZWN0b3Igb3IgZWxlbWVudC4gVGhlIHZhbHVlIGNhbiBiZTpcbiAqXG4gKiAgLSAqKmFuIEVsZW1lbnQqKiAtIG9ubHkgdGhhdCBlbGVtZW50IGNhbiBiZSBkcm9wcGVkIGludG8gdGhpcyBkcm9wem9uZS5cbiAqICAtICoqYSBzdHJpbmcqKiwgLSB0aGUgZWxlbWVudCBiZWluZyBkcmFnZ2VkIG11c3QgbWF0Y2ggaXQgYXMgYSBDU1Mgc2VsZWN0b3IuXG4gKiAgLSAqKmBudWxsYCoqIC0gYWNjZXB0IG9wdGlvbnMgaXMgY2xlYXJlZCAtIGl0IGFjY2VwdHMgYW55IGVsZW1lbnQuXG4gKlxuICogVXNlIHRoZSBgb3ZlcmxhcGAgb3B0aW9uIHRvIHNldCBob3cgZHJvcHMgYXJlIGNoZWNrZWQgZm9yLiBUaGUgYWxsb3dlZFxuICogdmFsdWVzIGFyZTpcbiAqXG4gKiAgIC0gYCdwb2ludGVyJ2AsIHRoZSBwb2ludGVyIG11c3QgYmUgb3ZlciB0aGUgZHJvcHpvbmUgKGRlZmF1bHQpXG4gKiAgIC0gYCdjZW50ZXInYCwgdGhlIGRyYWdnYWJsZSBlbGVtZW50J3MgY2VudGVyIG11c3QgYmUgb3ZlciB0aGUgZHJvcHpvbmVcbiAqICAgLSBhIG51bWJlciBmcm9tIDAtMSB3aGljaCBpcyB0aGUgYChpbnRlcnNlY3Rpb24gYXJlYSkgLyAoZHJhZ2dhYmxlIGFyZWEpYC5cbiAqICAgZS5nLiBgMC41YCBmb3IgZHJvcCB0byBoYXBwZW4gd2hlbiBoYWxmIG9mIHRoZSBhcmVhIG9mIHRoZSBkcmFnZ2FibGUgaXNcbiAqICAgb3ZlciB0aGUgZHJvcHpvbmVcbiAqXG4gKiBVc2UgdGhlIGBjaGVja2VyYCBvcHRpb24gdG8gc3BlY2lmeSBhIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIGEgZHJhZ2dlZFxuICogZWxlbWVudCBpcyBvdmVyIHRoaXMgSW50ZXJhY3RhYmxlLlxuICpcbiB8IGludGVyYWN0KHRhcmdldClcbiB8IC5kcm9wQ2hlY2tlcihmdW5jdGlvbihkcmFnRXZlbnQsICAgICAgICAgLy8gcmVsYXRlZCBkcmFnbW92ZSBvciBkcmFnZW5kIGV2ZW50XG4gfCAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQsICAgICAgICAgICAgIC8vIFRvdWNoRXZlbnQvUG9pbnRlckV2ZW50L01vdXNlRXZlbnRcbiB8ICAgICAgICAgICAgICAgICAgICAgICBkcm9wcGVkLCAgICAgICAgICAgLy8gYm9vbCByZXN1bHQgb2YgdGhlIGRlZmF1bHQgY2hlY2tlclxuIHwgICAgICAgICAgICAgICAgICAgICAgIGRyb3B6b25lLCAgICAgICAgICAvLyBkcm9wem9uZSBJbnRlcmFjdGFibGVcbiB8ICAgICAgICAgICAgICAgICAgICAgICBkcm9wRWxlbWVudCwgICAgICAgLy8gZHJvcHpvbmUgZWxlbW50XG4gfCAgICAgICAgICAgICAgICAgICAgICAgZHJhZ2dhYmxlLCAgICAgICAgIC8vIGRyYWdnYWJsZSBJbnRlcmFjdGFibGVcbiB8ICAgICAgICAgICAgICAgICAgICAgICBkcmFnZ2FibGVFbGVtZW50KSB7Ly8gZHJhZ2dhYmxlIGVsZW1lbnRcbiB8XG4gfCAgIHJldHVybiBkcm9wcGVkICYmIGV2ZW50LnRhcmdldC5oYXNBdHRyaWJ1dGUoJ2FsbG93LWRyb3AnKTtcbiB8IH1cbiAqXG4gKlxuIC0gb3B0aW9ucyAoYm9vbGVhbiB8IG9iamVjdCB8IG51bGwpICNvcHRpb25hbCBUaGUgbmV3IHZhbHVlIHRvIGJlIHNldC5cbiB8IGludGVyYWN0KCcuZHJvcCcpLmRyb3B6b25lKHtcbiB8ICAgYWNjZXB0OiAnLmNhbi1kcm9wJyB8fCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2luZ2xlLWRyb3AnKSxcbiB8ICAgb3ZlcmxhcDogJ3BvaW50ZXInIHx8ICdjZW50ZXInIHx8IHplcm9Ub09uZVxuIHwgfVxuID0gKGJvb2xlYW4gfCBvYmplY3QpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgdGhpcyBJbnRlcmFjdGFibGVcblxcKi9cbkludGVyYWN0YWJsZS5wcm90b3R5cGUuZHJvcHpvbmUgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICBpZiAodXRpbHMuaXMub2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgdGhpcy5vcHRpb25zLmRyb3AuZW5hYmxlZCA9IG9wdGlvbnMuZW5hYmxlZCA9PT0gZmFsc2UgPyBmYWxzZSA6IHRydWU7XG5cbiAgICBpZiAodXRpbHMuaXMuZnVuY3Rpb24ob3B0aW9ucy5vbmRyb3ApKSB7XG4gICAgICB0aGlzLmV2ZW50cy5vbmRyb3AgPSBvcHRpb25zLm9uZHJvcDtcbiAgICB9XG4gICAgaWYgKHV0aWxzLmlzLmZ1bmN0aW9uKG9wdGlvbnMub25kcm9wYWN0aXZhdGUpKSB7XG4gICAgICB0aGlzLmV2ZW50cy5vbmRyb3BhY3RpdmF0ZSA9IG9wdGlvbnMub25kcm9wYWN0aXZhdGU7XG4gICAgfVxuICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihvcHRpb25zLm9uZHJvcGRlYWN0aXZhdGUpKSB7XG4gICAgICB0aGlzLmV2ZW50cy5vbmRyb3BkZWFjdGl2YXRlID0gb3B0aW9ucy5vbmRyb3BkZWFjdGl2YXRlO1xuICAgIH1cbiAgICBpZiAodXRpbHMuaXMuZnVuY3Rpb24ob3B0aW9ucy5vbmRyYWdlbnRlcikpIHtcbiAgICAgIHRoaXMuZXZlbnRzLm9uZHJhZ2VudGVyID0gb3B0aW9ucy5vbmRyYWdlbnRlcjtcbiAgICB9XG4gICAgaWYgKHV0aWxzLmlzLmZ1bmN0aW9uKG9wdGlvbnMub25kcmFnbGVhdmUpKSB7XG4gICAgICB0aGlzLmV2ZW50cy5vbmRyYWdsZWF2ZSA9IG9wdGlvbnMub25kcmFnbGVhdmU7XG4gICAgfVxuICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihvcHRpb25zLm9uZHJvcG1vdmUpKSB7XG4gICAgICB0aGlzLmV2ZW50cy5vbmRyb3Btb3ZlID0gb3B0aW9ucy5vbmRyb3Btb3ZlO1xuICAgIH1cblxuICAgIGlmICgvXihwb2ludGVyfGNlbnRlcikkLy50ZXN0KG9wdGlvbnMub3ZlcmxhcCkpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5kcm9wLm92ZXJsYXAgPSBvcHRpb25zLm92ZXJsYXA7XG4gICAgfSBlbHNlIGlmICh1dGlscy5pcy5udW1iZXIob3B0aW9ucy5vdmVybGFwKSkge1xuICAgICAgdGhpcy5vcHRpb25zLmRyb3Aub3ZlcmxhcCA9IE1hdGgubWF4KE1hdGgubWluKDEsIG9wdGlvbnMub3ZlcmxhcCksIDApO1xuICAgIH1cbiAgICBpZiAoJ2FjY2VwdCcgaW4gb3B0aW9ucykge1xuICAgICAgdGhpcy5vcHRpb25zLmRyb3AuYWNjZXB0ID0gb3B0aW9ucy5hY2NlcHQ7XG4gICAgfVxuICAgIGlmICgnY2hlY2tlcicgaW4gb3B0aW9ucykge1xuICAgICAgdGhpcy5vcHRpb25zLmRyb3AuY2hlY2tlciA9IG9wdGlvbnMuY2hlY2tlcjtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGlmICh1dGlscy5pcy5ib29sKG9wdGlvbnMpKSB7XG4gICAgdGhpcy5vcHRpb25zLmRyb3AuZW5hYmxlZCA9IG9wdGlvbnM7XG5cbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIHRoaXMub25kcmFnZW50ZXIgPSB0aGlzLm9uZHJhZ2xlYXZlID0gdGhpcy5vbmRyb3AgPSB0aGlzLm9uZHJvcGFjdGl2YXRlID0gdGhpcy5vbmRyb3BkZWFjdGl2YXRlID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHJldHVybiB0aGlzLm9wdGlvbnMuZHJvcDtcbn07XG5cbkludGVyYWN0YWJsZS5wcm90b3R5cGUuZHJvcENoZWNrID0gZnVuY3Rpb24gKGRyYWdFdmVudCwgZXZlbnQsIGRyYWdnYWJsZSwgZHJhZ2dhYmxlRWxlbWVudCwgZHJvcEVsZW1lbnQsIHJlY3QpIHtcbiAgdmFyIGRyb3BwZWQgPSBmYWxzZTtcblxuICAvLyBpZiB0aGUgZHJvcHpvbmUgaGFzIG5vIHJlY3QgKGVnLiBkaXNwbGF5OiBub25lKVxuICAvLyBjYWxsIHRoZSBjdXN0b20gZHJvcENoZWNrZXIgb3IganVzdCByZXR1cm4gZmFsc2VcbiAgaWYgKCEocmVjdCA9IHJlY3QgfHwgdGhpcy5nZXRSZWN0KGRyb3BFbGVtZW50KSkpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmRyb3AuY2hlY2tlciA/IHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXIoZHJhZ0V2ZW50LCBldmVudCwgZHJvcHBlZCwgdGhpcywgZHJvcEVsZW1lbnQsIGRyYWdnYWJsZSwgZHJhZ2dhYmxlRWxlbWVudCkgOiBmYWxzZTtcbiAgfVxuXG4gIHZhciBkcm9wT3ZlcmxhcCA9IHRoaXMub3B0aW9ucy5kcm9wLm92ZXJsYXA7XG5cbiAgaWYgKGRyb3BPdmVybGFwID09PSAncG9pbnRlcicpIHtcbiAgICB2YXIgb3JpZ2luID0gdXRpbHMuZ2V0T3JpZ2luWFkoZHJhZ2dhYmxlLCBkcmFnZ2FibGVFbGVtZW50LCAnZHJhZycpO1xuICAgIHZhciBwYWdlID0gdXRpbHMuZ2V0UGFnZVhZKGRyYWdFdmVudCk7XG5cbiAgICBwYWdlLnggKz0gb3JpZ2luLng7XG4gICAgcGFnZS55ICs9IG9yaWdpbi55O1xuXG4gICAgdmFyIGhvcml6b250YWwgPSBwYWdlLnggPiByZWN0LmxlZnQgJiYgcGFnZS54IDwgcmVjdC5yaWdodDtcbiAgICB2YXIgdmVydGljYWwgPSBwYWdlLnkgPiByZWN0LnRvcCAmJiBwYWdlLnkgPCByZWN0LmJvdHRvbTtcblxuICAgIGRyb3BwZWQgPSBob3Jpem9udGFsICYmIHZlcnRpY2FsO1xuICB9XG5cbiAgdmFyIGRyYWdSZWN0ID0gZHJhZ2dhYmxlLmdldFJlY3QoZHJhZ2dhYmxlRWxlbWVudCk7XG5cbiAgaWYgKGRyYWdSZWN0ICYmIGRyb3BPdmVybGFwID09PSAnY2VudGVyJykge1xuICAgIHZhciBjeCA9IGRyYWdSZWN0LmxlZnQgKyBkcmFnUmVjdC53aWR0aCAvIDI7XG4gICAgdmFyIGN5ID0gZHJhZ1JlY3QudG9wICsgZHJhZ1JlY3QuaGVpZ2h0IC8gMjtcblxuICAgIGRyb3BwZWQgPSBjeCA+PSByZWN0LmxlZnQgJiYgY3ggPD0gcmVjdC5yaWdodCAmJiBjeSA+PSByZWN0LnRvcCAmJiBjeSA8PSByZWN0LmJvdHRvbTtcbiAgfVxuXG4gIGlmIChkcmFnUmVjdCAmJiB1dGlscy5pcy5udW1iZXIoZHJvcE92ZXJsYXApKSB7XG4gICAgdmFyIG92ZXJsYXBBcmVhID0gTWF0aC5tYXgoMCwgTWF0aC5taW4ocmVjdC5yaWdodCwgZHJhZ1JlY3QucmlnaHQpIC0gTWF0aC5tYXgocmVjdC5sZWZ0LCBkcmFnUmVjdC5sZWZ0KSkgKiBNYXRoLm1heCgwLCBNYXRoLm1pbihyZWN0LmJvdHRvbSwgZHJhZ1JlY3QuYm90dG9tKSAtIE1hdGgubWF4KHJlY3QudG9wLCBkcmFnUmVjdC50b3ApKTtcblxuICAgIHZhciBvdmVybGFwUmF0aW8gPSBvdmVybGFwQXJlYSAvIChkcmFnUmVjdC53aWR0aCAqIGRyYWdSZWN0LmhlaWdodCk7XG5cbiAgICBkcm9wcGVkID0gb3ZlcmxhcFJhdGlvID49IGRyb3BPdmVybGFwO1xuICB9XG5cbiAgaWYgKHRoaXMub3B0aW9ucy5kcm9wLmNoZWNrZXIpIHtcbiAgICBkcm9wcGVkID0gdGhpcy5vcHRpb25zLmRyb3AuY2hlY2tlcihkcmFnRXZlbnQsIGV2ZW50LCBkcm9wcGVkLCB0aGlzLCBkcm9wRWxlbWVudCwgZHJhZ2dhYmxlLCBkcmFnZ2FibGVFbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiBkcm9wcGVkO1xufTtcblxuSW50ZXJhY3RhYmxlLnNpZ25hbHMub24oJ3Vuc2V0JywgZnVuY3Rpb24gKF9yZWY3KSB7XG4gIHZhciBpbnRlcmFjdGFibGUgPSBfcmVmNy5pbnRlcmFjdGFibGU7XG5cbiAgaW50ZXJhY3RhYmxlLmRyb3B6b25lKGZhbHNlKTtcbn0pO1xuXG5JbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLnB1c2goJ2Ryb3BDaGVja2VyJyk7XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xuICBpbnRlcmFjdGlvbi5kcm9wVGFyZ2V0ID0gbnVsbDsgLy8gdGhlIGRyb3B6b25lIGEgZHJhZyB0YXJnZXQgbWlnaHQgYmUgZHJvcHBlZCBpbnRvXG4gIGludGVyYWN0aW9uLmRyb3BFbGVtZW50ID0gbnVsbDsgLy8gdGhlIGVsZW1lbnQgYXQgdGhlIHRpbWUgb2YgY2hlY2tpbmdcbiAgaW50ZXJhY3Rpb24ucHJldkRyb3BUYXJnZXQgPSBudWxsOyAvLyB0aGUgZHJvcHpvbmUgdGhhdCB3YXMgcmVjZW50bHkgZHJhZ2dlZCBhd2F5IGZyb21cbiAgaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50ID0gbnVsbDsgLy8gdGhlIGVsZW1lbnQgYXQgdGhlIHRpbWUgb2YgY2hlY2tpbmdcbiAgaW50ZXJhY3Rpb24uZHJvcEV2ZW50cyA9IG51bGw7IC8vIHRoZSBkcm9wRXZlbnRzIHJlbGF0ZWQgdG8gdGhlIGN1cnJlbnQgZHJhZyBldmVudFxuXG4gIGludGVyYWN0aW9uLmFjdGl2ZURyb3BzID0ge1xuICAgIGRyb3B6b25lczogW10sIC8vIHRoZSBkcm9wem9uZXMgdGhhdCBhcmUgbWVudGlvbmVkIGJlbG93XG4gICAgZWxlbWVudHM6IFtdLCAvLyBlbGVtZW50cyBvZiBkcm9wem9uZXMgdGhhdCBhY2NlcHQgdGhlIHRhcmdldCBkcmFnZ2FibGVcbiAgICByZWN0czogW10gLy8gdGhlIHJlY3RzIG9mIHRoZSBlbGVtZW50cyBtZW50aW9uZWQgYWJvdmVcbiAgfTtcbn0pO1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdzdG9wJywgZnVuY3Rpb24gKF9yZWY4KSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY4LmludGVyYWN0aW9uO1xuXG4gIGludGVyYWN0aW9uLmRyb3BUYXJnZXQgPSBpbnRlcmFjdGlvbi5kcm9wRWxlbWVudCA9IGludGVyYWN0aW9uLnByZXZEcm9wVGFyZ2V0ID0gaW50ZXJhY3Rpb24ucHJldkRyb3BFbGVtZW50ID0gbnVsbDtcbn0pO1xuXG4vKlxcXG4gKiBpbnRlcmFjdC5keW5hbWljRHJvcFxuIFsgbWV0aG9kIF1cbiAqXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciB0aGUgZGltZW5zaW9ucyBvZiBkcm9wem9uZSBlbGVtZW50cyBhcmVcbiAqIGNhbGN1bGF0ZWQgb24gZXZlcnkgZHJhZ21vdmUgb3Igb25seSBvbiBkcmFnc3RhcnQgZm9yIHRoZSBkZWZhdWx0XG4gKiBkcm9wQ2hlY2tlclxuICpcbiAtIG5ld1ZhbHVlIChib29sZWFuKSAjb3B0aW9uYWwgVHJ1ZSB0byBjaGVjayBvbiBlYWNoIG1vdmUuIEZhbHNlIHRvIGNoZWNrIG9ubHkgYmVmb3JlIHN0YXJ0XG4gPSAoYm9vbGVhbiB8IGludGVyYWN0KSBUaGUgY3VycmVudCBzZXR0aW5nIG9yIGludGVyYWN0XG5cXCovXG5pbnRlcmFjdC5keW5hbWljRHJvcCA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICBpZiAodXRpbHMuaXMuYm9vbChuZXdWYWx1ZSkpIHtcbiAgICAvL2lmIChkcmFnZ2luZyAmJiBkeW5hbWljRHJvcCAhPT0gbmV3VmFsdWUgJiYgIW5ld1ZhbHVlKSB7XG4gICAgLy9jYWxjUmVjdHMoZHJvcHpvbmVzKTtcbiAgICAvL31cblxuICAgIGR5bmFtaWNEcm9wID0gbmV3VmFsdWU7XG5cbiAgICByZXR1cm4gaW50ZXJhY3Q7XG4gIH1cbiAgcmV0dXJuIGR5bmFtaWNEcm9wO1xufTtcblxudXRpbHMubWVyZ2UoSW50ZXJhY3RhYmxlLmV2ZW50VHlwZXMsIFsnZHJhZ2VudGVyJywgJ2RyYWdsZWF2ZScsICdkcm9wYWN0aXZhdGUnLCAnZHJvcGRlYWN0aXZhdGUnLCAnZHJvcG1vdmUnLCAnZHJvcCddKTtcbmFjdGlvbnMubWV0aG9kRGljdC5kcm9wID0gJ2Ryb3B6b25lJztcblxuZGVmYXVsdE9wdGlvbnMuZHJvcCA9IGRyb3AuZGVmYXVsdHM7XG5cbm1vZHVsZS5leHBvcnRzID0gZHJvcDtcblxufSx7XCIuLi9JbnRlcmFjdEV2ZW50XCI6MyxcIi4uL0ludGVyYWN0YWJsZVwiOjQsXCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuLi9kZWZhdWx0T3B0aW9uc1wiOjE4LFwiLi4vaW50ZXJhY3RcIjoyMSxcIi4uL3Njb3BlXCI6MzQsXCIuLi91dGlsc1wiOjQ0LFwiLi9iYXNlXCI6Nn1dLDk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoJy4vYmFzZScpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBJbnRlcmFjdEV2ZW50ID0gcmVxdWlyZSgnLi4vSW50ZXJhY3RFdmVudCcpO1xudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4uL0ludGVyYWN0YWJsZScpO1xudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcbnZhciBkZWZhdWx0T3B0aW9ucyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRPcHRpb25zJyk7XG5cbnZhciBnZXN0dXJlID0ge1xuICBkZWZhdWx0czoge1xuICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgIG9yaWdpbjogbnVsbCxcbiAgICByZXN0cmljdDogbnVsbFxuICB9LFxuXG4gIGNoZWNrZXI6IGZ1bmN0aW9uIGNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0YWJsZSwgZWxlbWVudCwgaW50ZXJhY3Rpb24pIHtcbiAgICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlcklkcy5sZW5ndGggPj0gMikge1xuICAgICAgcmV0dXJuIHsgbmFtZTogJ2dlc3R1cmUnIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH0sXG5cbiAgZ2V0Q3Vyc29yOiBmdW5jdGlvbiBnZXRDdXJzb3IoKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG59O1xuXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmKSB7XG4gIHZhciBpRXZlbnQgPSBfcmVmLmlFdmVudCxcbiAgICAgIGludGVyYWN0aW9uID0gX3JlZi5pbnRlcmFjdGlvbjtcblxuICBpZiAoaUV2ZW50LnR5cGUgIT09ICdnZXN0dXJlc3RhcnQnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlFdmVudC5kcyA9IDA7XG5cbiAgaW50ZXJhY3Rpb24uZ2VzdHVyZS5zdGFydERpc3RhbmNlID0gaW50ZXJhY3Rpb24uZ2VzdHVyZS5wcmV2RGlzdGFuY2UgPSBpRXZlbnQuZGlzdGFuY2U7XG4gIGludGVyYWN0aW9uLmdlc3R1cmUuc3RhcnRBbmdsZSA9IGludGVyYWN0aW9uLmdlc3R1cmUucHJldkFuZ2xlID0gaUV2ZW50LmFuZ2xlO1xuICBpbnRlcmFjdGlvbi5nZXN0dXJlLnNjYWxlID0gMTtcbn0pO1xuXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmMikge1xuICB2YXIgaUV2ZW50ID0gX3JlZjIuaUV2ZW50LFxuICAgICAgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbjtcblxuICBpZiAoaUV2ZW50LnR5cGUgIT09ICdnZXN0dXJlbW92ZScpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpRXZlbnQuZHMgPSBpRXZlbnQuc2NhbGUgLSBpbnRlcmFjdGlvbi5nZXN0dXJlLnNjYWxlO1xuXG4gIGludGVyYWN0aW9uLnRhcmdldC5maXJlKGlFdmVudCk7XG5cbiAgaW50ZXJhY3Rpb24uZ2VzdHVyZS5wcmV2QW5nbGUgPSBpRXZlbnQuYW5nbGU7XG4gIGludGVyYWN0aW9uLmdlc3R1cmUucHJldkRpc3RhbmNlID0gaUV2ZW50LmRpc3RhbmNlO1xuXG4gIGlmIChpRXZlbnQuc2NhbGUgIT09IEluZmluaXR5ICYmIGlFdmVudC5zY2FsZSAhPT0gbnVsbCAmJiBpRXZlbnQuc2NhbGUgIT09IHVuZGVmaW5lZCAmJiAhaXNOYU4oaUV2ZW50LnNjYWxlKSkge1xuXG4gICAgaW50ZXJhY3Rpb24uZ2VzdHVyZS5zY2FsZSA9IGlFdmVudC5zY2FsZTtcbiAgfVxufSk7XG5cbi8qXFxcbiAqIEludGVyYWN0YWJsZS5nZXN0dXJhYmxlXG4gWyBtZXRob2QgXVxuICpcbiAqIEdldHMgb3Igc2V0cyB3aGV0aGVyIG11bHRpdG91Y2ggZ2VzdHVyZXMgY2FuIGJlIHBlcmZvcm1lZCBvbiB0aGVcbiAqIEludGVyYWN0YWJsZSdzIGVsZW1lbnRcbiAqXG4gPSAoYm9vbGVhbikgSW5kaWNhdGVzIGlmIHRoaXMgY2FuIGJlIHRoZSB0YXJnZXQgb2YgZ2VzdHVyZSBldmVudHNcbiAgIHwgdmFyIGlzR2VzdHVyZWFibGUgPSBpbnRlcmFjdChlbGVtZW50KS5nZXN0dXJhYmxlKCk7XG4gKiBvclxuIC0gb3B0aW9ucyAoYm9vbGVhbiB8IG9iamVjdCkgI29wdGlvbmFsIHRydWUvZmFsc2Ugb3IgQW4gb2JqZWN0IHdpdGggZXZlbnQgbGlzdGVuZXJzIHRvIGJlIGZpcmVkIG9uIGdlc3R1cmUgZXZlbnRzIChtYWtlcyB0aGUgSW50ZXJhY3RhYmxlIGdlc3R1cmFibGUpXG4gPSAob2JqZWN0KSB0aGlzIEludGVyYWN0YWJsZVxuIHwgaW50ZXJhY3QoZWxlbWVudCkuZ2VzdHVyYWJsZSh7XG4gfCAgICAgb25zdGFydDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcbiB8ICAgICBvbm1vdmUgOiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxuIHwgICAgIG9uZW5kICA6IGZ1bmN0aW9uIChldmVudCkge30sXG4gfFxuIHwgICAgIC8vIGxpbWl0IG11bHRpcGxlIGdlc3R1cmVzLlxuIHwgICAgIC8vIFNlZSB0aGUgZXhwbGFuYXRpb24gaW4gQEludGVyYWN0YWJsZS5kcmFnZ2FibGUgZXhhbXBsZVxuIHwgICAgIG1heDogSW5maW5pdHksXG4gfCAgICAgbWF4UGVyRWxlbWVudDogMSxcbiB8IH0pO1xuXFwqL1xuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5nZXN0dXJhYmxlID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgaWYgKHV0aWxzLmlzLm9iamVjdChvcHRpb25zKSkge1xuICAgIHRoaXMub3B0aW9ucy5nZXN0dXJlLmVuYWJsZWQgPSBvcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlO1xuICAgIHRoaXMuc2V0UGVyQWN0aW9uKCdnZXN0dXJlJywgb3B0aW9ucyk7XG4gICAgdGhpcy5zZXRPbkV2ZW50cygnZ2VzdHVyZScsIG9wdGlvbnMpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBpZiAodXRpbHMuaXMuYm9vbChvcHRpb25zKSkge1xuICAgIHRoaXMub3B0aW9ucy5nZXN0dXJlLmVuYWJsZWQgPSBvcHRpb25zO1xuXG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICB0aGlzLm9uZ2VzdHVyZXN0YXJ0ID0gdGhpcy5vbmdlc3R1cmVzdGFydCA9IHRoaXMub25nZXN0dXJlZW5kID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHJldHVybiB0aGlzLm9wdGlvbnMuZ2VzdHVyZTtcbn07XG5cbkludGVyYWN0RXZlbnQuc2lnbmFscy5vbignc2V0LWRlbHRhJywgZnVuY3Rpb24gKF9yZWYzKSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzLmludGVyYWN0aW9uLFxuICAgICAgaUV2ZW50ID0gX3JlZjMuaUV2ZW50LFxuICAgICAgYWN0aW9uID0gX3JlZjMuYWN0aW9uLFxuICAgICAgZXZlbnQgPSBfcmVmMy5ldmVudCxcbiAgICAgIHN0YXJ0aW5nID0gX3JlZjMuc3RhcnRpbmcsXG4gICAgICBlbmRpbmcgPSBfcmVmMy5lbmRpbmcsXG4gICAgICBkZWx0YVNvdXJjZSA9IF9yZWYzLmRlbHRhU291cmNlO1xuXG4gIGlmIChhY3Rpb24gIT09ICdnZXN0dXJlJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwb2ludGVycyA9IGludGVyYWN0aW9uLnBvaW50ZXJzO1xuXG4gIGlFdmVudC50b3VjaGVzID0gW3BvaW50ZXJzWzBdLCBwb2ludGVyc1sxXV07XG5cbiAgaWYgKHN0YXJ0aW5nKSB7XG4gICAgaUV2ZW50LmRpc3RhbmNlID0gdXRpbHMudG91Y2hEaXN0YW5jZShwb2ludGVycywgZGVsdGFTb3VyY2UpO1xuICAgIGlFdmVudC5ib3ggPSB1dGlscy50b3VjaEJCb3gocG9pbnRlcnMpO1xuICAgIGlFdmVudC5zY2FsZSA9IDE7XG4gICAgaUV2ZW50LmRzID0gMDtcbiAgICBpRXZlbnQuYW5nbGUgPSB1dGlscy50b3VjaEFuZ2xlKHBvaW50ZXJzLCB1bmRlZmluZWQsIGRlbHRhU291cmNlKTtcbiAgICBpRXZlbnQuZGEgPSAwO1xuICB9IGVsc2UgaWYgKGVuZGluZyB8fCBldmVudCBpbnN0YW5jZW9mIEludGVyYWN0RXZlbnQpIHtcbiAgICBpRXZlbnQuZGlzdGFuY2UgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQuZGlzdGFuY2U7XG4gICAgaUV2ZW50LmJveCA9IGludGVyYWN0aW9uLnByZXZFdmVudC5ib3g7XG4gICAgaUV2ZW50LnNjYWxlID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LnNjYWxlO1xuICAgIGlFdmVudC5kcyA9IGlFdmVudC5zY2FsZSAtIDE7XG4gICAgaUV2ZW50LmFuZ2xlID0gaW50ZXJhY3Rpb24ucHJldkV2ZW50LmFuZ2xlO1xuICAgIGlFdmVudC5kYSA9IGlFdmVudC5hbmdsZSAtIGludGVyYWN0aW9uLmdlc3R1cmUuc3RhcnRBbmdsZTtcbiAgfSBlbHNlIHtcbiAgICBpRXZlbnQuZGlzdGFuY2UgPSB1dGlscy50b3VjaERpc3RhbmNlKHBvaW50ZXJzLCBkZWx0YVNvdXJjZSk7XG4gICAgaUV2ZW50LmJveCA9IHV0aWxzLnRvdWNoQkJveChwb2ludGVycyk7XG4gICAgaUV2ZW50LnNjYWxlID0gaUV2ZW50LmRpc3RhbmNlIC8gaW50ZXJhY3Rpb24uZ2VzdHVyZS5zdGFydERpc3RhbmNlO1xuICAgIGlFdmVudC5hbmdsZSA9IHV0aWxzLnRvdWNoQW5nbGUocG9pbnRlcnMsIGludGVyYWN0aW9uLmdlc3R1cmUucHJldkFuZ2xlLCBkZWx0YVNvdXJjZSk7XG5cbiAgICBpRXZlbnQuZHMgPSBpRXZlbnQuc2NhbGUgLSBpbnRlcmFjdGlvbi5nZXN0dXJlLnByZXZTY2FsZTtcbiAgICBpRXZlbnQuZGEgPSBpRXZlbnQuYW5nbGUgLSBpbnRlcmFjdGlvbi5nZXN0dXJlLnByZXZBbmdsZTtcbiAgfVxufSk7XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xuICBpbnRlcmFjdGlvbi5nZXN0dXJlID0ge1xuICAgIHN0YXJ0OiB7IHg6IDAsIHk6IDAgfSxcblxuICAgIHN0YXJ0RGlzdGFuY2U6IDAsIC8vIGRpc3RhbmNlIGJldHdlZW4gdHdvIHRvdWNoZXMgb2YgdG91Y2hTdGFydFxuICAgIHByZXZEaXN0YW5jZTogMCxcbiAgICBkaXN0YW5jZTogMCxcblxuICAgIHNjYWxlOiAxLCAvLyBnZXN0dXJlLmRpc3RhbmNlIC8gZ2VzdHVyZS5zdGFydERpc3RhbmNlXG5cbiAgICBzdGFydEFuZ2xlOiAwLCAvLyBhbmdsZSBvZiBsaW5lIGpvaW5pbmcgdHdvIHRvdWNoZXNcbiAgICBwcmV2QW5nbGU6IDAgLy8gYW5nbGUgb2YgdGhlIHByZXZpb3VzIGdlc3R1cmUgZXZlbnRcbiAgfTtcbn0pO1xuXG5hY3Rpb25zLmdlc3R1cmUgPSBnZXN0dXJlO1xuYWN0aW9ucy5uYW1lcy5wdXNoKCdnZXN0dXJlJyk7XG51dGlscy5tZXJnZShJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgWydnZXN0dXJlc3RhcnQnLCAnZ2VzdHVyZW1vdmUnLCAnZ2VzdHVyZWVuZCddKTtcbmFjdGlvbnMubWV0aG9kRGljdC5nZXN0dXJlID0gJ2dlc3R1cmFibGUnO1xuXG5kZWZhdWx0T3B0aW9ucy5nZXN0dXJlID0gZ2VzdHVyZS5kZWZhdWx0cztcblxubW9kdWxlLmV4cG9ydHMgPSBnZXN0dXJlO1xuXG59LHtcIi4uL0ludGVyYWN0RXZlbnRcIjozLFwiLi4vSW50ZXJhY3RhYmxlXCI6NCxcIi4uL0ludGVyYWN0aW9uXCI6NSxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi9iYXNlXCI6Nn1dLDEwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuL2Jhc2UnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcbnZhciBJbnRlcmFjdEV2ZW50ID0gcmVxdWlyZSgnLi4vSW50ZXJhY3RFdmVudCcpO1xudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4uL0ludGVyYWN0YWJsZScpO1xudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcbnZhciBkZWZhdWx0T3B0aW9ucyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRPcHRpb25zJyk7XG5cbi8vIExlc3MgUHJlY2lzaW9uIHdpdGggdG91Y2ggaW5wdXRcbnZhciBkZWZhdWx0TWFyZ2luID0gYnJvd3Nlci5zdXBwb3J0c1RvdWNoIHx8IGJyb3dzZXIuc3VwcG9ydHNQb2ludGVyRXZlbnQgPyAyMCA6IDEwO1xuXG52YXIgcmVzaXplID0ge1xuICBkZWZhdWx0czoge1xuICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgIG1vdXNlQnV0dG9uczogbnVsbCxcblxuICAgIG9yaWdpbjogbnVsbCxcbiAgICBzbmFwOiBudWxsLFxuICAgIHJlc3RyaWN0OiBudWxsLFxuICAgIGluZXJ0aWE6IG51bGwsXG4gICAgYXV0b1Njcm9sbDogbnVsbCxcblxuICAgIHNxdWFyZTogZmFsc2UsXG4gICAgcHJlc2VydmVBc3BlY3RSYXRpbzogZmFsc2UsXG4gICAgYXhpczogJ3h5JyxcblxuICAgIC8vIHVzZSBkZWZhdWx0IG1hcmdpblxuICAgIG1hcmdpbjogTmFOLFxuXG4gICAgLy8gb2JqZWN0IHdpdGggcHJvcHMgbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tIHdoaWNoIGFyZVxuICAgIC8vIHRydWUvZmFsc2UgdmFsdWVzIHRvIHJlc2l6ZSB3aGVuIHRoZSBwb2ludGVyIGlzIG92ZXIgdGhhdCBlZGdlLFxuICAgIC8vIENTUyBzZWxlY3RvcnMgdG8gbWF0Y2ggdGhlIGhhbmRsZXMgZm9yIGVhY2ggZGlyZWN0aW9uXG4gICAgLy8gb3IgdGhlIEVsZW1lbnRzIGZvciBlYWNoIGhhbmRsZVxuICAgIGVkZ2VzOiBudWxsLFxuXG4gICAgLy8gYSB2YWx1ZSBvZiAnbm9uZScgd2lsbCBsaW1pdCB0aGUgcmVzaXplIHJlY3QgdG8gYSBtaW5pbXVtIG9mIDB4MFxuICAgIC8vICduZWdhdGUnIHdpbGwgYWxvdyB0aGUgcmVjdCB0byBoYXZlIG5lZ2F0aXZlIHdpZHRoL2hlaWdodFxuICAgIC8vICdyZXBvc2l0aW9uJyB3aWxsIGtlZXAgdGhlIHdpZHRoL2hlaWdodCBwb3NpdGl2ZSBieSBzd2FwcGluZ1xuICAgIC8vIHRoZSB0b3AgYW5kIGJvdHRvbSBlZGdlcyBhbmQvb3Igc3dhcHBpbmcgdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzXG4gICAgaW52ZXJ0OiAnbm9uZSdcbiAgfSxcblxuICBjaGVja2VyOiBmdW5jdGlvbiBjaGVja2VyKHBvaW50ZXIsIGV2ZW50LCBpbnRlcmFjdGFibGUsIGVsZW1lbnQsIGludGVyYWN0aW9uLCByZWN0KSB7XG4gICAgaWYgKCFyZWN0KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgcGFnZSA9IHV0aWxzLmV4dGVuZCh7fSwgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UpO1xuICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnM7XG5cbiAgICBpZiAob3B0aW9ucy5yZXNpemUuZW5hYmxlZCkge1xuICAgICAgdmFyIHJlc2l6ZU9wdGlvbnMgPSBvcHRpb25zLnJlc2l6ZTtcbiAgICAgIHZhciByZXNpemVFZGdlcyA9IHsgbGVmdDogZmFsc2UsIHJpZ2h0OiBmYWxzZSwgdG9wOiBmYWxzZSwgYm90dG9tOiBmYWxzZSB9O1xuXG4gICAgICAvLyBpZiB1c2luZyByZXNpemUuZWRnZXNcbiAgICAgIGlmICh1dGlscy5pcy5vYmplY3QocmVzaXplT3B0aW9ucy5lZGdlcykpIHtcbiAgICAgICAgZm9yICh2YXIgZWRnZSBpbiByZXNpemVFZGdlcykge1xuICAgICAgICAgIHJlc2l6ZUVkZ2VzW2VkZ2VdID0gY2hlY2tSZXNpemVFZGdlKGVkZ2UsIHJlc2l6ZU9wdGlvbnMuZWRnZXNbZWRnZV0sIHBhZ2UsIGludGVyYWN0aW9uLl9ldmVudFRhcmdldCwgZWxlbWVudCwgcmVjdCwgcmVzaXplT3B0aW9ucy5tYXJnaW4gfHwgZGVmYXVsdE1hcmdpbik7XG4gICAgICAgIH1cblxuICAgICAgICByZXNpemVFZGdlcy5sZWZ0ID0gcmVzaXplRWRnZXMubGVmdCAmJiAhcmVzaXplRWRnZXMucmlnaHQ7XG4gICAgICAgIHJlc2l6ZUVkZ2VzLnRvcCA9IHJlc2l6ZUVkZ2VzLnRvcCAmJiAhcmVzaXplRWRnZXMuYm90dG9tO1xuXG4gICAgICAgIGlmIChyZXNpemVFZGdlcy5sZWZ0IHx8IHJlc2l6ZUVkZ2VzLnJpZ2h0IHx8IHJlc2l6ZUVkZ2VzLnRvcCB8fCByZXNpemVFZGdlcy5ib3R0b20pIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZTogJ3Jlc2l6ZScsXG4gICAgICAgICAgICBlZGdlczogcmVzaXplRWRnZXNcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcmlnaHQgPSBvcHRpb25zLnJlc2l6ZS5heGlzICE9PSAneScgJiYgcGFnZS54ID4gcmVjdC5yaWdodCAtIGRlZmF1bHRNYXJnaW47XG4gICAgICAgIHZhciBib3R0b20gPSBvcHRpb25zLnJlc2l6ZS5heGlzICE9PSAneCcgJiYgcGFnZS55ID4gcmVjdC5ib3R0b20gLSBkZWZhdWx0TWFyZ2luO1xuXG4gICAgICAgIGlmIChyaWdodCB8fCBib3R0b20pIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZTogJ3Jlc2l6ZScsXG4gICAgICAgICAgICBheGVzOiAocmlnaHQgPyAneCcgOiAnJykgKyAoYm90dG9tID8gJ3knIDogJycpXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9LFxuXG4gIGN1cnNvcnM6IGJyb3dzZXIuaXNJZTlPck9sZGVyID8ge1xuICAgIHg6ICdlLXJlc2l6ZScsXG4gICAgeTogJ3MtcmVzaXplJyxcbiAgICB4eTogJ3NlLXJlc2l6ZScsXG5cbiAgICB0b3A6ICduLXJlc2l6ZScsXG4gICAgbGVmdDogJ3ctcmVzaXplJyxcbiAgICBib3R0b206ICdzLXJlc2l6ZScsXG4gICAgcmlnaHQ6ICdlLXJlc2l6ZScsXG4gICAgdG9wbGVmdDogJ3NlLXJlc2l6ZScsXG4gICAgYm90dG9tcmlnaHQ6ICdzZS1yZXNpemUnLFxuICAgIHRvcHJpZ2h0OiAnbmUtcmVzaXplJyxcbiAgICBib3R0b21sZWZ0OiAnbmUtcmVzaXplJ1xuICB9IDoge1xuICAgIHg6ICdldy1yZXNpemUnLFxuICAgIHk6ICducy1yZXNpemUnLFxuICAgIHh5OiAnbndzZS1yZXNpemUnLFxuXG4gICAgdG9wOiAnbnMtcmVzaXplJyxcbiAgICBsZWZ0OiAnZXctcmVzaXplJyxcbiAgICBib3R0b206ICducy1yZXNpemUnLFxuICAgIHJpZ2h0OiAnZXctcmVzaXplJyxcbiAgICB0b3BsZWZ0OiAnbndzZS1yZXNpemUnLFxuICAgIGJvdHRvbXJpZ2h0OiAnbndzZS1yZXNpemUnLFxuICAgIHRvcHJpZ2h0OiAnbmVzdy1yZXNpemUnLFxuICAgIGJvdHRvbWxlZnQ6ICduZXN3LXJlc2l6ZSdcbiAgfSxcblxuICBnZXRDdXJzb3I6IGZ1bmN0aW9uIGdldEN1cnNvcihhY3Rpb24pIHtcbiAgICBpZiAoYWN0aW9uLmF4aXMpIHtcbiAgICAgIHJldHVybiByZXNpemUuY3Vyc29yc1thY3Rpb24ubmFtZSArIGFjdGlvbi5heGlzXTtcbiAgICB9IGVsc2UgaWYgKGFjdGlvbi5lZGdlcykge1xuICAgICAgdmFyIGN1cnNvcktleSA9ICcnO1xuICAgICAgdmFyIGVkZ2VOYW1lcyA9IFsndG9wJywgJ2JvdHRvbScsICdsZWZ0JywgJ3JpZ2h0J107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgIGlmIChhY3Rpb24uZWRnZXNbZWRnZU5hbWVzW2ldXSkge1xuICAgICAgICAgIGN1cnNvcktleSArPSBlZGdlTmFtZXNbaV07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc2l6ZS5jdXJzb3JzW2N1cnNvcktleV07XG4gICAgfVxuICB9XG59O1xuXG4vLyByZXNpemVzdGFydFxuSW50ZXJhY3RFdmVudC5zaWduYWxzLm9uKCduZXcnLCBmdW5jdGlvbiAoX3JlZikge1xuICB2YXIgaUV2ZW50ID0gX3JlZi5pRXZlbnQsXG4gICAgICBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb247XG5cbiAgaWYgKGlFdmVudC50eXBlICE9PSAncmVzaXplc3RhcnQnIHx8ICFpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzdGFydFJlY3QgPSBpbnRlcmFjdGlvbi50YXJnZXQuZ2V0UmVjdChpbnRlcmFjdGlvbi5lbGVtZW50KTtcbiAgdmFyIHJlc2l6ZU9wdGlvbnMgPSBpbnRlcmFjdGlvbi50YXJnZXQub3B0aW9ucy5yZXNpemU7XG5cbiAgLypcbiAgICogV2hlbiB1c2luZyB0aGUgYHJlc2l6YWJsZS5zcXVhcmVgIG9yIGByZXNpemFibGUucHJlc2VydmVBc3BlY3RSYXRpb2Agb3B0aW9ucywgcmVzaXppbmcgZnJvbSBvbmUgZWRnZVxuICAgKiB3aWxsIGFmZmVjdCBhbm90aGVyLiBFLmcuIHdpdGggYHJlc2l6YWJsZS5zcXVhcmVgLCByZXNpemluZyB0byBtYWtlIHRoZSByaWdodCBlZGdlIGxhcmdlciB3aWxsIG1ha2VcbiAgICogdGhlIGJvdHRvbSBlZGdlIGxhcmdlciBieSB0aGUgc2FtZSBhbW91bnQuIFdlIGNhbGwgdGhlc2UgJ2xpbmtlZCcgZWRnZXMuIEFueSBsaW5rZWQgZWRnZXMgd2lsbCBkZXBlbmRcbiAgICogb24gdGhlIGFjdGl2ZSBlZGdlcyBhbmQgdGhlIGVkZ2UgYmVpbmcgaW50ZXJhY3RlZCB3aXRoLlxuICAgKi9cbiAgaWYgKHJlc2l6ZU9wdGlvbnMuc3F1YXJlIHx8IHJlc2l6ZU9wdGlvbnMucHJlc2VydmVBc3BlY3RSYXRpbykge1xuICAgIHZhciBsaW5rZWRFZGdlcyA9IHV0aWxzLmV4dGVuZCh7fSwgaW50ZXJhY3Rpb24ucHJlcGFyZWQuZWRnZXMpO1xuXG4gICAgbGlua2VkRWRnZXMudG9wID0gbGlua2VkRWRnZXMudG9wIHx8IGxpbmtlZEVkZ2VzLmxlZnQgJiYgIWxpbmtlZEVkZ2VzLmJvdHRvbTtcbiAgICBsaW5rZWRFZGdlcy5sZWZ0ID0gbGlua2VkRWRnZXMubGVmdCB8fCBsaW5rZWRFZGdlcy50b3AgJiYgIWxpbmtlZEVkZ2VzLnJpZ2h0O1xuICAgIGxpbmtlZEVkZ2VzLmJvdHRvbSA9IGxpbmtlZEVkZ2VzLmJvdHRvbSB8fCBsaW5rZWRFZGdlcy5yaWdodCAmJiAhbGlua2VkRWRnZXMudG9wO1xuICAgIGxpbmtlZEVkZ2VzLnJpZ2h0ID0gbGlua2VkRWRnZXMucmlnaHQgfHwgbGlua2VkRWRnZXMuYm90dG9tICYmICFsaW5rZWRFZGdlcy5sZWZ0O1xuXG4gICAgaW50ZXJhY3Rpb24ucHJlcGFyZWQuX2xpbmtlZEVkZ2VzID0gbGlua2VkRWRnZXM7XG4gIH0gZWxzZSB7XG4gICAgaW50ZXJhY3Rpb24ucHJlcGFyZWQuX2xpbmtlZEVkZ2VzID0gbnVsbDtcbiAgfVxuXG4gIC8vIGlmIHVzaW5nIGByZXNpemFibGUucHJlc2VydmVBc3BlY3RSYXRpb2Agb3B0aW9uLCByZWNvcmQgYXNwZWN0IHJhdGlvIGF0IHRoZSBzdGFydCBvZiB0aGUgcmVzaXplXG4gIGlmIChyZXNpemVPcHRpb25zLnByZXNlcnZlQXNwZWN0UmF0aW8pIHtcbiAgICBpbnRlcmFjdGlvbi5yZXNpemVTdGFydEFzcGVjdFJhdGlvID0gc3RhcnRSZWN0LndpZHRoIC8gc3RhcnRSZWN0LmhlaWdodDtcbiAgfVxuXG4gIGludGVyYWN0aW9uLnJlc2l6ZVJlY3RzID0ge1xuICAgIHN0YXJ0OiBzdGFydFJlY3QsXG4gICAgY3VycmVudDogdXRpbHMuZXh0ZW5kKHt9LCBzdGFydFJlY3QpLFxuICAgIGludmVydGVkOiB1dGlscy5leHRlbmQoe30sIHN0YXJ0UmVjdCksXG4gICAgcHJldmlvdXM6IHV0aWxzLmV4dGVuZCh7fSwgc3RhcnRSZWN0KSxcbiAgICBkZWx0YToge1xuICAgICAgbGVmdDogMCwgcmlnaHQ6IDAsIHdpZHRoOiAwLFxuICAgICAgdG9wOiAwLCBib3R0b206IDAsIGhlaWdodDogMFxuICAgIH1cbiAgfTtcblxuICBpRXZlbnQucmVjdCA9IGludGVyYWN0aW9uLnJlc2l6ZVJlY3RzLmludmVydGVkO1xuICBpRXZlbnQuZGVsdGFSZWN0ID0gaW50ZXJhY3Rpb24ucmVzaXplUmVjdHMuZGVsdGE7XG59KTtcblxuLy8gcmVzaXplbW92ZVxuSW50ZXJhY3RFdmVudC5zaWduYWxzLm9uKCduZXcnLCBmdW5jdGlvbiAoX3JlZjIpIHtcbiAgdmFyIGlFdmVudCA9IF9yZWYyLmlFdmVudCxcbiAgICAgIHBoYXNlID0gX3JlZjIucGhhc2UsXG4gICAgICBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uO1xuXG4gIGlmIChwaGFzZSAhPT0gJ21vdmUnIHx8ICFpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciByZXNpemVPcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnMucmVzaXplO1xuICB2YXIgaW52ZXJ0ID0gcmVzaXplT3B0aW9ucy5pbnZlcnQ7XG4gIHZhciBpbnZlcnRpYmxlID0gaW52ZXJ0ID09PSAncmVwb3NpdGlvbicgfHwgaW52ZXJ0ID09PSAnbmVnYXRlJztcblxuICB2YXIgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcztcblxuICB2YXIgc3RhcnQgPSBpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5zdGFydDtcbiAgdmFyIGN1cnJlbnQgPSBpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5jdXJyZW50O1xuICB2YXIgaW52ZXJ0ZWQgPSBpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5pbnZlcnRlZDtcbiAgdmFyIGRlbHRhID0gaW50ZXJhY3Rpb24ucmVzaXplUmVjdHMuZGVsdGE7XG4gIHZhciBwcmV2aW91cyA9IHV0aWxzLmV4dGVuZChpbnRlcmFjdGlvbi5yZXNpemVSZWN0cy5wcmV2aW91cywgaW52ZXJ0ZWQpO1xuICB2YXIgb3JpZ2luYWxFZGdlcyA9IGVkZ2VzO1xuXG4gIHZhciBkeCA9IGlFdmVudC5keDtcbiAgdmFyIGR5ID0gaUV2ZW50LmR5O1xuXG4gIGlmIChyZXNpemVPcHRpb25zLnByZXNlcnZlQXNwZWN0UmF0aW8gfHwgcmVzaXplT3B0aW9ucy5zcXVhcmUpIHtcbiAgICAvLyBgcmVzaXplLnByZXNlcnZlQXNwZWN0UmF0aW9gIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBgcmVzaXplLnNxdWFyZWBcbiAgICB2YXIgc3RhcnRBc3BlY3RSYXRpbyA9IHJlc2l6ZU9wdGlvbnMucHJlc2VydmVBc3BlY3RSYXRpbyA/IGludGVyYWN0aW9uLnJlc2l6ZVN0YXJ0QXNwZWN0UmF0aW8gOiAxO1xuXG4gICAgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5fbGlua2VkRWRnZXM7XG5cbiAgICBpZiAob3JpZ2luYWxFZGdlcy5sZWZ0ICYmIG9yaWdpbmFsRWRnZXMuYm90dG9tIHx8IG9yaWdpbmFsRWRnZXMucmlnaHQgJiYgb3JpZ2luYWxFZGdlcy50b3ApIHtcbiAgICAgIGR5ID0gLWR4IC8gc3RhcnRBc3BlY3RSYXRpbztcbiAgICB9IGVsc2UgaWYgKG9yaWdpbmFsRWRnZXMubGVmdCB8fCBvcmlnaW5hbEVkZ2VzLnJpZ2h0KSB7XG4gICAgICBkeSA9IGR4IC8gc3RhcnRBc3BlY3RSYXRpbztcbiAgICB9IGVsc2UgaWYgKG9yaWdpbmFsRWRnZXMudG9wIHx8IG9yaWdpbmFsRWRnZXMuYm90dG9tKSB7XG4gICAgICBkeCA9IGR5ICogc3RhcnRBc3BlY3RSYXRpbztcbiAgICB9XG4gIH1cblxuICAvLyB1cGRhdGUgdGhlICdjdXJyZW50JyByZWN0IHdpdGhvdXQgbW9kaWZpY2F0aW9uc1xuICBpZiAoZWRnZXMudG9wKSB7XG4gICAgY3VycmVudC50b3AgKz0gZHk7XG4gIH1cbiAgaWYgKGVkZ2VzLmJvdHRvbSkge1xuICAgIGN1cnJlbnQuYm90dG9tICs9IGR5O1xuICB9XG4gIGlmIChlZGdlcy5sZWZ0KSB7XG4gICAgY3VycmVudC5sZWZ0ICs9IGR4O1xuICB9XG4gIGlmIChlZGdlcy5yaWdodCkge1xuICAgIGN1cnJlbnQucmlnaHQgKz0gZHg7XG4gIH1cblxuICBpZiAoaW52ZXJ0aWJsZSkge1xuICAgIC8vIGlmIGludmVydGlibGUsIGNvcHkgdGhlIGN1cnJlbnQgcmVjdFxuICAgIHV0aWxzLmV4dGVuZChpbnZlcnRlZCwgY3VycmVudCk7XG5cbiAgICBpZiAoaW52ZXJ0ID09PSAncmVwb3NpdGlvbicpIHtcbiAgICAgIC8vIHN3YXAgZWRnZSB2YWx1ZXMgaWYgbmVjZXNzYXJ5IHRvIGtlZXAgd2lkdGgvaGVpZ2h0IHBvc2l0aXZlXG4gICAgICB2YXIgc3dhcCA9IHZvaWQgMDtcblxuICAgICAgaWYgKGludmVydGVkLnRvcCA+IGludmVydGVkLmJvdHRvbSkge1xuICAgICAgICBzd2FwID0gaW52ZXJ0ZWQudG9wO1xuXG4gICAgICAgIGludmVydGVkLnRvcCA9IGludmVydGVkLmJvdHRvbTtcbiAgICAgICAgaW52ZXJ0ZWQuYm90dG9tID0gc3dhcDtcbiAgICAgIH1cbiAgICAgIGlmIChpbnZlcnRlZC5sZWZ0ID4gaW52ZXJ0ZWQucmlnaHQpIHtcbiAgICAgICAgc3dhcCA9IGludmVydGVkLmxlZnQ7XG5cbiAgICAgICAgaW52ZXJ0ZWQubGVmdCA9IGludmVydGVkLnJpZ2h0O1xuICAgICAgICBpbnZlcnRlZC5yaWdodCA9IHN3YXA7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIGlmIG5vdCBpbnZlcnRpYmxlLCByZXN0cmljdCB0byBtaW5pbXVtIG9mIDB4MCByZWN0XG4gICAgaW52ZXJ0ZWQudG9wID0gTWF0aC5taW4oY3VycmVudC50b3AsIHN0YXJ0LmJvdHRvbSk7XG4gICAgaW52ZXJ0ZWQuYm90dG9tID0gTWF0aC5tYXgoY3VycmVudC5ib3R0b20sIHN0YXJ0LnRvcCk7XG4gICAgaW52ZXJ0ZWQubGVmdCA9IE1hdGgubWluKGN1cnJlbnQubGVmdCwgc3RhcnQucmlnaHQpO1xuICAgIGludmVydGVkLnJpZ2h0ID0gTWF0aC5tYXgoY3VycmVudC5yaWdodCwgc3RhcnQubGVmdCk7XG4gIH1cblxuICBpbnZlcnRlZC53aWR0aCA9IGludmVydGVkLnJpZ2h0IC0gaW52ZXJ0ZWQubGVmdDtcbiAgaW52ZXJ0ZWQuaGVpZ2h0ID0gaW52ZXJ0ZWQuYm90dG9tIC0gaW52ZXJ0ZWQudG9wO1xuXG4gIGZvciAodmFyIGVkZ2UgaW4gaW52ZXJ0ZWQpIHtcbiAgICBkZWx0YVtlZGdlXSA9IGludmVydGVkW2VkZ2VdIC0gcHJldmlvdXNbZWRnZV07XG4gIH1cblxuICBpRXZlbnQuZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcztcbiAgaUV2ZW50LnJlY3QgPSBpbnZlcnRlZDtcbiAgaUV2ZW50LmRlbHRhUmVjdCA9IGRlbHRhO1xufSk7XG5cbi8qXFxcbiAqIEludGVyYWN0YWJsZS5yZXNpemFibGVcbiBbIG1ldGhvZCBdXG4gKlxuICogR2V0cyBvciBzZXRzIHdoZXRoZXIgcmVzaXplIGFjdGlvbnMgY2FuIGJlIHBlcmZvcm1lZCBvbiB0aGVcbiAqIEludGVyYWN0YWJsZVxuICpcbiA9IChib29sZWFuKSBJbmRpY2F0ZXMgaWYgdGhpcyBjYW4gYmUgdGhlIHRhcmdldCBvZiByZXNpemUgZWxlbWVudHNcbiAgIHwgdmFyIGlzUmVzaXplYWJsZSA9IGludGVyYWN0KCdpbnB1dFt0eXBlPXRleHRdJykucmVzaXphYmxlKCk7XG4gKiBvclxuIC0gb3B0aW9ucyAoYm9vbGVhbiB8IG9iamVjdCkgI29wdGlvbmFsIHRydWUvZmFsc2Ugb3IgQW4gb2JqZWN0IHdpdGggZXZlbnQgbGlzdGVuZXJzIHRvIGJlIGZpcmVkIG9uIHJlc2l6ZSBldmVudHMgKG9iamVjdCBtYWtlcyB0aGUgSW50ZXJhY3RhYmxlIHJlc2l6YWJsZSlcbiA9IChvYmplY3QpIFRoaXMgSW50ZXJhY3RhYmxlXG4gICB8IGludGVyYWN0KGVsZW1lbnQpLnJlc2l6YWJsZSh7XG4gICB8ICAgb25zdGFydDogZnVuY3Rpb24gKGV2ZW50KSB7fSxcbiAgIHwgICBvbm1vdmUgOiBmdW5jdGlvbiAoZXZlbnQpIHt9LFxuICAgfCAgIG9uZW5kICA6IGZ1bmN0aW9uIChldmVudCkge30sXG4gICB8XG4gICB8ICAgZWRnZXM6IHtcbiAgIHwgICAgIHRvcCAgIDogdHJ1ZSwgICAgICAgLy8gVXNlIHBvaW50ZXIgY29vcmRzIHRvIGNoZWNrIGZvciByZXNpemUuXG4gICB8ICAgICBsZWZ0ICA6IGZhbHNlLCAgICAgIC8vIERpc2FibGUgcmVzaXppbmcgZnJvbSBsZWZ0IGVkZ2UuXG4gICB8ICAgICBib3R0b206ICcucmVzaXplLXMnLC8vIFJlc2l6ZSBpZiBwb2ludGVyIHRhcmdldCBtYXRjaGVzIHNlbGVjdG9yXG4gICB8ICAgICByaWdodCA6IGhhbmRsZUVsICAgIC8vIFJlc2l6ZSBpZiBwb2ludGVyIHRhcmdldCBpcyB0aGUgZ2l2ZW4gRWxlbWVudFxuICAgfCAgIH0sXG4gICB8XG4gICB8ICAgICAvLyBXaWR0aCBhbmQgaGVpZ2h0IGNhbiBiZSBhZGp1c3RlZCBpbmRlcGVuZGVudGx5LiBXaGVuIGB0cnVlYCwgd2lkdGggYW5kXG4gICB8ICAgICAvLyBoZWlnaHQgYXJlIGFkanVzdGVkIGF0IGEgMToxIHJhdGlvLlxuICAgfCAgICAgc3F1YXJlOiBmYWxzZSxcbiAgIHxcbiAgIHwgICAgIC8vIFdpZHRoIGFuZCBoZWlnaHQgY2FuIGJlIGFkanVzdGVkIGluZGVwZW5kZW50bHkuIFdoZW4gYHRydWVgLCB3aWR0aCBhbmRcbiAgIHwgICAgIC8vIGhlaWdodCBtYWludGFpbiB0aGUgYXNwZWN0IHJhdGlvIHRoZXkgaGFkIHdoZW4gcmVzaXppbmcgc3RhcnRlZC5cbiAgIHwgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IGZhbHNlLFxuICAgfFxuICAgfCAgIC8vIGEgdmFsdWUgb2YgJ25vbmUnIHdpbGwgbGltaXQgdGhlIHJlc2l6ZSByZWN0IHRvIGEgbWluaW11bSBvZiAweDBcbiAgIHwgICAvLyAnbmVnYXRlJyB3aWxsIGFsbG93IHRoZSByZWN0IHRvIGhhdmUgbmVnYXRpdmUgd2lkdGgvaGVpZ2h0XG4gICB8ICAgLy8gJ3JlcG9zaXRpb24nIHdpbGwga2VlcCB0aGUgd2lkdGgvaGVpZ2h0IHBvc2l0aXZlIGJ5IHN3YXBwaW5nXG4gICB8ICAgLy8gdGhlIHRvcCBhbmQgYm90dG9tIGVkZ2VzIGFuZC9vciBzd2FwcGluZyB0aGUgbGVmdCBhbmQgcmlnaHQgZWRnZXNcbiAgIHwgICBpbnZlcnQ6ICdub25lJyB8fCAnbmVnYXRlJyB8fCAncmVwb3NpdGlvbidcbiAgIHxcbiAgIHwgICAvLyBsaW1pdCBtdWx0aXBsZSByZXNpemVzLlxuICAgfCAgIC8vIFNlZSB0aGUgZXhwbGFuYXRpb24gaW4gdGhlIEBJbnRlcmFjdGFibGUuZHJhZ2dhYmxlIGV4YW1wbGVcbiAgIHwgICBtYXg6IEluZmluaXR5LFxuICAgfCAgIG1heFBlckVsZW1lbnQ6IDEsXG4gICB8IH0pO1xuICBcXCovXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLnJlc2l6YWJsZSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIGlmICh1dGlscy5pcy5vYmplY3Qob3B0aW9ucykpIHtcbiAgICB0aGlzLm9wdGlvbnMucmVzaXplLmVuYWJsZWQgPSBvcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlID8gZmFsc2UgOiB0cnVlO1xuICAgIHRoaXMuc2V0UGVyQWN0aW9uKCdyZXNpemUnLCBvcHRpb25zKTtcbiAgICB0aGlzLnNldE9uRXZlbnRzKCdyZXNpemUnLCBvcHRpb25zKTtcblxuICAgIGlmICgvXngkfF55JHxeeHkkLy50ZXN0KG9wdGlvbnMuYXhpcykpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5yZXNpemUuYXhpcyA9IG9wdGlvbnMuYXhpcztcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMuYXhpcyA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5vcHRpb25zLnJlc2l6ZS5heGlzID0gZGVmYXVsdE9wdGlvbnMucmVzaXplLmF4aXM7XG4gICAgfVxuXG4gICAgaWYgKHV0aWxzLmlzLmJvb2wob3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvKSkge1xuICAgICAgdGhpcy5vcHRpb25zLnJlc2l6ZS5wcmVzZXJ2ZUFzcGVjdFJhdGlvID0gb3B0aW9ucy5wcmVzZXJ2ZUFzcGVjdFJhdGlvO1xuICAgIH0gZWxzZSBpZiAodXRpbHMuaXMuYm9vbChvcHRpb25zLnNxdWFyZSkpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5yZXNpemUuc3F1YXJlID0gb3B0aW9ucy5zcXVhcmU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgaWYgKHV0aWxzLmlzLmJvb2wob3B0aW9ucykpIHtcbiAgICB0aGlzLm9wdGlvbnMucmVzaXplLmVuYWJsZWQgPSBvcHRpb25zO1xuXG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICB0aGlzLm9ucmVzaXplc3RhcnQgPSB0aGlzLm9ucmVzaXplc3RhcnQgPSB0aGlzLm9ucmVzaXplZW5kID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICByZXR1cm4gdGhpcy5vcHRpb25zLnJlc2l6ZTtcbn07XG5cbmZ1bmN0aW9uIGNoZWNrUmVzaXplRWRnZShuYW1lLCB2YWx1ZSwgcGFnZSwgZWxlbWVudCwgaW50ZXJhY3RhYmxlRWxlbWVudCwgcmVjdCwgbWFyZ2luKSB7XG4gIC8vIGZhbHNlLCAnJywgdW5kZWZpbmVkLCBudWxsXG4gIGlmICghdmFsdWUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyB0cnVlIHZhbHVlLCB1c2UgcG9pbnRlciBjb29yZHMgYW5kIGVsZW1lbnQgcmVjdFxuICBpZiAodmFsdWUgPT09IHRydWUpIHtcbiAgICAvLyBpZiBkaW1lbnNpb25zIGFyZSBuZWdhdGl2ZSwgXCJzd2l0Y2hcIiBlZGdlc1xuICAgIHZhciB3aWR0aCA9IHV0aWxzLmlzLm51bWJlcihyZWN0LndpZHRoKSA/IHJlY3Qud2lkdGggOiByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0O1xuICAgIHZhciBoZWlnaHQgPSB1dGlscy5pcy5udW1iZXIocmVjdC5oZWlnaHQpID8gcmVjdC5oZWlnaHQgOiByZWN0LmJvdHRvbSAtIHJlY3QudG9wO1xuXG4gICAgaWYgKHdpZHRoIDwgMCkge1xuICAgICAgaWYgKG5hbWUgPT09ICdsZWZ0Jykge1xuICAgICAgICBuYW1lID0gJ3JpZ2h0JztcbiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICBuYW1lID0gJ2xlZnQnO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaGVpZ2h0IDwgMCkge1xuICAgICAgaWYgKG5hbWUgPT09ICd0b3AnKSB7XG4gICAgICAgIG5hbWUgPSAnYm90dG9tJztcbiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ2JvdHRvbScpIHtcbiAgICAgICAgbmFtZSA9ICd0b3AnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChuYW1lID09PSAnbGVmdCcpIHtcbiAgICAgIHJldHVybiBwYWdlLnggPCAod2lkdGggPj0gMCA/IHJlY3QubGVmdCA6IHJlY3QucmlnaHQpICsgbWFyZ2luO1xuICAgIH1cbiAgICBpZiAobmFtZSA9PT0gJ3RvcCcpIHtcbiAgICAgIHJldHVybiBwYWdlLnkgPCAoaGVpZ2h0ID49IDAgPyByZWN0LnRvcCA6IHJlY3QuYm90dG9tKSArIG1hcmdpbjtcbiAgICB9XG5cbiAgICBpZiAobmFtZSA9PT0gJ3JpZ2h0Jykge1xuICAgICAgcmV0dXJuIHBhZ2UueCA+ICh3aWR0aCA+PSAwID8gcmVjdC5yaWdodCA6IHJlY3QubGVmdCkgLSBtYXJnaW47XG4gICAgfVxuICAgIGlmIChuYW1lID09PSAnYm90dG9tJykge1xuICAgICAgcmV0dXJuIHBhZ2UueSA+IChoZWlnaHQgPj0gMCA/IHJlY3QuYm90dG9tIDogcmVjdC50b3ApIC0gbWFyZ2luO1xuICAgIH1cbiAgfVxuXG4gIC8vIHRoZSByZW1haW5pbmcgY2hlY2tzIHJlcXVpcmUgYW4gZWxlbWVudFxuICBpZiAoIXV0aWxzLmlzLmVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdXRpbHMuaXMuZWxlbWVudCh2YWx1ZSlcbiAgLy8gdGhlIHZhbHVlIGlzIGFuIGVsZW1lbnQgdG8gdXNlIGFzIGEgcmVzaXplIGhhbmRsZVxuICA/IHZhbHVlID09PSBlbGVtZW50XG4gIC8vIG90aGVyd2lzZSBjaGVjayBpZiBlbGVtZW50IG1hdGNoZXMgdmFsdWUgYXMgc2VsZWN0b3JcbiAgOiB1dGlscy5tYXRjaGVzVXBUbyhlbGVtZW50LCB2YWx1ZSwgaW50ZXJhY3RhYmxlRWxlbWVudCk7XG59XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xuICBpbnRlcmFjdGlvbi5yZXNpemVBeGVzID0gJ3h5Jztcbn0pO1xuXG5JbnRlcmFjdEV2ZW50LnNpZ25hbHMub24oJ3NldC1kZWx0YScsIGZ1bmN0aW9uIChfcmVmMykge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbixcbiAgICAgIGlFdmVudCA9IF9yZWYzLmlFdmVudCxcbiAgICAgIGFjdGlvbiA9IF9yZWYzLmFjdGlvbjtcblxuICBpZiAoYWN0aW9uICE9PSAncmVzaXplJyB8fCAhaW50ZXJhY3Rpb24ucmVzaXplQXhlcykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBvcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnM7XG5cbiAgaWYgKG9wdGlvbnMucmVzaXplLnNxdWFyZSkge1xuICAgIGlmIChpbnRlcmFjdGlvbi5yZXNpemVBeGVzID09PSAneScpIHtcbiAgICAgIGlFdmVudC5keCA9IGlFdmVudC5keTtcbiAgICB9IGVsc2Uge1xuICAgICAgaUV2ZW50LmR5ID0gaUV2ZW50LmR4O1xuICAgIH1cbiAgICBpRXZlbnQuYXhlcyA9ICd4eSc7XG4gIH0gZWxzZSB7XG4gICAgaUV2ZW50LmF4ZXMgPSBpbnRlcmFjdGlvbi5yZXNpemVBeGVzO1xuXG4gICAgaWYgKGludGVyYWN0aW9uLnJlc2l6ZUF4ZXMgPT09ICd4Jykge1xuICAgICAgaUV2ZW50LmR5ID0gMDtcbiAgICB9IGVsc2UgaWYgKGludGVyYWN0aW9uLnJlc2l6ZUF4ZXMgPT09ICd5Jykge1xuICAgICAgaUV2ZW50LmR4ID0gMDtcbiAgICB9XG4gIH1cbn0pO1xuXG5hY3Rpb25zLnJlc2l6ZSA9IHJlc2l6ZTtcbmFjdGlvbnMubmFtZXMucHVzaCgncmVzaXplJyk7XG51dGlscy5tZXJnZShJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgWydyZXNpemVzdGFydCcsICdyZXNpemVtb3ZlJywgJ3Jlc2l6ZWluZXJ0aWFzdGFydCcsICdyZXNpemVpbmVydGlhcmVzdW1lJywgJ3Jlc2l6ZWVuZCddKTtcbmFjdGlvbnMubWV0aG9kRGljdC5yZXNpemUgPSAncmVzaXphYmxlJztcblxuZGVmYXVsdE9wdGlvbnMucmVzaXplID0gcmVzaXplLmRlZmF1bHRzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlc2l6ZTtcblxufSx7XCIuLi9JbnRlcmFjdEV2ZW50XCI6MyxcIi4uL0ludGVyYWN0YWJsZVwiOjQsXCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuLi9kZWZhdWx0T3B0aW9uc1wiOjE4LFwiLi4vdXRpbHNcIjo0NCxcIi4uL3V0aWxzL2Jyb3dzZXJcIjozNyxcIi4vYmFzZVwiOjZ9XSwxMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciByYWYgPSByZXF1aXJlKCcuL3V0aWxzL3JhZicpO1xudmFyIGdldFdpbmRvdyA9IHJlcXVpcmUoJy4vdXRpbHMvd2luZG93JykuZ2V0V2luZG93O1xudmFyIGlzID0gcmVxdWlyZSgnLi91dGlscy9pcycpO1xudmFyIGRvbVV0aWxzID0gcmVxdWlyZSgnLi91dGlscy9kb21VdGlscycpO1xudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi9JbnRlcmFjdGlvbicpO1xudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi9kZWZhdWx0T3B0aW9ucycpO1xuXG52YXIgYXV0b1Njcm9sbCA9IHtcbiAgZGVmYXVsdHM6IHtcbiAgICBlbmFibGVkOiBmYWxzZSxcbiAgICBjb250YWluZXI6IG51bGwsIC8vIHRoZSBpdGVtIHRoYXQgaXMgc2Nyb2xsZWQgKFdpbmRvdyBvciBIVE1MRWxlbWVudClcbiAgICBtYXJnaW46IDYwLFxuICAgIHNwZWVkOiAzMDAgLy8gdGhlIHNjcm9sbCBzcGVlZCBpbiBwaXhlbHMgcGVyIHNlY29uZFxuICB9LFxuXG4gIGludGVyYWN0aW9uOiBudWxsLFxuICBpOiBudWxsLCAvLyB0aGUgaGFuZGxlIHJldHVybmVkIGJ5IHdpbmRvdy5zZXRJbnRlcnZhbFxuICB4OiAwLCB5OiAwLCAvLyBEaXJlY3Rpb24gZWFjaCBwdWxzZSBpcyB0byBzY3JvbGwgaW5cblxuICBpc1Njcm9sbGluZzogZmFsc2UsXG4gIHByZXZUaW1lOiAwLFxuXG4gIHN0YXJ0OiBmdW5jdGlvbiBzdGFydChpbnRlcmFjdGlvbikge1xuICAgIGF1dG9TY3JvbGwuaXNTY3JvbGxpbmcgPSB0cnVlO1xuICAgIHJhZi5jYW5jZWwoYXV0b1Njcm9sbC5pKTtcblxuICAgIGF1dG9TY3JvbGwuaW50ZXJhY3Rpb24gPSBpbnRlcmFjdGlvbjtcbiAgICBhdXRvU2Nyb2xsLnByZXZUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgYXV0b1Njcm9sbC5pID0gcmFmLnJlcXVlc3QoYXV0b1Njcm9sbC5zY3JvbGwpO1xuICB9LFxuXG4gIHN0b3A6IGZ1bmN0aW9uIHN0b3AoKSB7XG4gICAgYXV0b1Njcm9sbC5pc1Njcm9sbGluZyA9IGZhbHNlO1xuICAgIHJhZi5jYW5jZWwoYXV0b1Njcm9sbC5pKTtcbiAgfSxcblxuICAvLyBzY3JvbGwgdGhlIHdpbmRvdyBieSB0aGUgdmFsdWVzIGluIHNjcm9sbC54L3lcbiAgc2Nyb2xsOiBmdW5jdGlvbiBzY3JvbGwoKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhdXRvU2Nyb2xsLmludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zW2F1dG9TY3JvbGwuaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uYXV0b1Njcm9sbDtcbiAgICB2YXIgY29udGFpbmVyID0gb3B0aW9ucy5jb250YWluZXIgfHwgZ2V0V2luZG93KGF1dG9TY3JvbGwuaW50ZXJhY3Rpb24uZWxlbWVudCk7XG4gICAgdmFyIG5vdyA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIC8vIGNoYW5nZSBpbiB0aW1lIGluIHNlY29uZHNcbiAgICB2YXIgZHQgPSAobm93IC0gYXV0b1Njcm9sbC5wcmV2VGltZSkgLyAxMDAwO1xuICAgIC8vIGRpc3BsYWNlbWVudFxuICAgIHZhciBzID0gb3B0aW9ucy5zcGVlZCAqIGR0O1xuXG4gICAgaWYgKHMgPj0gMSkge1xuICAgICAgaWYgKGlzLndpbmRvdyhjb250YWluZXIpKSB7XG4gICAgICAgIGNvbnRhaW5lci5zY3JvbGxCeShhdXRvU2Nyb2xsLnggKiBzLCBhdXRvU2Nyb2xsLnkgKiBzKTtcbiAgICAgIH0gZWxzZSBpZiAoY29udGFpbmVyKSB7XG4gICAgICAgIGNvbnRhaW5lci5zY3JvbGxMZWZ0ICs9IGF1dG9TY3JvbGwueCAqIHM7XG4gICAgICAgIGNvbnRhaW5lci5zY3JvbGxUb3AgKz0gYXV0b1Njcm9sbC55ICogcztcbiAgICAgIH1cblxuICAgICAgYXV0b1Njcm9sbC5wcmV2VGltZSA9IG5vdztcbiAgICB9XG5cbiAgICBpZiAoYXV0b1Njcm9sbC5pc1Njcm9sbGluZykge1xuICAgICAgcmFmLmNhbmNlbChhdXRvU2Nyb2xsLmkpO1xuICAgICAgYXV0b1Njcm9sbC5pID0gcmFmLnJlcXVlc3QoYXV0b1Njcm9sbC5zY3JvbGwpO1xuICAgIH1cbiAgfSxcbiAgY2hlY2s6IGZ1bmN0aW9uIGNoZWNrKGludGVyYWN0YWJsZSwgYWN0aW9uTmFtZSkge1xuICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnM7XG5cbiAgICByZXR1cm4gb3B0aW9uc1thY3Rpb25OYW1lXS5hdXRvU2Nyb2xsICYmIG9wdGlvbnNbYWN0aW9uTmFtZV0uYXV0b1Njcm9sbC5lbmFibGVkO1xuICB9LFxuICBvbkludGVyYWN0aW9uTW92ZTogZnVuY3Rpb24gb25JbnRlcmFjdGlvbk1vdmUoX3JlZikge1xuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb24sXG4gICAgICAgIHBvaW50ZXIgPSBfcmVmLnBvaW50ZXI7XG5cbiAgICBpZiAoIShpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpICYmIGF1dG9TY3JvbGwuY2hlY2soaW50ZXJhY3Rpb24udGFyZ2V0LCBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoaW50ZXJhY3Rpb24uc2ltdWxhdGlvbikge1xuICAgICAgYXV0b1Njcm9sbC54ID0gYXV0b1Njcm9sbC55ID0gMDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgdG9wID0gdm9pZCAwO1xuICAgIHZhciByaWdodCA9IHZvaWQgMDtcbiAgICB2YXIgYm90dG9tID0gdm9pZCAwO1xuICAgIHZhciBsZWZ0ID0gdm9pZCAwO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBpbnRlcmFjdGlvbi50YXJnZXQub3B0aW9uc1tpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXS5hdXRvU2Nyb2xsO1xuICAgIHZhciBjb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lciB8fCBnZXRXaW5kb3coaW50ZXJhY3Rpb24uZWxlbWVudCk7XG5cbiAgICBpZiAoaXMud2luZG93KGNvbnRhaW5lcikpIHtcbiAgICAgIGxlZnQgPSBwb2ludGVyLmNsaWVudFggPCBhdXRvU2Nyb2xsLm1hcmdpbjtcbiAgICAgIHRvcCA9IHBvaW50ZXIuY2xpZW50WSA8IGF1dG9TY3JvbGwubWFyZ2luO1xuICAgICAgcmlnaHQgPSBwb2ludGVyLmNsaWVudFggPiBjb250YWluZXIuaW5uZXJXaWR0aCAtIGF1dG9TY3JvbGwubWFyZ2luO1xuICAgICAgYm90dG9tID0gcG9pbnRlci5jbGllbnRZID4gY29udGFpbmVyLmlubmVySGVpZ2h0IC0gYXV0b1Njcm9sbC5tYXJnaW47XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciByZWN0ID0gZG9tVXRpbHMuZ2V0RWxlbWVudENsaWVudFJlY3QoY29udGFpbmVyKTtcblxuICAgICAgbGVmdCA9IHBvaW50ZXIuY2xpZW50WCA8IHJlY3QubGVmdCArIGF1dG9TY3JvbGwubWFyZ2luO1xuICAgICAgdG9wID0gcG9pbnRlci5jbGllbnRZIDwgcmVjdC50b3AgKyBhdXRvU2Nyb2xsLm1hcmdpbjtcbiAgICAgIHJpZ2h0ID0gcG9pbnRlci5jbGllbnRYID4gcmVjdC5yaWdodCAtIGF1dG9TY3JvbGwubWFyZ2luO1xuICAgICAgYm90dG9tID0gcG9pbnRlci5jbGllbnRZID4gcmVjdC5ib3R0b20gLSBhdXRvU2Nyb2xsLm1hcmdpbjtcbiAgICB9XG5cbiAgICBhdXRvU2Nyb2xsLnggPSByaWdodCA/IDEgOiBsZWZ0ID8gLTEgOiAwO1xuICAgIGF1dG9TY3JvbGwueSA9IGJvdHRvbSA/IDEgOiB0b3AgPyAtMSA6IDA7XG5cbiAgICBpZiAoIWF1dG9TY3JvbGwuaXNTY3JvbGxpbmcpIHtcbiAgICAgIC8vIHNldCB0aGUgYXV0b1Njcm9sbCBwcm9wZXJ0aWVzIHRvIHRob3NlIG9mIHRoZSB0YXJnZXRcbiAgICAgIGF1dG9TY3JvbGwubWFyZ2luID0gb3B0aW9ucy5tYXJnaW47XG4gICAgICBhdXRvU2Nyb2xsLnNwZWVkID0gb3B0aW9ucy5zcGVlZDtcblxuICAgICAgYXV0b1Njcm9sbC5zdGFydChpbnRlcmFjdGlvbik7XG4gICAgfVxuICB9XG59O1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdzdG9wLWFjdGl2ZScsIGZ1bmN0aW9uICgpIHtcbiAgYXV0b1Njcm9sbC5zdG9wKCk7XG59KTtcblxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYWN0aW9uLW1vdmUnLCBhdXRvU2Nyb2xsLm9uSW50ZXJhY3Rpb25Nb3ZlKTtcblxuZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uLmF1dG9TY3JvbGwgPSBhdXRvU2Nyb2xsLmRlZmF1bHRzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGF1dG9TY3JvbGw7XG5cbn0se1wiLi9JbnRlcmFjdGlvblwiOjUsXCIuL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuL3V0aWxzL2RvbVV0aWxzXCI6MzksXCIuL3V0aWxzL2lzXCI6NDYsXCIuL3V0aWxzL3JhZlwiOjUwLFwiLi91dGlscy93aW5kb3dcIjo1Mn1dLDEyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4uL0ludGVyYWN0YWJsZScpO1xudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuLi9hY3Rpb25zL2Jhc2UnKTtcbnZhciBpcyA9IHJlcXVpcmUoJy4uL3V0aWxzL2lzJyk7XG52YXIgZG9tVXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9kb21VdGlscycpO1xuXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLmdldEFjdGlvbiA9IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpIHtcbiAgdmFyIGFjdGlvbiA9IHRoaXMuZGVmYXVsdEFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KTtcblxuICBpZiAodGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgdGhpcywgZWxlbWVudCwgaW50ZXJhY3Rpb24pO1xuICB9XG5cbiAgcmV0dXJuIGFjdGlvbjtcbn07XG5cbi8qXFxcbiAqIEludGVyYWN0YWJsZS5pZ25vcmVGcm9tXG4gWyBtZXRob2QgXVxuICpcbiAqIElmIHRoZSB0YXJnZXQgb2YgdGhlIGBtb3VzZWRvd25gLCBgcG9pbnRlcmRvd25gIG9yIGB0b3VjaHN0YXJ0YFxuICogZXZlbnQgb3IgYW55IG9mIGl0J3MgcGFyZW50cyBtYXRjaCB0aGUgZ2l2ZW4gQ1NTIHNlbGVjdG9yIG9yXG4gKiBFbGVtZW50LCBubyBkcmFnL3Jlc2l6ZS9nZXN0dXJlIGlzIHN0YXJ0ZWQuXG4gKlxuIC0gbmV3VmFsdWUgKHN0cmluZyB8IEVsZW1lbnQgfCBudWxsKSAjb3B0aW9uYWwgYSBDU1Mgc2VsZWN0b3Igc3RyaW5nLCBhbiBFbGVtZW50IG9yIGBudWxsYCB0byBub3QgaWdub3JlIGFueSBlbGVtZW50c1xuID0gKHN0cmluZyB8IEVsZW1lbnQgfCBvYmplY3QpIFRoZSBjdXJyZW50IGlnbm9yZUZyb20gdmFsdWUgb3IgdGhpcyBJbnRlcmFjdGFibGVcbiAqKlxuIHwgaW50ZXJhY3QoZWxlbWVudCwgeyBpZ25vcmVGcm9tOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbm8tYWN0aW9uJykgfSk7XG4gfCAvLyBvclxuIHwgaW50ZXJhY3QoZWxlbWVudCkuaWdub3JlRnJvbSgnaW5wdXQsIHRleHRhcmVhLCBhJyk7XG5cXCovXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLmlnbm9yZUZyb20gPSBmdW5jdGlvbiAobmV3VmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMuX2JhY2tDb21wYXRPcHRpb24oJ2lnbm9yZUZyb20nLCBuZXdWYWx1ZSk7XG59O1xuXG4vKlxcXG4gKiBJbnRlcmFjdGFibGUuYWxsb3dGcm9tXG4gWyBtZXRob2QgXVxuICpcbiAqIEEgZHJhZy9yZXNpemUvZ2VzdHVyZSBpcyBzdGFydGVkIG9ubHkgSWYgdGhlIHRhcmdldCBvZiB0aGVcbiAqIGBtb3VzZWRvd25gLCBgcG9pbnRlcmRvd25gIG9yIGB0b3VjaHN0YXJ0YCBldmVudCBvciBhbnkgb2YgaXQnc1xuICogcGFyZW50cyBtYXRjaCB0aGUgZ2l2ZW4gQ1NTIHNlbGVjdG9yIG9yIEVsZW1lbnQuXG4gKlxuIC0gbmV3VmFsdWUgKHN0cmluZyB8IEVsZW1lbnQgfCBudWxsKSAjb3B0aW9uYWwgYSBDU1Mgc2VsZWN0b3Igc3RyaW5nLCBhbiBFbGVtZW50IG9yIGBudWxsYCB0byBhbGxvdyBmcm9tIGFueSBlbGVtZW50XG4gPSAoc3RyaW5nIHwgRWxlbWVudCB8IG9iamVjdCkgVGhlIGN1cnJlbnQgYWxsb3dGcm9tIHZhbHVlIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG4gKipcbiB8IGludGVyYWN0KGVsZW1lbnQsIHsgYWxsb3dGcm9tOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHJhZy1oYW5kbGUnKSB9KTtcbiB8IC8vIG9yXG4gfCBpbnRlcmFjdChlbGVtZW50KS5hbGxvd0Zyb20oJy5oYW5kbGUnKTtcblxcKi9cbkludGVyYWN0YWJsZS5wcm90b3R5cGUuYWxsb3dGcm9tID0gZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gIHJldHVybiB0aGlzLl9iYWNrQ29tcGF0T3B0aW9uKCdhbGxvd0Zyb20nLCBuZXdWYWx1ZSk7XG59O1xuXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLnRlc3RJZ25vcmUgPSBmdW5jdGlvbiAoaWdub3JlRnJvbSwgaW50ZXJhY3RhYmxlRWxlbWVudCwgZWxlbWVudCkge1xuICBpZiAoIWlnbm9yZUZyb20gfHwgIWlzLmVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoaXMuc3RyaW5nKGlnbm9yZUZyb20pKSB7XG4gICAgcmV0dXJuIGRvbVV0aWxzLm1hdGNoZXNVcFRvKGVsZW1lbnQsIGlnbm9yZUZyb20sIGludGVyYWN0YWJsZUVsZW1lbnQpO1xuICB9IGVsc2UgaWYgKGlzLmVsZW1lbnQoaWdub3JlRnJvbSkpIHtcbiAgICByZXR1cm4gZG9tVXRpbHMubm9kZUNvbnRhaW5zKGlnbm9yZUZyb20sIGVsZW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS50ZXN0QWxsb3cgPSBmdW5jdGlvbiAoYWxsb3dGcm9tLCBpbnRlcmFjdGFibGVFbGVtZW50LCBlbGVtZW50KSB7XG4gIGlmICghYWxsb3dGcm9tKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAoIWlzLmVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoaXMuc3RyaW5nKGFsbG93RnJvbSkpIHtcbiAgICByZXR1cm4gZG9tVXRpbHMubWF0Y2hlc1VwVG8oZWxlbWVudCwgYWxsb3dGcm9tLCBpbnRlcmFjdGFibGVFbGVtZW50KTtcbiAgfSBlbHNlIGlmIChpcy5lbGVtZW50KGFsbG93RnJvbSkpIHtcbiAgICByZXR1cm4gZG9tVXRpbHMubm9kZUNvbnRhaW5zKGFsbG93RnJvbSwgZWxlbWVudCk7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLnRlc3RJZ25vcmVBbGxvdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBpbnRlcmFjdGFibGVFbGVtZW50LCBldmVudFRhcmdldCkge1xuICByZXR1cm4gIXRoaXMudGVzdElnbm9yZShvcHRpb25zLmlnbm9yZUZyb20sIGludGVyYWN0YWJsZUVsZW1lbnQsIGV2ZW50VGFyZ2V0KSAmJiB0aGlzLnRlc3RBbGxvdyhvcHRpb25zLmFsbG93RnJvbSwgaW50ZXJhY3RhYmxlRWxlbWVudCwgZXZlbnRUYXJnZXQpO1xufTtcblxuLypcXFxuICogSW50ZXJhY3RhYmxlLmFjdGlvbkNoZWNrZXJcbiBbIG1ldGhvZCBdXG4gKlxuICogR2V0cyBvciBzZXRzIHRoZSBmdW5jdGlvbiB1c2VkIHRvIGNoZWNrIGFjdGlvbiB0byBiZSBwZXJmb3JtZWQgb25cbiAqIHBvaW50ZXJEb3duXG4gKlxuIC0gY2hlY2tlciAoZnVuY3Rpb24gfCBudWxsKSAjb3B0aW9uYWwgQSBmdW5jdGlvbiB3aGljaCB0YWtlcyBhIHBvaW50ZXIgZXZlbnQsIGRlZmF1bHRBY3Rpb24gc3RyaW5nLCBpbnRlcmFjdGFibGUsIGVsZW1lbnQgYW5kIGludGVyYWN0aW9uIGFzIHBhcmFtZXRlcnMgYW5kIHJldHVybnMgYW4gb2JqZWN0IHdpdGggbmFtZSBwcm9wZXJ0eSAnZHJhZycgJ3Jlc2l6ZScgb3IgJ2dlc3R1cmUnIGFuZCBvcHRpb25hbGx5IGFuIGBlZGdlc2Agb2JqZWN0IHdpdGggYm9vbGVhbiAndG9wJywgJ2xlZnQnLCAnYm90dG9tJyBhbmQgcmlnaHQgcHJvcHMuXG4gPSAoRnVuY3Rpb24gfCBJbnRlcmFjdGFibGUpIFRoZSBjaGVja2VyIGZ1bmN0aW9uIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG4gKlxuIHwgaW50ZXJhY3QoJy5yZXNpemUtZHJhZycpXG4gfCAgIC5yZXNpemFibGUodHJ1ZSlcbiB8ICAgLmRyYWdnYWJsZSh0cnVlKVxuIHwgICAuYWN0aW9uQ2hlY2tlcihmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBpbnRlcmFjdGlvbikge1xuIHxcbiB8ICAgaWYgKGludGVyYWN0Lm1hdGNoZXNTZWxlY3RvcihldmVudC50YXJnZXQsICcuZHJhZy1oYW5kbGUnKSB7XG4gfCAgICAgLy8gZm9yY2UgZHJhZyB3aXRoIGhhbmRsZSB0YXJnZXRcbiB8ICAgICBhY3Rpb24ubmFtZSA9IGRyYWc7XG4gfCAgIH1cbiB8ICAgZWxzZSB7XG4gfCAgICAgLy8gcmVzaXplIGZyb20gdGhlIHRvcCBhbmQgcmlnaHQgZWRnZXNcbiB8ICAgICBhY3Rpb24ubmFtZSAgPSAncmVzaXplJztcbiB8ICAgICBhY3Rpb24uZWRnZXMgPSB7IHRvcDogdHJ1ZSwgcmlnaHQ6IHRydWUgfTtcbiB8ICAgfVxuIHxcbiB8ICAgcmV0dXJuIGFjdGlvbjtcbiB8IH0pO1xuXFwqL1xuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5hY3Rpb25DaGVja2VyID0gZnVuY3Rpb24gKGNoZWNrZXIpIHtcbiAgaWYgKGlzLmZ1bmN0aW9uKGNoZWNrZXIpKSB7XG4gICAgdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIgPSBjaGVja2VyO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBpZiAoY2hlY2tlciA9PT0gbnVsbCkge1xuICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMuYWN0aW9uQ2hlY2tlcjtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyO1xufTtcblxuLypcXFxuICogSW50ZXJhY3RhYmxlLnN0eWxlQ3Vyc29yXG4gWyBtZXRob2QgXVxuICpcbiAqIFJldHVybnMgb3Igc2V0cyB3aGV0aGVyIHRoZSB0aGUgY3Vyc29yIHNob3VsZCBiZSBjaGFuZ2VkIGRlcGVuZGluZyBvbiB0aGVcbiAqIGFjdGlvbiB0aGF0IHdvdWxkIGJlIHBlcmZvcm1lZCBpZiB0aGUgbW91c2Ugd2VyZSBwcmVzc2VkIGFuZCBkcmFnZ2VkLlxuICpcbiAtIG5ld1ZhbHVlIChib29sZWFuKSAjb3B0aW9uYWxcbiA9IChib29sZWFuIHwgSW50ZXJhY3RhYmxlKSBUaGUgY3VycmVudCBzZXR0aW5nIG9yIHRoaXMgSW50ZXJhY3RhYmxlXG5cXCovXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLnN0eWxlQ3Vyc29yID0gZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gIGlmIChpcy5ib29sKG5ld1ZhbHVlKSkge1xuICAgIHRoaXMub3B0aW9ucy5zdHlsZUN1cnNvciA9IG5ld1ZhbHVlO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBpZiAobmV3VmFsdWUgPT09IG51bGwpIHtcbiAgICBkZWxldGUgdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICByZXR1cm4gdGhpcy5vcHRpb25zLnN0eWxlQ3Vyc29yO1xufTtcblxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5kZWZhdWx0QWN0aW9uQ2hlY2tlciA9IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpIHtcbiAgdmFyIHJlY3QgPSB0aGlzLmdldFJlY3QoZWxlbWVudCk7XG4gIHZhciBhY3Rpb24gPSBudWxsO1xuXG4gIGZvciAodmFyIF9pdGVyYXRvciA9IGFjdGlvbnMubmFtZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgdmFyIF9yZWY7XG5cbiAgICBpZiAoX2lzQXJyYXkpIHtcbiAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcbiAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XG4gICAgfSBlbHNlIHtcbiAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcbiAgICAgIGlmIChfaS5kb25lKSBicmVhaztcbiAgICAgIF9yZWYgPSBfaS52YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgYWN0aW9uTmFtZSA9IF9yZWY7XG5cbiAgICAvLyBjaGVjayBtb3VzZUJ1dHRvbiBzZXR0aW5nIGlmIHRoZSBwb2ludGVyIGlzIGRvd25cbiAgICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlcklzRG93biAmJiBpbnRlcmFjdGlvbi5tb3VzZSAmJiAoZXZlbnQuYnV0dG9ucyAmIHRoaXMub3B0aW9uc1thY3Rpb25OYW1lXS5tb3VzZUJ1dHRvbnMpID09PSAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBhY3Rpb24gPSBhY3Rpb25zW2FjdGlvbk5hbWVdLmNoZWNrZXIocG9pbnRlciwgZXZlbnQsIHRoaXMsIGVsZW1lbnQsIGludGVyYWN0aW9uLCByZWN0KTtcblxuICAgIGlmIChhY3Rpb24pIHtcbiAgICAgIHJldHVybiBhY3Rpb247XG4gICAgfVxuICB9XG59O1xuXG59LHtcIi4uL0ludGVyYWN0YWJsZVwiOjQsXCIuLi9hY3Rpb25zL2Jhc2VcIjo2LFwiLi4vdXRpbHMvZG9tVXRpbHNcIjozOSxcIi4uL3V0aWxzL2lzXCI6NDZ9XSwxMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBpbnRlcmFjdCA9IHJlcXVpcmUoJy4uL2ludGVyYWN0Jyk7XG52YXIgSW50ZXJhY3RhYmxlID0gcmVxdWlyZSgnLi4vSW50ZXJhY3RhYmxlJyk7XG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuLi9JbnRlcmFjdGlvbicpO1xudmFyIGFjdGlvbnMgPSByZXF1aXJlKCcuLi9hY3Rpb25zL2Jhc2UnKTtcbnZhciBkZWZhdWx0T3B0aW9ucyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRPcHRpb25zJyk7XG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcbnZhciBzY29wZSA9IHJlcXVpcmUoJy4uL3Njb3BlJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIHNpZ25hbHMgPSByZXF1aXJlKCcuLi91dGlscy9TaWduYWxzJykubmV3KCk7XG5cbnJlcXVpcmUoJy4vSW50ZXJhY3RhYmxlTWV0aG9kcycpO1xuXG52YXIgYXV0b1N0YXJ0ID0ge1xuICBzaWduYWxzOiBzaWduYWxzLFxuICB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0OiB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0LFxuICAvLyBBbGxvdyB0aGlzIG1hbnkgaW50ZXJhY3Rpb25zIHRvIGhhcHBlbiBzaW11bHRhbmVvdXNseVxuICBtYXhJbnRlcmFjdGlvbnM6IEluZmluaXR5LFxuICBkZWZhdWx0czoge1xuICAgIHBlckFjdGlvbjoge1xuICAgICAgbWFudWFsU3RhcnQ6IGZhbHNlLFxuICAgICAgbWF4OiBJbmZpbml0eSxcbiAgICAgIG1heFBlckVsZW1lbnQ6IDEsXG4gICAgICBhbGxvd0Zyb206IG51bGwsXG4gICAgICBpZ25vcmVGcm9tOiBudWxsXG4gICAgfVxuICB9LFxuICBzZXRBY3Rpb25EZWZhdWx0czogZnVuY3Rpb24gc2V0QWN0aW9uRGVmYXVsdHMoYWN0aW9uKSB7XG4gICAgdXRpbHMuZXh0ZW5kKGFjdGlvbi5kZWZhdWx0cywgYXV0b1N0YXJ0LmRlZmF1bHRzLnBlckFjdGlvbik7XG4gIH1cbn07XG5cbi8vIHNldCBjdXJzb3Igc3R5bGUgb24gbW91c2Vkb3duXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdkb3duJywgZnVuY3Rpb24gKF9yZWYpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZi5pbnRlcmFjdGlvbixcbiAgICAgIHBvaW50ZXIgPSBfcmVmLnBvaW50ZXIsXG4gICAgICBldmVudCA9IF9yZWYuZXZlbnQsXG4gICAgICBldmVudFRhcmdldCA9IF9yZWYuZXZlbnRUYXJnZXQ7XG5cbiAgaWYgKGludGVyYWN0aW9uLmludGVyYWN0aW5nKCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgYWN0aW9uSW5mbyA9IGdldEFjdGlvbkluZm8oaW50ZXJhY3Rpb24sIHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCk7XG4gIHByZXBhcmUoaW50ZXJhY3Rpb24sIGFjdGlvbkluZm8pO1xufSk7XG5cbi8vIHNldCBjdXJzb3Igc3R5bGUgb24gbW91c2Vtb3ZlXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdtb3ZlJywgZnVuY3Rpb24gKF9yZWYyKSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxuICAgICAgcG9pbnRlciA9IF9yZWYyLnBvaW50ZXIsXG4gICAgICBldmVudCA9IF9yZWYyLmV2ZW50LFxuICAgICAgZXZlbnRUYXJnZXQgPSBfcmVmMi5ldmVudFRhcmdldDtcblxuICBpZiAoIWludGVyYWN0aW9uLm1vdXNlIHx8IGludGVyYWN0aW9uLnBvaW50ZXJJc0Rvd24gfHwgaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBhY3Rpb25JbmZvID0gZ2V0QWN0aW9uSW5mbyhpbnRlcmFjdGlvbiwgcG9pbnRlciwgZXZlbnQsIGV2ZW50VGFyZ2V0KTtcbiAgcHJlcGFyZShpbnRlcmFjdGlvbiwgYWN0aW9uSW5mbyk7XG59KTtcblxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbW92ZScsIGZ1bmN0aW9uIChhcmcpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxuICAgICAgZXZlbnQgPSBhcmcuZXZlbnQ7XG5cblxuICBpZiAoIWludGVyYWN0aW9uLnBvaW50ZXJJc0Rvd24gfHwgaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSB8fCAhaW50ZXJhY3Rpb24ucG9pbnRlcldhc01vdmVkIHx8ICFpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgc2lnbmFscy5maXJlKCdiZWZvcmUtc3RhcnQnLCBhcmcpO1xuXG4gIHZhciB0YXJnZXQgPSBpbnRlcmFjdGlvbi50YXJnZXQ7XG5cbiAgaWYgKGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgJiYgdGFyZ2V0KSB7XG4gICAgLy8gY2hlY2sgbWFudWFsU3RhcnQgYW5kIGludGVyYWN0aW9uIGxpbWl0XG4gICAgaWYgKHRhcmdldC5vcHRpb25zW2ludGVyYWN0aW9uLnByZXBhcmVkLm5hbWVdLm1hbnVhbFN0YXJ0IHx8ICF3aXRoaW5JbnRlcmFjdGlvbkxpbWl0KHRhcmdldCwgaW50ZXJhY3Rpb24uZWxlbWVudCwgaW50ZXJhY3Rpb24ucHJlcGFyZWQpKSB7XG4gICAgICBpbnRlcmFjdGlvbi5zdG9wKGV2ZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW50ZXJhY3Rpb24uc3RhcnQoaW50ZXJhY3Rpb24ucHJlcGFyZWQsIHRhcmdldCwgaW50ZXJhY3Rpb24uZWxlbWVudCk7XG4gICAgfVxuICB9XG59KTtcblxuLy8gQ2hlY2sgaWYgdGhlIGN1cnJlbnQgdGFyZ2V0IHN1cHBvcnRzIHRoZSBhY3Rpb24uXG4vLyBJZiBzbywgcmV0dXJuIHRoZSB2YWxpZGF0ZWQgYWN0aW9uLiBPdGhlcndpc2UsIHJldHVybiBudWxsXG5mdW5jdGlvbiB2YWxpZGF0ZUFjdGlvbihhY3Rpb24sIGludGVyYWN0YWJsZSwgZWxlbWVudCwgZXZlbnRUYXJnZXQpIHtcbiAgaWYgKHV0aWxzLmlzLm9iamVjdChhY3Rpb24pICYmIGludGVyYWN0YWJsZS50ZXN0SWdub3JlQWxsb3coaW50ZXJhY3RhYmxlLm9wdGlvbnNbYWN0aW9uLm5hbWVdLCBlbGVtZW50LCBldmVudFRhcmdldCkgJiYgaW50ZXJhY3RhYmxlLm9wdGlvbnNbYWN0aW9uLm5hbWVdLmVuYWJsZWQgJiYgd2l0aGluSW50ZXJhY3Rpb25MaW1pdChpbnRlcmFjdGFibGUsIGVsZW1lbnQsIGFjdGlvbikpIHtcbiAgICByZXR1cm4gYWN0aW9uO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlU2VsZWN0b3IoaW50ZXJhY3Rpb24sIHBvaW50ZXIsIGV2ZW50LCBtYXRjaGVzLCBtYXRjaEVsZW1lbnRzLCBldmVudFRhcmdldCkge1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gbWF0Y2hlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIHZhciBtYXRjaCA9IG1hdGNoZXNbaV07XG4gICAgdmFyIG1hdGNoRWxlbWVudCA9IG1hdGNoRWxlbWVudHNbaV07XG4gICAgdmFyIGFjdGlvbiA9IHZhbGlkYXRlQWN0aW9uKG1hdGNoLmdldEFjdGlvbihwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIG1hdGNoRWxlbWVudCksIG1hdGNoLCBtYXRjaEVsZW1lbnQsIGV2ZW50VGFyZ2V0KTtcblxuICAgIGlmIChhY3Rpb24pIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFjdGlvbjogYWN0aW9uLFxuICAgICAgICB0YXJnZXQ6IG1hdGNoLFxuICAgICAgICBlbGVtZW50OiBtYXRjaEVsZW1lbnRcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHt9O1xufVxuXG5mdW5jdGlvbiBnZXRBY3Rpb25JbmZvKGludGVyYWN0aW9uLCBwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQpIHtcbiAgdmFyIG1hdGNoZXMgPSBbXTtcbiAgdmFyIG1hdGNoRWxlbWVudHMgPSBbXTtcblxuICB2YXIgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xuICB2YXIgYWN0aW9uID0gbnVsbDtcblxuICBmdW5jdGlvbiBwdXNoTWF0Y2hlcyhpbnRlcmFjdGFibGUsIHNlbGVjdG9yLCBjb250ZXh0KSB7XG4gICAgdmFyIGVsZW1lbnRzID0gYnJvd3Nlci51c2VNYXRjaGVzU2VsZWN0b3JQb2x5ZmlsbCA/IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAodXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yLCBlbGVtZW50cykpIHtcblxuICAgICAgbWF0Y2hlcy5wdXNoKGludGVyYWN0YWJsZSk7XG4gICAgICBtYXRjaEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgd2hpbGUgKHV0aWxzLmlzLmVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICBtYXRjaGVzID0gW107XG4gICAgbWF0Y2hFbGVtZW50cyA9IFtdO1xuXG4gICAgdmFyIGVsZW1lbnRJbnRlcmFjdGFibGUgPSBzY29wZS5pbnRlcmFjdGFibGVzLmdldChlbGVtZW50KTtcblxuICAgIGlmIChlbGVtZW50SW50ZXJhY3RhYmxlICYmIChhY3Rpb24gPSB2YWxpZGF0ZUFjdGlvbihlbGVtZW50SW50ZXJhY3RhYmxlLmdldEFjdGlvbihwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQsIGV2ZW50VGFyZ2V0KSwgZWxlbWVudEludGVyYWN0YWJsZSwgZWxlbWVudCwgZXZlbnRUYXJnZXQpKSAmJiAhZWxlbWVudEludGVyYWN0YWJsZS5vcHRpb25zW2FjdGlvbi5uYW1lXS5tYW51YWxTdGFydCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgYWN0aW9uOiBhY3Rpb24sXG4gICAgICAgIHRhcmdldDogZWxlbWVudEludGVyYWN0YWJsZVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NvcGUuaW50ZXJhY3RhYmxlcy5mb3JFYWNoU2VsZWN0b3IocHVzaE1hdGNoZXMsIGVsZW1lbnQpO1xuXG4gICAgICB2YXIgYWN0aW9uSW5mbyA9IHZhbGlkYXRlU2VsZWN0b3IoaW50ZXJhY3Rpb24sIHBvaW50ZXIsIGV2ZW50LCBtYXRjaGVzLCBtYXRjaEVsZW1lbnRzLCBldmVudFRhcmdldCk7XG5cbiAgICAgIGlmIChhY3Rpb25JbmZvLmFjdGlvbiAmJiAhYWN0aW9uSW5mby50YXJnZXQub3B0aW9uc1thY3Rpb25JbmZvLmFjdGlvbi5uYW1lXS5tYW51YWxTdGFydCkge1xuICAgICAgICByZXR1cm4gYWN0aW9uSW5mbztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBlbGVtZW50ID0gdXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiB7fTtcbn1cblxuZnVuY3Rpb24gcHJlcGFyZShpbnRlcmFjdGlvbiwgX3JlZjMpIHtcbiAgdmFyIGFjdGlvbiA9IF9yZWYzLmFjdGlvbixcbiAgICAgIHRhcmdldCA9IF9yZWYzLnRhcmdldCxcbiAgICAgIGVsZW1lbnQgPSBfcmVmMy5lbGVtZW50O1xuXG4gIGFjdGlvbiA9IGFjdGlvbiB8fCB7fTtcblxuICBpZiAoaW50ZXJhY3Rpb24udGFyZ2V0ICYmIGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zLnN0eWxlQ3Vyc29yKSB7XG4gICAgaW50ZXJhY3Rpb24udGFyZ2V0Ll9kb2MuZG9jdW1lbnRFbGVtZW50LnN0eWxlLmN1cnNvciA9ICcnO1xuICB9XG5cbiAgaW50ZXJhY3Rpb24udGFyZ2V0ID0gdGFyZ2V0O1xuICBpbnRlcmFjdGlvbi5lbGVtZW50ID0gZWxlbWVudDtcbiAgdXRpbHMuY29weUFjdGlvbihpbnRlcmFjdGlvbi5wcmVwYXJlZCwgYWN0aW9uKTtcblxuICBpZiAodGFyZ2V0ICYmIHRhcmdldC5vcHRpb25zLnN0eWxlQ3Vyc29yKSB7XG4gICAgdmFyIGN1cnNvciA9IGFjdGlvbiA/IGFjdGlvbnNbYWN0aW9uLm5hbWVdLmdldEN1cnNvcihhY3Rpb24pIDogJyc7XG4gICAgaW50ZXJhY3Rpb24udGFyZ2V0Ll9kb2MuZG9jdW1lbnRFbGVtZW50LnN0eWxlLmN1cnNvciA9IGN1cnNvcjtcbiAgfVxuXG4gIHNpZ25hbHMuZmlyZSgncHJlcGFyZWQnLCB7IGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbiB9KTtcbn1cblxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignc3RvcCcsIGZ1bmN0aW9uIChfcmVmNCkge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmNC5pbnRlcmFjdGlvbjtcblxuICB2YXIgdGFyZ2V0ID0gaW50ZXJhY3Rpb24udGFyZ2V0O1xuXG4gIGlmICh0YXJnZXQgJiYgdGFyZ2V0Lm9wdGlvbnMuc3R5bGVDdXJzb3IpIHtcbiAgICB0YXJnZXQuX2RvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gJyc7XG4gIH1cbn0pO1xuXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLmdldEFjdGlvbiA9IGZ1bmN0aW9uIChwb2ludGVyLCBldmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpIHtcbiAgdmFyIGFjdGlvbiA9IHRoaXMuZGVmYXVsdEFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KTtcblxuICBpZiAodGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXIocG9pbnRlciwgZXZlbnQsIGFjdGlvbiwgdGhpcywgZWxlbWVudCwgaW50ZXJhY3Rpb24pO1xuICB9XG5cbiAgcmV0dXJuIGFjdGlvbjtcbn07XG5cbi8qXFxcbiAqIEludGVyYWN0YWJsZS5hY3Rpb25DaGVja2VyXG4gWyBtZXRob2QgXVxuICpcbiAqIEdldHMgb3Igc2V0cyB0aGUgZnVuY3Rpb24gdXNlZCB0byBjaGVjayBhY3Rpb24gdG8gYmUgcGVyZm9ybWVkIG9uXG4gKiBwb2ludGVyRG93blxuICpcbiAtIGNoZWNrZXIgKGZ1bmN0aW9uIHwgbnVsbCkgI29wdGlvbmFsIEEgZnVuY3Rpb24gd2hpY2ggdGFrZXMgYSBwb2ludGVyIGV2ZW50LCBkZWZhdWx0QWN0aW9uIHN0cmluZywgaW50ZXJhY3RhYmxlLCBlbGVtZW50IGFuZCBpbnRlcmFjdGlvbiBhcyBwYXJhbWV0ZXJzIGFuZCByZXR1cm5zIGFuIG9iamVjdCB3aXRoIG5hbWUgcHJvcGVydHkgJ2RyYWcnICdyZXNpemUnIG9yICdnZXN0dXJlJyBhbmQgb3B0aW9uYWxseSBhbiBgZWRnZXNgIG9iamVjdCB3aXRoIGJvb2xlYW4gJ3RvcCcsICdsZWZ0JywgJ2JvdHRvbScgYW5kIHJpZ2h0IHByb3BzLlxuID0gKEZ1bmN0aW9uIHwgSW50ZXJhY3RhYmxlKSBUaGUgY2hlY2tlciBmdW5jdGlvbiBvciB0aGlzIEludGVyYWN0YWJsZVxuICpcbiB8IGludGVyYWN0KCcucmVzaXplLWRyYWcnKVxuIHwgICAucmVzaXphYmxlKHRydWUpXG4gfCAgIC5kcmFnZ2FibGUodHJ1ZSlcbiB8ICAgLmFjdGlvbkNoZWNrZXIoZnVuY3Rpb24gKHBvaW50ZXIsIGV2ZW50LCBhY3Rpb24sIGludGVyYWN0YWJsZSwgZWxlbWVudCwgaW50ZXJhY3Rpb24pIHtcbiB8XG4gfCAgIGlmIChpbnRlcmFjdC5tYXRjaGVzU2VsZWN0b3IoZXZlbnQudGFyZ2V0LCAnLmRyYWctaGFuZGxlJykge1xuIHwgICAgIC8vIGZvcmNlIGRyYWcgd2l0aCBoYW5kbGUgdGFyZ2V0XG4gfCAgICAgYWN0aW9uLm5hbWUgPSBkcmFnO1xuIHwgICB9XG4gfCAgIGVsc2Uge1xuIHwgICAgIC8vIHJlc2l6ZSBmcm9tIHRoZSB0b3AgYW5kIHJpZ2h0IGVkZ2VzXG4gfCAgICAgYWN0aW9uLm5hbWUgID0gJ3Jlc2l6ZSc7XG4gfCAgICAgYWN0aW9uLmVkZ2VzID0geyB0b3A6IHRydWUsIHJpZ2h0OiB0cnVlIH07XG4gfCAgIH1cbiB8XG4gfCAgIHJldHVybiBhY3Rpb247XG4gfCB9KTtcblxcKi9cbkludGVyYWN0YWJsZS5wcm90b3R5cGUuYWN0aW9uQ2hlY2tlciA9IGZ1bmN0aW9uIChjaGVja2VyKSB7XG4gIGlmICh1dGlscy5pcy5mdW5jdGlvbihjaGVja2VyKSkge1xuICAgIHRoaXMub3B0aW9ucy5hY3Rpb25DaGVja2VyID0gY2hlY2tlcjtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgaWYgKGNoZWNrZXIgPT09IG51bGwpIHtcbiAgICBkZWxldGUgdGhpcy5vcHRpb25zLmFjdGlvbkNoZWNrZXI7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHJldHVybiB0aGlzLm9wdGlvbnMuYWN0aW9uQ2hlY2tlcjtcbn07XG5cbi8qXFxcbiAqIEludGVyYWN0YWJsZS5zdHlsZUN1cnNvclxuIFsgbWV0aG9kIF1cbiAqXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciB0aGUgdGhlIGN1cnNvciBzaG91bGQgYmUgY2hhbmdlZCBkZXBlbmRpbmcgb24gdGhlXG4gKiBhY3Rpb24gdGhhdCB3b3VsZCBiZSBwZXJmb3JtZWQgaWYgdGhlIG1vdXNlIHdlcmUgcHJlc3NlZCBhbmQgZHJhZ2dlZC5cbiAqXG4gLSBuZXdWYWx1ZSAoYm9vbGVhbikgI29wdGlvbmFsXG4gPSAoYm9vbGVhbiB8IEludGVyYWN0YWJsZSkgVGhlIGN1cnJlbnQgc2V0dGluZyBvciB0aGlzIEludGVyYWN0YWJsZVxuXFwqL1xuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5zdHlsZUN1cnNvciA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICBpZiAodXRpbHMuaXMuYm9vbChuZXdWYWx1ZSkpIHtcbiAgICB0aGlzLm9wdGlvbnMuc3R5bGVDdXJzb3IgPSBuZXdWYWx1ZTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgaWYgKG5ld1ZhbHVlID09PSBudWxsKSB7XG4gICAgZGVsZXRlIHRoaXMub3B0aW9ucy5zdHlsZUN1cnNvcjtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMub3B0aW9ucy5zdHlsZUN1cnNvcjtcbn07XG5cbkludGVyYWN0YWJsZS5wcm90b3R5cGUuZGVmYXVsdEFjdGlvbkNoZWNrZXIgPSBmdW5jdGlvbiAocG9pbnRlciwgZXZlbnQsIGludGVyYWN0aW9uLCBlbGVtZW50KSB7XG4gIHZhciByZWN0ID0gdGhpcy5nZXRSZWN0KGVsZW1lbnQpO1xuICB2YXIgYnV0dG9ucyA9IGV2ZW50LmJ1dHRvbnMgfHwge1xuICAgIDA6IDEsXG4gICAgMTogNCxcbiAgICAzOiA4LFxuICAgIDQ6IDE2XG4gIH1bZXZlbnQuYnV0dG9uXTtcbiAgdmFyIGFjdGlvbiA9IG51bGw7XG5cbiAgZm9yICh2YXIgX2l0ZXJhdG9yID0gYWN0aW9ucy5uYW1lcywgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcbiAgICB2YXIgX3JlZjU7XG5cbiAgICBpZiAoX2lzQXJyYXkpIHtcbiAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcbiAgICAgIF9yZWY1ID0gX2l0ZXJhdG9yW19pKytdO1xuICAgIH0gZWxzZSB7XG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XG4gICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XG4gICAgICBfcmVmNSA9IF9pLnZhbHVlO1xuICAgIH1cblxuICAgIHZhciBhY3Rpb25OYW1lID0gX3JlZjU7XG5cbiAgICAvLyBjaGVjayBtb3VzZUJ1dHRvbiBzZXR0aW5nIGlmIHRoZSBwb2ludGVyIGlzIGRvd25cbiAgICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlcklzRG93biAmJiBpbnRlcmFjdGlvbi5tb3VzZSAmJiAoYnV0dG9ucyAmIHRoaXMub3B0aW9uc1thY3Rpb25OYW1lXS5tb3VzZUJ1dHRvbnMpID09PSAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBhY3Rpb24gPSBhY3Rpb25zW2FjdGlvbk5hbWVdLmNoZWNrZXIocG9pbnRlciwgZXZlbnQsIHRoaXMsIGVsZW1lbnQsIGludGVyYWN0aW9uLCByZWN0KTtcblxuICAgIGlmIChhY3Rpb24pIHtcbiAgICAgIHJldHVybiBhY3Rpb247XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiB3aXRoaW5JbnRlcmFjdGlvbkxpbWl0KGludGVyYWN0YWJsZSwgZWxlbWVudCwgYWN0aW9uKSB7XG4gIHZhciBvcHRpb25zID0gaW50ZXJhY3RhYmxlLm9wdGlvbnM7XG4gIHZhciBtYXhBY3Rpb25zID0gb3B0aW9uc1thY3Rpb24ubmFtZV0ubWF4O1xuICB2YXIgbWF4UGVyRWxlbWVudCA9IG9wdGlvbnNbYWN0aW9uLm5hbWVdLm1heFBlckVsZW1lbnQ7XG4gIHZhciBhY3RpdmVJbnRlcmFjdGlvbnMgPSAwO1xuICB2YXIgdGFyZ2V0Q291bnQgPSAwO1xuICB2YXIgdGFyZ2V0RWxlbWVudENvdW50ID0gMDtcblxuICAvLyBubyBhY3Rpb25zIGlmIGFueSBvZiB0aGVzZSB2YWx1ZXMgPT0gMFxuICBpZiAoIShtYXhBY3Rpb25zICYmIG1heFBlckVsZW1lbnQgJiYgYXV0b1N0YXJ0Lm1heEludGVyYWN0aW9ucykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2NvcGUuaW50ZXJhY3Rpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIGludGVyYWN0aW9uID0gc2NvcGUuaW50ZXJhY3Rpb25zW2ldO1xuICAgIHZhciBvdGhlckFjdGlvbiA9IGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWU7XG5cbiAgICBpZiAoIWludGVyYWN0aW9uLmludGVyYWN0aW5nKCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGFjdGl2ZUludGVyYWN0aW9ucysrO1xuXG4gICAgaWYgKGFjdGl2ZUludGVyYWN0aW9ucyA+PSBhdXRvU3RhcnQubWF4SW50ZXJhY3Rpb25zKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKGludGVyYWN0aW9uLnRhcmdldCAhPT0gaW50ZXJhY3RhYmxlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB0YXJnZXRDb3VudCArPSBvdGhlckFjdGlvbiA9PT0gYWN0aW9uLm5hbWUgfCAwO1xuXG4gICAgaWYgKHRhcmdldENvdW50ID49IG1heEFjdGlvbnMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoaW50ZXJhY3Rpb24uZWxlbWVudCA9PT0gZWxlbWVudCkge1xuICAgICAgdGFyZ2V0RWxlbWVudENvdW50Kys7XG5cbiAgICAgIGlmIChvdGhlckFjdGlvbiAhPT0gYWN0aW9uLm5hbWUgfHwgdGFyZ2V0RWxlbWVudENvdW50ID49IG1heFBlckVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBhdXRvU3RhcnQubWF4SW50ZXJhY3Rpb25zID4gMDtcbn1cblxuLypcXFxuICogaW50ZXJhY3QubWF4SW50ZXJhY3Rpb25zXG4gWyBtZXRob2QgXVxuICoqXG4gKiBSZXR1cm5zIG9yIHNldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGNvbmN1cnJlbnQgaW50ZXJhY3Rpb25zIGFsbG93ZWQuXG4gKiBCeSBkZWZhdWx0IG9ubHkgMSBpbnRlcmFjdGlvbiBpcyBhbGxvd2VkIGF0IGEgdGltZSAoZm9yIGJhY2t3YXJkc1xuICogY29tcGF0aWJpbGl0eSkuIFRvIGFsbG93IG11bHRpcGxlIGludGVyYWN0aW9ucyBvbiB0aGUgc2FtZSBJbnRlcmFjdGFibGVzXG4gKiBhbmQgZWxlbWVudHMsIHlvdSBuZWVkIHRvIGVuYWJsZSBpdCBpbiB0aGUgZHJhZ2dhYmxlLCByZXNpemFibGUgYW5kXG4gKiBnZXN0dXJhYmxlIGAnbWF4J2AgYW5kIGAnbWF4UGVyRWxlbWVudCdgIG9wdGlvbnMuXG4gKipcbiAtIG5ld1ZhbHVlIChudW1iZXIpICNvcHRpb25hbCBBbnkgbnVtYmVyLiBuZXdWYWx1ZSA8PSAwIG1lYW5zIG5vIGludGVyYWN0aW9ucy5cblxcKi9cbmludGVyYWN0Lm1heEludGVyYWN0aW9ucyA9IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICBpZiAodXRpbHMuaXMubnVtYmVyKG5ld1ZhbHVlKSkge1xuICAgIGF1dG9TdGFydC5tYXhJbnRlcmFjdGlvbnMgPSBuZXdWYWx1ZTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmV0dXJuIGF1dG9TdGFydC5tYXhJbnRlcmFjdGlvbnM7XG59O1xuXG5JbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLnB1c2goJ3N0eWxlQ3Vyc29yJyk7XG5JbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLnB1c2goJ2FjdGlvbkNoZWNrZXInKTtcbkludGVyYWN0YWJsZS5zZXR0aW5nc01ldGhvZHMucHVzaCgnaWdub3JlRnJvbScpO1xuSW50ZXJhY3RhYmxlLnNldHRpbmdzTWV0aG9kcy5wdXNoKCdhbGxvd0Zyb20nKTtcblxuZGVmYXVsdE9wdGlvbnMuYmFzZS5hY3Rpb25DaGVja2VyID0gbnVsbDtcbmRlZmF1bHRPcHRpb25zLmJhc2Uuc3R5bGVDdXJzb3IgPSB0cnVlO1xuXG51dGlscy5leHRlbmQoZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uLCBhdXRvU3RhcnQuZGVmYXVsdHMucGVyQWN0aW9uKTtcblxubW9kdWxlLmV4cG9ydHMgPSBhdXRvU3RhcnQ7XG5cbn0se1wiLi4vSW50ZXJhY3RhYmxlXCI6NCxcIi4uL0ludGVyYWN0aW9uXCI6NSxcIi4uL2FjdGlvbnMvYmFzZVwiOjYsXCIuLi9kZWZhdWx0T3B0aW9uc1wiOjE4LFwiLi4vaW50ZXJhY3RcIjoyMSxcIi4uL3Njb3BlXCI6MzQsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvU2lnbmFsc1wiOjM1LFwiLi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi9JbnRlcmFjdGFibGVNZXRob2RzXCI6MTJ9XSwxNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBhdXRvU3RhcnQgPSByZXF1aXJlKCcuL2Jhc2UnKTtcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xuICBpbnRlcmFjdGlvbi5kZWxheVRpbWVyID0gbnVsbDtcbn0pO1xuXG5hdXRvU3RhcnQuc2lnbmFscy5vbigncHJlcGFyZWQnLCBmdW5jdGlvbiAoX3JlZikge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmLmludGVyYWN0aW9uO1xuXG4gIHZhciBhY3Rpb25OYW1lID0gaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZTtcblxuICBpZiAoIWFjdGlvbk5hbWUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZGVsYXkgPSBpbnRlcmFjdGlvbi50YXJnZXQub3B0aW9uc1thY3Rpb25OYW1lXS5kZWxheTtcblxuICBpZiAoZGVsYXkgPiAwKSB7XG4gICAgaW50ZXJhY3Rpb24uZGVsYXlUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgaW50ZXJhY3Rpb24uc3RhcnQoaW50ZXJhY3Rpb24ucHJlcGFyZWQsIGludGVyYWN0aW9uLnRhcmdldCwgaW50ZXJhY3Rpb24uZWxlbWVudCk7XG4gICAgfSwgZGVsYXkpO1xuICB9XG59KTtcblxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbW92ZScsIGZ1bmN0aW9uIChfcmVmMikge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbixcbiAgICAgIGR1cGxpY2F0ZSA9IF9yZWYyLmR1cGxpY2F0ZTtcblxuICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlcldhc01vdmVkICYmICFkdXBsaWNhdGUpIHtcbiAgICBjbGVhclRpbWVvdXQoaW50ZXJhY3Rpb24uZGVsYXlUaW1lcik7XG4gIH1cbn0pO1xuXG4vLyBwcmV2ZW50IHJlZ3VsYXIgZG93bi0+bW92ZSBhdXRvU3RhcnRcbmF1dG9TdGFydC5zaWduYWxzLm9uKCdiZWZvcmUtc3RhcnQnLCBmdW5jdGlvbiAoX3JlZjMpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjMuaW50ZXJhY3Rpb247XG5cbiAgdmFyIGFjdGlvbk5hbWUgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lO1xuXG4gIGlmICghYWN0aW9uTmFtZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBkZWxheSA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zW2FjdGlvbk5hbWVdLmRlbGF5O1xuXG4gIGlmIChkZWxheSA+IDApIHtcbiAgICBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lID0gbnVsbDtcbiAgfVxufSk7XG5cbn0se1wiLi4vSW50ZXJhY3Rpb25cIjo1LFwiLi9iYXNlXCI6MTN9XSwxNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBhdXRvU3RhcnQgPSByZXF1aXJlKCcuL2Jhc2UnKTtcbnZhciBzY29wZSA9IHJlcXVpcmUoJy4uL3Njb3BlJyk7XG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcbnZhciBpcyA9IHJlcXVpcmUoJy4uL3V0aWxzL2lzJyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4uL3V0aWxzL2RvbVV0aWxzJyksXG4gICAgbWF0Y2hlc1NlbGVjdG9yID0gX3JlcXVpcmUubWF0Y2hlc1NlbGVjdG9yLFxuICAgIHBhcmVudE5vZGUgPSBfcmVxdWlyZS5wYXJlbnROb2RlO1xuXG5hdXRvU3RhcnQuc2V0QWN0aW9uRGVmYXVsdHMocmVxdWlyZSgnLi4vYWN0aW9ucy9kcmFnJykpO1xuXG5hdXRvU3RhcnQuc2lnbmFscy5vbignYmVmb3JlLXN0YXJ0JywgZnVuY3Rpb24gKF9yZWYpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZi5pbnRlcmFjdGlvbixcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZi5ldmVudFRhcmdldCxcbiAgICAgIGR4ID0gX3JlZi5keCxcbiAgICAgIGR5ID0gX3JlZi5keTtcblxuICBpZiAoaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSAhPT0gJ2RyYWcnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gY2hlY2sgaWYgYSBkcmFnIGlzIGluIHRoZSBjb3JyZWN0IGF4aXNcbiAgdmFyIGFic1ggPSBNYXRoLmFicyhkeCk7XG4gIHZhciBhYnNZID0gTWF0aC5hYnMoZHkpO1xuICB2YXIgb3B0aW9ucyA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zLmRyYWc7XG4gIHZhciBzdGFydEF4aXMgPSBvcHRpb25zLnN0YXJ0QXhpcztcbiAgdmFyIGN1cnJlbnRBeGlzID0gYWJzWCA+IGFic1kgPyAneCcgOiBhYnNYIDwgYWJzWSA/ICd5JyA6ICd4eSc7XG5cbiAgaW50ZXJhY3Rpb24ucHJlcGFyZWQuYXhpcyA9IG9wdGlvbnMubG9ja0F4aXMgPT09ICdzdGFydCcgPyBjdXJyZW50QXhpc1swXSAvLyBhbHdheXMgbG9jayB0byBvbmUgYXhpcyBldmVuIGlmIGN1cnJlbnRBeGlzID09PSAneHknXG4gIDogb3B0aW9ucy5sb2NrQXhpcztcblxuICAvLyBpZiB0aGUgbW92ZW1lbnQgaXNuJ3QgaW4gdGhlIHN0YXJ0QXhpcyBvZiB0aGUgaW50ZXJhY3RhYmxlXG4gIGlmIChjdXJyZW50QXhpcyAhPT0gJ3h5JyAmJiBzdGFydEF4aXMgIT09ICd4eScgJiYgc3RhcnRBeGlzICE9PSBjdXJyZW50QXhpcykge1xuICAgIC8vIGNhbmNlbCB0aGUgcHJlcGFyZWQgYWN0aW9uXG4gICAgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSA9IG51bGw7XG5cbiAgICAvLyB0aGVuIHRyeSB0byBnZXQgYSBkcmFnIGZyb20gYW5vdGhlciBpbmVyYWN0YWJsZVxuXG4gICAgaWYgKCFpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lKSB7XG5cbiAgICAgIHZhciBlbGVtZW50ID0gZXZlbnRUYXJnZXQ7XG5cbiAgICAgIHZhciBnZXREcmFnZ2FibGUgPSBmdW5jdGlvbiBnZXREcmFnZ2FibGUoaW50ZXJhY3RhYmxlLCBzZWxlY3RvciwgY29udGV4dCkge1xuICAgICAgICB2YXIgZWxlbWVudHMgPSBicm93c2VyLnVzZU1hdGNoZXNTZWxlY3RvclBvbHlmaWxsID8gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSA6IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoaW50ZXJhY3RhYmxlID09PSBpbnRlcmFjdGlvbi50YXJnZXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW9wdGlvbnMubWFudWFsU3RhcnQgJiYgIWludGVyYWN0YWJsZS50ZXN0SWdub3JlQWxsb3cob3B0aW9ucywgZWxlbWVudCwgZXZlbnRUYXJnZXQpICYmIG1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvciwgZWxlbWVudHMpKSB7XG5cbiAgICAgICAgICB2YXIgX2FjdGlvbiA9IGludGVyYWN0YWJsZS5nZXRBY3Rpb24oaW50ZXJhY3Rpb24uZG93blBvaW50ZXIsIGludGVyYWN0aW9uLmRvd25FdmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpO1xuXG4gICAgICAgICAgaWYgKF9hY3Rpb24gJiYgX2FjdGlvbi5uYW1lID09PSAnZHJhZycgJiYgY2hlY2tTdGFydEF4aXMoY3VycmVudEF4aXMsIGludGVyYWN0YWJsZSkgJiYgYXV0b1N0YXJ0LnZhbGlkYXRlQWN0aW9uKF9hY3Rpb24sIGludGVyYWN0YWJsZSwgZWxlbWVudCwgZXZlbnRUYXJnZXQpKSB7XG5cbiAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdGFibGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICB2YXIgYWN0aW9uID0gbnVsbDtcblxuICAgICAgLy8gY2hlY2sgYWxsIGludGVyYWN0YWJsZXNcbiAgICAgIHdoaWxlIChpcy5lbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgICAgIHZhciBlbGVtZW50SW50ZXJhY3RhYmxlID0gc2NvcGUuaW50ZXJhY3RhYmxlcy5nZXQoZWxlbWVudCk7XG5cbiAgICAgICAgaWYgKGVsZW1lbnRJbnRlcmFjdGFibGUgJiYgZWxlbWVudEludGVyYWN0YWJsZSAhPT0gaW50ZXJhY3Rpb24udGFyZ2V0ICYmICFlbGVtZW50SW50ZXJhY3RhYmxlLm9wdGlvbnMuZHJhZy5tYW51YWxTdGFydCkge1xuXG4gICAgICAgICAgYWN0aW9uID0gZWxlbWVudEludGVyYWN0YWJsZS5nZXRBY3Rpb24oaW50ZXJhY3Rpb24uZG93blBvaW50ZXIsIGludGVyYWN0aW9uLmRvd25FdmVudCwgaW50ZXJhY3Rpb24sIGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhY3Rpb24gJiYgYWN0aW9uLm5hbWUgPT09ICdkcmFnJyAmJiBjaGVja1N0YXJ0QXhpcyhjdXJyZW50QXhpcywgZWxlbWVudEludGVyYWN0YWJsZSkpIHtcblxuICAgICAgICAgIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgPSAnZHJhZyc7XG4gICAgICAgICAgaW50ZXJhY3Rpb24udGFyZ2V0ID0gZWxlbWVudEludGVyYWN0YWJsZTtcbiAgICAgICAgICBpbnRlcmFjdGlvbi5lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzZWxlY3RvckludGVyYWN0YWJsZSA9IHNjb3BlLmludGVyYWN0YWJsZXMuZm9yRWFjaFNlbGVjdG9yKGdldERyYWdnYWJsZSwgZWxlbWVudCk7XG5cbiAgICAgICAgaWYgKHNlbGVjdG9ySW50ZXJhY3RhYmxlKSB7XG4gICAgICAgICAgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSA9ICdkcmFnJztcbiAgICAgICAgICBpbnRlcmFjdGlvbi50YXJnZXQgPSBzZWxlY3RvckludGVyYWN0YWJsZTtcbiAgICAgICAgICBpbnRlcmFjdGlvbi5lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGVsZW1lbnQgPSBwYXJlbnROb2RlKGVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufSk7XG5cbmZ1bmN0aW9uIGNoZWNrU3RhcnRBeGlzKHN0YXJ0QXhpcywgaW50ZXJhY3RhYmxlKSB7XG4gIGlmICghaW50ZXJhY3RhYmxlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIHRoaXNBeGlzID0gaW50ZXJhY3RhYmxlLm9wdGlvbnMuZHJhZy5zdGFydEF4aXM7XG5cbiAgcmV0dXJuIHN0YXJ0QXhpcyA9PT0gJ3h5JyB8fCB0aGlzQXhpcyA9PT0gJ3h5JyB8fCB0aGlzQXhpcyA9PT0gc3RhcnRBeGlzO1xufVxuXG59LHtcIi4uL2FjdGlvbnMvZHJhZ1wiOjcsXCIuLi9zY29wZVwiOjM0LFwiLi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi4vdXRpbHMvZG9tVXRpbHNcIjozOSxcIi4uL3V0aWxzL2lzXCI6NDYsXCIuL2Jhc2VcIjoxM31dLDE2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxucmVxdWlyZSgnLi9iYXNlJykuc2V0QWN0aW9uRGVmYXVsdHMocmVxdWlyZSgnLi4vYWN0aW9ucy9nZXN0dXJlJykpO1xuXG59LHtcIi4uL2FjdGlvbnMvZ2VzdHVyZVwiOjksXCIuL2Jhc2VcIjoxM31dLDE3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxucmVxdWlyZSgnLi9iYXNlJykuc2V0QWN0aW9uRGVmYXVsdHMocmVxdWlyZSgnLi4vYWN0aW9ucy9yZXNpemUnKSk7XG5cbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4vYmFzZVwiOjEzfV0sMTg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYmFzZToge1xuICAgIGFjY2VwdDogbnVsbCxcbiAgICBwcmV2ZW50RGVmYXVsdDogJ2F1dG8nLFxuICAgIGRlbHRhU291cmNlOiAncGFnZSdcbiAgfSxcblxuICBwZXJBY3Rpb246IHtcbiAgICBvcmlnaW46IHsgeDogMCwgeTogMCB9LFxuXG4gICAgLy8gb25seSBhbGxvdyBsZWZ0IGJ1dHRvbiBieSBkZWZhdWx0XG4gICAgLy8gc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Nb3VzZUV2ZW50L2J1dHRvbnMjUmV0dXJuX3ZhbHVlXG4gICAgbW91c2VCdXR0b25zOiAxLFxuXG4gICAgaW5lcnRpYToge1xuICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICByZXNpc3RhbmNlOiAxMCwgLy8gdGhlIGxhbWJkYSBpbiBleHBvbmVudGlhbCBkZWNheVxuICAgICAgbWluU3BlZWQ6IDEwMCwgLy8gdGFyZ2V0IHNwZWVkIG11c3QgYmUgYWJvdmUgdGhpcyBmb3IgaW5lcnRpYSB0byBzdGFydFxuICAgICAgZW5kU3BlZWQ6IDEwLCAvLyB0aGUgc3BlZWQgYXQgd2hpY2ggaW5lcnRpYSBpcyBzbG93IGVub3VnaCB0byBzdG9wXG4gICAgICBhbGxvd1Jlc3VtZTogdHJ1ZSwgLy8gYWxsb3cgcmVzdW1pbmcgYW4gYWN0aW9uIGluIGluZXJ0aWEgcGhhc2VcbiAgICAgIHNtb290aEVuZER1cmF0aW9uOiAzMDAgLy8gYW5pbWF0ZSB0byBzbmFwL3Jlc3RyaWN0IGVuZE9ubHkgaWYgdGhlcmUncyBubyBpbmVydGlhXG4gICAgfVxuICB9XG59O1xuXG59LHt9XSwxOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbi8qIGJyb3dzZXIgZW50cnkgcG9pbnQgKi9cblxuLy8gTGVnYWN5IGJyb3dzZXIgc3VwcG9ydFxucmVxdWlyZSgnLi9sZWdhY3lCcm93c2VycycpO1xuXG4vLyBpbmVydGlhXG5yZXF1aXJlKCcuL2luZXJ0aWEnKTtcblxuLy8gbW9kaWZpZXJzXG5yZXF1aXJlKCcuL21vZGlmaWVycy9zbmFwJyk7XG5yZXF1aXJlKCcuL21vZGlmaWVycy9yZXN0cmljdCcpO1xuXG4vLyBwb2ludGVyRXZlbnRzXG5yZXF1aXJlKCcuL3BvaW50ZXJFdmVudHMvYmFzZScpO1xucmVxdWlyZSgnLi9wb2ludGVyRXZlbnRzL2hvbGRSZXBlYXQnKTtcbnJlcXVpcmUoJy4vcG9pbnRlckV2ZW50cy9pbnRlcmFjdGFibGVUYXJnZXRzJyk7XG5cbi8vIGRlbGF5XG5yZXF1aXJlKCcuL2F1dG9TdGFydC9kZWxheScpO1xuXG4vLyBhY3Rpb25zXG5yZXF1aXJlKCcuL2FjdGlvbnMvZ2VzdHVyZScpO1xucmVxdWlyZSgnLi9hY3Rpb25zL3Jlc2l6ZScpO1xucmVxdWlyZSgnLi9hY3Rpb25zL2RyYWcnKTtcbnJlcXVpcmUoJy4vYWN0aW9ucy9kcm9wJyk7XG5cbi8vIGxvYWQgdGhlc2UgbW9kaWZpZXJzIGFmdGVyIHJlc2l6ZSBpcyBsb2FkZWRcbnJlcXVpcmUoJy4vbW9kaWZpZXJzL3NuYXBTaXplJyk7XG5yZXF1aXJlKCcuL21vZGlmaWVycy9yZXN0cmljdEVkZ2VzJyk7XG5yZXF1aXJlKCcuL21vZGlmaWVycy9yZXN0cmljdFNpemUnKTtcblxuLy8gYXV0b1N0YXJ0IGFjdGlvbnNcbnJlcXVpcmUoJy4vYXV0b1N0YXJ0L2dlc3R1cmUnKTtcbnJlcXVpcmUoJy4vYXV0b1N0YXJ0L3Jlc2l6ZScpO1xucmVxdWlyZSgnLi9hdXRvU3RhcnQvZHJhZycpO1xuXG4vLyBJbnRlcmFjdGFibGUgcHJldmVudERlZmF1bHQgc2V0dGluZ1xucmVxdWlyZSgnLi9pbnRlcmFjdGFibGVQcmV2ZW50RGVmYXVsdC5qcycpO1xuXG4vLyBhdXRvU2Nyb2xsXG5yZXF1aXJlKCcuL2F1dG9TY3JvbGwnKTtcblxuLy8gZXhwb3J0IGludGVyYWN0XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vaW50ZXJhY3QnKTtcblxufSx7XCIuL2FjdGlvbnMvZHJhZ1wiOjcsXCIuL2FjdGlvbnMvZHJvcFwiOjgsXCIuL2FjdGlvbnMvZ2VzdHVyZVwiOjksXCIuL2FjdGlvbnMvcmVzaXplXCI6MTAsXCIuL2F1dG9TY3JvbGxcIjoxMSxcIi4vYXV0b1N0YXJ0L2RlbGF5XCI6MTQsXCIuL2F1dG9TdGFydC9kcmFnXCI6MTUsXCIuL2F1dG9TdGFydC9nZXN0dXJlXCI6MTYsXCIuL2F1dG9TdGFydC9yZXNpemVcIjoxNyxcIi4vaW5lcnRpYVwiOjIwLFwiLi9pbnRlcmFjdFwiOjIxLFwiLi9pbnRlcmFjdGFibGVQcmV2ZW50RGVmYXVsdC5qc1wiOjIyLFwiLi9sZWdhY3lCcm93c2Vyc1wiOjIzLFwiLi9tb2RpZmllcnMvcmVzdHJpY3RcIjoyNSxcIi4vbW9kaWZpZXJzL3Jlc3RyaWN0RWRnZXNcIjoyNixcIi4vbW9kaWZpZXJzL3Jlc3RyaWN0U2l6ZVwiOjI3LFwiLi9tb2RpZmllcnMvc25hcFwiOjI4LFwiLi9tb2RpZmllcnMvc25hcFNpemVcIjoyOSxcIi4vcG9pbnRlckV2ZW50cy9iYXNlXCI6MzEsXCIuL3BvaW50ZXJFdmVudHMvaG9sZFJlcGVhdFwiOjMyLFwiLi9wb2ludGVyRXZlbnRzL2ludGVyYWN0YWJsZVRhcmdldHNcIjozM31dLDIwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIEludGVyYWN0RXZlbnQgPSByZXF1aXJlKCcuL0ludGVyYWN0RXZlbnQnKTtcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4vSW50ZXJhY3Rpb24nKTtcbnZhciBtb2RpZmllcnMgPSByZXF1aXJlKCcuL21vZGlmaWVycycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGFuaW1hdGlvbkZyYW1lID0gcmVxdWlyZSgnLi91dGlscy9yYWYnKTtcblxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignbmV3JywgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XG4gIGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXMgPSB7XG4gICAgYWN0aXZlOiBmYWxzZSxcbiAgICBzbW9vdGhFbmQ6IGZhbHNlLFxuICAgIGFsbG93UmVzdW1lOiBmYWxzZSxcblxuICAgIHN0YXJ0RXZlbnQ6IG51bGwsXG4gICAgdXBDb29yZHM6IHt9LFxuXG4gICAgeGU6IDAsIHllOiAwLFxuICAgIHN4OiAwLCBzeTogMCxcblxuICAgIHQwOiAwLFxuICAgIHZ4MDogMCwgdnlzOiAwLFxuICAgIGR1cmF0aW9uOiAwLFxuXG4gICAgbGFtYmRhX3YwOiAwLFxuICAgIG9uZV92ZV92MDogMCxcbiAgICBpOiBudWxsXG4gIH07XG5cbiAgaW50ZXJhY3Rpb24uYm91bmRJbmVydGlhRnJhbWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGluZXJ0aWFGcmFtZS5hcHBseShpbnRlcmFjdGlvbik7XG4gIH07XG4gIGludGVyYWN0aW9uLmJvdW5kU21vb3RoRW5kRnJhbWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHNtb290aEVuZEZyYW1lLmFwcGx5KGludGVyYWN0aW9uKTtcbiAgfTtcbn0pO1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdkb3duJywgZnVuY3Rpb24gKF9yZWYpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZi5pbnRlcmFjdGlvbixcbiAgICAgIGV2ZW50ID0gX3JlZi5ldmVudCxcbiAgICAgIHBvaW50ZXIgPSBfcmVmLnBvaW50ZXIsXG4gICAgICBldmVudFRhcmdldCA9IF9yZWYuZXZlbnRUYXJnZXQ7XG5cbiAgdmFyIHN0YXR1cyA9IGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXM7XG5cbiAgLy8gQ2hlY2sgaWYgdGhlIGRvd24gZXZlbnQgaGl0cyB0aGUgY3VycmVudCBpbmVydGlhIHRhcmdldFxuICBpZiAoc3RhdHVzLmFjdGl2ZSkge1xuICAgIHZhciBlbGVtZW50ID0gZXZlbnRUYXJnZXQ7XG5cbiAgICAvLyBjbGltYiB1cCB0aGUgRE9NIHRyZWUgZnJvbSB0aGUgZXZlbnQgdGFyZ2V0XG4gICAgd2hpbGUgKHV0aWxzLmlzLmVsZW1lbnQoZWxlbWVudCkpIHtcblxuICAgICAgLy8gaWYgaW50ZXJhY3Rpb24gZWxlbWVudCBpcyB0aGUgY3VycmVudCBpbmVydGlhIHRhcmdldCBlbGVtZW50XG4gICAgICBpZiAoZWxlbWVudCA9PT0gaW50ZXJhY3Rpb24uZWxlbWVudCkge1xuICAgICAgICAvLyBzdG9wIGluZXJ0aWFcbiAgICAgICAgYW5pbWF0aW9uRnJhbWUuY2FuY2VsKHN0YXR1cy5pKTtcbiAgICAgICAgc3RhdHVzLmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgICBpbnRlcmFjdGlvbi5zaW11bGF0aW9uID0gbnVsbDtcblxuICAgICAgICAvLyB1cGRhdGUgcG9pbnRlcnMgdG8gdGhlIGRvd24gZXZlbnQncyBjb29yZGluYXRlc1xuICAgICAgICBpbnRlcmFjdGlvbi51cGRhdGVQb2ludGVyKHBvaW50ZXIpO1xuICAgICAgICB1dGlscy5zZXRDb29yZHMoaW50ZXJhY3Rpb24uY3VyQ29vcmRzLCBpbnRlcmFjdGlvbi5wb2ludGVycyk7XG5cbiAgICAgICAgLy8gZmlyZSBhcHByb3ByaWF0ZSBzaWduYWxzXG4gICAgICAgIHZhciBzaWduYWxBcmcgPSB7IGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbiB9O1xuICAgICAgICBJbnRlcmFjdGlvbi5zaWduYWxzLmZpcmUoJ2JlZm9yZS1hY3Rpb24tbW92ZScsIHNpZ25hbEFyZyk7XG4gICAgICAgIEludGVyYWN0aW9uLnNpZ25hbHMuZmlyZSgnYWN0aW9uLXJlc3VtZScsIHNpZ25hbEFyZyk7XG5cbiAgICAgICAgLy8gZmlyZSBhIHJldW1lIGV2ZW50XG4gICAgICAgIHZhciByZXN1bWVFdmVudCA9IG5ldyBJbnRlcmFjdEV2ZW50KGludGVyYWN0aW9uLCBldmVudCwgaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZSwgJ2luZXJ0aWFyZXN1bWUnLCBpbnRlcmFjdGlvbi5lbGVtZW50KTtcblxuICAgICAgICBpbnRlcmFjdGlvbi50YXJnZXQuZmlyZShyZXN1bWVFdmVudCk7XG4gICAgICAgIGludGVyYWN0aW9uLnByZXZFdmVudCA9IHJlc3VtZUV2ZW50O1xuICAgICAgICBtb2RpZmllcnMucmVzZXRTdGF0dXNlcyhpbnRlcmFjdGlvbi5tb2RpZmllclN0YXR1c2VzKTtcblxuICAgICAgICB1dGlscy5jb3B5Q29vcmRzKGludGVyYWN0aW9uLnByZXZDb29yZHMsIGludGVyYWN0aW9uLmN1ckNvb3Jkcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBlbGVtZW50ID0gdXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcbiAgICB9XG4gIH1cbn0pO1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCd1cCcsIGZ1bmN0aW9uIChfcmVmMikge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbixcbiAgICAgIGV2ZW50ID0gX3JlZjIuZXZlbnQ7XG5cbiAgdmFyIHN0YXR1cyA9IGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXM7XG5cbiAgaWYgKCFpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpIHx8IHN0YXR1cy5hY3RpdmUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgdGFyZ2V0ID0gaW50ZXJhY3Rpb24udGFyZ2V0O1xuICB2YXIgb3B0aW9ucyA9IHRhcmdldCAmJiB0YXJnZXQub3B0aW9ucztcbiAgdmFyIGluZXJ0aWFPcHRpb25zID0gb3B0aW9ucyAmJiBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lICYmIG9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uaW5lcnRpYTtcblxuICB2YXIgbm93ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIHZhciBzdGF0dXNlcyA9IHt9O1xuICB2YXIgcGFnZSA9IHV0aWxzLmV4dGVuZCh7fSwgaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnBhZ2UpO1xuICB2YXIgcG9pbnRlclNwZWVkID0gaW50ZXJhY3Rpb24ucG9pbnRlckRlbHRhLmNsaWVudC5zcGVlZDtcblxuICB2YXIgc21vb3RoRW5kID0gZmFsc2U7XG4gIHZhciBtb2RpZmllclJlc3VsdCA9IHZvaWQgMDtcblxuICAvLyBjaGVjayBpZiBpbmVydGlhIHNob3VsZCBiZSBzdGFydGVkXG4gIHZhciBpbmVydGlhUG9zc2libGUgPSBpbmVydGlhT3B0aW9ucyAmJiBpbmVydGlhT3B0aW9ucy5lbmFibGVkICYmIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUgIT09ICdnZXN0dXJlJyAmJiBldmVudCAhPT0gc3RhdHVzLnN0YXJ0RXZlbnQ7XG5cbiAgdmFyIGluZXJ0aWEgPSBpbmVydGlhUG9zc2libGUgJiYgbm93IC0gaW50ZXJhY3Rpb24uY3VyQ29vcmRzLnRpbWVTdGFtcCA8IDUwICYmIHBvaW50ZXJTcGVlZCA+IGluZXJ0aWFPcHRpb25zLm1pblNwZWVkICYmIHBvaW50ZXJTcGVlZCA+IGluZXJ0aWFPcHRpb25zLmVuZFNwZWVkO1xuXG4gIHZhciBtb2RpZmllckFyZyA9IHtcbiAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXG4gICAgcGFnZUNvb3JkczogcGFnZSxcbiAgICBzdGF0dXNlczogc3RhdHVzZXMsXG4gICAgcHJlRW5kOiB0cnVlLFxuICAgIHJlcXVpcmVFbmRPbmx5OiB0cnVlXG4gIH07XG5cbiAgLy8gc21vb3RoRW5kXG4gIGlmIChpbmVydGlhUG9zc2libGUgJiYgIWluZXJ0aWEpIHtcbiAgICBtb2RpZmllcnMucmVzZXRTdGF0dXNlcyhzdGF0dXNlcyk7XG5cbiAgICBtb2RpZmllclJlc3VsdCA9IG1vZGlmaWVycy5zZXRBbGwobW9kaWZpZXJBcmcpO1xuXG4gICAgaWYgKG1vZGlmaWVyUmVzdWx0LnNob3VsZE1vdmUgJiYgbW9kaWZpZXJSZXN1bHQubG9ja2VkKSB7XG4gICAgICBzbW9vdGhFbmQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICghKGluZXJ0aWEgfHwgc21vb3RoRW5kKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHV0aWxzLmNvcHlDb29yZHMoc3RhdHVzLnVwQ29vcmRzLCBpbnRlcmFjdGlvbi5jdXJDb29yZHMpO1xuXG4gIGludGVyYWN0aW9uLnBvaW50ZXJzWzBdID0gc3RhdHVzLnN0YXJ0RXZlbnQgPSBuZXcgSW50ZXJhY3RFdmVudChpbnRlcmFjdGlvbiwgZXZlbnQsIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUsICdpbmVydGlhc3RhcnQnLCBpbnRlcmFjdGlvbi5lbGVtZW50KTtcblxuICBzdGF0dXMudDAgPSBub3c7XG5cbiAgc3RhdHVzLmFjdGl2ZSA9IHRydWU7XG4gIHN0YXR1cy5hbGxvd1Jlc3VtZSA9IGluZXJ0aWFPcHRpb25zLmFsbG93UmVzdW1lO1xuICBpbnRlcmFjdGlvbi5zaW11bGF0aW9uID0gc3RhdHVzO1xuXG4gIHRhcmdldC5maXJlKHN0YXR1cy5zdGFydEV2ZW50KTtcblxuICBpZiAoaW5lcnRpYSkge1xuICAgIHN0YXR1cy52eDAgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnZ4O1xuICAgIHN0YXR1cy52eTAgPSBpbnRlcmFjdGlvbi5wb2ludGVyRGVsdGEuY2xpZW50LnZ5O1xuICAgIHN0YXR1cy52MCA9IHBvaW50ZXJTcGVlZDtcblxuICAgIGNhbGNJbmVydGlhKGludGVyYWN0aW9uLCBzdGF0dXMpO1xuXG4gICAgdXRpbHMuZXh0ZW5kKHBhZ2UsIGludGVyYWN0aW9uLmN1ckNvb3Jkcy5wYWdlKTtcblxuICAgIHBhZ2UueCArPSBzdGF0dXMueGU7XG4gICAgcGFnZS55ICs9IHN0YXR1cy55ZTtcblxuICAgIG1vZGlmaWVycy5yZXNldFN0YXR1c2VzKHN0YXR1c2VzKTtcblxuICAgIG1vZGlmaWVyUmVzdWx0ID0gbW9kaWZpZXJzLnNldEFsbChtb2RpZmllckFyZyk7XG5cbiAgICBzdGF0dXMubW9kaWZpZWRYZSArPSBtb2RpZmllclJlc3VsdC5keDtcbiAgICBzdGF0dXMubW9kaWZpZWRZZSArPSBtb2RpZmllclJlc3VsdC5keTtcblxuICAgIHN0YXR1cy5pID0gYW5pbWF0aW9uRnJhbWUucmVxdWVzdChpbnRlcmFjdGlvbi5ib3VuZEluZXJ0aWFGcmFtZSk7XG4gIH0gZWxzZSB7XG4gICAgc3RhdHVzLnNtb290aEVuZCA9IHRydWU7XG4gICAgc3RhdHVzLnhlID0gbW9kaWZpZXJSZXN1bHQuZHg7XG4gICAgc3RhdHVzLnllID0gbW9kaWZpZXJSZXN1bHQuZHk7XG5cbiAgICBzdGF0dXMuc3ggPSBzdGF0dXMuc3kgPSAwO1xuXG4gICAgc3RhdHVzLmkgPSBhbmltYXRpb25GcmFtZS5yZXF1ZXN0KGludGVyYWN0aW9uLmJvdW5kU21vb3RoRW5kRnJhbWUpO1xuICB9XG59KTtcblxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignc3RvcC1hY3RpdmUnLCBmdW5jdGlvbiAoX3JlZjMpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjMuaW50ZXJhY3Rpb247XG5cbiAgdmFyIHN0YXR1cyA9IGludGVyYWN0aW9uLmluZXJ0aWFTdGF0dXM7XG5cbiAgaWYgKHN0YXR1cy5hY3RpdmUpIHtcbiAgICBhbmltYXRpb25GcmFtZS5jYW5jZWwoc3RhdHVzLmkpO1xuICAgIHN0YXR1cy5hY3RpdmUgPSBmYWxzZTtcbiAgICBpbnRlcmFjdGlvbi5zaW11bGF0aW9uID0gbnVsbDtcbiAgfVxufSk7XG5cbmZ1bmN0aW9uIGNhbGNJbmVydGlhKGludGVyYWN0aW9uLCBzdGF0dXMpIHtcbiAgdmFyIGluZXJ0aWFPcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV0uaW5lcnRpYTtcbiAgdmFyIGxhbWJkYSA9IGluZXJ0aWFPcHRpb25zLnJlc2lzdGFuY2U7XG4gIHZhciBpbmVydGlhRHVyID0gLU1hdGgubG9nKGluZXJ0aWFPcHRpb25zLmVuZFNwZWVkIC8gc3RhdHVzLnYwKSAvIGxhbWJkYTtcblxuICBzdGF0dXMueDAgPSBpbnRlcmFjdGlvbi5wcmV2RXZlbnQucGFnZVg7XG4gIHN0YXR1cy55MCA9IGludGVyYWN0aW9uLnByZXZFdmVudC5wYWdlWTtcbiAgc3RhdHVzLnQwID0gc3RhdHVzLnN0YXJ0RXZlbnQudGltZVN0YW1wIC8gMTAwMDtcbiAgc3RhdHVzLnN4ID0gc3RhdHVzLnN5ID0gMDtcblxuICBzdGF0dXMubW9kaWZpZWRYZSA9IHN0YXR1cy54ZSA9IChzdGF0dXMudngwIC0gaW5lcnRpYUR1cikgLyBsYW1iZGE7XG4gIHN0YXR1cy5tb2RpZmllZFllID0gc3RhdHVzLnllID0gKHN0YXR1cy52eTAgLSBpbmVydGlhRHVyKSAvIGxhbWJkYTtcbiAgc3RhdHVzLnRlID0gaW5lcnRpYUR1cjtcblxuICBzdGF0dXMubGFtYmRhX3YwID0gbGFtYmRhIC8gc3RhdHVzLnYwO1xuICBzdGF0dXMub25lX3ZlX3YwID0gMSAtIGluZXJ0aWFPcHRpb25zLmVuZFNwZWVkIC8gc3RhdHVzLnYwO1xufVxuXG5mdW5jdGlvbiBpbmVydGlhRnJhbWUoKSB7XG4gIHVwZGF0ZUluZXJ0aWFDb29yZHModGhpcyk7XG4gIHV0aWxzLnNldENvb3JkRGVsdGFzKHRoaXMucG9pbnRlckRlbHRhLCB0aGlzLnByZXZDb29yZHMsIHRoaXMuY3VyQ29vcmRzKTtcblxuICB2YXIgc3RhdHVzID0gdGhpcy5pbmVydGlhU3RhdHVzO1xuICB2YXIgb3B0aW9ucyA9IHRoaXMudGFyZ2V0Lm9wdGlvbnNbdGhpcy5wcmVwYXJlZC5uYW1lXS5pbmVydGlhO1xuICB2YXIgbGFtYmRhID0gb3B0aW9ucy5yZXNpc3RhbmNlO1xuICB2YXIgdCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCAtIHN0YXR1cy50MDtcblxuICBpZiAodCA8IHN0YXR1cy50ZSkge1xuXG4gICAgdmFyIHByb2dyZXNzID0gMSAtIChNYXRoLmV4cCgtbGFtYmRhICogdCkgLSBzdGF0dXMubGFtYmRhX3YwKSAvIHN0YXR1cy5vbmVfdmVfdjA7XG5cbiAgICBpZiAoc3RhdHVzLm1vZGlmaWVkWGUgPT09IHN0YXR1cy54ZSAmJiBzdGF0dXMubW9kaWZpZWRZZSA9PT0gc3RhdHVzLnllKSB7XG4gICAgICBzdGF0dXMuc3ggPSBzdGF0dXMueGUgKiBwcm9ncmVzcztcbiAgICAgIHN0YXR1cy5zeSA9IHN0YXR1cy55ZSAqIHByb2dyZXNzO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcXVhZFBvaW50ID0gdXRpbHMuZ2V0UXVhZHJhdGljQ3VydmVQb2ludCgwLCAwLCBzdGF0dXMueGUsIHN0YXR1cy55ZSwgc3RhdHVzLm1vZGlmaWVkWGUsIHN0YXR1cy5tb2RpZmllZFllLCBwcm9ncmVzcyk7XG5cbiAgICAgIHN0YXR1cy5zeCA9IHF1YWRQb2ludC54O1xuICAgICAgc3RhdHVzLnN5ID0gcXVhZFBvaW50Lnk7XG4gICAgfVxuXG4gICAgdGhpcy5kb01vdmUoKTtcblxuICAgIHN0YXR1cy5pID0gYW5pbWF0aW9uRnJhbWUucmVxdWVzdCh0aGlzLmJvdW5kSW5lcnRpYUZyYW1lKTtcbiAgfSBlbHNlIHtcbiAgICBzdGF0dXMuc3ggPSBzdGF0dXMubW9kaWZpZWRYZTtcbiAgICBzdGF0dXMuc3kgPSBzdGF0dXMubW9kaWZpZWRZZTtcblxuICAgIHRoaXMuZG9Nb3ZlKCk7XG4gICAgdGhpcy5lbmQoc3RhdHVzLnN0YXJ0RXZlbnQpO1xuICAgIHN0YXR1cy5hY3RpdmUgPSBmYWxzZTtcbiAgICB0aGlzLnNpbXVsYXRpb24gPSBudWxsO1xuICB9XG5cbiAgdXRpbHMuY29weUNvb3Jkcyh0aGlzLnByZXZDb29yZHMsIHRoaXMuY3VyQ29vcmRzKTtcbn1cblxuZnVuY3Rpb24gc21vb3RoRW5kRnJhbWUoKSB7XG4gIHVwZGF0ZUluZXJ0aWFDb29yZHModGhpcyk7XG5cbiAgdmFyIHN0YXR1cyA9IHRoaXMuaW5lcnRpYVN0YXR1cztcbiAgdmFyIHQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHN0YXR1cy50MDtcbiAgdmFyIGR1cmF0aW9uID0gdGhpcy50YXJnZXQub3B0aW9uc1t0aGlzLnByZXBhcmVkLm5hbWVdLmluZXJ0aWEuc21vb3RoRW5kRHVyYXRpb247XG5cbiAgaWYgKHQgPCBkdXJhdGlvbikge1xuICAgIHN0YXR1cy5zeCA9IHV0aWxzLmVhc2VPdXRRdWFkKHQsIDAsIHN0YXR1cy54ZSwgZHVyYXRpb24pO1xuICAgIHN0YXR1cy5zeSA9IHV0aWxzLmVhc2VPdXRRdWFkKHQsIDAsIHN0YXR1cy55ZSwgZHVyYXRpb24pO1xuXG4gICAgdGhpcy5wb2ludGVyTW92ZShzdGF0dXMuc3RhcnRFdmVudCwgc3RhdHVzLnN0YXJ0RXZlbnQpO1xuXG4gICAgc3RhdHVzLmkgPSBhbmltYXRpb25GcmFtZS5yZXF1ZXN0KHRoaXMuYm91bmRTbW9vdGhFbmRGcmFtZSk7XG4gIH0gZWxzZSB7XG4gICAgc3RhdHVzLnN4ID0gc3RhdHVzLnhlO1xuICAgIHN0YXR1cy5zeSA9IHN0YXR1cy55ZTtcblxuICAgIHRoaXMucG9pbnRlck1vdmUoc3RhdHVzLnN0YXJ0RXZlbnQsIHN0YXR1cy5zdGFydEV2ZW50KTtcbiAgICB0aGlzLmVuZChzdGF0dXMuc3RhcnRFdmVudCk7XG5cbiAgICBzdGF0dXMuc21vb3RoRW5kID0gc3RhdHVzLmFjdGl2ZSA9IGZhbHNlO1xuICAgIHRoaXMuc2ltdWxhdGlvbiA9IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlSW5lcnRpYUNvb3JkcyhpbnRlcmFjdGlvbikge1xuICB2YXIgc3RhdHVzID0gaW50ZXJhY3Rpb24uaW5lcnRpYVN0YXR1cztcblxuICAvLyByZXR1cm4gaWYgaW5lcnRpYSBpc24ndCBydW5uaW5nXG4gIGlmICghc3RhdHVzLmFjdGl2ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwYWdlVXAgPSBzdGF0dXMudXBDb29yZHMucGFnZTtcbiAgdmFyIGNsaWVudFVwID0gc3RhdHVzLnVwQ29vcmRzLmNsaWVudDtcblxuICB1dGlscy5zZXRDb29yZHMoaW50ZXJhY3Rpb24uY3VyQ29vcmRzLCBbe1xuICAgIHBhZ2VYOiBwYWdlVXAueCArIHN0YXR1cy5zeCxcbiAgICBwYWdlWTogcGFnZVVwLnkgKyBzdGF0dXMuc3ksXG4gICAgY2xpZW50WDogY2xpZW50VXAueCArIHN0YXR1cy5zeCxcbiAgICBjbGllbnRZOiBjbGllbnRVcC55ICsgc3RhdHVzLnN5XG4gIH1dKTtcbn1cblxufSx7XCIuL0ludGVyYWN0RXZlbnRcIjozLFwiLi9JbnRlcmFjdGlvblwiOjUsXCIuL21vZGlmaWVyc1wiOjI0LFwiLi91dGlsc1wiOjQ0LFwiLi91dGlscy9yYWZcIjo1MH1dLDIxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGJyb3dzZXIgPSByZXF1aXJlKCcuL3V0aWxzL2Jyb3dzZXInKTtcbnZhciBldmVudHMgPSByZXF1aXJlKCcuL3V0aWxzL2V2ZW50cycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIHNjb3BlID0gcmVxdWlyZSgnLi9zY29wZScpO1xudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4vSW50ZXJhY3RhYmxlJyk7XG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuL0ludGVyYWN0aW9uJyk7XG5cbnZhciBnbG9iYWxFdmVudHMgPSB7fTtcblxuLypcXFxuICogaW50ZXJhY3RcbiBbIG1ldGhvZCBdXG4gKlxuICogVGhlIG1ldGhvZHMgb2YgdGhpcyB2YXJpYWJsZSBjYW4gYmUgdXNlZCB0byBzZXQgZWxlbWVudHMgYXNcbiAqIGludGVyYWN0YWJsZXMgYW5kIGFsc28gdG8gY2hhbmdlIHZhcmlvdXMgZGVmYXVsdCBzZXR0aW5ncy5cbiAqXG4gKiBDYWxsaW5nIGl0IGFzIGEgZnVuY3Rpb24gYW5kIHBhc3NpbmcgYW4gZWxlbWVudCBvciBhIHZhbGlkIENTUyBzZWxlY3RvclxuICogc3RyaW5nIHJldHVybnMgYW4gSW50ZXJhY3RhYmxlIG9iamVjdCB3aGljaCBoYXMgdmFyaW91cyBtZXRob2RzIHRvXG4gKiBjb25maWd1cmUgaXQuXG4gKlxuIC0gZWxlbWVudCAoRWxlbWVudCB8IHN0cmluZykgVGhlIEhUTUwgb3IgU1ZHIEVsZW1lbnQgdG8gaW50ZXJhY3Qgd2l0aCBvciBDU1Mgc2VsZWN0b3JcbiA9IChvYmplY3QpIEFuIEBJbnRlcmFjdGFibGVcbiAqXG4gPiBVc2FnZVxuIHwgaW50ZXJhY3QoJyNkcmFnZ2FibGUnKS5kcmFnZ2FibGUodHJ1ZSk7XG4gfFxuIHwgdmFyIHJlY3RhYmxlcyA9IGludGVyYWN0KCdyZWN0Jyk7XG4gfCByZWN0YWJsZXNcbiB8ICAgICAuZ2VzdHVyYWJsZSh0cnVlKVxuIHwgICAgIC5vbignZ2VzdHVyZW1vdmUnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiB8ICAgICAgICAgLy8gLi4uXG4gfCAgICAgfSk7XG5cXCovXG5mdW5jdGlvbiBpbnRlcmFjdChlbGVtZW50LCBvcHRpb25zKSB7XG4gIHZhciBpbnRlcmFjdGFibGUgPSBzY29wZS5pbnRlcmFjdGFibGVzLmdldChlbGVtZW50LCBvcHRpb25zKTtcblxuICBpZiAoIWludGVyYWN0YWJsZSkge1xuICAgIGludGVyYWN0YWJsZSA9IG5ldyBJbnRlcmFjdGFibGUoZWxlbWVudCwgb3B0aW9ucyk7XG4gICAgaW50ZXJhY3RhYmxlLmV2ZW50cy5nbG9iYWwgPSBnbG9iYWxFdmVudHM7XG4gIH1cblxuICByZXR1cm4gaW50ZXJhY3RhYmxlO1xufVxuXG4vKlxcXG4gKiBpbnRlcmFjdC5pc1NldFxuIFsgbWV0aG9kIF1cbiAqXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IGhhcyBiZWVuIHNldFxuIC0gZWxlbWVudCAoRWxlbWVudCkgVGhlIEVsZW1lbnQgYmVpbmcgc2VhcmNoZWQgZm9yXG4gPSAoYm9vbGVhbikgSW5kaWNhdGVzIGlmIHRoZSBlbGVtZW50IG9yIENTUyBzZWxlY3RvciB3YXMgcHJldmlvdXNseSBwYXNzZWQgdG8gaW50ZXJhY3RcblxcKi9cbmludGVyYWN0LmlzU2V0ID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHNjb3BlLmludGVyYWN0YWJsZXMuaW5kZXhPZkVsZW1lbnQoZWxlbWVudCwgb3B0aW9ucyAmJiBvcHRpb25zLmNvbnRleHQpICE9PSAtMTtcbn07XG5cbi8qXFxcbiAqIGludGVyYWN0Lm9uXG4gWyBtZXRob2QgXVxuICpcbiAqIEFkZHMgYSBnbG9iYWwgbGlzdGVuZXIgZm9yIGFuIEludGVyYWN0RXZlbnQgb3IgYWRkcyBhIERPTSBldmVudCB0b1xuICogYGRvY3VtZW50YFxuICpcbiAtIHR5cGUgICAgICAgKHN0cmluZyB8IGFycmF5IHwgb2JqZWN0KSBUaGUgdHlwZXMgb2YgZXZlbnRzIHRvIGxpc3RlbiBmb3JcbiAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgZnVuY3Rpb24gZXZlbnQgKHMpXG4gLSBvcHRpb25zICAgIChvYmplY3QgfCBib29sZWFuKSAjb3B0aW9uYWwgb3B0aW9ucyBvYmplY3Qgb3IgdXNlQ2FwdHVyZSBmbGFnIGZvciBhZGRFdmVudExpc3RlbmVyXG4gPSAob2JqZWN0KSBpbnRlcmFjdFxuXFwqL1xuaW50ZXJhY3Qub24gPSBmdW5jdGlvbiAodHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgaWYgKHV0aWxzLmlzLnN0cmluZyh0eXBlKSAmJiB0eXBlLnNlYXJjaCgnICcpICE9PSAtMSkge1xuICAgIHR5cGUgPSB0eXBlLnRyaW0oKS5zcGxpdCgvICsvKTtcbiAgfVxuXG4gIGlmICh1dGlscy5pcy5hcnJheSh0eXBlKSkge1xuICAgIGZvciAodmFyIF9pdGVyYXRvciA9IHR5cGUsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICB2YXIgX3JlZjtcblxuICAgICAgaWYgKF9pc0FycmF5KSB7XG4gICAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcbiAgICAgICAgX3JlZiA9IF9pdGVyYXRvcltfaSsrXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKF9pLmRvbmUpIGJyZWFrO1xuICAgICAgICBfcmVmID0gX2kudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBldmVudFR5cGUgPSBfcmVmO1xuXG4gICAgICBpbnRlcmFjdC5vbihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaW50ZXJhY3Q7XG4gIH1cblxuICBpZiAodXRpbHMuaXMub2JqZWN0KHR5cGUpKSB7XG4gICAgZm9yICh2YXIgcHJvcCBpbiB0eXBlKSB7XG4gICAgICBpbnRlcmFjdC5vbihwcm9wLCB0eXBlW3Byb3BdLCBsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVyYWN0O1xuICB9XG5cbiAgLy8gaWYgaXQgaXMgYW4gSW50ZXJhY3RFdmVudCB0eXBlLCBhZGQgbGlzdGVuZXIgdG8gZ2xvYmFsRXZlbnRzXG4gIGlmICh1dGlscy5jb250YWlucyhJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgdHlwZSkpIHtcbiAgICAvLyBpZiB0aGlzIHR5cGUgb2YgZXZlbnQgd2FzIG5ldmVyIGJvdW5kXG4gICAgaWYgKCFnbG9iYWxFdmVudHNbdHlwZV0pIHtcbiAgICAgIGdsb2JhbEV2ZW50c1t0eXBlXSA9IFtsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIGdsb2JhbEV2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgICB9XG4gIH1cbiAgLy8gSWYgbm9uIEludGVyYWN0RXZlbnQgdHlwZSwgYWRkRXZlbnRMaXN0ZW5lciB0byBkb2N1bWVudFxuICBlbHNlIHtcbiAgICAgIGV2ZW50cy5hZGQoc2NvcGUuZG9jdW1lbnQsIHR5cGUsIGxpc3RlbmVyLCB7IG9wdGlvbnM6IG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gIHJldHVybiBpbnRlcmFjdDtcbn07XG5cbi8qXFxcbiAqIGludGVyYWN0Lm9mZlxuIFsgbWV0aG9kIF1cbiAqXG4gKiBSZW1vdmVzIGEgZ2xvYmFsIEludGVyYWN0RXZlbnQgbGlzdGVuZXIgb3IgRE9NIGV2ZW50IGZyb20gYGRvY3VtZW50YFxuICpcbiAtIHR5cGUgICAgICAgKHN0cmluZyB8IGFycmF5IHwgb2JqZWN0KSBUaGUgdHlwZXMgb2YgZXZlbnRzIHRoYXQgd2VyZSBsaXN0ZW5lZCBmb3JcbiAtIGxpc3RlbmVyICAgKGZ1bmN0aW9uKSBUaGUgbGlzdGVuZXIgZnVuY3Rpb24gdG8gYmUgcmVtb3ZlZFxuIC0gb3B0aW9ucyAgICAob2JqZWN0IHwgYm9vbGVhbikgI29wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IG9yIHVzZUNhcHR1cmUgZmxhZyBmb3IgcmVtb3ZlRXZlbnRMaXN0ZW5lclxuID0gKG9iamVjdCkgaW50ZXJhY3RcbiBcXCovXG5pbnRlcmFjdC5vZmYgPSBmdW5jdGlvbiAodHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgaWYgKHV0aWxzLmlzLnN0cmluZyh0eXBlKSAmJiB0eXBlLnNlYXJjaCgnICcpICE9PSAtMSkge1xuICAgIHR5cGUgPSB0eXBlLnRyaW0oKS5zcGxpdCgvICsvKTtcbiAgfVxuXG4gIGlmICh1dGlscy5pcy5hcnJheSh0eXBlKSkge1xuICAgIGZvciAodmFyIF9pdGVyYXRvcjIgPSB0eXBlLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcbiAgICAgIHZhciBfcmVmMjtcblxuICAgICAgaWYgKF9pc0FycmF5Mikge1xuICAgICAgICBpZiAoX2kyID49IF9pdGVyYXRvcjIubGVuZ3RoKSBicmVhaztcbiAgICAgICAgX3JlZjIgPSBfaXRlcmF0b3IyW19pMisrXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9pMiA9IF9pdGVyYXRvcjIubmV4dCgpO1xuICAgICAgICBpZiAoX2kyLmRvbmUpIGJyZWFrO1xuICAgICAgICBfcmVmMiA9IF9pMi52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIGV2ZW50VHlwZSA9IF9yZWYyO1xuXG4gICAgICBpbnRlcmFjdC5vZmYoZXZlbnRUeXBlLCBsaXN0ZW5lciwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVyYWN0O1xuICB9XG5cbiAgaWYgKHV0aWxzLmlzLm9iamVjdCh0eXBlKSkge1xuICAgIGZvciAodmFyIHByb3AgaW4gdHlwZSkge1xuICAgICAgaW50ZXJhY3Qub2ZmKHByb3AsIHR5cGVbcHJvcF0sIGxpc3RlbmVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaW50ZXJhY3Q7XG4gIH1cblxuICBpZiAoIXV0aWxzLmNvbnRhaW5zKEludGVyYWN0YWJsZS5ldmVudFR5cGVzLCB0eXBlKSkge1xuICAgIGV2ZW50cy5yZW1vdmUoc2NvcGUuZG9jdW1lbnQsIHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaW5kZXggPSB2b2lkIDA7XG5cbiAgICBpZiAodHlwZSBpbiBnbG9iYWxFdmVudHMgJiYgKGluZGV4ID0gdXRpbHMuaW5kZXhPZihnbG9iYWxFdmVudHNbdHlwZV0sIGxpc3RlbmVyKSkgIT09IC0xKSB7XG4gICAgICBnbG9iYWxFdmVudHNbdHlwZV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaW50ZXJhY3Q7XG59O1xuXG4vKlxcXG4gKiBpbnRlcmFjdC5kZWJ1Z1xuIFsgbWV0aG9kIF1cbiAqXG4gKiBSZXR1cm5zIGFuIG9iamVjdCB3aGljaCBleHBvc2VzIGludGVybmFsIGRhdGFcbiA9IChvYmplY3QpIEFuIG9iamVjdCB3aXRoIHByb3BlcnRpZXMgdGhhdCBvdXRsaW5lIHRoZSBjdXJyZW50IHN0YXRlIGFuZCBleHBvc2UgaW50ZXJuYWwgZnVuY3Rpb25zIGFuZCB2YXJpYWJsZXNcblxcKi9cbmludGVyYWN0LmRlYnVnID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gc2NvcGU7XG59O1xuXG4vLyBleHBvc2UgdGhlIGZ1bmN0aW9ucyB1c2VkIHRvIGNhbGN1bGF0ZSBtdWx0aS10b3VjaCBwcm9wZXJ0aWVzXG5pbnRlcmFjdC5nZXRQb2ludGVyQXZlcmFnZSA9IHV0aWxzLnBvaW50ZXJBdmVyYWdlO1xuaW50ZXJhY3QuZ2V0VG91Y2hCQm94ID0gdXRpbHMudG91Y2hCQm94O1xuaW50ZXJhY3QuZ2V0VG91Y2hEaXN0YW5jZSA9IHV0aWxzLnRvdWNoRGlzdGFuY2U7XG5pbnRlcmFjdC5nZXRUb3VjaEFuZ2xlID0gdXRpbHMudG91Y2hBbmdsZTtcblxuaW50ZXJhY3QuZ2V0RWxlbWVudFJlY3QgPSB1dGlscy5nZXRFbGVtZW50UmVjdDtcbmludGVyYWN0LmdldEVsZW1lbnRDbGllbnRSZWN0ID0gdXRpbHMuZ2V0RWxlbWVudENsaWVudFJlY3Q7XG5pbnRlcmFjdC5tYXRjaGVzU2VsZWN0b3IgPSB1dGlscy5tYXRjaGVzU2VsZWN0b3I7XG5pbnRlcmFjdC5jbG9zZXN0ID0gdXRpbHMuY2xvc2VzdDtcblxuLypcXFxuICogaW50ZXJhY3Quc3VwcG9ydHNUb3VjaFxuIFsgbWV0aG9kIF1cbiAqXG4gPSAoYm9vbGVhbikgV2hldGhlciBvciBub3QgdGhlIGJyb3dzZXIgc3VwcG9ydHMgdG91Y2ggaW5wdXRcblxcKi9cbmludGVyYWN0LnN1cHBvcnRzVG91Y2ggPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBicm93c2VyLnN1cHBvcnRzVG91Y2g7XG59O1xuXG4vKlxcXG4gKiBpbnRlcmFjdC5zdXBwb3J0c1BvaW50ZXJFdmVudFxuIFsgbWV0aG9kIF1cbiAqXG4gPSAoYm9vbGVhbikgV2hldGhlciBvciBub3QgdGhlIGJyb3dzZXIgc3VwcG9ydHMgUG9pbnRlckV2ZW50c1xuXFwqL1xuaW50ZXJhY3Quc3VwcG9ydHNQb2ludGVyRXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBicm93c2VyLnN1cHBvcnRzUG9pbnRlckV2ZW50O1xufTtcblxuLypcXFxuICogaW50ZXJhY3Quc3RvcFxuIFsgbWV0aG9kIF1cbiAqXG4gKiBDYW5jZWxzIGFsbCBpbnRlcmFjdGlvbnMgKGVuZCBldmVudHMgYXJlIG5vdCBmaXJlZClcbiAqXG4gLSBldmVudCAoRXZlbnQpIEFuIGV2ZW50IG9uIHdoaWNoIHRvIGNhbGwgcHJldmVudERlZmF1bHQoKVxuID0gKG9iamVjdCkgaW50ZXJhY3RcblxcKi9cbmludGVyYWN0LnN0b3AgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgZm9yICh2YXIgaSA9IHNjb3BlLmludGVyYWN0aW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIHNjb3BlLmludGVyYWN0aW9uc1tpXS5zdG9wKGV2ZW50KTtcbiAgfVxuXG4gIHJldHVybiBpbnRlcmFjdDtcbn07XG5cbi8qXFxcbiAqIGludGVyYWN0LnBvaW50ZXJNb3ZlVG9sZXJhbmNlXG4gWyBtZXRob2QgXVxuICogUmV0dXJucyBvciBzZXRzIHRoZSBkaXN0YW5jZSB0aGUgcG9pbnRlciBtdXN0IGJlIG1vdmVkIGJlZm9yZSBhbiBhY3Rpb25cbiAqIHNlcXVlbmNlIG9jY3Vycy4gVGhpcyBhbHNvIGFmZmVjdHMgdG9sZXJhbmNlIGZvciB0YXAgZXZlbnRzLlxuICpcbiAtIG5ld1ZhbHVlIChudW1iZXIpICNvcHRpb25hbCBUaGUgbW92ZW1lbnQgZnJvbSB0aGUgc3RhcnQgcG9zaXRpb24gbXVzdCBiZSBncmVhdGVyIHRoYW4gdGhpcyB2YWx1ZVxuID0gKG51bWJlciB8IEludGVyYWN0YWJsZSkgVGhlIGN1cnJlbnQgc2V0dGluZyBvciBpbnRlcmFjdFxuXFwqL1xuaW50ZXJhY3QucG9pbnRlck1vdmVUb2xlcmFuY2UgPSBmdW5jdGlvbiAobmV3VmFsdWUpIHtcbiAgaWYgKHV0aWxzLmlzLm51bWJlcihuZXdWYWx1ZSkpIHtcbiAgICBJbnRlcmFjdGlvbi5wb2ludGVyTW92ZVRvbGVyYW5jZSA9IG5ld1ZhbHVlO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICByZXR1cm4gSW50ZXJhY3Rpb24ucG9pbnRlck1vdmVUb2xlcmFuY2U7XG59O1xuXG5pbnRlcmFjdC5hZGREb2N1bWVudCA9IHNjb3BlLmFkZERvY3VtZW50O1xuaW50ZXJhY3QucmVtb3ZlRG9jdW1lbnQgPSBzY29wZS5yZW1vdmVEb2N1bWVudDtcblxuc2NvcGUuaW50ZXJhY3QgPSBpbnRlcmFjdDtcblxubW9kdWxlLmV4cG9ydHMgPSBpbnRlcmFjdDtcblxufSx7XCIuL0ludGVyYWN0YWJsZVwiOjQsXCIuL0ludGVyYWN0aW9uXCI6NSxcIi4vc2NvcGVcIjozNCxcIi4vdXRpbHNcIjo0NCxcIi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi91dGlscy9ldmVudHNcIjo0MH1dLDIyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIEludGVyYWN0YWJsZSA9IHJlcXVpcmUoJy4vSW50ZXJhY3RhYmxlJyk7XG52YXIgSW50ZXJhY3Rpb24gPSByZXF1aXJlKCcuL0ludGVyYWN0aW9uJyk7XG52YXIgc2NvcGUgPSByZXF1aXJlKCcuL3Njb3BlJyk7XG52YXIgaXMgPSByZXF1aXJlKCcuL3V0aWxzL2lzJyk7XG52YXIgZXZlbnRzID0gcmVxdWlyZSgnLi91dGlscy9ldmVudHMnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi91dGlscy9kb21VdGlscycpLFxuICAgIG5vZGVDb250YWlucyA9IF9yZXF1aXJlLm5vZGVDb250YWlucyxcbiAgICBtYXRjaGVzU2VsZWN0b3IgPSBfcmVxdWlyZS5tYXRjaGVzU2VsZWN0b3I7XG5cbi8qXFxcbiAqIEludGVyYWN0YWJsZS5wcmV2ZW50RGVmYXVsdFxuIFsgbWV0aG9kIF1cbiAqXG4gKiBSZXR1cm5zIG9yIHNldHMgd2hldGhlciB0byBwcmV2ZW50IHRoZSBicm93c2VyJ3MgZGVmYXVsdCBiZWhhdmlvdXJcbiAqIGluIHJlc3BvbnNlIHRvIHBvaW50ZXIgZXZlbnRzLiBDYW4gYmUgc2V0IHRvOlxuICogIC0gYCdhbHdheXMnYCB0byBhbHdheXMgcHJldmVudFxuICogIC0gYCduZXZlcidgIHRvIG5ldmVyIHByZXZlbnRcbiAqICAtIGAnYXV0bydgIHRvIGxldCBpbnRlcmFjdC5qcyB0cnkgdG8gZGV0ZXJtaW5lIHdoYXQgd291bGQgYmUgYmVzdFxuICpcbiAtIG5ld1ZhbHVlIChzdHJpbmcpICNvcHRpb25hbCBgdHJ1ZWAsIGBmYWxzZWAgb3IgYCdhdXRvJ2BcbiA9IChzdHJpbmcgfCBJbnRlcmFjdGFibGUpIFRoZSBjdXJyZW50IHNldHRpbmcgb3IgdGhpcyBJbnRlcmFjdGFibGVcblxcKi9cblxuXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gIGlmICgvXihhbHdheXN8bmV2ZXJ8YXV0bykkLy50ZXN0KG5ld1ZhbHVlKSkge1xuICAgIHRoaXMub3B0aW9ucy5wcmV2ZW50RGVmYXVsdCA9IG5ld1ZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgaWYgKGlzLmJvb2wobmV3VmFsdWUpKSB7XG4gICAgdGhpcy5vcHRpb25zLnByZXZlbnREZWZhdWx0ID0gbmV3VmFsdWUgPyAnYWx3YXlzJyA6ICduZXZlcic7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICByZXR1cm4gdGhpcy5vcHRpb25zLnByZXZlbnREZWZhdWx0O1xufTtcblxuSW50ZXJhY3RhYmxlLnByb3RvdHlwZS5jaGVja0FuZFByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIHZhciBzZXR0aW5nID0gdGhpcy5vcHRpb25zLnByZXZlbnREZWZhdWx0O1xuXG4gIGlmIChzZXR0aW5nID09PSAnbmV2ZXInKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHNldHRpbmcgPT09ICdhbHdheXMnKSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBzZXR0aW5nID09PSAnYXV0bydcblxuICAvLyBkb24ndCBwcmV2ZW50RGVmYXVsdCBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBwYXNzaXZlRXZlbnRzXG4gIC8vIENTUyB0b3VjaC1hY3Rpb24gYW5kIHVzZXItc2VsZWNjdCBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkXG4gIGlmIChldmVudHMuc3VwcG9ydHNPcHRpb25zKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZG9uJ3QgcHJldmVudERlZmF1bHQgb2YgcG9pbnRlcmRvd24gZXZlbnRzXG4gIGlmICgvXihtb3VzZXxwb2ludGVyfHRvdWNoKSooZG93bnxzdGFydCkvaS50ZXN0KGV2ZW50LnR5cGUpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZG9uJ3QgcHJldmVudERlZmF1bHQgb24gZWRpdGFibGUgZWxlbWVudHNcbiAgaWYgKGlzLmVsZW1lbnQoZXZlbnQudGFyZ2V0KSAmJiBtYXRjaGVzU2VsZWN0b3IoZXZlbnQudGFyZ2V0LCAnaW5wdXQsc2VsZWN0LHRleHRhcmVhLFtjb250ZW50ZWRpdGFibGU9dHJ1ZV0sW2NvbnRlbnRlZGl0YWJsZT10cnVlXSAqJykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xufTtcblxuZnVuY3Rpb24gb25JbnRlcmFjdGlvbkV2ZW50KF9yZWYpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZi5pbnRlcmFjdGlvbixcbiAgICAgIGV2ZW50ID0gX3JlZi5ldmVudDtcblxuICBpZiAoaW50ZXJhY3Rpb24udGFyZ2V0KSB7XG4gICAgaW50ZXJhY3Rpb24udGFyZ2V0LmNoZWNrQW5kUHJldmVudERlZmF1bHQoZXZlbnQpO1xuICB9XG59XG5cbnZhciBfYXJyID0gWydkb3duJywgJ21vdmUnLCAndXAnLCAnY2FuY2VsJ107XG5mb3IgKHZhciBfaSA9IDA7IF9pIDwgX2Fyci5sZW5ndGg7IF9pKyspIHtcbiAgdmFyIGV2ZW50U2lnbmFsID0gX2FycltfaV07XG4gIEludGVyYWN0aW9uLnNpZ25hbHMub24oZXZlbnRTaWduYWwsIG9uSW50ZXJhY3Rpb25FdmVudCk7XG59XG5cbi8vIHByZXZlbnQgbmF0aXZlIEhUTUw1IGRyYWcgb24gaW50ZXJhY3QuanMgdGFyZ2V0IGVsZW1lbnRzXG5JbnRlcmFjdGlvbi5kb2NFdmVudHMuZHJhZ3N0YXJ0ID0gZnVuY3Rpb24gcHJldmVudE5hdGl2ZURyYWcoZXZlbnQpIHtcbiAgZm9yICh2YXIgX2l0ZXJhdG9yID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kyID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcbiAgICB2YXIgX3JlZjI7XG5cbiAgICBpZiAoX2lzQXJyYXkpIHtcbiAgICAgIGlmIChfaTIgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XG4gICAgICBfcmVmMiA9IF9pdGVyYXRvcltfaTIrK107XG4gICAgfSBlbHNlIHtcbiAgICAgIF9pMiA9IF9pdGVyYXRvci5uZXh0KCk7XG4gICAgICBpZiAoX2kyLmRvbmUpIGJyZWFrO1xuICAgICAgX3JlZjIgPSBfaTIudmFsdWU7XG4gICAgfVxuXG4gICAgdmFyIGludGVyYWN0aW9uID0gX3JlZjI7XG5cblxuICAgIGlmIChpbnRlcmFjdGlvbi5lbGVtZW50ICYmIChpbnRlcmFjdGlvbi5lbGVtZW50ID09PSBldmVudC50YXJnZXQgfHwgbm9kZUNvbnRhaW5zKGludGVyYWN0aW9uLmVsZW1lbnQsIGV2ZW50LnRhcmdldCkpKSB7XG5cbiAgICAgIGludGVyYWN0aW9uLnRhcmdldC5jaGVja0FuZFByZXZlbnREZWZhdWx0KGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cbn07XG5cbn0se1wiLi9JbnRlcmFjdGFibGVcIjo0LFwiLi9JbnRlcmFjdGlvblwiOjUsXCIuL3Njb3BlXCI6MzQsXCIuL3V0aWxzL2RvbVV0aWxzXCI6MzksXCIuL3V0aWxzL2V2ZW50c1wiOjQwLFwiLi91dGlscy9pc1wiOjQ2fV0sMjM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgc2NvcGUgPSByZXF1aXJlKCcuL3Njb3BlJyk7XG52YXIgZXZlbnRzID0gcmVxdWlyZSgnLi91dGlscy9ldmVudHMnKTtcbnZhciBicm93c2VyID0gcmVxdWlyZSgnLi91dGlscy9icm93c2VyJyk7XG52YXIgaUZpbmRlciA9IHJlcXVpcmUoJy4vdXRpbHMvaW50ZXJhY3Rpb25GaW5kZXInKTtcbnZhciBwb2ludGVyRXZlbnRzID0gcmVxdWlyZSgnLi9wb2ludGVyRXZlbnRzL2Jhc2UnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi91dGlscy93aW5kb3cnKSxcbiAgICB3aW5kb3cgPSBfcmVxdWlyZS53aW5kb3c7XG5cbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbmlmICghd2luZG93LkFycmF5LmlzQXJyYXkpIHtcbiAgd2luZG93LkFycmF5LmlzQXJyYXkgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbiAgfTtcbn1cblxuaWYgKCFTdHJpbmcucHJvdG90eXBlLnRyaW0pIHtcbiAgU3RyaW5nLnByb3RvdHlwZS50cmltID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLCAnJyk7XG4gIH07XG59XG5cbi8vIGh0dHA6Ly93d3cucXVpcmtzbW9kZS5vcmcvZG9tL2V2ZW50cy9jbGljay5odG1sXG4vLyA+RXZlbnRzIGxlYWRpbmcgdG8gZGJsY2xpY2tcbi8vXG4vLyBJRTggZG9lc24ndCBmaXJlIGRvd24gZXZlbnQgYmVmb3JlIGRibGNsaWNrLlxuLy8gVGhpcyB3b3JrYXJvdW5kIHRyaWVzIHRvIGZpcmUgYSB0YXAgYW5kIGRvdWJsZXRhcCBhZnRlciBkYmxjbGlja1xuZnVuY3Rpb24gb25JRThEYmxjbGljayhldmVudCkge1xuICB2YXIgZXZlbnRUYXJnZXQgPSBldmVudC50YXJnZXQ7XG4gIHZhciBpbnRlcmFjdGlvbiA9IGlGaW5kZXIuc2VhcmNoKGV2ZW50LCBldmVudC50eXBlLCBldmVudFRhcmdldCk7XG5cbiAgaWYgKCFpbnRlcmFjdGlvbikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChpbnRlcmFjdGlvbi5wcmV2VGFwICYmIGV2ZW50LmNsaWVudFggPT09IGludGVyYWN0aW9uLnByZXZUYXAuY2xpZW50WCAmJiBldmVudC5jbGllbnRZID09PSBpbnRlcmFjdGlvbi5wcmV2VGFwLmNsaWVudFkgJiYgZXZlbnRUYXJnZXQgPT09IGludGVyYWN0aW9uLnByZXZUYXAudGFyZ2V0KSB7XG5cbiAgICBpbnRlcmFjdGlvbi5kb3duVGFyZ2V0c1swXSA9IGV2ZW50VGFyZ2V0O1xuICAgIGludGVyYWN0aW9uLmRvd25UaW1lc1swXSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgcG9pbnRlckV2ZW50cy5maXJlKHtcbiAgICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcbiAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcbiAgICAgIHBvaW50ZXI6IGV2ZW50LFxuICAgICAgdHlwZTogJ3RhcCdcbiAgICB9KTtcbiAgfVxufVxuXG5pZiAoYnJvd3Nlci5pc0lFOCkge1xuICB2YXIgc2VsZWN0Rml4ID0gZnVuY3Rpb24gc2VsZWN0Rml4KGV2ZW50KSB7XG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xuICAgICAgdmFyIF9yZWY7XG5cbiAgICAgIGlmIChfaXNBcnJheSkge1xuICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XG4gICAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIGlmIChfaS5kb25lKSBicmVhaztcbiAgICAgICAgX3JlZiA9IF9pLnZhbHVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmO1xuXG4gICAgICBpZiAoaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSkge1xuICAgICAgICBpbnRlcmFjdGlvbi50YXJnZXQuY2hlY2tBbmRQcmV2ZW50RGVmYXVsdChldmVudCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBvbkRvY0lFOCA9IGZ1bmN0aW9uIG9uRG9jSUU4KF9yZWYyLCBzaWduYWxOYW1lKSB7XG4gICAgdmFyIGRvYyA9IF9yZWYyLmRvYyxcbiAgICAgICAgd2luID0gX3JlZjIud2luO1xuXG4gICAgdmFyIGV2ZW50TWV0aG9kID0gc2lnbmFsTmFtZS5pbmRleE9mKCdsaXN0ZW4nKSA9PT0gMCA/IGV2ZW50cy5hZGQgOiBldmVudHMucmVtb3ZlO1xuXG4gICAgLy8gRm9yIElFJ3MgbGFjayBvZiBFdmVudCNwcmV2ZW50RGVmYXVsdFxuICAgIGV2ZW50TWV0aG9kKGRvYywgJ3NlbGVjdHN0YXJ0Jywgc2VsZWN0Rml4KTtcblxuICAgIGlmIChwb2ludGVyRXZlbnRzKSB7XG4gICAgICBldmVudE1ldGhvZChkb2MsICdkYmxjbGljaycsIG9uSUU4RGJsY2xpY2spO1xuICAgIH1cbiAgfTtcblxuICBzY29wZS5zaWduYWxzLm9uKCdhZGQtZG9jdW1lbnQnLCBvbkRvY0lFOCk7XG4gIHNjb3BlLnNpZ25hbHMub24oJ3JlbW92ZS1kb2N1bWVudCcsIG9uRG9jSUU4KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBudWxsO1xuXG59LHtcIi4vcG9pbnRlckV2ZW50cy9iYXNlXCI6MzEsXCIuL3Njb3BlXCI6MzQsXCIuL3V0aWxzL2Jyb3dzZXJcIjozNyxcIi4vdXRpbHMvZXZlbnRzXCI6NDAsXCIuL3V0aWxzL2ludGVyYWN0aW9uRmluZGVyXCI6NDUsXCIuL3V0aWxzL3dpbmRvd1wiOjUyfV0sMjQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgSW50ZXJhY3RFdmVudCA9IHJlcXVpcmUoJy4uL0ludGVyYWN0RXZlbnQnKTtcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi4vdXRpbHMvZXh0ZW5kJyk7XG5cbnZhciBtb2RpZmllcnMgPSB7XG4gIG5hbWVzOiBbXSxcblxuICBzZXRPZmZzZXRzOiBmdW5jdGlvbiBzZXRPZmZzZXRzKGFyZykge1xuICAgIHZhciBpbnRlcmFjdGlvbiA9IGFyZy5pbnRlcmFjdGlvbixcbiAgICAgICAgcGFnZSA9IGFyZy5wYWdlQ29vcmRzO1xuICAgIHZhciB0YXJnZXQgPSBpbnRlcmFjdGlvbi50YXJnZXQsXG4gICAgICAgIGVsZW1lbnQgPSBpbnRlcmFjdGlvbi5lbGVtZW50LFxuICAgICAgICBzdGFydE9mZnNldCA9IGludGVyYWN0aW9uLnN0YXJ0T2Zmc2V0O1xuXG4gICAgdmFyIHJlY3QgPSB0YXJnZXQuZ2V0UmVjdChlbGVtZW50KTtcblxuICAgIGlmIChyZWN0KSB7XG4gICAgICBzdGFydE9mZnNldC5sZWZ0ID0gcGFnZS54IC0gcmVjdC5sZWZ0O1xuICAgICAgc3RhcnRPZmZzZXQudG9wID0gcGFnZS55IC0gcmVjdC50b3A7XG5cbiAgICAgIHN0YXJ0T2Zmc2V0LnJpZ2h0ID0gcmVjdC5yaWdodCAtIHBhZ2UueDtcbiAgICAgIHN0YXJ0T2Zmc2V0LmJvdHRvbSA9IHJlY3QuYm90dG9tIC0gcGFnZS55O1xuXG4gICAgICBpZiAoISgnd2lkdGgnIGluIHJlY3QpKSB7XG4gICAgICAgIHJlY3Qud2lkdGggPSByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0O1xuICAgICAgfVxuICAgICAgaWYgKCEoJ2hlaWdodCcgaW4gcmVjdCkpIHtcbiAgICAgICAgcmVjdC5oZWlnaHQgPSByZWN0LmJvdHRvbSAtIHJlY3QudG9wO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdGFydE9mZnNldC5sZWZ0ID0gc3RhcnRPZmZzZXQudG9wID0gc3RhcnRPZmZzZXQucmlnaHQgPSBzdGFydE9mZnNldC5ib3R0b20gPSAwO1xuICAgIH1cblxuICAgIGFyZy5yZWN0ID0gcmVjdDtcbiAgICBhcmcuaW50ZXJhY3RhYmxlID0gdGFyZ2V0O1xuICAgIGFyZy5lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbW9kaWZpZXJzLm5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbW9kaWZpZXJOYW1lID0gbW9kaWZpZXJzLm5hbWVzW2ldO1xuXG4gICAgICBhcmcub3B0aW9ucyA9IHRhcmdldC5vcHRpb25zW2ludGVyYWN0aW9uLnByZXBhcmVkLm5hbWVdW21vZGlmaWVyTmFtZV07XG5cbiAgICAgIGlmICghYXJnLm9wdGlvbnMpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGludGVyYWN0aW9uLm1vZGlmaWVyT2Zmc2V0c1ttb2RpZmllck5hbWVdID0gbW9kaWZpZXJzW21vZGlmaWVyTmFtZV0uc2V0T2Zmc2V0KGFyZyk7XG4gICAgfVxuICB9LFxuXG4gIHNldEFsbDogZnVuY3Rpb24gc2V0QWxsKGFyZykge1xuICAgIHZhciBpbnRlcmFjdGlvbiA9IGFyZy5pbnRlcmFjdGlvbixcbiAgICAgICAgc3RhdHVzZXMgPSBhcmcuc3RhdHVzZXMsXG4gICAgICAgIHByZUVuZCA9IGFyZy5wcmVFbmQsXG4gICAgICAgIHJlcXVpcmVFbmRPbmx5ID0gYXJnLnJlcXVpcmVFbmRPbmx5O1xuXG4gICAgdmFyIGNvb3JkcyA9IGV4dGVuZCh7fSwgYXJnLnBhZ2VDb29yZHMpO1xuICAgIHZhciByZXN1bHQgPSB7XG4gICAgICBkeDogMCxcbiAgICAgIGR5OiAwLFxuICAgICAgY2hhbmdlZDogZmFsc2UsXG4gICAgICBsb2NrZWQ6IGZhbHNlLFxuICAgICAgc2hvdWxkTW92ZTogdHJ1ZVxuICAgIH07XG5cbiAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBtb2RpZmllcnMubmFtZXMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICB2YXIgX3JlZjtcblxuICAgICAgaWYgKF9pc0FycmF5KSB7XG4gICAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcbiAgICAgICAgX3JlZiA9IF9pdGVyYXRvcltfaSsrXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKF9pLmRvbmUpIGJyZWFrO1xuICAgICAgICBfcmVmID0gX2kudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBtb2RpZmllck5hbWUgPSBfcmVmO1xuXG4gICAgICB2YXIgbW9kaWZpZXIgPSBtb2RpZmllcnNbbW9kaWZpZXJOYW1lXTtcbiAgICAgIHZhciBvcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV1bbW9kaWZpZXJOYW1lXTtcblxuICAgICAgaWYgKCFzaG91bGREbyhvcHRpb25zLCBwcmVFbmQsIHJlcXVpcmVFbmRPbmx5KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgYXJnLnN0YXR1cyA9IGFyZy5zdGF0dXMgPSBzdGF0dXNlc1ttb2RpZmllck5hbWVdO1xuICAgICAgYXJnLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgYXJnLm9mZnNldCA9IGFyZy5pbnRlcmFjdGlvbi5tb2RpZmllck9mZnNldHNbbW9kaWZpZXJOYW1lXTtcblxuICAgICAgbW9kaWZpZXIuc2V0KGFyZyk7XG5cbiAgICAgIGlmIChhcmcuc3RhdHVzLmxvY2tlZCkge1xuICAgICAgICBjb29yZHMueCArPSBhcmcuc3RhdHVzLmR4O1xuICAgICAgICBjb29yZHMueSArPSBhcmcuc3RhdHVzLmR5O1xuXG4gICAgICAgIHJlc3VsdC5keCArPSBhcmcuc3RhdHVzLmR4O1xuICAgICAgICByZXN1bHQuZHkgKz0gYXJnLnN0YXR1cy5keTtcblxuICAgICAgICByZXN1bHQubG9ja2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhIG1vdmUgc2hvdWxkIGJlIGZpcmVkIGlmOlxuICAgIC8vICAtIHRoZXJlIGFyZSBubyBtb2RpZmllcnMgZW5hYmxlZCxcbiAgICAvLyAgLSBubyBtb2RpZmllcnMgYXJlIFwibG9ja2VkXCIgaS5lLiBoYXZlIGNoYW5nZWQgdGhlIHBvaW50ZXIncyBjb29yZGluYXRlcywgb3JcbiAgICAvLyAgLSB0aGUgbG9ja2VkIGNvb3JkcyBoYXZlIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgcG9pbnRlciBtb3ZlXG4gICAgcmVzdWx0LnNob3VsZE1vdmUgPSAhYXJnLnN0YXR1cyB8fCAhcmVzdWx0LmxvY2tlZCB8fCBhcmcuc3RhdHVzLmNoYW5nZWQ7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuXG4gIHJlc2V0U3RhdHVzZXM6IGZ1bmN0aW9uIHJlc2V0U3RhdHVzZXMoc3RhdHVzZXMpIHtcbiAgICBmb3IgKHZhciBfaXRlcmF0b3IyID0gbW9kaWZpZXJzLm5hbWVzLCBfaXNBcnJheTIgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjIpLCBfaTIgPSAwLCBfaXRlcmF0b3IyID0gX2lzQXJyYXkyID8gX2l0ZXJhdG9yMiA6IF9pdGVyYXRvcjJbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcbiAgICAgIHZhciBfcmVmMjtcblxuICAgICAgaWYgKF9pc0FycmF5Mikge1xuICAgICAgICBpZiAoX2kyID49IF9pdGVyYXRvcjIubGVuZ3RoKSBicmVhaztcbiAgICAgICAgX3JlZjIgPSBfaXRlcmF0b3IyW19pMisrXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9pMiA9IF9pdGVyYXRvcjIubmV4dCgpO1xuICAgICAgICBpZiAoX2kyLmRvbmUpIGJyZWFrO1xuICAgICAgICBfcmVmMiA9IF9pMi52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIG1vZGlmaWVyTmFtZSA9IF9yZWYyO1xuXG4gICAgICB2YXIgc3RhdHVzID0gc3RhdHVzZXNbbW9kaWZpZXJOYW1lXSB8fCB7fTtcblxuICAgICAgc3RhdHVzLmR4ID0gc3RhdHVzLmR5ID0gMDtcbiAgICAgIHN0YXR1cy5tb2RpZmllZFggPSBzdGF0dXMubW9kaWZpZWRZID0gTmFOO1xuICAgICAgc3RhdHVzLmxvY2tlZCA9IGZhbHNlO1xuICAgICAgc3RhdHVzLmNoYW5nZWQgPSB0cnVlO1xuXG4gICAgICBzdGF0dXNlc1ttb2RpZmllck5hbWVdID0gc3RhdHVzO1xuICAgIH1cblxuICAgIHJldHVybiBzdGF0dXNlcztcbiAgfSxcblxuICBzdGFydDogZnVuY3Rpb24gc3RhcnQoX3JlZjMsIHNpZ25hbE5hbWUpIHtcbiAgICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMy5pbnRlcmFjdGlvbjtcblxuICAgIHZhciBhcmcgPSB7XG4gICAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXG4gICAgICBwYWdlQ29vcmRzOiAoc2lnbmFsTmFtZSA9PT0gJ2FjdGlvbi1yZXN1bWUnID8gaW50ZXJhY3Rpb24uY3VyQ29vcmRzIDogaW50ZXJhY3Rpb24uc3RhcnRDb29yZHMpLnBhZ2UsXG4gICAgICBzdGFydE9mZnNldDogaW50ZXJhY3Rpb24uc3RhcnRPZmZzZXQsXG4gICAgICBzdGF0dXNlczogaW50ZXJhY3Rpb24ubW9kaWZpZXJTdGF0dXNlcyxcbiAgICAgIHByZUVuZDogZmFsc2UsXG4gICAgICByZXF1aXJlRW5kT25seTogZmFsc2VcbiAgICB9O1xuXG4gICAgbW9kaWZpZXJzLnNldE9mZnNldHMoYXJnKTtcbiAgICBtb2RpZmllcnMucmVzZXRTdGF0dXNlcyhhcmcuc3RhdHVzZXMpO1xuXG4gICAgYXJnLnBhZ2VDb29yZHMgPSBleHRlbmQoe30sIGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLnBhZ2UpO1xuICAgIGludGVyYWN0aW9uLm1vZGlmaWVyUmVzdWx0ID0gbW9kaWZpZXJzLnNldEFsbChhcmcpO1xuICB9XG59O1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCduZXcnLCBmdW5jdGlvbiAoaW50ZXJhY3Rpb24pIHtcbiAgaW50ZXJhY3Rpb24uc3RhcnRPZmZzZXQgPSB7IGxlZnQ6IDAsIHJpZ2h0OiAwLCB0b3A6IDAsIGJvdHRvbTogMCB9O1xuICBpbnRlcmFjdGlvbi5tb2RpZmllck9mZnNldHMgPSB7fTtcbiAgaW50ZXJhY3Rpb24ubW9kaWZpZXJTdGF0dXNlcyA9IG1vZGlmaWVycy5yZXNldFN0YXR1c2VzKHt9KTtcbiAgaW50ZXJhY3Rpb24ubW9kaWZpZXJSZXN1bHQgPSBudWxsO1xufSk7XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ2FjdGlvbi1zdGFydCcsIG1vZGlmaWVycy5zdGFydCk7XG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdhY3Rpb24tcmVzdW1lJywgbW9kaWZpZXJzLnN0YXJ0KTtcblxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYmVmb3JlLWFjdGlvbi1tb3ZlJywgZnVuY3Rpb24gKF9yZWY0KSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY0LmludGVyYWN0aW9uLFxuICAgICAgcHJlRW5kID0gX3JlZjQucHJlRW5kLFxuICAgICAgaW50ZXJhY3RpbmdCZWZvcmVNb3ZlID0gX3JlZjQuaW50ZXJhY3RpbmdCZWZvcmVNb3ZlO1xuXG4gIHZhciBtb2RpZmllclJlc3VsdCA9IG1vZGlmaWVycy5zZXRBbGwoe1xuICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcbiAgICBwcmVFbmQ6IHByZUVuZCxcbiAgICBwYWdlQ29vcmRzOiBpbnRlcmFjdGlvbi5jdXJDb29yZHMucGFnZSxcbiAgICBzdGF0dXNlczogaW50ZXJhY3Rpb24ubW9kaWZpZXJTdGF0dXNlcyxcbiAgICByZXF1aXJlRW5kT25seTogZmFsc2VcbiAgfSk7XG5cbiAgLy8gZG9uJ3QgZmlyZSBhbiBhY3Rpb24gbW92ZSBpZiBhIG1vZGlmaWVyIHdvdWxkIGtlZXAgdGhlIGV2ZW50IGluIHRoZSBzYW1lXG4gIC8vIGNvcmRpbmF0ZXMgYXMgYmVmb3JlXG4gIGlmICghbW9kaWZpZXJSZXN1bHQuc2hvdWxkTW92ZSAmJiBpbnRlcmFjdGluZ0JlZm9yZU1vdmUpIHtcbiAgICBpbnRlcmFjdGlvbi5fZG9udEZpcmVNb3ZlID0gdHJ1ZTtcbiAgfVxuXG4gIGludGVyYWN0aW9uLm1vZGlmaWVyUmVzdWx0ID0gbW9kaWZpZXJSZXN1bHQ7XG59KTtcblxuSW50ZXJhY3Rpb24uc2lnbmFscy5vbignYWN0aW9uLWVuZCcsIGZ1bmN0aW9uIChfcmVmNSkge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmNS5pbnRlcmFjdGlvbixcbiAgICAgIGV2ZW50ID0gX3JlZjUuZXZlbnQ7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtb2RpZmllcnMubmFtZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgb3B0aW9ucyA9IGludGVyYWN0aW9uLnRhcmdldC5vcHRpb25zW2ludGVyYWN0aW9uLnByZXBhcmVkLm5hbWVdW21vZGlmaWVycy5uYW1lc1tpXV07XG5cbiAgICAvLyBpZiB0aGUgZW5kT25seSBvcHRpb24gaXMgdHJ1ZSBmb3IgYW55IG1vZGlmaWVyXG4gICAgaWYgKHNob3VsZERvKG9wdGlvbnMsIHRydWUsIHRydWUpKSB7XG4gICAgICAvLyBmaXJlIGEgbW92ZSBldmVudCBhdCB0aGUgbW9kaWZpZWQgY29vcmRpbmF0ZXNcbiAgICAgIGludGVyYWN0aW9uLmRvTW92ZSh7IGV2ZW50OiBldmVudCwgcHJlRW5kOiB0cnVlIH0pO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59KTtcblxuSW50ZXJhY3RFdmVudC5zaWduYWxzLm9uKCdzZXQteHknLCBmdW5jdGlvbiAoYXJnKSB7XG4gIHZhciBpRXZlbnQgPSBhcmcuaUV2ZW50LFxuICAgICAgaW50ZXJhY3Rpb24gPSBhcmcuaW50ZXJhY3Rpb247XG5cbiAgdmFyIG1vZGlmaWVyQXJnID0gZXh0ZW5kKHt9LCBhcmcpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbW9kaWZpZXJzLm5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG1vZGlmaWVyTmFtZSA9IG1vZGlmaWVycy5uYW1lc1tpXTtcbiAgICBtb2RpZmllckFyZy5vcHRpb25zID0gaW50ZXJhY3Rpb24udGFyZ2V0Lm9wdGlvbnNbaW50ZXJhY3Rpb24ucHJlcGFyZWQubmFtZV1bbW9kaWZpZXJOYW1lXTtcblxuICAgIGlmICghbW9kaWZpZXJBcmcub3B0aW9ucykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIG1vZGlmaWVyID0gbW9kaWZpZXJzW21vZGlmaWVyTmFtZV07XG5cbiAgICBtb2RpZmllckFyZy5zdGF0dXMgPSBpbnRlcmFjdGlvbi5tb2RpZmllclN0YXR1c2VzW21vZGlmaWVyTmFtZV07XG5cbiAgICBpRXZlbnRbbW9kaWZpZXJOYW1lXSA9IG1vZGlmaWVyLm1vZGlmeUNvb3Jkcyhtb2RpZmllckFyZyk7XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiBzaG91bGREbyhvcHRpb25zLCBwcmVFbmQsIHJlcXVpcmVFbmRPbmx5KSB7XG4gIHJldHVybiBvcHRpb25zICYmIG9wdGlvbnMuZW5hYmxlZCAmJiAocHJlRW5kIHx8ICFvcHRpb25zLmVuZE9ubHkpICYmICghcmVxdWlyZUVuZE9ubHkgfHwgb3B0aW9ucy5lbmRPbmx5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtb2RpZmllcnM7XG5cbn0se1wiLi4vSW50ZXJhY3RFdmVudFwiOjMsXCIuLi9JbnRlcmFjdGlvblwiOjUsXCIuLi91dGlscy9leHRlbmRcIjo0MX1dLDI1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIG1vZGlmaWVycyA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xuXG52YXIgcmVzdHJpY3QgPSB7XG4gIGRlZmF1bHRzOiB7XG4gICAgZW5hYmxlZDogZmFsc2UsXG4gICAgZW5kT25seTogZmFsc2UsXG4gICAgcmVzdHJpY3Rpb246IG51bGwsXG4gICAgZWxlbWVudFJlY3Q6IG51bGxcbiAgfSxcblxuICBzZXRPZmZzZXQ6IGZ1bmN0aW9uIHNldE9mZnNldChfcmVmKSB7XG4gICAgdmFyIHJlY3QgPSBfcmVmLnJlY3QsXG4gICAgICAgIHN0YXJ0T2Zmc2V0ID0gX3JlZi5zdGFydE9mZnNldCxcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucztcblxuICAgIHZhciBlbGVtZW50UmVjdCA9IG9wdGlvbnMgJiYgb3B0aW9ucy5lbGVtZW50UmVjdDtcbiAgICB2YXIgb2Zmc2V0ID0ge307XG5cbiAgICBpZiAocmVjdCAmJiBlbGVtZW50UmVjdCkge1xuICAgICAgb2Zmc2V0LmxlZnQgPSBzdGFydE9mZnNldC5sZWZ0IC0gcmVjdC53aWR0aCAqIGVsZW1lbnRSZWN0LmxlZnQ7XG4gICAgICBvZmZzZXQudG9wID0gc3RhcnRPZmZzZXQudG9wIC0gcmVjdC5oZWlnaHQgKiBlbGVtZW50UmVjdC50b3A7XG5cbiAgICAgIG9mZnNldC5yaWdodCA9IHN0YXJ0T2Zmc2V0LnJpZ2h0IC0gcmVjdC53aWR0aCAqICgxIC0gZWxlbWVudFJlY3QucmlnaHQpO1xuICAgICAgb2Zmc2V0LmJvdHRvbSA9IHN0YXJ0T2Zmc2V0LmJvdHRvbSAtIHJlY3QuaGVpZ2h0ICogKDEgLSBlbGVtZW50UmVjdC5ib3R0b20pO1xuICAgIH0gZWxzZSB7XG4gICAgICBvZmZzZXQubGVmdCA9IG9mZnNldC50b3AgPSBvZmZzZXQucmlnaHQgPSBvZmZzZXQuYm90dG9tID0gMDtcbiAgICB9XG5cbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9LFxuXG4gIHNldDogZnVuY3Rpb24gc2V0KF9yZWYyKSB7XG4gICAgdmFyIHBhZ2VDb29yZHMgPSBfcmVmMi5wYWdlQ29vcmRzLFxuICAgICAgICBpbnRlcmFjdGlvbiA9IF9yZWYyLmludGVyYWN0aW9uLFxuICAgICAgICBzdGF0dXMgPSBfcmVmMi5zdGF0dXMsXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmMi5vcHRpb25zO1xuXG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICByZXR1cm4gc3RhdHVzO1xuICAgIH1cblxuICAgIHZhciBwYWdlID0gc3RhdHVzLnVzZVN0YXR1c1hZID8geyB4OiBzdGF0dXMueCwgeTogc3RhdHVzLnkgfSA6IHV0aWxzLmV4dGVuZCh7fSwgcGFnZUNvb3Jkcyk7XG5cbiAgICB2YXIgcmVzdHJpY3Rpb24gPSBnZXRSZXN0cmljdGlvblJlY3Qob3B0aW9ucy5yZXN0cmljdGlvbiwgaW50ZXJhY3Rpb24sIHBhZ2UpO1xuXG4gICAgaWYgKCFyZXN0cmljdGlvbikge1xuICAgICAgcmV0dXJuIHN0YXR1cztcbiAgICB9XG5cbiAgICBzdGF0dXMuZHggPSAwO1xuICAgIHN0YXR1cy5keSA9IDA7XG4gICAgc3RhdHVzLmxvY2tlZCA9IGZhbHNlO1xuXG4gICAgdmFyIHJlY3QgPSByZXN0cmljdGlvbjtcbiAgICB2YXIgbW9kaWZpZWRYID0gcGFnZS54O1xuICAgIHZhciBtb2RpZmllZFkgPSBwYWdlLnk7XG5cbiAgICB2YXIgb2Zmc2V0ID0gaW50ZXJhY3Rpb24ubW9kaWZpZXJPZmZzZXRzLnJlc3RyaWN0O1xuXG4gICAgLy8gb2JqZWN0IGlzIGFzc3VtZWQgdG8gaGF2ZVxuICAgIC8vIHgsIHksIHdpZHRoLCBoZWlnaHQgb3JcbiAgICAvLyBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b21cbiAgICBpZiAoJ3gnIGluIHJlc3RyaWN0aW9uICYmICd5JyBpbiByZXN0cmljdGlvbikge1xuICAgICAgbW9kaWZpZWRYID0gTWF0aC5tYXgoTWF0aC5taW4ocmVjdC54ICsgcmVjdC53aWR0aCAtIG9mZnNldC5yaWdodCwgcGFnZS54KSwgcmVjdC54ICsgb2Zmc2V0LmxlZnQpO1xuICAgICAgbW9kaWZpZWRZID0gTWF0aC5tYXgoTWF0aC5taW4ocmVjdC55ICsgcmVjdC5oZWlnaHQgLSBvZmZzZXQuYm90dG9tLCBwYWdlLnkpLCByZWN0LnkgKyBvZmZzZXQudG9wKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbW9kaWZpZWRYID0gTWF0aC5tYXgoTWF0aC5taW4ocmVjdC5yaWdodCAtIG9mZnNldC5yaWdodCwgcGFnZS54KSwgcmVjdC5sZWZ0ICsgb2Zmc2V0LmxlZnQpO1xuICAgICAgbW9kaWZpZWRZID0gTWF0aC5tYXgoTWF0aC5taW4ocmVjdC5ib3R0b20gLSBvZmZzZXQuYm90dG9tLCBwYWdlLnkpLCByZWN0LnRvcCArIG9mZnNldC50b3ApO1xuICAgIH1cblxuICAgIHN0YXR1cy5keCA9IG1vZGlmaWVkWCAtIHBhZ2UueDtcbiAgICBzdGF0dXMuZHkgPSBtb2RpZmllZFkgLSBwYWdlLnk7XG5cbiAgICBzdGF0dXMuY2hhbmdlZCA9IHN0YXR1cy5tb2RpZmllZFggIT09IG1vZGlmaWVkWCB8fCBzdGF0dXMubW9kaWZpZWRZICE9PSBtb2RpZmllZFk7XG4gICAgc3RhdHVzLmxvY2tlZCA9ICEhKHN0YXR1cy5keCB8fCBzdGF0dXMuZHkpO1xuXG4gICAgc3RhdHVzLm1vZGlmaWVkWCA9IG1vZGlmaWVkWDtcbiAgICBzdGF0dXMubW9kaWZpZWRZID0gbW9kaWZpZWRZO1xuICB9LFxuXG4gIG1vZGlmeUNvb3JkczogZnVuY3Rpb24gbW9kaWZ5Q29vcmRzKF9yZWYzKSB7XG4gICAgdmFyIHBhZ2UgPSBfcmVmMy5wYWdlLFxuICAgICAgICBjbGllbnQgPSBfcmVmMy5jbGllbnQsXG4gICAgICAgIHN0YXR1cyA9IF9yZWYzLnN0YXR1cyxcbiAgICAgICAgcGhhc2UgPSBfcmVmMy5waGFzZSxcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYzLm9wdGlvbnM7XG5cbiAgICB2YXIgZWxlbWVudFJlY3QgPSBvcHRpb25zICYmIG9wdGlvbnMuZWxlbWVudFJlY3Q7XG5cbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmVuYWJsZWQgJiYgIShwaGFzZSA9PT0gJ3N0YXJ0JyAmJiBlbGVtZW50UmVjdCAmJiBzdGF0dXMubG9ja2VkKSkge1xuXG4gICAgICBpZiAoc3RhdHVzLmxvY2tlZCkge1xuICAgICAgICBwYWdlLnggKz0gc3RhdHVzLmR4O1xuICAgICAgICBwYWdlLnkgKz0gc3RhdHVzLmR5O1xuICAgICAgICBjbGllbnQueCArPSBzdGF0dXMuZHg7XG4gICAgICAgIGNsaWVudC55ICs9IHN0YXR1cy5keTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGR4OiBzdGF0dXMuZHgsXG4gICAgICAgICAgZHk6IHN0YXR1cy5keVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBnZXRSZXN0cmljdGlvblJlY3Q6IGdldFJlc3RyaWN0aW9uUmVjdFxufTtcblxuZnVuY3Rpb24gZ2V0UmVzdHJpY3Rpb25SZWN0KHZhbHVlLCBpbnRlcmFjdGlvbiwgcGFnZSkge1xuICBpZiAodXRpbHMuaXMuZnVuY3Rpb24odmFsdWUpKSB7XG4gICAgcmV0dXJuIHV0aWxzLnJlc29sdmVSZWN0TGlrZSh2YWx1ZSwgaW50ZXJhY3Rpb24udGFyZ2V0LCBpbnRlcmFjdGlvbi5lbGVtZW50LCBbcGFnZS54LCBwYWdlLnksIGludGVyYWN0aW9uXSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHV0aWxzLnJlc29sdmVSZWN0TGlrZSh2YWx1ZSwgaW50ZXJhY3Rpb24udGFyZ2V0LCBpbnRlcmFjdGlvbi5lbGVtZW50KTtcbiAgfVxufVxuXG5tb2RpZmllcnMucmVzdHJpY3QgPSByZXN0cmljdDtcbm1vZGlmaWVycy5uYW1lcy5wdXNoKCdyZXN0cmljdCcpO1xuXG5kZWZhdWx0T3B0aW9ucy5wZXJBY3Rpb24ucmVzdHJpY3QgPSByZXN0cmljdC5kZWZhdWx0cztcblxubW9kdWxlLmV4cG9ydHMgPSByZXN0cmljdDtcblxufSx7XCIuLi9kZWZhdWx0T3B0aW9uc1wiOjE4LFwiLi4vdXRpbHNcIjo0NCxcIi4vaW5kZXhcIjoyNH1dLDI2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxuLy8gVGhpcyBtb2R1bGUgYWRkcyB0aGUgb3B0aW9ucy5yZXNpemUucmVzdHJpY3RFZGdlcyBzZXR0aW5nIHdoaWNoIHNldHMgbWluIGFuZFxuLy8gbWF4IGZvciB0aGUgdG9wLCBsZWZ0LCBib3R0b20gYW5kIHJpZ2h0IGVkZ2VzIG9mIHRoZSB0YXJnZXQgYmVpbmcgcmVzaXplZC5cbi8vXG4vLyBpbnRlcmFjdCh0YXJnZXQpLnJlc2l6ZSh7XG4vLyAgIGVkZ2VzOiB7IHRvcDogdHJ1ZSwgbGVmdDogdHJ1ZSB9LFxuLy8gICByZXN0cmljdEVkZ2VzOiB7XG4vLyAgICAgaW5uZXI6IHsgdG9wOiAyMDAsIGxlZnQ6IDIwMCwgcmlnaHQ6IDQwMCwgYm90dG9tOiA0MDAgfSxcbi8vICAgICBvdXRlcjogeyB0b3A6ICAgMCwgbGVmdDogICAwLCByaWdodDogNjAwLCBib3R0b206IDYwMCB9LFxuLy8gICB9LFxuLy8gfSk7XG5cbnZhciBtb2RpZmllcnMgPSByZXF1aXJlKCcuL2luZGV4Jyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIHJlY3RVdGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzL3JlY3QnKTtcbnZhciBkZWZhdWx0T3B0aW9ucyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRPcHRpb25zJyk7XG52YXIgcmVzaXplID0gcmVxdWlyZSgnLi4vYWN0aW9ucy9yZXNpemUnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi9yZXN0cmljdCcpLFxuICAgIGdldFJlc3RyaWN0aW9uUmVjdCA9IF9yZXF1aXJlLmdldFJlc3RyaWN0aW9uUmVjdDtcblxudmFyIG5vSW5uZXIgPSB7IHRvcDogK0luZmluaXR5LCBsZWZ0OiArSW5maW5pdHksIGJvdHRvbTogLUluZmluaXR5LCByaWdodDogLUluZmluaXR5IH07XG52YXIgbm9PdXRlciA9IHsgdG9wOiAtSW5maW5pdHksIGxlZnQ6IC1JbmZpbml0eSwgYm90dG9tOiArSW5maW5pdHksIHJpZ2h0OiArSW5maW5pdHkgfTtcblxudmFyIHJlc3RyaWN0RWRnZXMgPSB7XG4gIGRlZmF1bHRzOiB7XG4gICAgZW5hYmxlZDogZmFsc2UsXG4gICAgZW5kT25seTogZmFsc2UsXG4gICAgbWluOiBudWxsLFxuICAgIG1heDogbnVsbCxcbiAgICBvZmZzZXQ6IG51bGxcbiAgfSxcblxuICBzZXRPZmZzZXQ6IGZ1bmN0aW9uIHNldE9mZnNldChfcmVmKSB7XG4gICAgdmFyIGludGVyYWN0aW9uID0gX3JlZi5pbnRlcmFjdGlvbixcbiAgICAgICAgc3RhcnRPZmZzZXQgPSBfcmVmLnN0YXJ0T2Zmc2V0LFxuICAgICAgICBvcHRpb25zID0gX3JlZi5vcHRpb25zO1xuXG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICByZXR1cm4gdXRpbHMuZXh0ZW5kKHt9LCBzdGFydE9mZnNldCk7XG4gICAgfVxuXG4gICAgdmFyIG9mZnNldCA9IGdldFJlc3RyaWN0aW9uUmVjdChvcHRpb25zLm9mZnNldCwgaW50ZXJhY3Rpb24sIGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLnBhZ2UpO1xuXG4gICAgaWYgKG9mZnNldCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiBzdGFydE9mZnNldC50b3AgKyBvZmZzZXQueSxcbiAgICAgICAgbGVmdDogc3RhcnRPZmZzZXQubGVmdCArIG9mZnNldC54LFxuICAgICAgICBib3R0b206IHN0YXJ0T2Zmc2V0LmJvdHRvbSArIG9mZnNldC55LFxuICAgICAgICByaWdodDogc3RhcnRPZmZzZXQucmlnaHQgKyBvZmZzZXQueFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3RhcnRPZmZzZXQ7XG4gIH0sXG5cbiAgc2V0OiBmdW5jdGlvbiBzZXQoX3JlZjIpIHtcbiAgICB2YXIgcGFnZUNvb3JkcyA9IF9yZWYyLnBhZ2VDb29yZHMsXG4gICAgICAgIGludGVyYWN0aW9uID0gX3JlZjIuaW50ZXJhY3Rpb24sXG4gICAgICAgIHN0YXR1cyA9IF9yZWYyLnN0YXR1cyxcbiAgICAgICAgb2Zmc2V0ID0gX3JlZjIub2Zmc2V0LFxuICAgICAgICBvcHRpb25zID0gX3JlZjIub3B0aW9ucztcblxuICAgIHZhciBlZGdlcyA9IGludGVyYWN0aW9uLnByZXBhcmVkLmxpbmtlZEVkZ2VzIHx8IGludGVyYWN0aW9uLnByZXBhcmVkLmVkZ2VzO1xuXG4gICAgaWYgKCFpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpIHx8ICFlZGdlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBwYWdlID0gc3RhdHVzLnVzZVN0YXR1c1hZID8geyB4OiBzdGF0dXMueCwgeTogc3RhdHVzLnkgfSA6IHV0aWxzLmV4dGVuZCh7fSwgcGFnZUNvb3Jkcyk7XG4gICAgdmFyIGlubmVyID0gcmVjdFV0aWxzLnh5d2hUb1RsYnIoZ2V0UmVzdHJpY3Rpb25SZWN0KG9wdGlvbnMuaW5uZXIsIGludGVyYWN0aW9uLCBwYWdlKSkgfHwgbm9Jbm5lcjtcbiAgICB2YXIgb3V0ZXIgPSByZWN0VXRpbHMueHl3aFRvVGxicihnZXRSZXN0cmljdGlvblJlY3Qob3B0aW9ucy5vdXRlciwgaW50ZXJhY3Rpb24sIHBhZ2UpKSB8fCBub091dGVyO1xuXG4gICAgdmFyIG1vZGlmaWVkWCA9IHBhZ2UueDtcbiAgICB2YXIgbW9kaWZpZWRZID0gcGFnZS55O1xuXG4gICAgc3RhdHVzLmR4ID0gMDtcbiAgICBzdGF0dXMuZHkgPSAwO1xuICAgIHN0YXR1cy5sb2NrZWQgPSBmYWxzZTtcblxuICAgIGlmIChlZGdlcy50b3ApIHtcbiAgICAgIG1vZGlmaWVkWSA9IE1hdGgubWluKE1hdGgubWF4KG91dGVyLnRvcCArIG9mZnNldC50b3AsIHBhZ2UueSksIGlubmVyLnRvcCArIG9mZnNldC50b3ApO1xuICAgIH0gZWxzZSBpZiAoZWRnZXMuYm90dG9tKSB7XG4gICAgICBtb2RpZmllZFkgPSBNYXRoLm1heChNYXRoLm1pbihvdXRlci5ib3R0b20gLSBvZmZzZXQuYm90dG9tLCBwYWdlLnkpLCBpbm5lci5ib3R0b20gLSBvZmZzZXQuYm90dG9tKTtcbiAgICB9XG4gICAgaWYgKGVkZ2VzLmxlZnQpIHtcbiAgICAgIG1vZGlmaWVkWCA9IE1hdGgubWluKE1hdGgubWF4KG91dGVyLmxlZnQgKyBvZmZzZXQubGVmdCwgcGFnZS54KSwgaW5uZXIubGVmdCArIG9mZnNldC5sZWZ0KTtcbiAgICB9IGVsc2UgaWYgKGVkZ2VzLnJpZ2h0KSB7XG4gICAgICBtb2RpZmllZFggPSBNYXRoLm1heChNYXRoLm1pbihvdXRlci5yaWdodCAtIG9mZnNldC5yaWdodCwgcGFnZS54KSwgaW5uZXIucmlnaHQgLSBvZmZzZXQucmlnaHQpO1xuICAgIH1cblxuICAgIHN0YXR1cy5keCA9IG1vZGlmaWVkWCAtIHBhZ2UueDtcbiAgICBzdGF0dXMuZHkgPSBtb2RpZmllZFkgLSBwYWdlLnk7XG5cbiAgICBzdGF0dXMuY2hhbmdlZCA9IHN0YXR1cy5tb2RpZmllZFggIT09IG1vZGlmaWVkWCB8fCBzdGF0dXMubW9kaWZpZWRZICE9PSBtb2RpZmllZFk7XG4gICAgc3RhdHVzLmxvY2tlZCA9ICEhKHN0YXR1cy5keCB8fCBzdGF0dXMuZHkpO1xuXG4gICAgc3RhdHVzLm1vZGlmaWVkWCA9IG1vZGlmaWVkWDtcbiAgICBzdGF0dXMubW9kaWZpZWRZID0gbW9kaWZpZWRZO1xuICB9LFxuXG4gIG1vZGlmeUNvb3JkczogZnVuY3Rpb24gbW9kaWZ5Q29vcmRzKF9yZWYzKSB7XG4gICAgdmFyIHBhZ2UgPSBfcmVmMy5wYWdlLFxuICAgICAgICBjbGllbnQgPSBfcmVmMy5jbGllbnQsXG4gICAgICAgIHN0YXR1cyA9IF9yZWYzLnN0YXR1cyxcbiAgICAgICAgcGhhc2UgPSBfcmVmMy5waGFzZSxcbiAgICAgICAgb3B0aW9ucyA9IF9yZWYzLm9wdGlvbnM7XG5cbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmVuYWJsZWQgJiYgIShwaGFzZSA9PT0gJ3N0YXJ0JyAmJiBzdGF0dXMubG9ja2VkKSkge1xuXG4gICAgICBpZiAoc3RhdHVzLmxvY2tlZCkge1xuICAgICAgICBwYWdlLnggKz0gc3RhdHVzLmR4O1xuICAgICAgICBwYWdlLnkgKz0gc3RhdHVzLmR5O1xuICAgICAgICBjbGllbnQueCArPSBzdGF0dXMuZHg7XG4gICAgICAgIGNsaWVudC55ICs9IHN0YXR1cy5keTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGR4OiBzdGF0dXMuZHgsXG4gICAgICAgICAgZHk6IHN0YXR1cy5keVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBub0lubmVyOiBub0lubmVyLFxuICBub091dGVyOiBub091dGVyLFxuICBnZXRSZXN0cmljdGlvblJlY3Q6IGdldFJlc3RyaWN0aW9uUmVjdFxufTtcblxubW9kaWZpZXJzLnJlc3RyaWN0RWRnZXMgPSByZXN0cmljdEVkZ2VzO1xubW9kaWZpZXJzLm5hbWVzLnB1c2goJ3Jlc3RyaWN0RWRnZXMnKTtcblxuZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uLnJlc3RyaWN0RWRnZXMgPSByZXN0cmljdEVkZ2VzLmRlZmF1bHRzO1xucmVzaXplLmRlZmF1bHRzLnJlc3RyaWN0RWRnZXMgPSByZXN0cmljdEVkZ2VzLmRlZmF1bHRzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlc3RyaWN0RWRnZXM7XG5cbn0se1wiLi4vYWN0aW9ucy9yZXNpemVcIjoxMCxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvcmVjdFwiOjUxLFwiLi9pbmRleFwiOjI0LFwiLi9yZXN0cmljdFwiOjI1fV0sMjc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBUaGlzIG1vZHVsZSBhZGRzIHRoZSBvcHRpb25zLnJlc2l6ZS5yZXN0cmljdFNpemUgc2V0dGluZyB3aGljaCBzZXRzIG1pbiBhbmRcbi8vIG1heCB3aWR0aCBhbmQgaGVpZ2h0IGZvciB0aGUgdGFyZ2V0IGJlaW5nIHJlc2l6ZWQuXG4vL1xuLy8gaW50ZXJhY3QodGFyZ2V0KS5yZXNpemUoe1xuLy8gICBlZGdlczogeyB0b3A6IHRydWUsIGxlZnQ6IHRydWUgfSxcbi8vICAgcmVzdHJpY3RTaXplOiB7XG4vLyAgICAgbWluOiB7IHdpZHRoOiAtNjAwLCBoZWlnaHQ6IC02MDAgfSxcbi8vICAgICBtYXg6IHsgd2lkdGg6ICA2MDAsIGhlaWdodDogIDYwMCB9LFxuLy8gICB9LFxuLy8gfSk7XG5cbnZhciBtb2RpZmllcnMgPSByZXF1aXJlKCcuL2luZGV4Jyk7XG52YXIgcmVzdHJpY3RFZGdlcyA9IHJlcXVpcmUoJy4vcmVzdHJpY3RFZGdlcycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciByZWN0VXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9yZWN0Jyk7XG52YXIgZGVmYXVsdE9wdGlvbnMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xudmFyIHJlc2l6ZSA9IHJlcXVpcmUoJy4uL2FjdGlvbnMvcmVzaXplJyk7XG5cbnZhciBub01pbiA9IHsgd2lkdGg6IC1JbmZpbml0eSwgaGVpZ2h0OiAtSW5maW5pdHkgfTtcbnZhciBub01heCA9IHsgd2lkdGg6ICtJbmZpbml0eSwgaGVpZ2h0OiArSW5maW5pdHkgfTtcblxudmFyIHJlc3RyaWN0U2l6ZSA9IHtcbiAgZGVmYXVsdHM6IHtcbiAgICBlbmFibGVkOiBmYWxzZSxcbiAgICBlbmRPbmx5OiBmYWxzZSxcbiAgICBtaW46IG51bGwsXG4gICAgbWF4OiBudWxsXG4gIH0sXG5cbiAgc2V0T2Zmc2V0OiBmdW5jdGlvbiBzZXRPZmZzZXQoX3JlZikge1xuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb247XG5cbiAgICByZXR1cm4gaW50ZXJhY3Rpb24uc3RhcnRPZmZzZXQ7XG4gIH0sXG5cbiAgc2V0OiBmdW5jdGlvbiBzZXQoYXJnKSB7XG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxuICAgICAgICBvcHRpb25zID0gYXJnLm9wdGlvbnM7XG5cbiAgICB2YXIgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5saW5rZWRFZGdlcyB8fCBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcztcblxuICAgIGlmICghaW50ZXJhY3Rpb24uaW50ZXJhY3RpbmcoKSB8fCAhZWRnZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcmVjdCA9IHJlY3RVdGlscy54eXdoVG9UbGJyKGludGVyYWN0aW9uLnJlc2l6ZVJlY3RzLmludmVydGVkKTtcblxuICAgIHZhciBtaW5TaXplID0gcmVjdFV0aWxzLnRsYnJUb1h5d2gocmVzdHJpY3RFZGdlcy5nZXRSZXN0cmljdGlvblJlY3Qob3B0aW9ucy5taW4sIGludGVyYWN0aW9uKSkgfHwgbm9NaW47XG4gICAgdmFyIG1heFNpemUgPSByZWN0VXRpbHMudGxiclRvWHl3aChyZXN0cmljdEVkZ2VzLmdldFJlc3RyaWN0aW9uUmVjdChvcHRpb25zLm1heCwgaW50ZXJhY3Rpb24pKSB8fCBub01heDtcblxuICAgIGFyZy5vcHRpb25zID0ge1xuICAgICAgZW5hYmxlZDogb3B0aW9ucy5lbmFibGVkLFxuICAgICAgZW5kT25seTogb3B0aW9ucy5lbmRPbmx5LFxuICAgICAgaW5uZXI6IHV0aWxzLmV4dGVuZCh7fSwgcmVzdHJpY3RFZGdlcy5ub0lubmVyKSxcbiAgICAgIG91dGVyOiB1dGlscy5leHRlbmQoe30sIHJlc3RyaWN0RWRnZXMubm9PdXRlcilcbiAgICB9O1xuXG4gICAgaWYgKGVkZ2VzLnRvcCkge1xuICAgICAgYXJnLm9wdGlvbnMuaW5uZXIudG9wID0gcmVjdC5ib3R0b20gLSBtaW5TaXplLmhlaWdodDtcbiAgICAgIGFyZy5vcHRpb25zLm91dGVyLnRvcCA9IHJlY3QuYm90dG9tIC0gbWF4U2l6ZS5oZWlnaHQ7XG4gICAgfSBlbHNlIGlmIChlZGdlcy5ib3R0b20pIHtcbiAgICAgIGFyZy5vcHRpb25zLmlubmVyLmJvdHRvbSA9IHJlY3QudG9wICsgbWluU2l6ZS5oZWlnaHQ7XG4gICAgICBhcmcub3B0aW9ucy5vdXRlci5ib3R0b20gPSByZWN0LnRvcCArIG1heFNpemUuaGVpZ2h0O1xuICAgIH1cbiAgICBpZiAoZWRnZXMubGVmdCkge1xuICAgICAgYXJnLm9wdGlvbnMuaW5uZXIubGVmdCA9IHJlY3QucmlnaHQgLSBtaW5TaXplLndpZHRoO1xuICAgICAgYXJnLm9wdGlvbnMub3V0ZXIubGVmdCA9IHJlY3QucmlnaHQgLSBtYXhTaXplLndpZHRoO1xuICAgIH0gZWxzZSBpZiAoZWRnZXMucmlnaHQpIHtcbiAgICAgIGFyZy5vcHRpb25zLmlubmVyLnJpZ2h0ID0gcmVjdC5sZWZ0ICsgbWluU2l6ZS53aWR0aDtcbiAgICAgIGFyZy5vcHRpb25zLm91dGVyLnJpZ2h0ID0gcmVjdC5sZWZ0ICsgbWF4U2l6ZS53aWR0aDtcbiAgICB9XG5cbiAgICByZXN0cmljdEVkZ2VzLnNldChhcmcpO1xuICB9LFxuXG4gIG1vZGlmeUNvb3JkczogcmVzdHJpY3RFZGdlcy5tb2RpZnlDb29yZHNcbn07XG5cbm1vZGlmaWVycy5yZXN0cmljdFNpemUgPSByZXN0cmljdFNpemU7XG5tb2RpZmllcnMubmFtZXMucHVzaCgncmVzdHJpY3RTaXplJyk7XG5cbmRlZmF1bHRPcHRpb25zLnBlckFjdGlvbi5yZXN0cmljdFNpemUgPSByZXN0cmljdFNpemUuZGVmYXVsdHM7XG5yZXNpemUuZGVmYXVsdHMucmVzdHJpY3RTaXplID0gcmVzdHJpY3RTaXplLmRlZmF1bHRzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlc3RyaWN0U2l6ZTtcblxufSx7XCIuLi9hY3Rpb25zL3Jlc2l6ZVwiOjEwLFwiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL3V0aWxzXCI6NDQsXCIuLi91dGlscy9yZWN0XCI6NTEsXCIuL2luZGV4XCI6MjQsXCIuL3Jlc3RyaWN0RWRnZXNcIjoyNn1dLDI4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIG1vZGlmaWVycyA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcbnZhciBpbnRlcmFjdCA9IHJlcXVpcmUoJy4uL2ludGVyYWN0Jyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcblxudmFyIHNuYXAgPSB7XG4gIGRlZmF1bHRzOiB7XG4gICAgZW5hYmxlZDogZmFsc2UsXG4gICAgZW5kT25seTogZmFsc2UsXG4gICAgcmFuZ2U6IEluZmluaXR5LFxuICAgIHRhcmdldHM6IG51bGwsXG4gICAgb2Zmc2V0czogbnVsbCxcblxuICAgIHJlbGF0aXZlUG9pbnRzOiBudWxsXG4gIH0sXG5cbiAgc2V0T2Zmc2V0OiBmdW5jdGlvbiBzZXRPZmZzZXQoX3JlZikge1xuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb24sXG4gICAgICAgIGludGVyYWN0YWJsZSA9IF9yZWYuaW50ZXJhY3RhYmxlLFxuICAgICAgICBlbGVtZW50ID0gX3JlZi5lbGVtZW50LFxuICAgICAgICByZWN0ID0gX3JlZi5yZWN0LFxuICAgICAgICBzdGFydE9mZnNldCA9IF9yZWYuc3RhcnRPZmZzZXQsXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XG5cbiAgICB2YXIgb2Zmc2V0cyA9IFtdO1xuICAgIHZhciBvcHRpb25zT3JpZ2luID0gdXRpbHMucmVjdFRvWFkodXRpbHMucmVzb2x2ZVJlY3RMaWtlKG9wdGlvbnMub3JpZ2luKSk7XG4gICAgdmFyIG9yaWdpbiA9IG9wdGlvbnNPcmlnaW4gfHwgdXRpbHMuZ2V0T3JpZ2luWFkoaW50ZXJhY3RhYmxlLCBlbGVtZW50LCBpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lKTtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCBpbnRlcmFjdGFibGUub3B0aW9uc1tpbnRlcmFjdGlvbi5wcmVwYXJlZC5uYW1lXS5zbmFwIHx8IHt9O1xuXG4gICAgdmFyIHNuYXBPZmZzZXQgPSB2b2lkIDA7XG5cbiAgICBpZiAob3B0aW9ucy5vZmZzZXQgPT09ICdzdGFydENvb3JkcycpIHtcbiAgICAgIHNuYXBPZmZzZXQgPSB7XG4gICAgICAgIHg6IGludGVyYWN0aW9uLnN0YXJ0Q29vcmRzLnBhZ2UueCAtIG9yaWdpbi54LFxuICAgICAgICB5OiBpbnRlcmFjdGlvbi5zdGFydENvb3Jkcy5wYWdlLnkgLSBvcmlnaW4ueVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIG9mZnNldFJlY3QgPSB1dGlscy5yZXNvbHZlUmVjdExpa2Uob3B0aW9ucy5vZmZzZXQsIGludGVyYWN0YWJsZSwgZWxlbWVudCwgW2ludGVyYWN0aW9uXSk7XG5cbiAgICAgIHNuYXBPZmZzZXQgPSB1dGlscy5yZWN0VG9YWShvZmZzZXRSZWN0KSB8fCB7IHg6IDAsIHk6IDAgfTtcbiAgICB9XG5cbiAgICBpZiAocmVjdCAmJiBvcHRpb25zLnJlbGF0aXZlUG9pbnRzICYmIG9wdGlvbnMucmVsYXRpdmVQb2ludHMubGVuZ3RoKSB7XG4gICAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBvcHRpb25zLnJlbGF0aXZlUG9pbnRzLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xuICAgICAgICB2YXIgX3JlZjI7XG5cbiAgICAgICAgaWYgKF9pc0FycmF5KSB7XG4gICAgICAgICAgaWYgKF9pID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xuICAgICAgICAgIF9yZWYyID0gX2l0ZXJhdG9yW19pKytdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XG4gICAgICAgICAgX3JlZjIgPSBfaS52YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBfcmVmMyA9IF9yZWYyLFxuICAgICAgICAgICAgcmVsYXRpdmVYID0gX3JlZjMueCxcbiAgICAgICAgICAgIHJlbGF0aXZlWSA9IF9yZWYzLnk7XG5cbiAgICAgICAgb2Zmc2V0cy5wdXNoKHtcbiAgICAgICAgICB4OiBzdGFydE9mZnNldC5sZWZ0IC0gcmVjdC53aWR0aCAqIHJlbGF0aXZlWCArIHNuYXBPZmZzZXQueCxcbiAgICAgICAgICB5OiBzdGFydE9mZnNldC50b3AgLSByZWN0LmhlaWdodCAqIHJlbGF0aXZlWSArIHNuYXBPZmZzZXQueVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgb2Zmc2V0cy5wdXNoKHNuYXBPZmZzZXQpO1xuICAgIH1cblxuICAgIHJldHVybiBvZmZzZXRzO1xuICB9LFxuXG4gIHNldDogZnVuY3Rpb24gc2V0KF9yZWY0KSB7XG4gICAgdmFyIGludGVyYWN0aW9uID0gX3JlZjQuaW50ZXJhY3Rpb24sXG4gICAgICAgIHBhZ2VDb29yZHMgPSBfcmVmNC5wYWdlQ29vcmRzLFxuICAgICAgICBzdGF0dXMgPSBfcmVmNC5zdGF0dXMsXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmNC5vcHRpb25zLFxuICAgICAgICBvZmZzZXRzID0gX3JlZjQub2Zmc2V0O1xuXG4gICAgdmFyIHRhcmdldHMgPSBbXTtcbiAgICB2YXIgdGFyZ2V0ID0gdm9pZCAwO1xuICAgIHZhciBwYWdlID0gdm9pZCAwO1xuICAgIHZhciBpID0gdm9pZCAwO1xuXG4gICAgaWYgKHN0YXR1cy51c2VTdGF0dXNYWSkge1xuICAgICAgcGFnZSA9IHsgeDogc3RhdHVzLngsIHk6IHN0YXR1cy55IH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBvcmlnaW4gPSB1dGlscy5nZXRPcmlnaW5YWShpbnRlcmFjdGlvbi50YXJnZXQsIGludGVyYWN0aW9uLmVsZW1lbnQsIGludGVyYWN0aW9uLnByZXBhcmVkLm5hbWUpO1xuXG4gICAgICBwYWdlID0gdXRpbHMuZXh0ZW5kKHt9LCBwYWdlQ29vcmRzKTtcblxuICAgICAgcGFnZS54IC09IG9yaWdpbi54O1xuICAgICAgcGFnZS55IC09IG9yaWdpbi55O1xuICAgIH1cblxuICAgIHN0YXR1cy5yZWFsWCA9IHBhZ2UueDtcbiAgICBzdGF0dXMucmVhbFkgPSBwYWdlLnk7XG5cbiAgICB2YXIgbGVuID0gb3B0aW9ucy50YXJnZXRzID8gb3B0aW9ucy50YXJnZXRzLmxlbmd0aCA6IDA7XG5cbiAgICBmb3IgKHZhciBfaXRlcmF0b3IyID0gb2Zmc2V0cywgX2lzQXJyYXkyID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IyKSwgX2kyID0gMCwgX2l0ZXJhdG9yMiA9IF9pc0FycmF5MiA/IF9pdGVyYXRvcjIgOiBfaXRlcmF0b3IyW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICB2YXIgX3JlZjU7XG5cbiAgICAgIGlmIChfaXNBcnJheTIpIHtcbiAgICAgICAgaWYgKF9pMiA+PSBfaXRlcmF0b3IyLmxlbmd0aCkgYnJlYWs7XG4gICAgICAgIF9yZWY1ID0gX2l0ZXJhdG9yMltfaTIrK107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaTIgPSBfaXRlcmF0b3IyLm5leHQoKTtcbiAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcbiAgICAgICAgX3JlZjUgPSBfaTIudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBfcmVmNiA9IF9yZWY1LFxuICAgICAgICAgIG9mZnNldFggPSBfcmVmNi54LFxuICAgICAgICAgIG9mZnNldFkgPSBfcmVmNi55O1xuXG4gICAgICB2YXIgcmVsYXRpdmVYID0gcGFnZS54IC0gb2Zmc2V0WDtcbiAgICAgIHZhciByZWxhdGl2ZVkgPSBwYWdlLnkgLSBvZmZzZXRZO1xuXG4gICAgICBmb3IgKHZhciBfaXRlcmF0b3IzID0gb3B0aW9ucy50YXJnZXRzLCBfaXNBcnJheTMgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjMpLCBfaTMgPSAwLCBfaXRlcmF0b3IzID0gX2lzQXJyYXkzID8gX2l0ZXJhdG9yMyA6IF9pdGVyYXRvcjNbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcbiAgICAgICAgdmFyIF9yZWY3O1xuXG4gICAgICAgIGlmIChfaXNBcnJheTMpIHtcbiAgICAgICAgICBpZiAoX2kzID49IF9pdGVyYXRvcjMubGVuZ3RoKSBicmVhaztcbiAgICAgICAgICBfcmVmNyA9IF9pdGVyYXRvcjNbX2kzKytdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIF9pMyA9IF9pdGVyYXRvcjMubmV4dCgpO1xuICAgICAgICAgIGlmIChfaTMuZG9uZSkgYnJlYWs7XG4gICAgICAgICAgX3JlZjcgPSBfaTMudmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc25hcFRhcmdldCA9IF9yZWY3O1xuXG4gICAgICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihzbmFwVGFyZ2V0KSkge1xuICAgICAgICAgIHRhcmdldCA9IHNuYXBUYXJnZXQocmVsYXRpdmVYLCByZWxhdGl2ZVksIGludGVyYWN0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0YXJnZXQgPSBzbmFwVGFyZ2V0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRhcmdldHMucHVzaCh7XG4gICAgICAgICAgeDogdXRpbHMuaXMubnVtYmVyKHRhcmdldC54KSA/IHRhcmdldC54ICsgb2Zmc2V0WCA6IHJlbGF0aXZlWCxcbiAgICAgICAgICB5OiB1dGlscy5pcy5udW1iZXIodGFyZ2V0LnkpID8gdGFyZ2V0LnkgKyBvZmZzZXRZIDogcmVsYXRpdmVZLFxuXG4gICAgICAgICAgcmFuZ2U6IHV0aWxzLmlzLm51bWJlcih0YXJnZXQucmFuZ2UpID8gdGFyZ2V0LnJhbmdlIDogb3B0aW9ucy5yYW5nZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgY2xvc2VzdCA9IHtcbiAgICAgIHRhcmdldDogbnVsbCxcbiAgICAgIGluUmFuZ2U6IGZhbHNlLFxuICAgICAgZGlzdGFuY2U6IDAsXG4gICAgICByYW5nZTogMCxcbiAgICAgIGR4OiAwLFxuICAgICAgZHk6IDBcbiAgICB9O1xuXG4gICAgZm9yIChpID0gMCwgbGVuID0gdGFyZ2V0cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0ID0gdGFyZ2V0c1tpXTtcblxuICAgICAgdmFyIHJhbmdlID0gdGFyZ2V0LnJhbmdlO1xuICAgICAgdmFyIGR4ID0gdGFyZ2V0LnggLSBwYWdlLng7XG4gICAgICB2YXIgZHkgPSB0YXJnZXQueSAtIHBhZ2UueTtcbiAgICAgIHZhciBkaXN0YW5jZSA9IHV0aWxzLmh5cG90KGR4LCBkeSk7XG4gICAgICB2YXIgaW5SYW5nZSA9IGRpc3RhbmNlIDw9IHJhbmdlO1xuXG4gICAgICAvLyBJbmZpbml0ZSB0YXJnZXRzIGNvdW50IGFzIGJlaW5nIG91dCBvZiByYW5nZVxuICAgICAgLy8gY29tcGFyZWQgdG8gbm9uIGluZmluaXRlIG9uZXMgdGhhdCBhcmUgaW4gcmFuZ2VcbiAgICAgIGlmIChyYW5nZSA9PT0gSW5maW5pdHkgJiYgY2xvc2VzdC5pblJhbmdlICYmIGNsb3Nlc3QucmFuZ2UgIT09IEluZmluaXR5KSB7XG4gICAgICAgIGluUmFuZ2UgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFjbG9zZXN0LnRhcmdldCB8fCAoaW5SYW5nZVxuICAgICAgLy8gaXMgdGhlIGNsb3Nlc3QgdGFyZ2V0IGluIHJhbmdlP1xuICAgICAgPyBjbG9zZXN0LmluUmFuZ2UgJiYgcmFuZ2UgIT09IEluZmluaXR5XG4gICAgICAvLyB0aGUgcG9pbnRlciBpcyByZWxhdGl2ZWx5IGRlZXBlciBpbiB0aGlzIHRhcmdldFxuICAgICAgPyBkaXN0YW5jZSAvIHJhbmdlIDwgY2xvc2VzdC5kaXN0YW5jZSAvIGNsb3Nlc3QucmFuZ2VcbiAgICAgIC8vIHRoaXMgdGFyZ2V0IGhhcyBJbmZpbml0ZSByYW5nZSBhbmQgdGhlIGNsb3Nlc3QgZG9lc24ndFxuICAgICAgOiByYW5nZSA9PT0gSW5maW5pdHkgJiYgY2xvc2VzdC5yYW5nZSAhPT0gSW5maW5pdHkgfHxcbiAgICAgIC8vIE9SIHRoaXMgdGFyZ2V0IGlzIGNsb3NlciB0aGF0IHRoZSBwcmV2aW91cyBjbG9zZXN0XG4gICAgICBkaXN0YW5jZSA8IGNsb3Nlc3QuZGlzdGFuY2UgOlxuICAgICAgLy8gVGhlIG90aGVyIGlzIG5vdCBpbiByYW5nZSBhbmQgdGhlIHBvaW50ZXIgaXMgY2xvc2VyIHRvIHRoaXMgdGFyZ2V0XG4gICAgICAhY2xvc2VzdC5pblJhbmdlICYmIGRpc3RhbmNlIDwgY2xvc2VzdC5kaXN0YW5jZSkpIHtcblxuICAgICAgICBjbG9zZXN0LnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgY2xvc2VzdC5kaXN0YW5jZSA9IGRpc3RhbmNlO1xuICAgICAgICBjbG9zZXN0LnJhbmdlID0gcmFuZ2U7XG4gICAgICAgIGNsb3Nlc3QuaW5SYW5nZSA9IGluUmFuZ2U7XG4gICAgICAgIGNsb3Nlc3QuZHggPSBkeDtcbiAgICAgICAgY2xvc2VzdC5keSA9IGR5O1xuXG4gICAgICAgIHN0YXR1cy5yYW5nZSA9IHJhbmdlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBzbmFwQ2hhbmdlZCA9IHZvaWQgMDtcblxuICAgIGlmIChjbG9zZXN0LnRhcmdldCkge1xuICAgICAgc25hcENoYW5nZWQgPSBzdGF0dXMubW9kaWZpZWRYICE9PSBjbG9zZXN0LnRhcmdldC54IHx8IHN0YXR1cy5tb2RpZmllZFkgIT09IGNsb3Nlc3QudGFyZ2V0Lnk7XG5cbiAgICAgIHN0YXR1cy5tb2RpZmllZFggPSBjbG9zZXN0LnRhcmdldC54O1xuICAgICAgc3RhdHVzLm1vZGlmaWVkWSA9IGNsb3Nlc3QudGFyZ2V0Lnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNuYXBDaGFuZ2VkID0gdHJ1ZTtcblxuICAgICAgc3RhdHVzLm1vZGlmaWVkWCA9IE5hTjtcbiAgICAgIHN0YXR1cy5tb2RpZmllZFkgPSBOYU47XG4gICAgfVxuXG4gICAgc3RhdHVzLmR4ID0gY2xvc2VzdC5keDtcbiAgICBzdGF0dXMuZHkgPSBjbG9zZXN0LmR5O1xuXG4gICAgc3RhdHVzLmNoYW5nZWQgPSBzbmFwQ2hhbmdlZCB8fCBjbG9zZXN0LmluUmFuZ2UgJiYgIXN0YXR1cy5sb2NrZWQ7XG4gICAgc3RhdHVzLmxvY2tlZCA9IGNsb3Nlc3QuaW5SYW5nZTtcbiAgfSxcblxuICBtb2RpZnlDb29yZHM6IGZ1bmN0aW9uIG1vZGlmeUNvb3JkcyhfcmVmOCkge1xuICAgIHZhciBwYWdlID0gX3JlZjgucGFnZSxcbiAgICAgICAgY2xpZW50ID0gX3JlZjguY2xpZW50LFxuICAgICAgICBzdGF0dXMgPSBfcmVmOC5zdGF0dXMsXG4gICAgICAgIHBoYXNlID0gX3JlZjgucGhhc2UsXG4gICAgICAgIG9wdGlvbnMgPSBfcmVmOC5vcHRpb25zO1xuXG4gICAgdmFyIHJlbGF0aXZlUG9pbnRzID0gb3B0aW9ucyAmJiBvcHRpb25zLnJlbGF0aXZlUG9pbnRzO1xuXG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5lbmFibGVkICYmICEocGhhc2UgPT09ICdzdGFydCcgJiYgcmVsYXRpdmVQb2ludHMgJiYgcmVsYXRpdmVQb2ludHMubGVuZ3RoKSkge1xuXG4gICAgICBpZiAoc3RhdHVzLmxvY2tlZCkge1xuICAgICAgICBwYWdlLnggKz0gc3RhdHVzLmR4O1xuICAgICAgICBwYWdlLnkgKz0gc3RhdHVzLmR5O1xuICAgICAgICBjbGllbnQueCArPSBzdGF0dXMuZHg7XG4gICAgICAgIGNsaWVudC55ICs9IHN0YXR1cy5keTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmFuZ2U6IHN0YXR1cy5yYW5nZSxcbiAgICAgICAgbG9ja2VkOiBzdGF0dXMubG9ja2VkLFxuICAgICAgICB4OiBzdGF0dXMubW9kaWZpZWRYLFxuICAgICAgICB5OiBzdGF0dXMubW9kaWZpZWRZLFxuICAgICAgICByZWFsWDogc3RhdHVzLnJlYWxYLFxuICAgICAgICByZWFsWTogc3RhdHVzLnJlYWxZLFxuICAgICAgICBkeDogc3RhdHVzLmR4LFxuICAgICAgICBkeTogc3RhdHVzLmR5XG4gICAgICB9O1xuICAgIH1cbiAgfVxufTtcblxuaW50ZXJhY3QuY3JlYXRlU25hcEdyaWQgPSBmdW5jdGlvbiAoZ3JpZCkge1xuICByZXR1cm4gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICB2YXIgbGltaXRzID0gZ3JpZC5saW1pdHMgfHwge1xuICAgICAgbGVmdDogLUluZmluaXR5LFxuICAgICAgcmlnaHQ6IEluZmluaXR5LFxuICAgICAgdG9wOiAtSW5maW5pdHksXG4gICAgICBib3R0b206IEluZmluaXR5XG4gICAgfTtcbiAgICB2YXIgb2Zmc2V0WCA9IDA7XG4gICAgdmFyIG9mZnNldFkgPSAwO1xuXG4gICAgaWYgKHV0aWxzLmlzLm9iamVjdChncmlkLm9mZnNldCkpIHtcbiAgICAgIG9mZnNldFggPSBncmlkLm9mZnNldC54O1xuICAgICAgb2Zmc2V0WSA9IGdyaWQub2Zmc2V0Lnk7XG4gICAgfVxuXG4gICAgdmFyIGdyaWR4ID0gTWF0aC5yb3VuZCgoeCAtIG9mZnNldFgpIC8gZ3JpZC54KTtcbiAgICB2YXIgZ3JpZHkgPSBNYXRoLnJvdW5kKCh5IC0gb2Zmc2V0WSkgLyBncmlkLnkpO1xuXG4gICAgdmFyIG5ld1ggPSBNYXRoLm1heChsaW1pdHMubGVmdCwgTWF0aC5taW4obGltaXRzLnJpZ2h0LCBncmlkeCAqIGdyaWQueCArIG9mZnNldFgpKTtcbiAgICB2YXIgbmV3WSA9IE1hdGgubWF4KGxpbWl0cy50b3AsIE1hdGgubWluKGxpbWl0cy5ib3R0b20sIGdyaWR5ICogZ3JpZC55ICsgb2Zmc2V0WSkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IG5ld1gsXG4gICAgICB5OiBuZXdZLFxuICAgICAgcmFuZ2U6IGdyaWQucmFuZ2VcbiAgICB9O1xuICB9O1xufTtcblxubW9kaWZpZXJzLnNuYXAgPSBzbmFwO1xubW9kaWZpZXJzLm5hbWVzLnB1c2goJ3NuYXAnKTtcblxuZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uLnNuYXAgPSBzbmFwLmRlZmF1bHRzO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNuYXA7XG5cbn0se1wiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL2ludGVyYWN0XCI6MjEsXCIuLi91dGlsc1wiOjQ0LFwiLi9pbmRleFwiOjI0fV0sMjk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG4vLyBUaGlzIG1vZHVsZSBhbGxvd3Mgc25hcHBpbmcgb2YgdGhlIHNpemUgb2YgdGFyZ2V0cyBkdXJpbmcgcmVzaXplXG4vLyBpbnRlcmFjdGlvbnMuXG5cbnZhciBtb2RpZmllcnMgPSByZXF1aXJlKCcuL2luZGV4Jyk7XG52YXIgc25hcCA9IHJlcXVpcmUoJy4vc25hcCcpO1xudmFyIGRlZmF1bHRPcHRpb25zID0gcmVxdWlyZSgnLi4vZGVmYXVsdE9wdGlvbnMnKTtcbnZhciByZXNpemUgPSByZXF1aXJlKCcuLi9hY3Rpb25zL3Jlc2l6ZScpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvJyk7XG5cbnZhciBzbmFwU2l6ZSA9IHtcbiAgZGVmYXVsdHM6IHtcbiAgICBlbmFibGVkOiBmYWxzZSxcbiAgICBlbmRPbmx5OiBmYWxzZSxcbiAgICByYW5nZTogSW5maW5pdHksXG4gICAgdGFyZ2V0czogbnVsbCxcbiAgICBvZmZzZXRzOiBudWxsXG4gIH0sXG5cbiAgc2V0T2Zmc2V0OiBmdW5jdGlvbiBzZXRPZmZzZXQoYXJnKSB7XG4gICAgdmFyIGludGVyYWN0aW9uID0gYXJnLmludGVyYWN0aW9uLFxuICAgICAgICBvcHRpb25zID0gYXJnLm9wdGlvbnM7XG5cbiAgICB2YXIgZWRnZXMgPSBpbnRlcmFjdGlvbi5wcmVwYXJlZC5lZGdlcztcblxuICAgIGlmICghZWRnZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhcmcub3B0aW9ucyA9IHtcbiAgICAgIHJlbGF0aXZlUG9pbnRzOiBbe1xuICAgICAgICB4OiBlZGdlcy5sZWZ0ID8gMCA6IDEsXG4gICAgICAgIHk6IGVkZ2VzLnRvcCA/IDAgOiAxXG4gICAgICB9XSxcbiAgICAgIG9yaWdpbjogeyB4OiAwLCB5OiAwIH0sXG4gICAgICBvZmZzZXQ6ICdzZWxmJyxcbiAgICAgIHJhbmdlOiBvcHRpb25zLnJhbmdlXG4gICAgfTtcblxuICAgIHZhciBvZmZzZXRzID0gc25hcC5zZXRPZmZzZXQoYXJnKTtcbiAgICBhcmcub3B0aW9ucyA9IG9wdGlvbnM7XG5cbiAgICByZXR1cm4gb2Zmc2V0cztcbiAgfSxcblxuICBzZXQ6IGZ1bmN0aW9uIHNldChhcmcpIHtcbiAgICB2YXIgaW50ZXJhY3Rpb24gPSBhcmcuaW50ZXJhY3Rpb24sXG4gICAgICAgIG9wdGlvbnMgPSBhcmcub3B0aW9ucyxcbiAgICAgICAgb2Zmc2V0ID0gYXJnLm9mZnNldCxcbiAgICAgICAgcGFnZUNvb3JkcyA9IGFyZy5wYWdlQ29vcmRzO1xuXG4gICAgdmFyIHBhZ2UgPSB1dGlscy5leHRlbmQoe30sIHBhZ2VDb29yZHMpO1xuICAgIHZhciByZWxhdGl2ZVggPSBwYWdlLnggLSBvZmZzZXRbMF0ueDtcbiAgICB2YXIgcmVsYXRpdmVZID0gcGFnZS55IC0gb2Zmc2V0WzBdLnk7XG5cbiAgICBhcmcub3B0aW9ucyA9IHV0aWxzLmV4dGVuZCh7fSwgb3B0aW9ucyk7XG4gICAgYXJnLm9wdGlvbnMudGFyZ2V0cyA9IFtdO1xuXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gb3B0aW9ucy50YXJnZXRzLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xuICAgICAgdmFyIF9yZWY7XG5cbiAgICAgIGlmIChfaXNBcnJheSkge1xuICAgICAgICBpZiAoX2kgPj0gX2l0ZXJhdG9yLmxlbmd0aCkgYnJlYWs7XG4gICAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIGlmIChfaS5kb25lKSBicmVhaztcbiAgICAgICAgX3JlZiA9IF9pLnZhbHVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc25hcFRhcmdldCA9IF9yZWY7XG5cbiAgICAgIHZhciB0YXJnZXQgPSB2b2lkIDA7XG5cbiAgICAgIGlmICh1dGlscy5pcy5mdW5jdGlvbihzbmFwVGFyZ2V0KSkge1xuICAgICAgICB0YXJnZXQgPSBzbmFwVGFyZ2V0KHJlbGF0aXZlWCwgcmVsYXRpdmVZLCBpbnRlcmFjdGlvbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXQgPSBzbmFwVGFyZ2V0O1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCd3aWR0aCcgaW4gdGFyZ2V0ICYmICdoZWlnaHQnIGluIHRhcmdldCkge1xuICAgICAgICB0YXJnZXQueCA9IHRhcmdldC53aWR0aDtcbiAgICAgICAgdGFyZ2V0LnkgPSB0YXJnZXQuaGVpZ2h0O1xuICAgICAgfVxuXG4gICAgICBhcmcub3B0aW9ucy50YXJnZXRzLnB1c2godGFyZ2V0KTtcbiAgICB9XG5cbiAgICBzbmFwLnNldChhcmcpO1xuICB9LFxuXG4gIG1vZGlmeUNvb3JkczogZnVuY3Rpb24gbW9kaWZ5Q29vcmRzKGFyZykge1xuICAgIHZhciBvcHRpb25zID0gYXJnLm9wdGlvbnM7XG5cblxuICAgIGFyZy5vcHRpb25zID0gdXRpbHMuZXh0ZW5kKHt9LCBvcHRpb25zKTtcbiAgICBhcmcub3B0aW9ucy5lbmFibGVkID0gb3B0aW9ucy5lbmFibGVkO1xuICAgIGFyZy5vcHRpb25zLnJlbGF0aXZlUG9pbnRzID0gW251bGxdO1xuXG4gICAgc25hcC5tb2RpZnlDb29yZHMoYXJnKTtcbiAgfVxufTtcblxubW9kaWZpZXJzLnNuYXBTaXplID0gc25hcFNpemU7XG5tb2RpZmllcnMubmFtZXMucHVzaCgnc25hcFNpemUnKTtcblxuZGVmYXVsdE9wdGlvbnMucGVyQWN0aW9uLnNuYXBTaXplID0gc25hcFNpemUuZGVmYXVsdHM7XG5yZXNpemUuZGVmYXVsdHMuc25hcFNpemUgPSBzbmFwU2l6ZS5kZWZhdWx0cztcblxubW9kdWxlLmV4cG9ydHMgPSBzbmFwU2l6ZTtcblxufSx7XCIuLi9hY3Rpb25zL3Jlc2l6ZVwiOjEwLFwiLi4vZGVmYXVsdE9wdGlvbnNcIjoxOCxcIi4uL3V0aWxzL1wiOjQ0LFwiLi9pbmRleFwiOjI0LFwiLi9zbmFwXCI6Mjh9XSwzMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBwb2ludGVyVXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9wb2ludGVyVXRpbHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFBvaW50ZXJFdmVudCh0eXBlLCBwb2ludGVyLCBldmVudCwgZXZlbnRUYXJnZXQsIGludGVyYWN0aW9uKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFBvaW50ZXJFdmVudCk7XG5cbiAgICBwb2ludGVyVXRpbHMucG9pbnRlckV4dGVuZCh0aGlzLCBldmVudCk7XG5cbiAgICBpZiAoZXZlbnQgIT09IHBvaW50ZXIpIHtcbiAgICAgIHBvaW50ZXJVdGlscy5wb2ludGVyRXh0ZW5kKHRoaXMsIHBvaW50ZXIpO1xuICAgIH1cblxuICAgIHRoaXMuaW50ZXJhY3Rpb24gPSBpbnRlcmFjdGlvbjtcblxuICAgIHRoaXMudGltZVN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgdGhpcy5vcmlnaW5hbEV2ZW50ID0gZXZlbnQ7XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB0aGlzLnBvaW50ZXJJZCA9IHBvaW50ZXJVdGlscy5nZXRQb2ludGVySWQocG9pbnRlcik7XG4gICAgdGhpcy5wb2ludGVyVHlwZSA9IHBvaW50ZXJVdGlscy5nZXRQb2ludGVyVHlwZShwb2ludGVyKTtcbiAgICB0aGlzLnRhcmdldCA9IGV2ZW50VGFyZ2V0O1xuICAgIHRoaXMuY3VycmVudFRhcmdldCA9IG51bGw7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3RhcCcpIHtcbiAgICAgIHZhciBwb2ludGVySW5kZXggPSBpbnRlcmFjdGlvbi5nZXRQb2ludGVySW5kZXgocG9pbnRlcik7XG4gICAgICB0aGlzLmR0ID0gdGhpcy50aW1lU3RhbXAgLSBpbnRlcmFjdGlvbi5kb3duVGltZXNbcG9pbnRlckluZGV4XTtcblxuICAgICAgdmFyIGludGVydmFsID0gdGhpcy50aW1lU3RhbXAgLSBpbnRlcmFjdGlvbi50YXBUaW1lO1xuXG4gICAgICB0aGlzLmRvdWJsZSA9ICEhKGludGVyYWN0aW9uLnByZXZUYXAgJiYgaW50ZXJhY3Rpb24ucHJldlRhcC50eXBlICE9PSAnZG91YmxldGFwJyAmJiBpbnRlcmFjdGlvbi5wcmV2VGFwLnRhcmdldCA9PT0gdGhpcy50YXJnZXQgJiYgaW50ZXJ2YWwgPCA1MDApO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2RvdWJsZXRhcCcpIHtcbiAgICAgIHRoaXMuZHQgPSBwb2ludGVyLnRpbWVTdGFtcCAtIGludGVyYWN0aW9uLnRhcFRpbWU7XG4gICAgfVxuICB9XG5cbiAgUG9pbnRlckV2ZW50LnByb3RvdHlwZS5zdWJ0cmFjdE9yaWdpbiA9IGZ1bmN0aW9uIHN1YnRyYWN0T3JpZ2luKF9yZWYpIHtcbiAgICB2YXIgb3JpZ2luWCA9IF9yZWYueCxcbiAgICAgICAgb3JpZ2luWSA9IF9yZWYueTtcblxuICAgIHRoaXMucGFnZVggLT0gb3JpZ2luWDtcbiAgICB0aGlzLnBhZ2VZIC09IG9yaWdpblk7XG4gICAgdGhpcy5jbGllbnRYIC09IG9yaWdpblg7XG4gICAgdGhpcy5jbGllbnRZIC09IG9yaWdpblk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBQb2ludGVyRXZlbnQucHJvdG90eXBlLmFkZE9yaWdpbiA9IGZ1bmN0aW9uIGFkZE9yaWdpbihfcmVmMikge1xuICAgIHZhciBvcmlnaW5YID0gX3JlZjIueCxcbiAgICAgICAgb3JpZ2luWSA9IF9yZWYyLnk7XG5cbiAgICB0aGlzLnBhZ2VYICs9IG9yaWdpblg7XG4gICAgdGhpcy5wYWdlWSArPSBvcmlnaW5ZO1xuICAgIHRoaXMuY2xpZW50WCArPSBvcmlnaW5YO1xuICAgIHRoaXMuY2xpZW50WSArPSBvcmlnaW5ZO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgUG9pbnRlckV2ZW50LnByb3RvdHlwZS5wcmV2ZW50RGVmYXVsdCA9IGZ1bmN0aW9uIHByZXZlbnREZWZhdWx0KCkge1xuICAgIHRoaXMub3JpZ2luYWxFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9O1xuXG4gIFBvaW50ZXJFdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKCkge1xuICAgIHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTtcbiAgfTtcblxuICBQb2ludGVyRXZlbnQucHJvdG90eXBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpIHtcbiAgICB0aGlzLmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9IHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTtcbiAgfTtcblxuICByZXR1cm4gUG9pbnRlckV2ZW50O1xufSgpO1xuXG59LHtcIi4uL3V0aWxzL3BvaW50ZXJVdGlsc1wiOjQ5fV0sMzE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUG9pbnRlckV2ZW50ID0gcmVxdWlyZSgnLi9Qb2ludGVyRXZlbnQnKTtcbnZhciBJbnRlcmFjdGlvbiA9IHJlcXVpcmUoJy4uL0ludGVyYWN0aW9uJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGJyb3dzZXIgPSByZXF1aXJlKCcuLi91dGlscy9icm93c2VyJyk7XG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuLi9kZWZhdWx0T3B0aW9ucycpO1xudmFyIHNpZ25hbHMgPSByZXF1aXJlKCcuLi91dGlscy9TaWduYWxzJykubmV3KCk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4uL3V0aWxzL2FycicpLFxuICAgIGZpbHRlciA9IF9yZXF1aXJlLmZpbHRlcjtcblxudmFyIHNpbXBsZVNpZ25hbHMgPSBbJ2Rvd24nLCAndXAnLCAnY2FuY2VsJ107XG52YXIgc2ltcGxlRXZlbnRzID0gWydkb3duJywgJ3VwJywgJ2NhbmNlbCddO1xuXG52YXIgcG9pbnRlckV2ZW50cyA9IHtcbiAgUG9pbnRlckV2ZW50OiBQb2ludGVyRXZlbnQsXG4gIGZpcmU6IGZpcmUsXG4gIGNvbGxlY3RFdmVudFRhcmdldHM6IGNvbGxlY3RFdmVudFRhcmdldHMsXG4gIHNpZ25hbHM6IHNpZ25hbHMsXG4gIGRlZmF1bHRzOiB7XG4gICAgaG9sZER1cmF0aW9uOiA2MDAsXG4gICAgaWdub3JlRnJvbTogbnVsbCxcbiAgICBhbGxvd0Zyb206IG51bGwsXG4gICAgb3JpZ2luOiB7IHg6IDAsIHk6IDAgfVxuICB9LFxuICB0eXBlczogWydkb3duJywgJ21vdmUnLCAndXAnLCAnY2FuY2VsJywgJ3RhcCcsICdkb3VibGV0YXAnLCAnaG9sZCddXG59O1xuXG5mdW5jdGlvbiBmaXJlKGFyZykge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBhcmcuaW50ZXJhY3Rpb24sXG4gICAgICBwb2ludGVyID0gYXJnLnBvaW50ZXIsXG4gICAgICBldmVudCA9IGFyZy5ldmVudCxcbiAgICAgIGV2ZW50VGFyZ2V0ID0gYXJnLmV2ZW50VGFyZ2V0LFxuICAgICAgX2FyZyR0eXBlID0gYXJnLnR5cGUsXG4gICAgICB0eXBlID0gX2FyZyR0eXBlID09PSB1bmRlZmluZWQgPyBhcmcucG9pbnRlckV2ZW50LnR5cGUgOiBfYXJnJHR5cGUsXG4gICAgICBfYXJnJHRhcmdldHMgPSBhcmcudGFyZ2V0cyxcbiAgICAgIHRhcmdldHMgPSBfYXJnJHRhcmdldHMgPT09IHVuZGVmaW5lZCA/IGNvbGxlY3RFdmVudFRhcmdldHMoYXJnKSA6IF9hcmckdGFyZ2V0cyxcbiAgICAgIF9hcmckcG9pbnRlckV2ZW50ID0gYXJnLnBvaW50ZXJFdmVudCxcbiAgICAgIHBvaW50ZXJFdmVudCA9IF9hcmckcG9pbnRlckV2ZW50ID09PSB1bmRlZmluZWQgPyBuZXcgUG9pbnRlckV2ZW50KHR5cGUsIHBvaW50ZXIsIGV2ZW50LCBldmVudFRhcmdldCwgaW50ZXJhY3Rpb24pIDogX2FyZyRwb2ludGVyRXZlbnQ7XG5cblxuICB2YXIgc2lnbmFsQXJnID0ge1xuICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcbiAgICBwb2ludGVyOiBwb2ludGVyLFxuICAgIGV2ZW50OiBldmVudCxcbiAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXG4gICAgdGFyZ2V0czogdGFyZ2V0cyxcbiAgICB0eXBlOiB0eXBlLFxuICAgIHBvaW50ZXJFdmVudDogcG9pbnRlckV2ZW50XG4gIH07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YXJnZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHRhcmdldCA9IHRhcmdldHNbaV07XG5cbiAgICBmb3IgKHZhciBwcm9wIGluIHRhcmdldC5wcm9wcyB8fCB7fSkge1xuICAgICAgcG9pbnRlckV2ZW50W3Byb3BdID0gdGFyZ2V0LnByb3BzW3Byb3BdO1xuICAgIH1cblxuICAgIHZhciBvcmlnaW4gPSB1dGlscy5nZXRPcmlnaW5YWSh0YXJnZXQuZXZlbnRhYmxlLCB0YXJnZXQuZWxlbWVudCk7XG5cbiAgICBwb2ludGVyRXZlbnQuc3VidHJhY3RPcmlnaW4ob3JpZ2luKTtcbiAgICBwb2ludGVyRXZlbnQuZXZlbnRhYmxlID0gdGFyZ2V0LmV2ZW50YWJsZTtcbiAgICBwb2ludGVyRXZlbnQuY3VycmVudFRhcmdldCA9IHRhcmdldC5lbGVtZW50O1xuXG4gICAgdGFyZ2V0LmV2ZW50YWJsZS5maXJlKHBvaW50ZXJFdmVudCk7XG5cbiAgICBwb2ludGVyRXZlbnQuYWRkT3JpZ2luKG9yaWdpbik7XG5cbiAgICBpZiAocG9pbnRlckV2ZW50LmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCB8fCBwb2ludGVyRXZlbnQucHJvcGFnYXRpb25TdG9wcGVkICYmIGkgKyAxIDwgdGFyZ2V0cy5sZW5ndGggJiYgdGFyZ2V0c1tpICsgMV0uZWxlbWVudCAhPT0gcG9pbnRlckV2ZW50LmN1cnJlbnRUYXJnZXQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHNpZ25hbHMuZmlyZSgnZmlyZWQnLCBzaWduYWxBcmcpO1xuXG4gIGlmICh0eXBlID09PSAndGFwJykge1xuICAgIC8vIGlmIHBvaW50ZXJFdmVudCBzaG91bGQgbWFrZSBhIGRvdWJsZSB0YXAsIGNyZWF0ZSBhbmQgZmlyZSBhIGRvdWJsZXRhcFxuICAgIC8vIFBvaW50ZXJFdmVudCBhbmQgdXNlIHRoYXQgYXMgdGhlIHByZXZUYXBcbiAgICB2YXIgcHJldlRhcCA9IHBvaW50ZXJFdmVudC5kb3VibGUgPyBmaXJlKHtcbiAgICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbiwgcG9pbnRlcjogcG9pbnRlciwgZXZlbnQ6IGV2ZW50LCBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXG4gICAgICB0eXBlOiAnZG91YmxldGFwJ1xuICAgIH0pIDogcG9pbnRlckV2ZW50O1xuXG4gICAgaW50ZXJhY3Rpb24ucHJldlRhcCA9IHByZXZUYXA7XG4gICAgaW50ZXJhY3Rpb24udGFwVGltZSA9IHByZXZUYXAudGltZVN0YW1wO1xuICB9XG5cbiAgcmV0dXJuIHBvaW50ZXJFdmVudDtcbn1cblxuZnVuY3Rpb24gY29sbGVjdEV2ZW50VGFyZ2V0cyhfcmVmKSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYuaW50ZXJhY3Rpb24sXG4gICAgICBwb2ludGVyID0gX3JlZi5wb2ludGVyLFxuICAgICAgZXZlbnQgPSBfcmVmLmV2ZW50LFxuICAgICAgZXZlbnRUYXJnZXQgPSBfcmVmLmV2ZW50VGFyZ2V0LFxuICAgICAgdHlwZSA9IF9yZWYudHlwZTtcblxuICB2YXIgcG9pbnRlckluZGV4ID0gaW50ZXJhY3Rpb24uZ2V0UG9pbnRlckluZGV4KHBvaW50ZXIpO1xuXG4gIC8vIGRvIG5vdCBmaXJlIGEgdGFwIGV2ZW50IGlmIHRoZSBwb2ludGVyIHdhcyBtb3ZlZCBiZWZvcmUgYmVpbmcgbGlmdGVkXG4gIGlmICh0eXBlID09PSAndGFwJyAmJiAoaW50ZXJhY3Rpb24ucG9pbnRlcldhc01vdmVkXG4gIC8vIG9yIGlmIHRoZSBwb2ludGVydXAgdGFyZ2V0IGlzIGRpZmZlcmVudCB0byB0aGUgcG9pbnRlcmRvd24gdGFyZ2V0XG4gIHx8ICEoaW50ZXJhY3Rpb24uZG93blRhcmdldHNbcG9pbnRlckluZGV4XSAmJiBpbnRlcmFjdGlvbi5kb3duVGFyZ2V0c1twb2ludGVySW5kZXhdID09PSBldmVudFRhcmdldCkpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgdmFyIHBhdGggPSB1dGlscy5nZXRQYXRoKGV2ZW50VGFyZ2V0KTtcbiAgdmFyIHNpZ25hbEFyZyA9IHtcbiAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXG4gICAgcG9pbnRlcjogcG9pbnRlcixcbiAgICBldmVudDogZXZlbnQsXG4gICAgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxuICAgIHR5cGU6IHR5cGUsXG4gICAgcGF0aDogcGF0aCxcbiAgICB0YXJnZXRzOiBbXSxcbiAgICBlbGVtZW50OiBudWxsXG4gIH07XG5cbiAgZm9yICh2YXIgX2l0ZXJhdG9yID0gcGF0aCwgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcbiAgICB2YXIgX3JlZjI7XG5cbiAgICBpZiAoX2lzQXJyYXkpIHtcbiAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcbiAgICAgIF9yZWYyID0gX2l0ZXJhdG9yW19pKytdO1xuICAgIH0gZWxzZSB7XG4gICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XG4gICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XG4gICAgICBfcmVmMiA9IF9pLnZhbHVlO1xuICAgIH1cblxuICAgIHZhciBlbGVtZW50ID0gX3JlZjI7XG5cbiAgICBzaWduYWxBcmcuZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgICBzaWduYWxzLmZpcmUoJ2NvbGxlY3QtdGFyZ2V0cycsIHNpZ25hbEFyZyk7XG4gIH1cblxuICBpZiAodHlwZSA9PT0gJ2hvbGQnKSB7XG4gICAgc2lnbmFsQXJnLnRhcmdldHMgPSBmaWx0ZXIoc2lnbmFsQXJnLnRhcmdldHMsIGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgIHJldHVybiB0YXJnZXQuZXZlbnRhYmxlLm9wdGlvbnMuaG9sZER1cmF0aW9uID09PSBpbnRlcmFjdGlvbi5ob2xkVGltZXJzW3BvaW50ZXJJbmRleF0uZHVyYXRpb247XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gc2lnbmFsQXJnLnRhcmdldHM7XG59XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3VwZGF0ZS1wb2ludGVyLWRvd24nLCBmdW5jdGlvbiAoX3JlZjMpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjMuaW50ZXJhY3Rpb24sXG4gICAgICBwb2ludGVySW5kZXggPSBfcmVmMy5wb2ludGVySW5kZXg7XG5cbiAgaW50ZXJhY3Rpb24uaG9sZFRpbWVyc1twb2ludGVySW5kZXhdID0geyBkdXJhdGlvbjogSW5maW5pdHksIHRpbWVvdXQ6IG51bGwgfTtcbn0pO1xuXG5JbnRlcmFjdGlvbi5zaWduYWxzLm9uKCdyZW1vdmUtcG9pbnRlcicsIGZ1bmN0aW9uIChfcmVmNCkge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmNC5pbnRlcmFjdGlvbixcbiAgICAgIHBvaW50ZXJJbmRleCA9IF9yZWY0LnBvaW50ZXJJbmRleDtcblxuICBpbnRlcmFjdGlvbi5ob2xkVGltZXJzLnNwbGljZShwb2ludGVySW5kZXgsIDEpO1xufSk7XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ21vdmUnLCBmdW5jdGlvbiAoX3JlZjUpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjUuaW50ZXJhY3Rpb24sXG4gICAgICBwb2ludGVyID0gX3JlZjUucG9pbnRlcixcbiAgICAgIGV2ZW50ID0gX3JlZjUuZXZlbnQsXG4gICAgICBldmVudFRhcmdldCA9IF9yZWY1LmV2ZW50VGFyZ2V0LFxuICAgICAgZHVwbGljYXRlTW92ZSA9IF9yZWY1LmR1cGxpY2F0ZU1vdmU7XG5cbiAgdmFyIHBvaW50ZXJJbmRleCA9IGludGVyYWN0aW9uLmdldFBvaW50ZXJJbmRleChwb2ludGVyKTtcblxuICBpZiAoIWR1cGxpY2F0ZU1vdmUgJiYgKCFpbnRlcmFjdGlvbi5wb2ludGVySXNEb3duIHx8IGludGVyYWN0aW9uLnBvaW50ZXJXYXNNb3ZlZCkpIHtcbiAgICBpZiAoaW50ZXJhY3Rpb24ucG9pbnRlcklzRG93bikge1xuICAgICAgY2xlYXJUaW1lb3V0KGludGVyYWN0aW9uLmhvbGRUaW1lcnNbcG9pbnRlckluZGV4XS50aW1lb3V0KTtcbiAgICB9XG5cbiAgICBmaXJlKHtcbiAgICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbiwgcG9pbnRlcjogcG9pbnRlciwgZXZlbnQ6IGV2ZW50LCBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXG4gICAgICB0eXBlOiAnbW92ZSdcbiAgICB9KTtcbiAgfVxufSk7XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ2Rvd24nLCBmdW5jdGlvbiAoX3JlZjYpIHtcbiAgdmFyIGludGVyYWN0aW9uID0gX3JlZjYuaW50ZXJhY3Rpb24sXG4gICAgICBwb2ludGVyID0gX3JlZjYucG9pbnRlcixcbiAgICAgIGV2ZW50ID0gX3JlZjYuZXZlbnQsXG4gICAgICBldmVudFRhcmdldCA9IF9yZWY2LmV2ZW50VGFyZ2V0LFxuICAgICAgcG9pbnRlckluZGV4ID0gX3JlZjYucG9pbnRlckluZGV4O1xuXG4gIC8vIGNvcHkgZXZlbnQgdG8gYmUgdXNlZCBpbiB0aW1lb3V0IGZvciBJRThcbiAgdmFyIGV2ZW50Q29weSA9IGJyb3dzZXIuaXNJRTggPyB1dGlscy5leHRlbmQoe30sIGV2ZW50KSA6IGV2ZW50O1xuXG4gIHZhciB0aW1lciA9IGludGVyYWN0aW9uLmhvbGRUaW1lcnNbcG9pbnRlckluZGV4XTtcbiAgdmFyIHBhdGggPSB1dGlscy5nZXRQYXRoKGV2ZW50VGFyZ2V0KTtcbiAgdmFyIHNpZ25hbEFyZyA9IHtcbiAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXG4gICAgcG9pbnRlcjogcG9pbnRlcixcbiAgICBldmVudDogZXZlbnQsXG4gICAgZXZlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxuICAgIHR5cGU6ICdob2xkJyxcbiAgICB0YXJnZXRzOiBbXSxcbiAgICBwYXRoOiBwYXRoLFxuICAgIGVsZW1lbnQ6IG51bGxcbiAgfTtcblxuICBmb3IgKHZhciBfaXRlcmF0b3IyID0gcGF0aCwgX2lzQXJyYXkyID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IyKSwgX2kyID0gMCwgX2l0ZXJhdG9yMiA9IF9pc0FycmF5MiA/IF9pdGVyYXRvcjIgOiBfaXRlcmF0b3IyW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgdmFyIF9yZWY3O1xuXG4gICAgaWYgKF9pc0FycmF5Mikge1xuICAgICAgaWYgKF9pMiA+PSBfaXRlcmF0b3IyLmxlbmd0aCkgYnJlYWs7XG4gICAgICBfcmVmNyA9IF9pdGVyYXRvcjJbX2kyKytdO1xuICAgIH0gZWxzZSB7XG4gICAgICBfaTIgPSBfaXRlcmF0b3IyLm5leHQoKTtcbiAgICAgIGlmIChfaTIuZG9uZSkgYnJlYWs7XG4gICAgICBfcmVmNyA9IF9pMi52YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgZWxlbWVudCA9IF9yZWY3O1xuXG4gICAgc2lnbmFsQXJnLmVsZW1lbnQgPSBlbGVtZW50O1xuXG4gICAgc2lnbmFscy5maXJlKCdjb2xsZWN0LXRhcmdldHMnLCBzaWduYWxBcmcpO1xuICB9XG5cbiAgaWYgKCFzaWduYWxBcmcudGFyZ2V0cy5sZW5ndGgpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbWluRHVyYXRpb24gPSBJbmZpbml0eTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ25hbEFyZy50YXJnZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHRhcmdldCA9IHNpZ25hbEFyZy50YXJnZXRzW2ldO1xuICAgIHZhciBob2xkRHVyYXRpb24gPSB0YXJnZXQuZXZlbnRhYmxlLm9wdGlvbnMuaG9sZER1cmF0aW9uO1xuXG4gICAgaWYgKGhvbGREdXJhdGlvbiA8IG1pbkR1cmF0aW9uKSB7XG4gICAgICBtaW5EdXJhdGlvbiA9IGhvbGREdXJhdGlvbjtcbiAgICB9XG4gIH1cblxuICB0aW1lci5kdXJhdGlvbiA9IG1pbkR1cmF0aW9uO1xuICB0aW1lci50aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgZmlyZSh7XG4gICAgICBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sXG4gICAgICBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsXG4gICAgICBwb2ludGVyOiBicm93c2VyLmlzSUU4ID8gZXZlbnRDb3B5IDogcG9pbnRlcixcbiAgICAgIGV2ZW50OiBldmVudENvcHksXG4gICAgICB0eXBlOiAnaG9sZCdcbiAgICB9KTtcbiAgfSwgbWluRHVyYXRpb24pO1xufSk7XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ3VwJywgZnVuY3Rpb24gKF9yZWY4KSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY4LmludGVyYWN0aW9uLFxuICAgICAgcG9pbnRlciA9IF9yZWY4LnBvaW50ZXIsXG4gICAgICBldmVudCA9IF9yZWY4LmV2ZW50LFxuICAgICAgZXZlbnRUYXJnZXQgPSBfcmVmOC5ldmVudFRhcmdldDtcblxuICBpZiAoIWludGVyYWN0aW9uLnBvaW50ZXJXYXNNb3ZlZCkge1xuICAgIGZpcmUoeyBpbnRlcmFjdGlvbjogaW50ZXJhY3Rpb24sIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCwgcG9pbnRlcjogcG9pbnRlciwgZXZlbnQ6IGV2ZW50LCB0eXBlOiAndGFwJyB9KTtcbiAgfVxufSk7XG5cblsndXAnLCAnY2FuY2VsJ10uZm9yRWFjaChmdW5jdGlvbiAoc2lnbmFsTmFtZSkge1xuICBJbnRlcmFjdGlvbi5zaWduYWxzLm9uKHNpZ25hbE5hbWUsIGZ1bmN0aW9uIChfcmVmOSkge1xuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY5LmludGVyYWN0aW9uLFxuICAgICAgICBwb2ludGVySW5kZXggPSBfcmVmOS5wb2ludGVySW5kZXg7XG5cbiAgICBpZiAoaW50ZXJhY3Rpb24uaG9sZFRpbWVyc1twb2ludGVySW5kZXhdKSB7XG4gICAgICBjbGVhclRpbWVvdXQoaW50ZXJhY3Rpb24uaG9sZFRpbWVyc1twb2ludGVySW5kZXhdLnRpbWVvdXQpO1xuICAgIH1cbiAgfSk7XG59KTtcblxuZnVuY3Rpb24gY3JlYXRlU2lnbmFsTGlzdGVuZXIodHlwZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKF9yZWYxMCkge1xuICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYxMC5pbnRlcmFjdGlvbixcbiAgICAgICAgcG9pbnRlciA9IF9yZWYxMC5wb2ludGVyLFxuICAgICAgICBldmVudCA9IF9yZWYxMC5ldmVudCxcbiAgICAgICAgZXZlbnRUYXJnZXQgPSBfcmVmMTAuZXZlbnRUYXJnZXQ7XG5cbiAgICBmaXJlKHsgaW50ZXJhY3Rpb246IGludGVyYWN0aW9uLCBldmVudFRhcmdldDogZXZlbnRUYXJnZXQsIHBvaW50ZXI6IHBvaW50ZXIsIGV2ZW50OiBldmVudCwgdHlwZTogdHlwZSB9KTtcbiAgfTtcbn1cblxuZm9yICh2YXIgaSA9IDA7IGkgPCBzaW1wbGVTaWduYWxzLmxlbmd0aDsgaSsrKSB7XG4gIEludGVyYWN0aW9uLnNpZ25hbHMub24oc2ltcGxlU2lnbmFsc1tpXSwgY3JlYXRlU2lnbmFsTGlzdGVuZXIoc2ltcGxlRXZlbnRzW2ldKSk7XG59XG5cbkludGVyYWN0aW9uLnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xuICBpbnRlcmFjdGlvbi5wcmV2VGFwID0gbnVsbDsgLy8gdGhlIG1vc3QgcmVjZW50IHRhcCBldmVudCBvbiB0aGlzIGludGVyYWN0aW9uXG4gIGludGVyYWN0aW9uLnRhcFRpbWUgPSAwOyAvLyB0aW1lIG9mIHRoZSBtb3N0IHJlY2VudCB0YXAgZXZlbnRcbiAgaW50ZXJhY3Rpb24uaG9sZFRpbWVycyA9IFtdOyAvLyBbeyBkdXJhdGlvbiwgdGltZW91dCB9XVxufSk7XG5cbmRlZmF1bHRzLnBvaW50ZXJFdmVudHMgPSBwb2ludGVyRXZlbnRzLmRlZmF1bHRzO1xubW9kdWxlLmV4cG9ydHMgPSBwb2ludGVyRXZlbnRzO1xuXG59LHtcIi4uL0ludGVyYWN0aW9uXCI6NSxcIi4uL2RlZmF1bHRPcHRpb25zXCI6MTgsXCIuLi91dGlsc1wiOjQ0LFwiLi4vdXRpbHMvU2lnbmFsc1wiOjM1LFwiLi4vdXRpbHMvYXJyXCI6MzYsXCIuLi91dGlscy9icm93c2VyXCI6MzcsXCIuL1BvaW50ZXJFdmVudFwiOjMwfV0sMzI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgcG9pbnRlckV2ZW50cyA9IHJlcXVpcmUoJy4vYmFzZScpO1xudmFyIEludGVyYWN0aW9uID0gcmVxdWlyZSgnLi4vSW50ZXJhY3Rpb24nKTtcblxucG9pbnRlckV2ZW50cy5zaWduYWxzLm9uKCduZXcnLCBvbk5ldyk7XG5wb2ludGVyRXZlbnRzLnNpZ25hbHMub24oJ2ZpcmVkJywgb25GaXJlZCk7XG5cbnZhciBfYXJyID0gWydtb3ZlJywgJ3VwJywgJ2NhbmNlbCcsICdlbmRhbGwnXTtcbmZvciAodmFyIF9pID0gMDsgX2kgPCBfYXJyLmxlbmd0aDsgX2krKykge1xuICB2YXIgc2lnbmFsID0gX2FycltfaV07XG4gIEludGVyYWN0aW9uLnNpZ25hbHMub24oc2lnbmFsLCBlbmRIb2xkUmVwZWF0KTtcbn1cblxuZnVuY3Rpb24gb25OZXcoX3JlZikge1xuICB2YXIgcG9pbnRlckV2ZW50ID0gX3JlZi5wb2ludGVyRXZlbnQ7XG5cbiAgaWYgKHBvaW50ZXJFdmVudC50eXBlICE9PSAnaG9sZCcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwb2ludGVyRXZlbnQuY291bnQgPSAocG9pbnRlckV2ZW50LmNvdW50IHx8IDApICsgMTtcbn1cblxuZnVuY3Rpb24gb25GaXJlZChfcmVmMikge1xuICB2YXIgaW50ZXJhY3Rpb24gPSBfcmVmMi5pbnRlcmFjdGlvbixcbiAgICAgIHBvaW50ZXJFdmVudCA9IF9yZWYyLnBvaW50ZXJFdmVudCxcbiAgICAgIGV2ZW50VGFyZ2V0ID0gX3JlZjIuZXZlbnRUYXJnZXQsXG4gICAgICB0YXJnZXRzID0gX3JlZjIudGFyZ2V0cztcblxuICBpZiAocG9pbnRlckV2ZW50LnR5cGUgIT09ICdob2xkJyB8fCAhdGFyZ2V0cy5sZW5ndGgpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBnZXQgdGhlIHJlcGVhdCBpbnRlcnZhbCBmcm9tIHRoZSBmaXJzdCBldmVudGFibGVcbiAgdmFyIGludGVydmFsID0gdGFyZ2V0c1swXS5ldmVudGFibGUub3B0aW9ucy5ob2xkUmVwZWF0SW50ZXJ2YWw7XG5cbiAgLy8gZG9uJ3QgcmVwZWF0IGlmIHRoZSBpbnRlcnZhbCBpcyAwIG9yIGxlc3NcbiAgaWYgKGludGVydmFsIDw9IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBzZXQgYSB0aW1lb3V0IHRvIGZpcmUgdGhlIGhvbGRyZXBlYXQgZXZlbnRcbiAgaW50ZXJhY3Rpb24uaG9sZEludGVydmFsSGFuZGxlID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgcG9pbnRlckV2ZW50cy5maXJlKHtcbiAgICAgIGludGVyYWN0aW9uOiBpbnRlcmFjdGlvbixcbiAgICAgIGV2ZW50VGFyZ2V0OiBldmVudFRhcmdldCxcbiAgICAgIHR5cGU6ICdob2xkJyxcbiAgICAgIHBvaW50ZXI6IHBvaW50ZXJFdmVudCxcbiAgICAgIGV2ZW50OiBwb2ludGVyRXZlbnRcbiAgICB9KTtcbiAgfSwgaW50ZXJ2YWwpO1xufVxuXG5mdW5jdGlvbiBlbmRIb2xkUmVwZWF0KF9yZWYzKSB7XG4gIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzLmludGVyYWN0aW9uO1xuXG4gIC8vIHNldCB0aGUgaW50ZXJhY3Rpb24ncyBob2xkU3RvcFRpbWUgcHJvcGVydHlcbiAgLy8gdG8gc3RvcCBmdXJ0aGVyIGhvbGRSZXBlYXQgZXZlbnRzXG4gIGlmIChpbnRlcmFjdGlvbi5ob2xkSW50ZXJ2YWxIYW5kbGUpIHtcbiAgICBjbGVhckludGVydmFsKGludGVyYWN0aW9uLmhvbGRJbnRlcnZhbEhhbmRsZSk7XG4gICAgaW50ZXJhY3Rpb24uaG9sZEludGVydmFsSGFuZGxlID0gbnVsbDtcbiAgfVxufVxuXG4vLyBkb24ndCByZXBlYXQgYnkgZGVmYXVsdFxucG9pbnRlckV2ZW50cy5kZWZhdWx0cy5ob2xkUmVwZWF0SW50ZXJ2YWwgPSAwO1xucG9pbnRlckV2ZW50cy50eXBlcy5wdXNoKCdob2xkcmVwZWF0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBvbk5ldzogb25OZXcsXG4gIG9uRmlyZWQ6IG9uRmlyZWQsXG4gIGVuZEhvbGRSZXBlYXQ6IGVuZEhvbGRSZXBlYXRcbn07XG5cbn0se1wiLi4vSW50ZXJhY3Rpb25cIjo1LFwiLi9iYXNlXCI6MzF9XSwzMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBwb2ludGVyRXZlbnRzID0gcmVxdWlyZSgnLi9iYXNlJyk7XG52YXIgSW50ZXJhY3RhYmxlID0gcmVxdWlyZSgnLi4vSW50ZXJhY3RhYmxlJyk7XG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4uL3V0aWxzL2Jyb3dzZXInKTtcbnZhciBpcyA9IHJlcXVpcmUoJy4uL3V0aWxzL2lzJyk7XG52YXIgZG9tVXRpbHMgPSByZXF1aXJlKCcuLi91dGlscy9kb21VdGlscycpO1xudmFyIHNjb3BlID0gcmVxdWlyZSgnLi4vc2NvcGUnKTtcbnZhciBleHRlbmQgPSByZXF1aXJlKCcuLi91dGlscy9leHRlbmQnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi4vdXRpbHMvYXJyJyksXG4gICAgbWVyZ2UgPSBfcmVxdWlyZS5tZXJnZTtcblxucG9pbnRlckV2ZW50cy5zaWduYWxzLm9uKCdjb2xsZWN0LXRhcmdldHMnLCBmdW5jdGlvbiAoX3JlZikge1xuICB2YXIgdGFyZ2V0cyA9IF9yZWYudGFyZ2V0cyxcbiAgICAgIGVsZW1lbnQgPSBfcmVmLmVsZW1lbnQsXG4gICAgICB0eXBlID0gX3JlZi50eXBlLFxuICAgICAgZXZlbnRUYXJnZXQgPSBfcmVmLmV2ZW50VGFyZ2V0O1xuXG4gIGZ1bmN0aW9uIGNvbGxlY3RTZWxlY3RvcnMoaW50ZXJhY3RhYmxlLCBzZWxlY3RvciwgY29udGV4dCkge1xuICAgIHZhciBlbHMgPSBicm93c2VyLnVzZU1hdGNoZXNTZWxlY3RvclBvbHlmaWxsID8gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSA6IHVuZGVmaW5lZDtcblxuICAgIHZhciBldmVudGFibGUgPSBpbnRlcmFjdGFibGUuZXZlbnRzO1xuICAgIHZhciBvcHRpb25zID0gZXZlbnRhYmxlLm9wdGlvbnM7XG5cbiAgICBpZiAoZXZlbnRhYmxlW3R5cGVdICYmIGlzLmVsZW1lbnQoZWxlbWVudCkgJiYgZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yLCBlbHMpICYmIGludGVyYWN0YWJsZS50ZXN0SWdub3JlQWxsb3cob3B0aW9ucywgZWxlbWVudCwgZXZlbnRUYXJnZXQpKSB7XG5cbiAgICAgIHRhcmdldHMucHVzaCh7XG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGV2ZW50YWJsZTogZXZlbnRhYmxlLFxuICAgICAgICBwcm9wczogeyBpbnRlcmFjdGFibGU6IGludGVyYWN0YWJsZSB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICB2YXIgaW50ZXJhY3RhYmxlID0gc2NvcGUuaW50ZXJhY3RhYmxlcy5nZXQoZWxlbWVudCk7XG5cbiAgaWYgKGludGVyYWN0YWJsZSkge1xuICAgIHZhciBldmVudGFibGUgPSBpbnRlcmFjdGFibGUuZXZlbnRzO1xuICAgIHZhciBvcHRpb25zID0gZXZlbnRhYmxlLm9wdGlvbnM7XG5cbiAgICBpZiAoZXZlbnRhYmxlW3R5cGVdICYmIGludGVyYWN0YWJsZS50ZXN0SWdub3JlQWxsb3cob3B0aW9ucywgZWxlbWVudCwgZXZlbnRUYXJnZXQpKSB7XG4gICAgICB0YXJnZXRzLnB1c2goe1xuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBldmVudGFibGU6IGV2ZW50YWJsZSxcbiAgICAgICAgcHJvcHM6IHsgaW50ZXJhY3RhYmxlOiBpbnRlcmFjdGFibGUgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc2NvcGUuaW50ZXJhY3RhYmxlcy5mb3JFYWNoU2VsZWN0b3IoY29sbGVjdFNlbGVjdG9ycywgZWxlbWVudCk7XG59KTtcblxuSW50ZXJhY3RhYmxlLnNpZ25hbHMub24oJ25ldycsIGZ1bmN0aW9uIChfcmVmMikge1xuICB2YXIgaW50ZXJhY3RhYmxlID0gX3JlZjIuaW50ZXJhY3RhYmxlO1xuXG4gIGludGVyYWN0YWJsZS5ldmVudHMuZ2V0UmVjdCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgcmV0dXJuIGludGVyYWN0YWJsZS5nZXRSZWN0KGVsZW1lbnQpO1xuICB9O1xufSk7XG5cbkludGVyYWN0YWJsZS5zaWduYWxzLm9uKCdzZXQnLCBmdW5jdGlvbiAoX3JlZjMpIHtcbiAgdmFyIGludGVyYWN0YWJsZSA9IF9yZWYzLmludGVyYWN0YWJsZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmMy5vcHRpb25zO1xuXG4gIGV4dGVuZChpbnRlcmFjdGFibGUuZXZlbnRzLm9wdGlvbnMsIHBvaW50ZXJFdmVudHMuZGVmYXVsdHMpO1xuICBleHRlbmQoaW50ZXJhY3RhYmxlLmV2ZW50cy5vcHRpb25zLCBvcHRpb25zKTtcbn0pO1xuXG5tZXJnZShJbnRlcmFjdGFibGUuZXZlbnRUeXBlcywgcG9pbnRlckV2ZW50cy50eXBlcyk7XG5cbkludGVyYWN0YWJsZS5wcm90b3R5cGUucG9pbnRlckV2ZW50cyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIGV4dGVuZCh0aGlzLmV2ZW50cy5vcHRpb25zLCBvcHRpb25zKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbnZhciBfX2JhY2tDb21wYXRPcHRpb24gPSBJbnRlcmFjdGFibGUucHJvdG90eXBlLl9iYWNrQ29tcGF0T3B0aW9uO1xuXG5JbnRlcmFjdGFibGUucHJvdG90eXBlLl9iYWNrQ29tcGF0T3B0aW9uID0gZnVuY3Rpb24gKG9wdGlvbk5hbWUsIG5ld1ZhbHVlKSB7XG4gIHZhciByZXQgPSBfX2JhY2tDb21wYXRPcHRpb24uY2FsbCh0aGlzLCBvcHRpb25OYW1lLCBuZXdWYWx1ZSk7XG5cbiAgaWYgKHJldCA9PT0gdGhpcykge1xuICAgIHRoaXMuZXZlbnRzLm9wdGlvbnNbb3B0aW9uTmFtZV0gPSBuZXdWYWx1ZTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuXG5JbnRlcmFjdGFibGUuc2V0dGluZ3NNZXRob2RzLnB1c2goJ3BvaW50ZXJFdmVudHMnKTtcblxufSx7XCIuLi9JbnRlcmFjdGFibGVcIjo0LFwiLi4vc2NvcGVcIjozNCxcIi4uL3V0aWxzL2FyclwiOjM2LFwiLi4vdXRpbHMvYnJvd3NlclwiOjM3LFwiLi4vdXRpbHMvZG9tVXRpbHNcIjozOSxcIi4uL3V0aWxzL2V4dGVuZFwiOjQxLFwiLi4vdXRpbHMvaXNcIjo0NixcIi4vYmFzZVwiOjMxfV0sMzQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgZXZlbnRzID0gcmVxdWlyZSgnLi91dGlscy9ldmVudHMnKTtcbnZhciBzaWduYWxzID0gcmVxdWlyZSgnLi91dGlscy9TaWduYWxzJykubmV3KCk7XG5cbnZhciBzY29wZSA9IHtcbiAgc2lnbmFsczogc2lnbmFscyxcbiAgZXZlbnRzOiBldmVudHMsXG4gIHV0aWxzOiB1dGlscyxcblxuICAvLyBtYWluIGRvY3VtZW50XG4gIGRvY3VtZW50OiByZXF1aXJlKCcuL3V0aWxzL2RvbU9iamVjdHMnKS5kb2N1bWVudCxcbiAgLy8gYWxsIGRvY3VtZW50cyBiZWluZyBsaXN0ZW5lZCB0b1xuICBkb2N1bWVudHM6IFtdLFxuXG4gIGFkZERvY3VtZW50OiBmdW5jdGlvbiBhZGREb2N1bWVudChkb2MsIHdpbikge1xuICAgIC8vIGRvIG5vdGhpbmcgaWYgZG9jdW1lbnQgaXMgYWxyZWFkeSBrbm93blxuICAgIGlmICh1dGlscy5jb250YWlucyhzY29wZS5kb2N1bWVudHMsIGRvYykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB3aW4gPSB3aW4gfHwgc2NvcGUuZ2V0V2luZG93KGRvYyk7XG5cbiAgICBzY29wZS5kb2N1bWVudHMucHVzaChkb2MpO1xuICAgIGV2ZW50cy5kb2N1bWVudHMucHVzaChkb2MpO1xuXG4gICAgLy8gZG9uJ3QgYWRkIGFuIHVubG9hZCBldmVudCBmb3IgdGhlIG1haW4gZG9jdW1lbnRcbiAgICAvLyBzbyB0aGF0IHRoZSBwYWdlIG1heSBiZSBjYWNoZWQgaW4gYnJvd3NlciBoaXN0b3J5XG4gICAgaWYgKGRvYyAhPT0gc2NvcGUuZG9jdW1lbnQpIHtcbiAgICAgIGV2ZW50cy5hZGQod2luLCAndW5sb2FkJywgc2NvcGUub25XaW5kb3dVbmxvYWQpO1xuICAgIH1cblxuICAgIHNpZ25hbHMuZmlyZSgnYWRkLWRvY3VtZW50JywgeyBkb2M6IGRvYywgd2luOiB3aW4gfSk7XG4gIH0sXG5cbiAgcmVtb3ZlRG9jdW1lbnQ6IGZ1bmN0aW9uIHJlbW92ZURvY3VtZW50KGRvYywgd2luKSB7XG4gICAgdmFyIGluZGV4ID0gdXRpbHMuaW5kZXhPZihzY29wZS5kb2N1bWVudHMsIGRvYyk7XG5cbiAgICB3aW4gPSB3aW4gfHwgc2NvcGUuZ2V0V2luZG93KGRvYyk7XG5cbiAgICBldmVudHMucmVtb3ZlKHdpbiwgJ3VubG9hZCcsIHNjb3BlLm9uV2luZG93VW5sb2FkKTtcblxuICAgIHNjb3BlLmRvY3VtZW50cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIGV2ZW50cy5kb2N1bWVudHMuc3BsaWNlKGluZGV4LCAxKTtcblxuICAgIHNpZ25hbHMuZmlyZSgncmVtb3ZlLWRvY3VtZW50JywgeyB3aW46IHdpbiwgZG9jOiBkb2MgfSk7XG4gIH0sXG5cbiAgb25XaW5kb3dVbmxvYWQ6IGZ1bmN0aW9uIG9uV2luZG93VW5sb2FkKCkge1xuICAgIHNjb3BlLnJlbW92ZURvY3VtZW50KHRoaXMuZG9jdW1lbnQsIHRoaXMpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNjb3BlO1xuXG59LHtcIi4vdXRpbHNcIjo0NCxcIi4vdXRpbHMvU2lnbmFsc1wiOjM1LFwiLi91dGlscy9kb21PYmplY3RzXCI6MzgsXCIuL3V0aWxzL2V2ZW50c1wiOjQwfV0sMzU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL2FycicpLFxuICAgIGluZGV4T2YgPSBfcmVxdWlyZS5pbmRleE9mO1xuXG52YXIgU2lnbmFscyA9IGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gU2lnbmFscygpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU2lnbmFscyk7XG5cbiAgICB0aGlzLmxpc3RlbmVycyA9IHtcbiAgICAgIC8vIHNpZ25hbE5hbWU6IFtsaXN0ZW5lcnNdLFxuICAgIH07XG4gIH1cblxuICBTaWduYWxzLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKG5hbWUsIGxpc3RlbmVyKSB7XG4gICAgaWYgKCF0aGlzLmxpc3RlbmVyc1tuYW1lXSkge1xuICAgICAgdGhpcy5saXN0ZW5lcnNbbmFtZV0gPSBbbGlzdGVuZXJdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubGlzdGVuZXJzW25hbWVdLnB1c2gobGlzdGVuZXIpO1xuICB9O1xuXG4gIFNpZ25hbHMucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIG9mZihuYW1lLCBsaXN0ZW5lcikge1xuICAgIGlmICghdGhpcy5saXN0ZW5lcnNbbmFtZV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgaW5kZXggPSBpbmRleE9mKHRoaXMubGlzdGVuZXJzW25hbWVdLCBsaXN0ZW5lcik7XG5cbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICB0aGlzLmxpc3RlbmVyc1tuYW1lXS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgfTtcblxuICBTaWduYWxzLnByb3RvdHlwZS5maXJlID0gZnVuY3Rpb24gZmlyZShuYW1lLCBhcmcpIHtcbiAgICB2YXIgdGFyZ2V0TGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnNbbmFtZV07XG5cbiAgICBpZiAoIXRhcmdldExpc3RlbmVycykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFyZ2V0TGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGFyZ2V0TGlzdGVuZXJzW2ldKGFyZywgbmFtZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIFNpZ25hbHM7XG59KCk7XG5cblNpZ25hbHMubmV3ID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IFNpZ25hbHMoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gU2lnbmFscztcblxufSx7XCIuL2FyclwiOjM2fV0sMzY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbmZ1bmN0aW9uIGluZGV4T2YoYXJyYXksIHRhcmdldCkge1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoYXJyYXlbaV0gPT09IHRhcmdldCkge1xuICAgICAgcmV0dXJuIGk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIC0xO1xufVxuXG5mdW5jdGlvbiBjb250YWlucyhhcnJheSwgdGFyZ2V0KSB7XG4gIHJldHVybiBpbmRleE9mKGFycmF5LCB0YXJnZXQpICE9PSAtMTtcbn1cblxuZnVuY3Rpb24gbWVyZ2UodGFyZ2V0LCBzb3VyY2UpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyBpKyspIHtcbiAgICB0YXJnZXQucHVzaChzb3VyY2VbaV0pO1xuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuZnVuY3Rpb24gZmlsdGVyKGFycmF5LCB0ZXN0KSB7XG4gIHZhciByZXN1bHQgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRlc3QoYXJyYXlbaV0pKSB7XG4gICAgICByZXN1bHQucHVzaChhcnJheVtpXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGluZGV4T2Y6IGluZGV4T2YsXG4gIGNvbnRhaW5zOiBjb250YWlucyxcbiAgbWVyZ2U6IG1lcmdlLFxuICBmaWx0ZXI6IGZpbHRlclxufTtcblxufSx7fV0sMzc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL3dpbmRvdycpLFxuICAgIHdpbmRvdyA9IF9yZXF1aXJlLndpbmRvdztcblxudmFyIGlzID0gcmVxdWlyZSgnLi9pcycpO1xudmFyIGRvbU9iamVjdHMgPSByZXF1aXJlKCcuL2RvbU9iamVjdHMnKTtcblxudmFyIEVsZW1lbnQgPSBkb21PYmplY3RzLkVsZW1lbnQ7XG52YXIgbmF2aWdhdG9yID0gd2luZG93Lm5hdmlnYXRvcjtcblxudmFyIGJyb3dzZXIgPSB7XG4gIC8vIERvZXMgdGhlIGJyb3dzZXIgc3VwcG9ydCB0b3VjaCBpbnB1dD9cbiAgc3VwcG9ydHNUb3VjaDogISEoJ29udG91Y2hzdGFydCcgaW4gd2luZG93IHx8IGlzLmZ1bmN0aW9uKHdpbmRvdy5Eb2N1bWVudFRvdWNoKSAmJiBkb21PYmplY3RzLmRvY3VtZW50IGluc3RhbmNlb2Ygd2luZG93LkRvY3VtZW50VG91Y2gpLFxuXG4gIC8vIERvZXMgdGhlIGJyb3dzZXIgc3VwcG9ydCBQb2ludGVyRXZlbnRzXG4gIHN1cHBvcnRzUG9pbnRlckV2ZW50OiAhIWRvbU9iamVjdHMuUG9pbnRlckV2ZW50LFxuXG4gIGlzSUU4OiAnYXR0YWNoRXZlbnQnIGluIHdpbmRvdyAmJiAhKCdhZGRFdmVudExpc3RlbmVyJyBpbiB3aW5kb3cpLFxuXG4gIC8vIE9wZXJhIE1vYmlsZSBtdXN0IGJlIGhhbmRsZWQgZGlmZmVyZW50bHlcbiAgaXNPcGVyYU1vYmlsZTogbmF2aWdhdG9yLmFwcE5hbWUgPT09ICdPcGVyYScgJiYgYnJvd3Nlci5zdXBwb3J0c1RvdWNoICYmIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goJ1ByZXN0bycpLFxuXG4gIC8vIHNjcm9sbGluZyBkb2Vzbid0IGNoYW5nZSB0aGUgcmVzdWx0IG9mIGdldENsaWVudFJlY3RzIG9uIGlPUyA3XG4gIGlzSU9TNzogL2lQKGhvbmV8b2R8YWQpLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSkgJiYgL09TIDdbXlxcZF0vLnRlc3QobmF2aWdhdG9yLmFwcFZlcnNpb24pLFxuXG4gIGlzSWU5T3JPbGRlcjogL01TSUUgKDh8OSkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCksXG5cbiAgLy8gcHJlZml4IG1hdGNoZXNTZWxlY3RvclxuICBwcmVmaXhlZE1hdGNoZXNTZWxlY3RvcjogJ21hdGNoZXMnIGluIEVsZW1lbnQucHJvdG90eXBlID8gJ21hdGNoZXMnIDogJ3dlYmtpdE1hdGNoZXNTZWxlY3RvcicgaW4gRWxlbWVudC5wcm90b3R5cGUgPyAnd2Via2l0TWF0Y2hlc1NlbGVjdG9yJyA6ICdtb3pNYXRjaGVzU2VsZWN0b3InIGluIEVsZW1lbnQucHJvdG90eXBlID8gJ21vek1hdGNoZXNTZWxlY3RvcicgOiAnb01hdGNoZXNTZWxlY3RvcicgaW4gRWxlbWVudC5wcm90b3R5cGUgPyAnb01hdGNoZXNTZWxlY3RvcicgOiAnbXNNYXRjaGVzU2VsZWN0b3InLFxuXG4gIHVzZU1hdGNoZXNTZWxlY3RvclBvbHlmaWxsOiBmYWxzZSxcblxuICBwRXZlbnRUeXBlczogZG9tT2JqZWN0cy5Qb2ludGVyRXZlbnQgPyBkb21PYmplY3RzLlBvaW50ZXJFdmVudCA9PT0gd2luZG93Lk1TUG9pbnRlckV2ZW50ID8ge1xuICAgIHVwOiAnTVNQb2ludGVyVXAnLFxuICAgIGRvd246ICdNU1BvaW50ZXJEb3duJyxcbiAgICBvdmVyOiAnbW91c2VvdmVyJyxcbiAgICBvdXQ6ICdtb3VzZW91dCcsXG4gICAgbW92ZTogJ01TUG9pbnRlck1vdmUnLFxuICAgIGNhbmNlbDogJ01TUG9pbnRlckNhbmNlbCdcbiAgfSA6IHtcbiAgICB1cDogJ3BvaW50ZXJ1cCcsXG4gICAgZG93bjogJ3BvaW50ZXJkb3duJyxcbiAgICBvdmVyOiAncG9pbnRlcm92ZXInLFxuICAgIG91dDogJ3BvaW50ZXJvdXQnLFxuICAgIG1vdmU6ICdwb2ludGVybW92ZScsXG4gICAgY2FuY2VsOiAncG9pbnRlcmNhbmNlbCdcbiAgfSA6IG51bGwsXG5cbiAgLy8gYmVjYXVzZSBXZWJraXQgYW5kIE9wZXJhIHN0aWxsIHVzZSAnbW91c2V3aGVlbCcgZXZlbnQgdHlwZVxuICB3aGVlbEV2ZW50OiAnb25tb3VzZXdoZWVsJyBpbiBkb21PYmplY3RzLmRvY3VtZW50ID8gJ21vdXNld2hlZWwnIDogJ3doZWVsJ1xuXG59O1xuXG5icm93c2VyLnVzZU1hdGNoZXNTZWxlY3RvclBvbHlmaWxsID0gIWlzLmZ1bmN0aW9uKEVsZW1lbnQucHJvdG90eXBlW2Jyb3dzZXIucHJlZml4ZWRNYXRjaGVzU2VsZWN0b3JdKTtcblxubW9kdWxlLmV4cG9ydHMgPSBicm93c2VyO1xuXG59LHtcIi4vZG9tT2JqZWN0c1wiOjM4LFwiLi9pc1wiOjQ2LFwiLi93aW5kb3dcIjo1Mn1dLDM4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGRvbU9iamVjdHMgPSB7fTtcbnZhciB3aW4gPSByZXF1aXJlKCcuL3dpbmRvdycpLndpbmRvdztcblxuZnVuY3Rpb24gYmxhbmsoKSB7fVxuXG5kb21PYmplY3RzLmRvY3VtZW50ID0gd2luLmRvY3VtZW50O1xuZG9tT2JqZWN0cy5Eb2N1bWVudEZyYWdtZW50ID0gd2luLkRvY3VtZW50RnJhZ21lbnQgfHwgYmxhbms7XG5kb21PYmplY3RzLlNWR0VsZW1lbnQgPSB3aW4uU1ZHRWxlbWVudCB8fCBibGFuaztcbmRvbU9iamVjdHMuU1ZHU1ZHRWxlbWVudCA9IHdpbi5TVkdTVkdFbGVtZW50IHx8IGJsYW5rO1xuZG9tT2JqZWN0cy5TVkdFbGVtZW50SW5zdGFuY2UgPSB3aW4uU1ZHRWxlbWVudEluc3RhbmNlIHx8IGJsYW5rO1xuZG9tT2JqZWN0cy5FbGVtZW50ID0gd2luLkVsZW1lbnQgfHwgYmxhbms7XG5kb21PYmplY3RzLkhUTUxFbGVtZW50ID0gd2luLkhUTUxFbGVtZW50IHx8IGRvbU9iamVjdHMuRWxlbWVudDtcblxuZG9tT2JqZWN0cy5FdmVudCA9IHdpbi5FdmVudDtcbmRvbU9iamVjdHMuVG91Y2ggPSB3aW4uVG91Y2ggfHwgYmxhbms7XG5kb21PYmplY3RzLlBvaW50ZXJFdmVudCA9IHdpbi5Qb2ludGVyRXZlbnQgfHwgd2luLk1TUG9pbnRlckV2ZW50O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRvbU9iamVjdHM7XG5cbn0se1wiLi93aW5kb3dcIjo1Mn1dLDM5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIHdpbiA9IHJlcXVpcmUoJy4vd2luZG93Jyk7XG52YXIgYnJvd3NlciA9IHJlcXVpcmUoJy4vYnJvd3NlcicpO1xudmFyIGlzID0gcmVxdWlyZSgnLi9pcycpO1xudmFyIGRvbU9iamVjdHMgPSByZXF1aXJlKCcuL2RvbU9iamVjdHMnKTtcblxudmFyIGRvbVV0aWxzID0ge1xuICBub2RlQ29udGFpbnM6IGZ1bmN0aW9uIG5vZGVDb250YWlucyhwYXJlbnQsIGNoaWxkKSB7XG4gICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICBpZiAoY2hpbGQgPT09IHBhcmVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBjaGlsZC5wYXJlbnROb2RlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcblxuICBjbG9zZXN0OiBmdW5jdGlvbiBjbG9zZXN0KGVsZW1lbnQsIHNlbGVjdG9yKSB7XG4gICAgd2hpbGUgKGlzLmVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICAgIGlmIChkb21VdGlscy5tYXRjaGVzU2VsZWN0b3IoZWxlbWVudCwgc2VsZWN0b3IpKSB7XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgfVxuXG4gICAgICBlbGVtZW50ID0gZG9tVXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfSxcblxuICBwYXJlbnROb2RlOiBmdW5jdGlvbiBwYXJlbnROb2RlKG5vZGUpIHtcbiAgICB2YXIgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlO1xuXG4gICAgaWYgKGlzLmRvY0ZyYWcocGFyZW50KSkge1xuICAgICAgLy8gc2tpcCBwYXN0ICNzaGFkby1yb290IGZyYWdtZW50c1xuICAgICAgd2hpbGUgKChwYXJlbnQgPSBwYXJlbnQuaG9zdCkgJiYgaXMuZG9jRnJhZyhwYXJlbnQpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFyZW50O1xuICAgIH1cblxuICAgIHJldHVybiBwYXJlbnQ7XG4gIH0sXG5cbiAgLy8gdGFrZW4gZnJvbSBodHRwOi8vdGFuYWxpbi5jb20vZW4vYmxvZy8yMDEyLzEyL21hdGNoZXMtc2VsZWN0b3ItaWU4LyBhbmQgbW9kaWZpZWRcbiAgbWF0Y2hlc1NlbGVjdG9yUG9seWZpbGw6IGJyb3dzZXIudXNlTWF0Y2hlc1NlbGVjdG9yUG9seWZpbGwgPyBmdW5jdGlvbiAoZWxlbWVudCwgc2VsZWN0b3IsIGVsZW1zKSB7XG4gICAgZWxlbXMgPSBlbGVtcyB8fCBlbGVtZW50LnBhcmVudE5vZGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gZWxlbXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGlmIChlbGVtc1tpXSA9PT0gZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gOiBudWxsLFxuXG4gIG1hdGNoZXNTZWxlY3RvcjogZnVuY3Rpb24gbWF0Y2hlc1NlbGVjdG9yKGVsZW1lbnQsIHNlbGVjdG9yLCBub2RlTGlzdCkge1xuICAgIGlmIChicm93c2VyLnVzZU1hdGNoZXNTZWxlY3RvclBvbHlmaWxsKSB7XG4gICAgICByZXR1cm4gZG9tVXRpbHMubWF0Y2hlc1NlbGVjdG9yUG9seWZpbGwoZWxlbWVudCwgc2VsZWN0b3IsIG5vZGVMaXN0KTtcbiAgICB9XG5cbiAgICAvLyByZW1vdmUgL2RlZXAvIGZyb20gc2VsZWN0b3JzIGlmIHNoYWRvd0RPTSBwb2x5ZmlsbCBpcyB1c2VkXG4gICAgaWYgKHdpbi53aW5kb3cgIT09IHdpbi5yZWFsV2luZG93KSB7XG4gICAgICBzZWxlY3RvciA9IHNlbGVjdG9yLnJlcGxhY2UoL1xcL2RlZXBcXC8vZywgJyAnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudFticm93c2VyLnByZWZpeGVkTWF0Y2hlc1NlbGVjdG9yXShzZWxlY3Rvcik7XG4gIH0sXG5cbiAgLy8gVGVzdCBmb3IgdGhlIGVsZW1lbnQgdGhhdCdzIFwiYWJvdmVcIiBhbGwgb3RoZXIgcXVhbGlmaWVyc1xuICBpbmRleE9mRGVlcGVzdEVsZW1lbnQ6IGZ1bmN0aW9uIGluZGV4T2ZEZWVwZXN0RWxlbWVudChlbGVtZW50cykge1xuICAgIHZhciBkZWVwZXN0Wm9uZVBhcmVudHMgPSBbXTtcbiAgICB2YXIgZHJvcHpvbmVQYXJlbnRzID0gW107XG4gICAgdmFyIGRyb3B6b25lID0gdm9pZCAwO1xuICAgIHZhciBkZWVwZXN0Wm9uZSA9IGVsZW1lbnRzWzBdO1xuICAgIHZhciBpbmRleCA9IGRlZXBlc3Rab25lID8gMCA6IC0xO1xuICAgIHZhciBwYXJlbnQgPSB2b2lkIDA7XG4gICAgdmFyIGNoaWxkID0gdm9pZCAwO1xuICAgIHZhciBpID0gdm9pZCAwO1xuICAgIHZhciBuID0gdm9pZCAwO1xuXG4gICAgZm9yIChpID0gMTsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBkcm9wem9uZSA9IGVsZW1lbnRzW2ldO1xuXG4gICAgICAvLyBhbiBlbGVtZW50IG1pZ2h0IGJlbG9uZyB0byBtdWx0aXBsZSBzZWxlY3RvciBkcm9wem9uZXNcbiAgICAgIGlmICghZHJvcHpvbmUgfHwgZHJvcHpvbmUgPT09IGRlZXBlc3Rab25lKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWRlZXBlc3Rab25lKSB7XG4gICAgICAgIGRlZXBlc3Rab25lID0gZHJvcHpvbmU7XG4gICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGNoZWNrIGlmIHRoZSBkZWVwZXN0IG9yIGN1cnJlbnQgYXJlIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCBvciBkb2N1bWVudC5yb290RWxlbWVudFxuICAgICAgLy8gLSBpZiB0aGUgY3VycmVudCBkcm9wem9uZSBpcywgZG8gbm90aGluZyBhbmQgY29udGludWVcbiAgICAgIGlmIChkcm9wem9uZS5wYXJlbnROb2RlID09PSBkcm9wem9uZS5vd25lckRvY3VtZW50KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gLSBpZiBkZWVwZXN0IGlzLCB1cGRhdGUgd2l0aCB0aGUgY3VycmVudCBkcm9wem9uZSBhbmQgY29udGludWUgdG8gbmV4dFxuICAgICAgZWxzZSBpZiAoZGVlcGVzdFpvbmUucGFyZW50Tm9kZSA9PT0gZHJvcHpvbmUub3duZXJEb2N1bWVudCkge1xuICAgICAgICAgIGRlZXBlc3Rab25lID0gZHJvcHpvbmU7XG4gICAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgIGlmICghZGVlcGVzdFpvbmVQYXJlbnRzLmxlbmd0aCkge1xuICAgICAgICBwYXJlbnQgPSBkZWVwZXN0Wm9uZTtcbiAgICAgICAgd2hpbGUgKHBhcmVudC5wYXJlbnROb2RlICYmIHBhcmVudC5wYXJlbnROb2RlICE9PSBwYXJlbnQub3duZXJEb2N1bWVudCkge1xuICAgICAgICAgIGRlZXBlc3Rab25lUGFyZW50cy51bnNoaWZ0KHBhcmVudCk7XG4gICAgICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudE5vZGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gaWYgdGhpcyBlbGVtZW50IGlzIGFuIHN2ZyBlbGVtZW50IGFuZCB0aGUgY3VycmVudCBkZWVwZXN0IGlzXG4gICAgICAvLyBhbiBIVE1MRWxlbWVudFxuICAgICAgaWYgKGRlZXBlc3Rab25lIGluc3RhbmNlb2YgZG9tT2JqZWN0cy5IVE1MRWxlbWVudCAmJiBkcm9wem9uZSBpbnN0YW5jZW9mIGRvbU9iamVjdHMuU1ZHRWxlbWVudCAmJiAhKGRyb3B6b25lIGluc3RhbmNlb2YgZG9tT2JqZWN0cy5TVkdTVkdFbGVtZW50KSkge1xuXG4gICAgICAgIGlmIChkcm9wem9uZSA9PT0gZGVlcGVzdFpvbmUucGFyZW50Tm9kZSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcGFyZW50ID0gZHJvcHpvbmUub3duZXJTVkdFbGVtZW50O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFyZW50ID0gZHJvcHpvbmU7XG4gICAgICB9XG5cbiAgICAgIGRyb3B6b25lUGFyZW50cyA9IFtdO1xuXG4gICAgICB3aGlsZSAocGFyZW50LnBhcmVudE5vZGUgIT09IHBhcmVudC5vd25lckRvY3VtZW50KSB7XG4gICAgICAgIGRyb3B6b25lUGFyZW50cy51bnNoaWZ0KHBhcmVudCk7XG4gICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xuICAgICAgfVxuXG4gICAgICBuID0gMDtcblxuICAgICAgLy8gZ2V0IChwb3NpdGlvbiBvZiBsYXN0IGNvbW1vbiBhbmNlc3RvcikgKyAxXG4gICAgICB3aGlsZSAoZHJvcHpvbmVQYXJlbnRzW25dICYmIGRyb3B6b25lUGFyZW50c1tuXSA9PT0gZGVlcGVzdFpvbmVQYXJlbnRzW25dKSB7XG4gICAgICAgIG4rKztcbiAgICAgIH1cblxuICAgICAgdmFyIHBhcmVudHMgPSBbZHJvcHpvbmVQYXJlbnRzW24gLSAxXSwgZHJvcHpvbmVQYXJlbnRzW25dLCBkZWVwZXN0Wm9uZVBhcmVudHNbbl1dO1xuXG4gICAgICBjaGlsZCA9IHBhcmVudHNbMF0ubGFzdENoaWxkO1xuXG4gICAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgICAgaWYgKGNoaWxkID09PSBwYXJlbnRzWzFdKSB7XG4gICAgICAgICAgZGVlcGVzdFpvbmUgPSBkcm9wem9uZTtcbiAgICAgICAgICBpbmRleCA9IGk7XG4gICAgICAgICAgZGVlcGVzdFpvbmVQYXJlbnRzID0gW107XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIGlmIChjaGlsZCA9PT0gcGFyZW50c1syXSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQgPSBjaGlsZC5wcmV2aW91c1NpYmxpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGluZGV4O1xuICB9LFxuXG4gIG1hdGNoZXNVcFRvOiBmdW5jdGlvbiBtYXRjaGVzVXBUbyhlbGVtZW50LCBzZWxlY3RvciwgbGltaXQpIHtcbiAgICB3aGlsZSAoaXMuZWxlbWVudChlbGVtZW50KSkge1xuICAgICAgaWYgKGRvbVV0aWxzLm1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvcikpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGVsZW1lbnQgPSBkb21VdGlscy5wYXJlbnROb2RlKGVsZW1lbnQpO1xuXG4gICAgICBpZiAoZWxlbWVudCA9PT0gbGltaXQpIHtcbiAgICAgICAgcmV0dXJuIGRvbVV0aWxzLm1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3Rvcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LFxuXG4gIGdldEFjdHVhbEVsZW1lbnQ6IGZ1bmN0aW9uIGdldEFjdHVhbEVsZW1lbnQoZWxlbWVudCkge1xuICAgIHJldHVybiBlbGVtZW50IGluc3RhbmNlb2YgZG9tT2JqZWN0cy5TVkdFbGVtZW50SW5zdGFuY2UgPyBlbGVtZW50LmNvcnJlc3BvbmRpbmdVc2VFbGVtZW50IDogZWxlbWVudDtcbiAgfSxcblxuICBnZXRTY3JvbGxYWTogZnVuY3Rpb24gZ2V0U2Nyb2xsWFkocmVsZXZhbnRXaW5kb3cpIHtcbiAgICByZWxldmFudFdpbmRvdyA9IHJlbGV2YW50V2luZG93IHx8IHdpbi53aW5kb3c7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHJlbGV2YW50V2luZG93LnNjcm9sbFggfHwgcmVsZXZhbnRXaW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQsXG4gICAgICB5OiByZWxldmFudFdpbmRvdy5zY3JvbGxZIHx8IHJlbGV2YW50V2luZG93LmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3BcbiAgICB9O1xuICB9LFxuXG4gIGdldEVsZW1lbnRDbGllbnRSZWN0OiBmdW5jdGlvbiBnZXRFbGVtZW50Q2xpZW50UmVjdChlbGVtZW50KSB7XG4gICAgdmFyIGNsaWVudFJlY3QgPSBlbGVtZW50IGluc3RhbmNlb2YgZG9tT2JqZWN0cy5TVkdFbGVtZW50ID8gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSA6IGVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKVswXTtcblxuICAgIHJldHVybiBjbGllbnRSZWN0ICYmIHtcbiAgICAgIGxlZnQ6IGNsaWVudFJlY3QubGVmdCxcbiAgICAgIHJpZ2h0OiBjbGllbnRSZWN0LnJpZ2h0LFxuICAgICAgdG9wOiBjbGllbnRSZWN0LnRvcCxcbiAgICAgIGJvdHRvbTogY2xpZW50UmVjdC5ib3R0b20sXG4gICAgICB3aWR0aDogY2xpZW50UmVjdC53aWR0aCB8fCBjbGllbnRSZWN0LnJpZ2h0IC0gY2xpZW50UmVjdC5sZWZ0LFxuICAgICAgaGVpZ2h0OiBjbGllbnRSZWN0LmhlaWdodCB8fCBjbGllbnRSZWN0LmJvdHRvbSAtIGNsaWVudFJlY3QudG9wXG4gICAgfTtcbiAgfSxcblxuICBnZXRFbGVtZW50UmVjdDogZnVuY3Rpb24gZ2V0RWxlbWVudFJlY3QoZWxlbWVudCkge1xuICAgIHZhciBjbGllbnRSZWN0ID0gZG9tVXRpbHMuZ2V0RWxlbWVudENsaWVudFJlY3QoZWxlbWVudCk7XG5cbiAgICBpZiAoIWJyb3dzZXIuaXNJT1M3ICYmIGNsaWVudFJlY3QpIHtcbiAgICAgIHZhciBzY3JvbGwgPSBkb21VdGlscy5nZXRTY3JvbGxYWSh3aW4uZ2V0V2luZG93KGVsZW1lbnQpKTtcblxuICAgICAgY2xpZW50UmVjdC5sZWZ0ICs9IHNjcm9sbC54O1xuICAgICAgY2xpZW50UmVjdC5yaWdodCArPSBzY3JvbGwueDtcbiAgICAgIGNsaWVudFJlY3QudG9wICs9IHNjcm9sbC55O1xuICAgICAgY2xpZW50UmVjdC5ib3R0b20gKz0gc2Nyb2xsLnk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsaWVudFJlY3Q7XG4gIH0sXG5cbiAgZ2V0UGF0aDogZnVuY3Rpb24gZ2V0UGF0aChlbGVtZW50KSB7XG4gICAgdmFyIHBhdGggPSBbXTtcblxuICAgIHdoaWxlIChlbGVtZW50KSB7XG4gICAgICBwYXRoLnB1c2goZWxlbWVudCk7XG4gICAgICBlbGVtZW50ID0gZG9tVXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aDtcbiAgfSxcblxuICB0cnlTZWxlY3RvcjogZnVuY3Rpb24gdHJ5U2VsZWN0b3IodmFsdWUpIHtcbiAgICBpZiAoIWlzLnN0cmluZyh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBhbiBleGNlcHRpb24gd2lsbCBiZSByYWlzZWQgaWYgaXQgaXMgaW52YWxpZFxuICAgIGRvbU9iamVjdHMuZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih2YWx1ZSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZG9tVXRpbHM7XG5cbn0se1wiLi9icm93c2VyXCI6MzcsXCIuL2RvbU9iamVjdHNcIjozOCxcIi4vaXNcIjo0NixcIi4vd2luZG93XCI6NTJ9XSw0MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBpcyA9IHJlcXVpcmUoJy4vaXMnKTtcbnZhciBkb21VdGlscyA9IHJlcXVpcmUoJy4vZG9tVXRpbHMnKTtcbnZhciBwRXh0ZW5kID0gcmVxdWlyZSgnLi9wb2ludGVyRXh0ZW5kJyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4vd2luZG93JyksXG4gICAgd2luZG93ID0gX3JlcXVpcmUud2luZG93LFxuICAgIGdldFdpbmRvdyA9IF9yZXF1aXJlLmdldFdpbmRvdztcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJy4vYXJyJyksXG4gICAgaW5kZXhPZiA9IF9yZXF1aXJlMi5pbmRleE9mLFxuICAgIGNvbnRhaW5zID0gX3JlcXVpcmUyLmNvbnRhaW5zO1xuXG52YXIgdXNlQXR0YWNoRXZlbnQgPSAnYXR0YWNoRXZlbnQnIGluIHdpbmRvdyAmJiAhKCdhZGRFdmVudExpc3RlbmVyJyBpbiB3aW5kb3cpO1xudmFyIGFkZEV2ZW50ID0gdXNlQXR0YWNoRXZlbnQgPyAnYXR0YWNoRXZlbnQnIDogJ2FkZEV2ZW50TGlzdGVuZXInO1xudmFyIHJlbW92ZUV2ZW50ID0gdXNlQXR0YWNoRXZlbnQgPyAnZGV0YWNoRXZlbnQnIDogJ3JlbW92ZUV2ZW50TGlzdGVuZXInO1xudmFyIG9uID0gdXNlQXR0YWNoRXZlbnQgPyAnb24nIDogJyc7XG5cbnZhciBlbGVtZW50cyA9IFtdO1xudmFyIHRhcmdldHMgPSBbXTtcbnZhciBhdHRhY2hlZExpc3RlbmVycyA9IFtdO1xuXG4vLyB7XG4vLyAgIHR5cGU6IHtcbi8vICAgICBzZWxlY3RvcnM6IFsnc2VsZWN0b3InLCAuLi5dLFxuLy8gICAgIGNvbnRleHRzIDogW2RvY3VtZW50LCAuLi5dLFxuLy8gICAgIGxpc3RlbmVyczogW1tsaXN0ZW5lciwgY2FwdHVyZSwgcGFzc2l2ZV0sIC4uLl1cbi8vICAgfVxuLy8gIH1cbnZhciBkZWxlZ2F0ZWRFdmVudHMgPSB7fTtcblxudmFyIGRvY3VtZW50cyA9IFtdO1xuXG52YXIgc3VwcG9ydHNPcHRpb25zID0gIXVzZUF0dGFjaEV2ZW50ICYmIGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN1cHBvcnRlZCA9IGZhbHNlO1xuXG4gIHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKS5hZGRFdmVudExpc3RlbmVyKCd0ZXN0JywgbnVsbCwge1xuICAgIGdldCBjYXB0dXJlKCkge1xuICAgICAgc3VwcG9ydGVkID0gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBzdXBwb3J0ZWQ7XG59KCk7XG5cbmZ1bmN0aW9uIGFkZChlbGVtZW50LCB0eXBlLCBsaXN0ZW5lciwgb3B0aW9uYWxBcmcpIHtcbiAgdmFyIG9wdGlvbnMgPSBnZXRPcHRpb25zKG9wdGlvbmFsQXJnKTtcbiAgdmFyIGVsZW1lbnRJbmRleCA9IGluZGV4T2YoZWxlbWVudHMsIGVsZW1lbnQpO1xuICB2YXIgdGFyZ2V0ID0gdGFyZ2V0c1tlbGVtZW50SW5kZXhdO1xuXG4gIGlmICghdGFyZ2V0KSB7XG4gICAgdGFyZ2V0ID0ge1xuICAgICAgZXZlbnRzOiB7fSxcbiAgICAgIHR5cGVDb3VudDogMFxuICAgIH07XG5cbiAgICBlbGVtZW50SW5kZXggPSBlbGVtZW50cy5wdXNoKGVsZW1lbnQpIC0gMTtcbiAgICB0YXJnZXRzLnB1c2godGFyZ2V0KTtcblxuICAgIGF0dGFjaGVkTGlzdGVuZXJzLnB1c2godXNlQXR0YWNoRXZlbnQgPyB7XG4gICAgICBzdXBwbGllZDogW10sXG4gICAgICB3cmFwcGVkOiBbXSxcbiAgICAgIHVzZUNvdW50OiBbXVxuICAgIH0gOiBudWxsKTtcbiAgfVxuXG4gIGlmICghdGFyZ2V0LmV2ZW50c1t0eXBlXSkge1xuICAgIHRhcmdldC5ldmVudHNbdHlwZV0gPSBbXTtcbiAgICB0YXJnZXQudHlwZUNvdW50Kys7XG4gIH1cblxuICBpZiAoIWNvbnRhaW5zKHRhcmdldC5ldmVudHNbdHlwZV0sIGxpc3RlbmVyKSkge1xuICAgIHZhciByZXQgPSB2b2lkIDA7XG5cbiAgICBpZiAodXNlQXR0YWNoRXZlbnQpIHtcbiAgICAgIHZhciBfYXR0YWNoZWRMaXN0ZW5lcnMkZWwgPSBhdHRhY2hlZExpc3RlbmVyc1tlbGVtZW50SW5kZXhdLFxuICAgICAgICAgIHN1cHBsaWVkID0gX2F0dGFjaGVkTGlzdGVuZXJzJGVsLnN1cHBsaWVkLFxuICAgICAgICAgIHdyYXBwZWQgPSBfYXR0YWNoZWRMaXN0ZW5lcnMkZWwud3JhcHBlZCxcbiAgICAgICAgICB1c2VDb3VudCA9IF9hdHRhY2hlZExpc3RlbmVycyRlbC51c2VDb3VudDtcblxuICAgICAgdmFyIGxpc3RlbmVySW5kZXggPSBpbmRleE9mKHN1cHBsaWVkLCBsaXN0ZW5lcik7XG5cbiAgICAgIHZhciB3cmFwcGVkTGlzdGVuZXIgPSB3cmFwcGVkW2xpc3RlbmVySW5kZXhdIHx8IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCkge1xuICAgICAgICAgIGV2ZW50LnRhcmdldCA9IGV2ZW50LnNyY0VsZW1lbnQ7XG4gICAgICAgICAgZXZlbnQuY3VycmVudFRhcmdldCA9IGVsZW1lbnQ7XG5cbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCA9IGV2ZW50LnByZXZlbnREZWZhdWx0IHx8IHByZXZlbnREZWY7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uID0gZXZlbnQuc3RvcFByb3BhZ2F0aW9uIHx8IHN0b3BQcm9wO1xuICAgICAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9IGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiB8fCBzdG9wSW1tUHJvcDtcblxuICAgICAgICAgIGlmICgvbW91c2V8Y2xpY2svLnRlc3QoZXZlbnQudHlwZSkpIHtcbiAgICAgICAgICAgIGV2ZW50LnBhZ2VYID0gZXZlbnQuY2xpZW50WCArIGdldFdpbmRvdyhlbGVtZW50KS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICAgICAgICAgIGV2ZW50LnBhZ2VZID0gZXZlbnQuY2xpZW50WSArIGdldFdpbmRvdyhlbGVtZW50KS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxpc3RlbmVyKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgcmV0ID0gZWxlbWVudFthZGRFdmVudF0ob24gKyB0eXBlLCB3cmFwcGVkTGlzdGVuZXIsICEhb3B0aW9ucy5jYXB0dXJlKTtcblxuICAgICAgaWYgKGxpc3RlbmVySW5kZXggPT09IC0xKSB7XG4gICAgICAgIHN1cHBsaWVkLnB1c2gobGlzdGVuZXIpO1xuICAgICAgICB3cmFwcGVkLnB1c2god3JhcHBlZExpc3RlbmVyKTtcbiAgICAgICAgdXNlQ291bnQucHVzaCgxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVzZUNvdW50W2xpc3RlbmVySW5kZXhdKys7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldCA9IGVsZW1lbnRbYWRkRXZlbnRdKHR5cGUsIGxpc3RlbmVyLCBzdXBwb3J0c09wdGlvbnMgPyBvcHRpb25zIDogISFvcHRpb25zLmNhcHR1cmUpO1xuICAgIH1cbiAgICB0YXJnZXQuZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuXG4gICAgcmV0dXJuIHJldDtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmUoZWxlbWVudCwgdHlwZSwgbGlzdGVuZXIsIG9wdGlvbmFsQXJnKSB7XG4gIHZhciBvcHRpb25zID0gZ2V0T3B0aW9ucyhvcHRpb25hbEFyZyk7XG4gIHZhciBlbGVtZW50SW5kZXggPSBpbmRleE9mKGVsZW1lbnRzLCBlbGVtZW50KTtcbiAgdmFyIHRhcmdldCA9IHRhcmdldHNbZWxlbWVudEluZGV4XTtcblxuICBpZiAoIXRhcmdldCB8fCAhdGFyZ2V0LmV2ZW50cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciB3cmFwcGVkTGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdmFyIGxpc3RlbmVycyA9IHZvaWQgMDtcbiAgdmFyIGxpc3RlbmVySW5kZXggPSB2b2lkIDA7XG5cbiAgaWYgKHVzZUF0dGFjaEV2ZW50KSB7XG4gICAgbGlzdGVuZXJzID0gYXR0YWNoZWRMaXN0ZW5lcnNbZWxlbWVudEluZGV4XTtcbiAgICBsaXN0ZW5lckluZGV4ID0gaW5kZXhPZihsaXN0ZW5lcnMuc3VwcGxpZWQsIGxpc3RlbmVyKTtcbiAgICB3cmFwcGVkTGlzdGVuZXIgPSBsaXN0ZW5lcnMud3JhcHBlZFtsaXN0ZW5lckluZGV4XTtcbiAgfVxuXG4gIGlmICh0eXBlID09PSAnYWxsJykge1xuICAgIGZvciAodHlwZSBpbiB0YXJnZXQuZXZlbnRzKSB7XG4gICAgICBpZiAodGFyZ2V0LmV2ZW50cy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkge1xuICAgICAgICByZW1vdmUoZWxlbWVudCwgdHlwZSwgJ2FsbCcpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodGFyZ2V0LmV2ZW50c1t0eXBlXSkge1xuICAgIHZhciBsZW4gPSB0YXJnZXQuZXZlbnRzW3R5cGVdLmxlbmd0aDtcblxuICAgIGlmIChsaXN0ZW5lciA9PT0gJ2FsbCcpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgcmVtb3ZlKGVsZW1lbnQsIHR5cGUsIHRhcmdldC5ldmVudHNbdHlwZV1baV0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgbGVuOyBfaSsrKSB7XG4gICAgICAgIGlmICh0YXJnZXQuZXZlbnRzW3R5cGVdW19pXSA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICBlbGVtZW50W3JlbW92ZUV2ZW50XShvbiArIHR5cGUsIHdyYXBwZWRMaXN0ZW5lciwgc3VwcG9ydHNPcHRpb25zID8gb3B0aW9ucyA6ICEhb3B0aW9ucy5jYXB0dXJlKTtcbiAgICAgICAgICB0YXJnZXQuZXZlbnRzW3R5cGVdLnNwbGljZShfaSwgMSk7XG5cbiAgICAgICAgICBpZiAodXNlQXR0YWNoRXZlbnQgJiYgbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnMudXNlQ291bnRbbGlzdGVuZXJJbmRleF0tLTtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMudXNlQ291bnRbbGlzdGVuZXJJbmRleF0gPT09IDApIHtcbiAgICAgICAgICAgICAgbGlzdGVuZXJzLnN1cHBsaWVkLnNwbGljZShsaXN0ZW5lckluZGV4LCAxKTtcbiAgICAgICAgICAgICAgbGlzdGVuZXJzLndyYXBwZWQuc3BsaWNlKGxpc3RlbmVySW5kZXgsIDEpO1xuICAgICAgICAgICAgICBsaXN0ZW5lcnMudXNlQ291bnQuc3BsaWNlKGxpc3RlbmVySW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRhcmdldC5ldmVudHNbdHlwZV0gJiYgdGFyZ2V0LmV2ZW50c1t0eXBlXS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRhcmdldC5ldmVudHNbdHlwZV0gPSBudWxsO1xuICAgICAgdGFyZ2V0LnR5cGVDb3VudC0tO1xuICAgIH1cbiAgfVxuXG4gIGlmICghdGFyZ2V0LnR5cGVDb3VudCkge1xuICAgIHRhcmdldHMuc3BsaWNlKGVsZW1lbnRJbmRleCwgMSk7XG4gICAgZWxlbWVudHMuc3BsaWNlKGVsZW1lbnRJbmRleCwgMSk7XG4gICAgYXR0YWNoZWRMaXN0ZW5lcnMuc3BsaWNlKGVsZW1lbnRJbmRleCwgMSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkRGVsZWdhdGUoc2VsZWN0b3IsIGNvbnRleHQsIHR5cGUsIGxpc3RlbmVyLCBvcHRpb25hbEFyZykge1xuICB2YXIgb3B0aW9ucyA9IGdldE9wdGlvbnMob3B0aW9uYWxBcmcpO1xuICBpZiAoIWRlbGVnYXRlZEV2ZW50c1t0eXBlXSkge1xuICAgIGRlbGVnYXRlZEV2ZW50c1t0eXBlXSA9IHtcbiAgICAgIHNlbGVjdG9yczogW10sXG4gICAgICBjb250ZXh0czogW10sXG4gICAgICBsaXN0ZW5lcnM6IFtdXG4gICAgfTtcblxuICAgIC8vIGFkZCBkZWxlZ2F0ZSBsaXN0ZW5lciBmdW5jdGlvbnNcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRvY3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgYWRkKGRvY3VtZW50c1tpXSwgdHlwZSwgZGVsZWdhdGVMaXN0ZW5lcik7XG4gICAgICBhZGQoZG9jdW1lbnRzW2ldLCB0eXBlLCBkZWxlZ2F0ZVVzZUNhcHR1cmUsIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBkZWxlZ2F0ZWQgPSBkZWxlZ2F0ZWRFdmVudHNbdHlwZV07XG4gIHZhciBpbmRleCA9IHZvaWQgMDtcblxuICBmb3IgKGluZGV4ID0gZGVsZWdhdGVkLnNlbGVjdG9ycy5sZW5ndGggLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKSB7XG4gICAgaWYgKGRlbGVnYXRlZC5zZWxlY3RvcnNbaW5kZXhdID09PSBzZWxlY3RvciAmJiBkZWxlZ2F0ZWQuY29udGV4dHNbaW5kZXhdID09PSBjb250ZXh0KSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgaW5kZXggPSBkZWxlZ2F0ZWQuc2VsZWN0b3JzLmxlbmd0aDtcblxuICAgIGRlbGVnYXRlZC5zZWxlY3RvcnMucHVzaChzZWxlY3Rvcik7XG4gICAgZGVsZWdhdGVkLmNvbnRleHRzLnB1c2goY29udGV4dCk7XG4gICAgZGVsZWdhdGVkLmxpc3RlbmVycy5wdXNoKFtdKTtcbiAgfVxuXG4gIC8vIGtlZXAgbGlzdGVuZXIgYW5kIGNhcHR1cmUgYW5kIHBhc3NpdmUgZmxhZ3NcbiAgZGVsZWdhdGVkLmxpc3RlbmVyc1tpbmRleF0ucHVzaChbbGlzdGVuZXIsICEhb3B0aW9ucy5jYXB0dXJlLCBvcHRpb25zLnBhc3NpdmVdKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRGVsZWdhdGUoc2VsZWN0b3IsIGNvbnRleHQsIHR5cGUsIGxpc3RlbmVyLCBvcHRpb25hbEFyZykge1xuICB2YXIgb3B0aW9ucyA9IGdldE9wdGlvbnMob3B0aW9uYWxBcmcpO1xuICB2YXIgZGVsZWdhdGVkID0gZGVsZWdhdGVkRXZlbnRzW3R5cGVdO1xuICB2YXIgbWF0Y2hGb3VuZCA9IGZhbHNlO1xuICB2YXIgaW5kZXggPSB2b2lkIDA7XG5cbiAgaWYgKCFkZWxlZ2F0ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBjb3VudCBmcm9tIGxhc3QgaW5kZXggb2YgZGVsZWdhdGVkIHRvIDBcbiAgZm9yIChpbmRleCA9IGRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXgtLSkge1xuICAgIC8vIGxvb2sgZm9yIG1hdGNoaW5nIHNlbGVjdG9yIGFuZCBjb250ZXh0IE5vZGVcbiAgICBpZiAoZGVsZWdhdGVkLnNlbGVjdG9yc1tpbmRleF0gPT09IHNlbGVjdG9yICYmIGRlbGVnYXRlZC5jb250ZXh0c1tpbmRleF0gPT09IGNvbnRleHQpIHtcblxuICAgICAgdmFyIGxpc3RlbmVycyA9IGRlbGVnYXRlZC5saXN0ZW5lcnNbaW5kZXhdO1xuXG4gICAgICAvLyBlYWNoIGl0ZW0gb2YgdGhlIGxpc3RlbmVycyBhcnJheSBpcyBhbiBhcnJheTogW2Z1bmN0aW9uLCBjYXB0dXJlLCBwYXNzaXZlXVxuICAgICAgZm9yICh2YXIgaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICB2YXIgX2xpc3RlbmVycyRpID0gbGlzdGVuZXJzW2ldLFxuICAgICAgICAgICAgZm4gPSBfbGlzdGVuZXJzJGlbMF0sXG4gICAgICAgICAgICBjYXB0dXJlID0gX2xpc3RlbmVycyRpWzFdLFxuICAgICAgICAgICAgcGFzc2l2ZSA9IF9saXN0ZW5lcnMkaVsyXTtcblxuICAgICAgICAvLyBjaGVjayBpZiB0aGUgbGlzdGVuZXIgZnVuY3Rpb25zIGFuZCBjYXB0dXJlIGFuZCBwYXNzaXZlIGZsYWdzIG1hdGNoXG5cbiAgICAgICAgaWYgKGZuID09PSBsaXN0ZW5lciAmJiBjYXB0dXJlID09PSAhIW9wdGlvbnMuY2FwdHVyZSAmJiBwYXNzaXZlID09PSBvcHRpb25zLnBhc3NpdmUpIHtcbiAgICAgICAgICAvLyByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGFycmF5IG9mIGxpc3RlbmVyc1xuICAgICAgICAgIGxpc3RlbmVycy5zcGxpY2UoaSwgMSk7XG5cbiAgICAgICAgICAvLyBpZiBhbGwgbGlzdGVuZXJzIGZvciB0aGlzIGludGVyYWN0YWJsZSBoYXZlIGJlZW4gcmVtb3ZlZFxuICAgICAgICAgIC8vIHJlbW92ZSB0aGUgaW50ZXJhY3RhYmxlIGZyb20gdGhlIGRlbGVnYXRlZCBhcnJheXNcbiAgICAgICAgICBpZiAoIWxpc3RlbmVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRlbGVnYXRlZC5zZWxlY3RvcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIGRlbGVnYXRlZC5jb250ZXh0cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgZGVsZWdhdGVkLmxpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuXG4gICAgICAgICAgICAvLyByZW1vdmUgZGVsZWdhdGUgZnVuY3Rpb24gZnJvbSBjb250ZXh0XG4gICAgICAgICAgICByZW1vdmUoY29udGV4dCwgdHlwZSwgZGVsZWdhdGVMaXN0ZW5lcik7XG4gICAgICAgICAgICByZW1vdmUoY29udGV4dCwgdHlwZSwgZGVsZWdhdGVVc2VDYXB0dXJlLCB0cnVlKTtcblxuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBhcnJheXMgaWYgdGhleSBhcmUgZW1wdHlcbiAgICAgICAgICAgIGlmICghZGVsZWdhdGVkLnNlbGVjdG9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgZGVsZWdhdGVkRXZlbnRzW3R5cGVdID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBvbmx5IHJlbW92ZSBvbmUgbGlzdGVuZXJcbiAgICAgICAgICBtYXRjaEZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobWF0Y2hGb3VuZCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gYm91bmQgdG8gdGhlIGludGVyYWN0YWJsZSBjb250ZXh0IHdoZW4gYSBET00gZXZlbnRcbi8vIGxpc3RlbmVyIGlzIGFkZGVkIHRvIGEgc2VsZWN0b3IgaW50ZXJhY3RhYmxlXG5mdW5jdGlvbiBkZWxlZ2F0ZUxpc3RlbmVyKGV2ZW50LCBvcHRpb25hbEFyZykge1xuICB2YXIgb3B0aW9ucyA9IGdldE9wdGlvbnMob3B0aW9uYWxBcmcpO1xuICB2YXIgZmFrZUV2ZW50ID0ge307XG4gIHZhciBkZWxlZ2F0ZWQgPSBkZWxlZ2F0ZWRFdmVudHNbZXZlbnQudHlwZV07XG4gIHZhciBldmVudFRhcmdldCA9IGRvbVV0aWxzLmdldEFjdHVhbEVsZW1lbnQoZXZlbnQucGF0aCA/IGV2ZW50LnBhdGhbMF0gOiBldmVudC50YXJnZXQpO1xuICB2YXIgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xuXG4gIC8vIGR1cGxpY2F0ZSB0aGUgZXZlbnQgc28gdGhhdCBjdXJyZW50VGFyZ2V0IGNhbiBiZSBjaGFuZ2VkXG4gIHBFeHRlbmQoZmFrZUV2ZW50LCBldmVudCk7XG5cbiAgZmFrZUV2ZW50Lm9yaWdpbmFsRXZlbnQgPSBldmVudDtcbiAgZmFrZUV2ZW50LnByZXZlbnREZWZhdWx0ID0gcHJldmVudE9yaWdpbmFsRGVmYXVsdDtcblxuICAvLyBjbGltYiB1cCBkb2N1bWVudCB0cmVlIGxvb2tpbmcgZm9yIHNlbGVjdG9yIG1hdGNoZXNcbiAgd2hpbGUgKGlzLmVsZW1lbnQoZWxlbWVudCkpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRlbGVnYXRlZC5zZWxlY3RvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzZWxlY3RvciA9IGRlbGVnYXRlZC5zZWxlY3RvcnNbaV07XG4gICAgICB2YXIgY29udGV4dCA9IGRlbGVnYXRlZC5jb250ZXh0c1tpXTtcblxuICAgICAgaWYgKGRvbVV0aWxzLm1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvcikgJiYgZG9tVXRpbHMubm9kZUNvbnRhaW5zKGNvbnRleHQsIGV2ZW50VGFyZ2V0KSAmJiBkb21VdGlscy5ub2RlQ29udGFpbnMoY29udGV4dCwgZWxlbWVudCkpIHtcblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gZGVsZWdhdGVkLmxpc3RlbmVyc1tpXTtcblxuICAgICAgICBmYWtlRXZlbnQuY3VycmVudFRhcmdldCA9IGVsZW1lbnQ7XG5cbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBsaXN0ZW5lcnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICB2YXIgX2xpc3RlbmVycyRqID0gbGlzdGVuZXJzW2pdLFxuICAgICAgICAgICAgICBmbiA9IF9saXN0ZW5lcnMkalswXSxcbiAgICAgICAgICAgICAgY2FwdHVyZSA9IF9saXN0ZW5lcnMkalsxXSxcbiAgICAgICAgICAgICAgcGFzc2l2ZSA9IF9saXN0ZW5lcnMkalsyXTtcblxuXG4gICAgICAgICAgaWYgKGNhcHR1cmUgPT09ICEhb3B0aW9ucy5jYXB0dXJlICYmIHBhc3NpdmUgPT09IG9wdGlvbnMucGFzc2l2ZSkge1xuICAgICAgICAgICAgZm4oZmFrZUV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBlbGVtZW50ID0gZG9tVXRpbHMucGFyZW50Tm9kZShlbGVtZW50KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWxlZ2F0ZVVzZUNhcHR1cmUoZXZlbnQpIHtcbiAgcmV0dXJuIGRlbGVnYXRlTGlzdGVuZXIuY2FsbCh0aGlzLCBldmVudCwgdHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIHByZXZlbnREZWYoKSB7XG4gIHRoaXMucmV0dXJuVmFsdWUgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcHJldmVudE9yaWdpbmFsRGVmYXVsdCgpIHtcbiAgdGhpcy5vcmlnaW5hbEV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG59XG5cbmZ1bmN0aW9uIHN0b3BQcm9wKCkge1xuICB0aGlzLmNhbmNlbEJ1YmJsZSA9IHRydWU7XG59XG5cbmZ1bmN0aW9uIHN0b3BJbW1Qcm9wKCkge1xuICB0aGlzLmNhbmNlbEJ1YmJsZSA9IHRydWU7XG4gIHRoaXMuaW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gZ2V0T3B0aW9ucyhwYXJhbSkge1xuICByZXR1cm4gaXMub2JqZWN0KHBhcmFtKSA/IHBhcmFtIDogeyBjYXB0dXJlOiBwYXJhbSB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYWRkOiBhZGQsXG4gIHJlbW92ZTogcmVtb3ZlLFxuXG4gIGFkZERlbGVnYXRlOiBhZGREZWxlZ2F0ZSxcbiAgcmVtb3ZlRGVsZWdhdGU6IHJlbW92ZURlbGVnYXRlLFxuXG4gIGRlbGVnYXRlTGlzdGVuZXI6IGRlbGVnYXRlTGlzdGVuZXIsXG4gIGRlbGVnYXRlVXNlQ2FwdHVyZTogZGVsZWdhdGVVc2VDYXB0dXJlLFxuICBkZWxlZ2F0ZWRFdmVudHM6IGRlbGVnYXRlZEV2ZW50cyxcbiAgZG9jdW1lbnRzOiBkb2N1bWVudHMsXG5cbiAgdXNlQXR0YWNoRXZlbnQ6IHVzZUF0dGFjaEV2ZW50LFxuICBzdXBwb3J0c09wdGlvbnM6IHN1cHBvcnRzT3B0aW9ucyxcblxuICBfZWxlbWVudHM6IGVsZW1lbnRzLFxuICBfdGFyZ2V0czogdGFyZ2V0cyxcbiAgX2F0dGFjaGVkTGlzdGVuZXJzOiBhdHRhY2hlZExpc3RlbmVyc1xufTtcblxufSx7XCIuL2FyclwiOjM2LFwiLi9kb21VdGlsc1wiOjM5LFwiLi9pc1wiOjQ2LFwiLi9wb2ludGVyRXh0ZW5kXCI6NDgsXCIuL3dpbmRvd1wiOjUyfV0sNDE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZXh0ZW5kKGRlc3QsIHNvdXJjZSkge1xuICBmb3IgKHZhciBwcm9wIGluIHNvdXJjZSkge1xuICAgIGRlc3RbcHJvcF0gPSBzb3VyY2VbcHJvcF07XG4gIH1cbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG59LHt9XSw0MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJy4vcmVjdCcpLFxuICAgIHJlc29sdmVSZWN0TGlrZSA9IF9yZXF1aXJlLnJlc29sdmVSZWN0TGlrZSxcbiAgICByZWN0VG9YWSA9IF9yZXF1aXJlLnJlY3RUb1hZO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIGVsZW1lbnQsIGFjdGlvbikge1xuICB2YXIgYWN0aW9uT3B0aW9ucyA9IHRhcmdldC5vcHRpb25zW2FjdGlvbl07XG4gIHZhciBhY3Rpb25PcmlnaW4gPSBhY3Rpb25PcHRpb25zICYmIGFjdGlvbk9wdGlvbnMub3JpZ2luO1xuICB2YXIgb3JpZ2luID0gYWN0aW9uT3JpZ2luIHx8IHRhcmdldC5vcHRpb25zLm9yaWdpbjtcblxuICB2YXIgb3JpZ2luUmVjdCA9IHJlc29sdmVSZWN0TGlrZShvcmlnaW4sIHRhcmdldCwgZWxlbWVudCwgW3RhcmdldCAmJiBlbGVtZW50XSk7XG5cbiAgcmV0dXJuIHJlY3RUb1hZKG9yaWdpblJlY3QpIHx8IHsgeDogMCwgeTogMCB9O1xufTtcblxufSx7XCIuL3JlY3RcIjo1MX1dLDQzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gIHJldHVybiBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSk7XG59O1xuXG59LHt9XSw0NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBleHRlbmQgPSByZXF1aXJlKCcuL2V4dGVuZCcpO1xudmFyIHdpbiA9IHJlcXVpcmUoJy4vd2luZG93Jyk7XG5cbnZhciB1dGlscyA9IHtcbiAgd2Fybk9uY2U6IGZ1bmN0aW9uIHdhcm5PbmNlKG1ldGhvZCwgbWVzc2FnZSkge1xuICAgIHZhciB3YXJuZWQgPSBmYWxzZTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgICB3aW4ud2luZG93LmNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG1ldGhvZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH0sXG5cbiAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNTYzNDUyOC8yMjgwODg4XG4gIF9nZXRRQmV6aWVyVmFsdWU6IGZ1bmN0aW9uIF9nZXRRQmV6aWVyVmFsdWUodCwgcDEsIHAyLCBwMykge1xuICAgIHZhciBpVCA9IDEgLSB0O1xuICAgIHJldHVybiBpVCAqIGlUICogcDEgKyAyICogaVQgKiB0ICogcDIgKyB0ICogdCAqIHAzO1xuICB9LFxuXG4gIGdldFF1YWRyYXRpY0N1cnZlUG9pbnQ6IGZ1bmN0aW9uIGdldFF1YWRyYXRpY0N1cnZlUG9pbnQoc3RhcnRYLCBzdGFydFksIGNwWCwgY3BZLCBlbmRYLCBlbmRZLCBwb3NpdGlvbikge1xuICAgIHJldHVybiB7XG4gICAgICB4OiB1dGlscy5fZ2V0UUJlemllclZhbHVlKHBvc2l0aW9uLCBzdGFydFgsIGNwWCwgZW5kWCksXG4gICAgICB5OiB1dGlscy5fZ2V0UUJlemllclZhbHVlKHBvc2l0aW9uLCBzdGFydFksIGNwWSwgZW5kWSlcbiAgICB9O1xuICB9LFxuXG4gIC8vIGh0dHA6Ly9naXptYS5jb20vZWFzaW5nL1xuICBlYXNlT3V0UXVhZDogZnVuY3Rpb24gZWFzZU91dFF1YWQodCwgYiwgYywgZCkge1xuICAgIHQgLz0gZDtcbiAgICByZXR1cm4gLWMgKiB0ICogKHQgLSAyKSArIGI7XG4gIH0sXG5cbiAgY29weUFjdGlvbjogZnVuY3Rpb24gY29weUFjdGlvbihkZXN0LCBzcmMpIHtcbiAgICBkZXN0Lm5hbWUgPSBzcmMubmFtZTtcbiAgICBkZXN0LmF4aXMgPSBzcmMuYXhpcztcbiAgICBkZXN0LmVkZ2VzID0gc3JjLmVkZ2VzO1xuXG4gICAgcmV0dXJuIGRlc3Q7XG4gIH0sXG5cbiAgaXM6IHJlcXVpcmUoJy4vaXMnKSxcbiAgZXh0ZW5kOiBleHRlbmQsXG4gIGh5cG90OiByZXF1aXJlKCcuL2h5cG90JyksXG4gIGdldE9yaWdpblhZOiByZXF1aXJlKCcuL2dldE9yaWdpblhZJylcbn07XG5cbmV4dGVuZCh1dGlscywgcmVxdWlyZSgnLi9hcnInKSk7XG5leHRlbmQodXRpbHMsIHJlcXVpcmUoJy4vZG9tVXRpbHMnKSk7XG5leHRlbmQodXRpbHMsIHJlcXVpcmUoJy4vcG9pbnRlclV0aWxzJykpO1xuZXh0ZW5kKHV0aWxzLCByZXF1aXJlKCcuL3JlY3QnKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gdXRpbHM7XG5cbn0se1wiLi9hcnJcIjozNixcIi4vZG9tVXRpbHNcIjozOSxcIi4vZXh0ZW5kXCI6NDEsXCIuL2dldE9yaWdpblhZXCI6NDIsXCIuL2h5cG90XCI6NDMsXCIuL2lzXCI6NDYsXCIuL3BvaW50ZXJVdGlsc1wiOjQ5LFwiLi9yZWN0XCI6NTEsXCIuL3dpbmRvd1wiOjUyfV0sNDU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgc2NvcGUgPSByZXF1aXJlKCcuLi9zY29wZScpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi9pbmRleCcpO1xuXG52YXIgZmluZGVyID0ge1xuICBtZXRob2RPcmRlcjogWydzaW11bGF0aW9uUmVzdW1lJywgJ21vdXNlT3JQZW4nLCAnaGFzUG9pbnRlcicsICdpZGxlJ10sXG5cbiAgc2VhcmNoOiBmdW5jdGlvbiBzZWFyY2gocG9pbnRlciwgZXZlbnRUeXBlLCBldmVudFRhcmdldCkge1xuICAgIHZhciBwb2ludGVyVHlwZSA9IHV0aWxzLmdldFBvaW50ZXJUeXBlKHBvaW50ZXIpO1xuICAgIHZhciBwb2ludGVySWQgPSB1dGlscy5nZXRQb2ludGVySWQocG9pbnRlcik7XG4gICAgdmFyIGRldGFpbHMgPSB7IHBvaW50ZXI6IHBvaW50ZXIsIHBvaW50ZXJJZDogcG9pbnRlcklkLCBwb2ludGVyVHlwZTogcG9pbnRlclR5cGUsIGV2ZW50VHlwZTogZXZlbnRUeXBlLCBldmVudFRhcmdldDogZXZlbnRUYXJnZXQgfTtcblxuICAgIGZvciAodmFyIF9pdGVyYXRvciA9IGZpbmRlci5tZXRob2RPcmRlciwgX2lzQXJyYXkgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvciksIF9pID0gMCwgX2l0ZXJhdG9yID0gX2lzQXJyYXkgPyBfaXRlcmF0b3IgOiBfaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcbiAgICAgIHZhciBfcmVmO1xuXG4gICAgICBpZiAoX2lzQXJyYXkpIHtcbiAgICAgICAgaWYgKF9pID49IF9pdGVyYXRvci5sZW5ndGgpIGJyZWFrO1xuICAgICAgICBfcmVmID0gX2l0ZXJhdG9yW19pKytdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX2kgPSBfaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XG4gICAgICAgIF9yZWYgPSBfaS52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIG1ldGhvZCA9IF9yZWY7XG5cbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IGZpbmRlclttZXRob2RdKGRldGFpbHMpO1xuXG4gICAgICBpZiAoaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGludGVyYWN0aW9uO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvLyB0cnkgdG8gcmVzdW1lIHNpbXVsYXRpb24gd2l0aCBhIG5ldyBwb2ludGVyXG4gIHNpbXVsYXRpb25SZXN1bWU6IGZ1bmN0aW9uIHNpbXVsYXRpb25SZXN1bWUoX3JlZjIpIHtcbiAgICB2YXIgcG9pbnRlclR5cGUgPSBfcmVmMi5wb2ludGVyVHlwZSxcbiAgICAgICAgZXZlbnRUeXBlID0gX3JlZjIuZXZlbnRUeXBlLFxuICAgICAgICBldmVudFRhcmdldCA9IF9yZWYyLmV2ZW50VGFyZ2V0O1xuXG4gICAgaWYgKCEvZG93bnxzdGFydC9pLnRlc3QoZXZlbnRUeXBlKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IHNjb3BlLmludGVyYWN0aW9ucywgX2lzQXJyYXkyID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IyKSwgX2kyID0gMCwgX2l0ZXJhdG9yMiA9IF9pc0FycmF5MiA/IF9pdGVyYXRvcjIgOiBfaXRlcmF0b3IyW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICB2YXIgX3JlZjM7XG5cbiAgICAgIGlmIChfaXNBcnJheTIpIHtcbiAgICAgICAgaWYgKF9pMiA+PSBfaXRlcmF0b3IyLmxlbmd0aCkgYnJlYWs7XG4gICAgICAgIF9yZWYzID0gX2l0ZXJhdG9yMltfaTIrK107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaTIgPSBfaXRlcmF0b3IyLm5leHQoKTtcbiAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcbiAgICAgICAgX3JlZjMgPSBfaTIudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWYzO1xuXG4gICAgICB2YXIgZWxlbWVudCA9IGV2ZW50VGFyZ2V0O1xuXG4gICAgICBpZiAoaW50ZXJhY3Rpb24uc2ltdWxhdGlvbiAmJiBpbnRlcmFjdGlvbi5zaW11bGF0aW9uLmFsbG93UmVzdW1lICYmIGludGVyYWN0aW9uLnBvaW50ZXJUeXBlID09PSBwb2ludGVyVHlwZSkge1xuICAgICAgICB3aGlsZSAoZWxlbWVudCkge1xuICAgICAgICAgIC8vIGlmIHRoZSBlbGVtZW50IGlzIHRoZSBpbnRlcmFjdGlvbiBlbGVtZW50XG4gICAgICAgICAgaWYgKGVsZW1lbnQgPT09IGludGVyYWN0aW9uLmVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdGlvbjtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxlbWVudCA9IHV0aWxzLnBhcmVudE5vZGUoZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfSxcblxuICAvLyBpZiBpdCdzIGEgbW91c2Ugb3IgcGVuIGludGVyYWN0aW9uXG4gIG1vdXNlT3JQZW46IGZ1bmN0aW9uIG1vdXNlT3JQZW4oX3JlZjQpIHtcbiAgICB2YXIgcG9pbnRlcklkID0gX3JlZjQucG9pbnRlcklkLFxuICAgICAgICBwb2ludGVyVHlwZSA9IF9yZWY0LnBvaW50ZXJUeXBlLFxuICAgICAgICBldmVudFR5cGUgPSBfcmVmNC5ldmVudFR5cGU7XG5cbiAgICBpZiAocG9pbnRlclR5cGUgIT09ICdtb3VzZScgJiYgcG9pbnRlclR5cGUgIT09ICdwZW4nKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgZmlyc3ROb25BY3RpdmUgPSB2b2lkIDA7XG5cbiAgICBmb3IgKHZhciBfaXRlcmF0b3IzID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheTMgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjMpLCBfaTMgPSAwLCBfaXRlcmF0b3IzID0gX2lzQXJyYXkzID8gX2l0ZXJhdG9yMyA6IF9pdGVyYXRvcjNbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcbiAgICAgIHZhciBfcmVmNTtcblxuICAgICAgaWYgKF9pc0FycmF5Mykge1xuICAgICAgICBpZiAoX2kzID49IF9pdGVyYXRvcjMubGVuZ3RoKSBicmVhaztcbiAgICAgICAgX3JlZjUgPSBfaXRlcmF0b3IzW19pMysrXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9pMyA9IF9pdGVyYXRvcjMubmV4dCgpO1xuICAgICAgICBpZiAoX2kzLmRvbmUpIGJyZWFrO1xuICAgICAgICBfcmVmNSA9IF9pMy52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIGludGVyYWN0aW9uID0gX3JlZjU7XG5cbiAgICAgIGlmIChpbnRlcmFjdGlvbi5wb2ludGVyVHlwZSA9PT0gcG9pbnRlclR5cGUpIHtcbiAgICAgICAgLy8gaWYgaXQncyBhIGRvd24gZXZlbnQsIHNraXAgaW50ZXJhY3Rpb25zIHdpdGggcnVubmluZyBzaW11bGF0aW9uc1xuICAgICAgICBpZiAoaW50ZXJhY3Rpb24uc2ltdWxhdGlvbiAmJiAhdXRpbHMuY29udGFpbnMoaW50ZXJhY3Rpb24ucG9pbnRlcklkcywgcG9pbnRlcklkKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgdGhlIGludGVyYWN0aW9uIGlzIGFjdGl2ZSwgcmV0dXJuIGl0IGltbWVkaWF0ZWx5XG4gICAgICAgIGlmIChpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpKSB7XG4gICAgICAgICAgcmV0dXJuIGludGVyYWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIC8vIG90aGVyd2lzZSBzYXZlIGl0IGFuZCBsb29rIGZvciBhbm90aGVyIGFjdGl2ZSBpbnRlcmFjdGlvblxuICAgICAgICBlbHNlIGlmICghZmlyc3ROb25BY3RpdmUpIHtcbiAgICAgICAgICAgIGZpcnN0Tm9uQWN0aXZlID0gaW50ZXJhY3Rpb247XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGlmIG5vIGFjdGl2ZSBtb3VzZSBpbnRlcmFjdGlvbiB3YXMgZm91bmQgdXNlIHRoZSBmaXJzdCBpbmFjdGl2ZSBtb3VzZVxuICAgIC8vIGludGVyYWN0aW9uXG4gICAgaWYgKGZpcnN0Tm9uQWN0aXZlKSB7XG4gICAgICByZXR1cm4gZmlyc3ROb25BY3RpdmU7XG4gICAgfVxuXG4gICAgLy8gZmluZCBhbnkgbW91c2Ugb3IgcGVuIGludGVyYWN0aW9uLlxuICAgIC8vIGlnbm9yZSB0aGUgaW50ZXJhY3Rpb24gaWYgdGhlIGV2ZW50VHlwZSBpcyBhICpkb3duLCBhbmQgYSBzaW11bGF0aW9uXG4gICAgLy8gaXMgYWN0aXZlXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yNCA9IHNjb3BlLmludGVyYWN0aW9ucywgX2lzQXJyYXk0ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3I0KSwgX2k0ID0gMCwgX2l0ZXJhdG9yNCA9IF9pc0FycmF5NCA/IF9pdGVyYXRvcjQgOiBfaXRlcmF0b3I0W1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICB2YXIgX3JlZjY7XG5cbiAgICAgIGlmIChfaXNBcnJheTQpIHtcbiAgICAgICAgaWYgKF9pNCA+PSBfaXRlcmF0b3I0Lmxlbmd0aCkgYnJlYWs7XG4gICAgICAgIF9yZWY2ID0gX2l0ZXJhdG9yNFtfaTQrK107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaTQgPSBfaXRlcmF0b3I0Lm5leHQoKTtcbiAgICAgICAgaWYgKF9pNC5kb25lKSBicmVhaztcbiAgICAgICAgX3JlZjYgPSBfaTQudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBfaW50ZXJhY3Rpb24gPSBfcmVmNjtcblxuICAgICAgaWYgKF9pbnRlcmFjdGlvbi5wb2ludGVyVHlwZSA9PT0gcG9pbnRlclR5cGUgJiYgISgvZG93bi9pLnRlc3QoZXZlbnRUeXBlKSAmJiBfaW50ZXJhY3Rpb24uc2ltdWxhdGlvbikpIHtcbiAgICAgICAgcmV0dXJuIF9pbnRlcmFjdGlvbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfSxcblxuICAvLyBnZXQgaW50ZXJhY3Rpb24gdGhhdCBoYXMgdGhpcyBwb2ludGVyXG4gIGhhc1BvaW50ZXI6IGZ1bmN0aW9uIGhhc1BvaW50ZXIoX3JlZjcpIHtcbiAgICB2YXIgcG9pbnRlcklkID0gX3JlZjcucG9pbnRlcklkO1xuXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yNSA9IHNjb3BlLmludGVyYWN0aW9ucywgX2lzQXJyYXk1ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3I1KSwgX2k1ID0gMCwgX2l0ZXJhdG9yNSA9IF9pc0FycmF5NSA/IF9pdGVyYXRvcjUgOiBfaXRlcmF0b3I1W1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICB2YXIgX3JlZjg7XG5cbiAgICAgIGlmIChfaXNBcnJheTUpIHtcbiAgICAgICAgaWYgKF9pNSA+PSBfaXRlcmF0b3I1Lmxlbmd0aCkgYnJlYWs7XG4gICAgICAgIF9yZWY4ID0gX2l0ZXJhdG9yNVtfaTUrK107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaTUgPSBfaXRlcmF0b3I1Lm5leHQoKTtcbiAgICAgICAgaWYgKF9pNS5kb25lKSBicmVhaztcbiAgICAgICAgX3JlZjggPSBfaTUudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBpbnRlcmFjdGlvbiA9IF9yZWY4O1xuXG4gICAgICBpZiAodXRpbHMuY29udGFpbnMoaW50ZXJhY3Rpb24ucG9pbnRlcklkcywgcG9pbnRlcklkKSkge1xuICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb247XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8vIGdldCBmaXJzdCBpZGxlIGludGVyYWN0aW9uIHdpdGggYSBtYXRjaGluZyBwb2ludGVyVHlwZVxuICBpZGxlOiBmdW5jdGlvbiBpZGxlKF9yZWY5KSB7XG4gICAgdmFyIHBvaW50ZXJUeXBlID0gX3JlZjkucG9pbnRlclR5cGU7XG5cbiAgICBmb3IgKHZhciBfaXRlcmF0b3I2ID0gc2NvcGUuaW50ZXJhY3Rpb25zLCBfaXNBcnJheTYgPSBBcnJheS5pc0FycmF5KF9pdGVyYXRvcjYpLCBfaTYgPSAwLCBfaXRlcmF0b3I2ID0gX2lzQXJyYXk2ID8gX2l0ZXJhdG9yNiA6IF9pdGVyYXRvcjZbU3ltYm9sLml0ZXJhdG9yXSgpOzspIHtcbiAgICAgIHZhciBfcmVmMTA7XG5cbiAgICAgIGlmIChfaXNBcnJheTYpIHtcbiAgICAgICAgaWYgKF9pNiA+PSBfaXRlcmF0b3I2Lmxlbmd0aCkgYnJlYWs7XG4gICAgICAgIF9yZWYxMCA9IF9pdGVyYXRvcjZbX2k2KytdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX2k2ID0gX2l0ZXJhdG9yNi5uZXh0KCk7XG4gICAgICAgIGlmIChfaTYuZG9uZSkgYnJlYWs7XG4gICAgICAgIF9yZWYxMCA9IF9pNi52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIGludGVyYWN0aW9uID0gX3JlZjEwO1xuXG4gICAgICAvLyBpZiB0aGVyZSdzIGFscmVhZHkgYSBwb2ludGVyIGhlbGQgZG93blxuICAgICAgaWYgKGludGVyYWN0aW9uLnBvaW50ZXJJZHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHZhciB0YXJnZXQgPSBpbnRlcmFjdGlvbi50YXJnZXQ7XG4gICAgICAgIC8vIGRvbid0IGFkZCB0aGlzIHBvaW50ZXIgaWYgdGhlcmUgaXMgYSB0YXJnZXQgaW50ZXJhY3RhYmxlIGFuZCBpdFxuICAgICAgICAvLyBpc24ndCBnZXN0dXJhYmxlXG4gICAgICAgIGlmICh0YXJnZXQgJiYgIXRhcmdldC5vcHRpb25zLmdlc3R1cmUuZW5hYmxlZCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBtYXhpbXVtIG9mIDIgcG9pbnRlcnMgcGVyIGludGVyYWN0aW9uXG4gICAgICBlbHNlIGlmIChpbnRlcmFjdGlvbi5wb2ludGVySWRzLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgaWYgKCFpbnRlcmFjdGlvbi5pbnRlcmFjdGluZygpICYmIHBvaW50ZXJUeXBlID09PSBpbnRlcmFjdGlvbi5wb2ludGVyVHlwZSkge1xuICAgICAgICByZXR1cm4gaW50ZXJhY3Rpb247XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZmluZGVyO1xuXG59LHtcIi4uL3Njb3BlXCI6MzQsXCIuL2luZGV4XCI6NDR9XSw0NjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcblxudmFyIHdpbiA9IHJlcXVpcmUoJy4vd2luZG93Jyk7XG52YXIgaXNXaW5kb3cgPSByZXF1aXJlKCcuL2lzV2luZG93Jyk7XG5cbnZhciBpcyA9IHtcbiAgYXJyYXk6IGZ1bmN0aW9uIGFycmF5KCkge30sXG5cbiAgd2luZG93OiBmdW5jdGlvbiB3aW5kb3codGhpbmcpIHtcbiAgICByZXR1cm4gdGhpbmcgPT09IHdpbi53aW5kb3cgfHwgaXNXaW5kb3codGhpbmcpO1xuICB9LFxuXG4gIGRvY0ZyYWc6IGZ1bmN0aW9uIGRvY0ZyYWcodGhpbmcpIHtcbiAgICByZXR1cm4gaXMub2JqZWN0KHRoaW5nKSAmJiB0aGluZy5ub2RlVHlwZSA9PT0gMTE7XG4gIH0sXG5cbiAgb2JqZWN0OiBmdW5jdGlvbiBvYmplY3QodGhpbmcpIHtcbiAgICByZXR1cm4gISF0aGluZyAmJiAodHlwZW9mIHRoaW5nID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZih0aGluZykpID09PSAnb2JqZWN0JztcbiAgfSxcblxuICBmdW5jdGlvbjogZnVuY3Rpb24gX2Z1bmN0aW9uKHRoaW5nKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gJ2Z1bmN0aW9uJztcbiAgfSxcblxuICBudW1iZXI6IGZ1bmN0aW9uIG51bWJlcih0aGluZykge1xuICAgIHJldHVybiB0eXBlb2YgdGhpbmcgPT09ICdudW1iZXInO1xuICB9LFxuXG4gIGJvb2w6IGZ1bmN0aW9uIGJvb2wodGhpbmcpIHtcbiAgICByZXR1cm4gdHlwZW9mIHRoaW5nID09PSAnYm9vbGVhbic7XG4gIH0sXG5cbiAgc3RyaW5nOiBmdW5jdGlvbiBzdHJpbmcodGhpbmcpIHtcbiAgICByZXR1cm4gdHlwZW9mIHRoaW5nID09PSAnc3RyaW5nJztcbiAgfSxcblxuICBlbGVtZW50OiBmdW5jdGlvbiBlbGVtZW50KHRoaW5nKSB7XG4gICAgaWYgKCF0aGluZyB8fCAodHlwZW9mIHRoaW5nID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZih0aGluZykpICE9PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBfd2luZG93ID0gd2luLmdldFdpbmRvdyh0aGluZykgfHwgd2luLndpbmRvdztcblxuICAgIHJldHVybiAoL29iamVjdHxmdW5jdGlvbi8udGVzdChfdHlwZW9mKF93aW5kb3cuRWxlbWVudCkpID8gdGhpbmcgaW5zdGFuY2VvZiBfd2luZG93LkVsZW1lbnQgLy9ET00yXG4gICAgICA6IHRoaW5nLm5vZGVUeXBlID09PSAxICYmIHR5cGVvZiB0aGluZy5ub2RlTmFtZSA9PT0gJ3N0cmluZydcbiAgICApO1xuICB9XG59O1xuXG5pcy5hcnJheSA9IGZ1bmN0aW9uICh0aGluZykge1xuICByZXR1cm4gaXMub2JqZWN0KHRoaW5nKSAmJiB0eXBlb2YgdGhpbmcubGVuZ3RoICE9PSAndW5kZWZpbmVkJyAmJiBpcy5mdW5jdGlvbih0aGluZy5zcGxpY2UpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBpcztcblxufSx7XCIuL2lzV2luZG93XCI6NDcsXCIuL3dpbmRvd1wiOjUyfV0sNDc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRoaW5nKSB7XG4gIHJldHVybiAhISh0aGluZyAmJiB0aGluZy5XaW5kb3cpICYmIHRoaW5nIGluc3RhbmNlb2YgdGhpbmcuV2luZG93O1xufTtcblxufSx7fV0sNDg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBwb2ludGVyRXh0ZW5kKGRlc3QsIHNvdXJjZSkge1xuICBmb3IgKHZhciBwcm9wIGluIHNvdXJjZSkge1xuICAgIHZhciBwcmVmaXhlZFByb3BSRXMgPSBtb2R1bGUuZXhwb3J0cy5wcmVmaXhlZFByb3BSRXM7XG4gICAgdmFyIGRlcHJlY2F0ZWQgPSBmYWxzZTtcblxuICAgIC8vIHNraXAgZGVwcmVjYXRlZCBwcmVmaXhlZCBwcm9wZXJ0aWVzXG4gICAgZm9yICh2YXIgdmVuZG9yIGluIHByZWZpeGVkUHJvcFJFcykge1xuICAgICAgaWYgKHByb3AuaW5kZXhPZih2ZW5kb3IpID09PSAwICYmIHByZWZpeGVkUHJvcFJFc1t2ZW5kb3JdLnRlc3QocHJvcCkpIHtcbiAgICAgICAgZGVwcmVjYXRlZCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghZGVwcmVjYXRlZCAmJiB0eXBlb2Ygc291cmNlW3Byb3BdICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBkZXN0W3Byb3BdID0gc291cmNlW3Byb3BdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGVzdDtcbn1cblxucG9pbnRlckV4dGVuZC5wcmVmaXhlZFByb3BSRXMgPSB7XG4gIHdlYmtpdDogLyhNb3ZlbWVudFtYWV18UmFkaXVzW1hZXXxSb3RhdGlvbkFuZ2xlfEZvcmNlKSQvXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHBvaW50ZXJFeHRlbmQ7XG5cbn0se31dLDQ5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGh5cG90ID0gcmVxdWlyZSgnLi9oeXBvdCcpO1xudmFyIGJyb3dzZXIgPSByZXF1aXJlKCcuL2Jyb3dzZXInKTtcbnZhciBkb20gPSByZXF1aXJlKCcuL2RvbU9iamVjdHMnKTtcbnZhciBkb21VdGlscyA9IHJlcXVpcmUoJy4vZG9tVXRpbHMnKTtcbnZhciBkb21PYmplY3RzID0gcmVxdWlyZSgnLi9kb21PYmplY3RzJyk7XG52YXIgaXMgPSByZXF1aXJlKCcuL2lzJyk7XG52YXIgcG9pbnRlckV4dGVuZCA9IHJlcXVpcmUoJy4vcG9pbnRlckV4dGVuZCcpO1xuXG52YXIgcG9pbnRlclV0aWxzID0ge1xuICBjb3B5Q29vcmRzOiBmdW5jdGlvbiBjb3B5Q29vcmRzKGRlc3QsIHNyYykge1xuICAgIGRlc3QucGFnZSA9IGRlc3QucGFnZSB8fCB7fTtcbiAgICBkZXN0LnBhZ2UueCA9IHNyYy5wYWdlLng7XG4gICAgZGVzdC5wYWdlLnkgPSBzcmMucGFnZS55O1xuXG4gICAgZGVzdC5jbGllbnQgPSBkZXN0LmNsaWVudCB8fCB7fTtcbiAgICBkZXN0LmNsaWVudC54ID0gc3JjLmNsaWVudC54O1xuICAgIGRlc3QuY2xpZW50LnkgPSBzcmMuY2xpZW50Lnk7XG5cbiAgICBkZXN0LnRpbWVTdGFtcCA9IHNyYy50aW1lU3RhbXA7XG4gIH0sXG5cbiAgc2V0Q29vcmREZWx0YXM6IGZ1bmN0aW9uIHNldENvb3JkRGVsdGFzKHRhcmdldE9iaiwgcHJldiwgY3VyKSB7XG4gICAgdGFyZ2V0T2JqLnBhZ2UueCA9IGN1ci5wYWdlLnggLSBwcmV2LnBhZ2UueDtcbiAgICB0YXJnZXRPYmoucGFnZS55ID0gY3VyLnBhZ2UueSAtIHByZXYucGFnZS55O1xuICAgIHRhcmdldE9iai5jbGllbnQueCA9IGN1ci5jbGllbnQueCAtIHByZXYuY2xpZW50Lng7XG4gICAgdGFyZ2V0T2JqLmNsaWVudC55ID0gY3VyLmNsaWVudC55IC0gcHJldi5jbGllbnQueTtcbiAgICB0YXJnZXRPYmoudGltZVN0YW1wID0gY3VyLnRpbWVTdGFtcCAtIHByZXYudGltZVN0YW1wO1xuXG4gICAgLy8gc2V0IHBvaW50ZXIgdmVsb2NpdHlcbiAgICB2YXIgZHQgPSBNYXRoLm1heCh0YXJnZXRPYmoudGltZVN0YW1wIC8gMTAwMCwgMC4wMDEpO1xuXG4gICAgdGFyZ2V0T2JqLnBhZ2Uuc3BlZWQgPSBoeXBvdCh0YXJnZXRPYmoucGFnZS54LCB0YXJnZXRPYmoucGFnZS55KSAvIGR0O1xuICAgIHRhcmdldE9iai5wYWdlLnZ4ID0gdGFyZ2V0T2JqLnBhZ2UueCAvIGR0O1xuICAgIHRhcmdldE9iai5wYWdlLnZ5ID0gdGFyZ2V0T2JqLnBhZ2UueSAvIGR0O1xuXG4gICAgdGFyZ2V0T2JqLmNsaWVudC5zcGVlZCA9IGh5cG90KHRhcmdldE9iai5jbGllbnQueCwgdGFyZ2V0T2JqLnBhZ2UueSkgLyBkdDtcbiAgICB0YXJnZXRPYmouY2xpZW50LnZ4ID0gdGFyZ2V0T2JqLmNsaWVudC54IC8gZHQ7XG4gICAgdGFyZ2V0T2JqLmNsaWVudC52eSA9IHRhcmdldE9iai5jbGllbnQueSAvIGR0O1xuICB9LFxuXG4gIGlzTmF0aXZlUG9pbnRlcjogZnVuY3Rpb24gaXNOYXRpdmVQb2ludGVyKHBvaW50ZXIpIHtcbiAgICByZXR1cm4gcG9pbnRlciBpbnN0YW5jZW9mIGRvbS5FdmVudCB8fCBwb2ludGVyIGluc3RhbmNlb2YgZG9tLlRvdWNoO1xuICB9LFxuXG4gIC8vIEdldCBzcGVjaWZpZWQgWC9ZIGNvb3JkcyBmb3IgbW91c2Ugb3IgZXZlbnQudG91Y2hlc1swXVxuICBnZXRYWTogZnVuY3Rpb24gZ2V0WFkodHlwZSwgcG9pbnRlciwgeHkpIHtcbiAgICB4eSA9IHh5IHx8IHt9O1xuICAgIHR5cGUgPSB0eXBlIHx8ICdwYWdlJztcblxuICAgIHh5LnggPSBwb2ludGVyW3R5cGUgKyAnWCddO1xuICAgIHh5LnkgPSBwb2ludGVyW3R5cGUgKyAnWSddO1xuXG4gICAgcmV0dXJuIHh5O1xuICB9LFxuXG4gIGdldFBhZ2VYWTogZnVuY3Rpb24gZ2V0UGFnZVhZKHBvaW50ZXIsIHBhZ2UpIHtcbiAgICBwYWdlID0gcGFnZSB8fCB7fTtcblxuICAgIC8vIE9wZXJhIE1vYmlsZSBoYW5kbGVzIHRoZSB2aWV3cG9ydCBhbmQgc2Nyb2xsaW5nIG9kZGx5XG4gICAgaWYgKGJyb3dzZXIuaXNPcGVyYU1vYmlsZSAmJiBwb2ludGVyVXRpbHMuaXNOYXRpdmVQb2ludGVyKHBvaW50ZXIpKSB7XG4gICAgICBwb2ludGVyVXRpbHMuZ2V0WFkoJ3NjcmVlbicsIHBvaW50ZXIsIHBhZ2UpO1xuXG4gICAgICBwYWdlLnggKz0gd2luZG93LnNjcm9sbFg7XG4gICAgICBwYWdlLnkgKz0gd2luZG93LnNjcm9sbFk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBvaW50ZXJVdGlscy5nZXRYWSgncGFnZScsIHBvaW50ZXIsIHBhZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBwYWdlO1xuICB9LFxuXG4gIGdldENsaWVudFhZOiBmdW5jdGlvbiBnZXRDbGllbnRYWShwb2ludGVyLCBjbGllbnQpIHtcbiAgICBjbGllbnQgPSBjbGllbnQgfHwge307XG5cbiAgICBpZiAoYnJvd3Nlci5pc09wZXJhTW9iaWxlICYmIHBvaW50ZXJVdGlscy5pc05hdGl2ZVBvaW50ZXIocG9pbnRlcikpIHtcbiAgICAgIC8vIE9wZXJhIE1vYmlsZSBoYW5kbGVzIHRoZSB2aWV3cG9ydCBhbmQgc2Nyb2xsaW5nIG9kZGx5XG4gICAgICBwb2ludGVyVXRpbHMuZ2V0WFkoJ3NjcmVlbicsIHBvaW50ZXIsIGNsaWVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBvaW50ZXJVdGlscy5nZXRYWSgnY2xpZW50JywgcG9pbnRlciwgY2xpZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xpZW50O1xuICB9LFxuXG4gIGdldFBvaW50ZXJJZDogZnVuY3Rpb24gZ2V0UG9pbnRlcklkKHBvaW50ZXIpIHtcbiAgICByZXR1cm4gaXMubnVtYmVyKHBvaW50ZXIucG9pbnRlcklkKSA/IHBvaW50ZXIucG9pbnRlcklkIDogcG9pbnRlci5pZGVudGlmaWVyO1xuICB9LFxuXG4gIHNldENvb3JkczogZnVuY3Rpb24gc2V0Q29vcmRzKHRhcmdldE9iaiwgcG9pbnRlcnMsIHRpbWVTdGFtcCkge1xuICAgIHZhciBwb2ludGVyID0gcG9pbnRlcnMubGVuZ3RoID4gMSA/IHBvaW50ZXJVdGlscy5wb2ludGVyQXZlcmFnZShwb2ludGVycykgOiBwb2ludGVyc1swXTtcblxuICAgIHZhciB0bXBYWSA9IHt9O1xuXG4gICAgcG9pbnRlclV0aWxzLmdldFBhZ2VYWShwb2ludGVyLCB0bXBYWSk7XG4gICAgdGFyZ2V0T2JqLnBhZ2UueCA9IHRtcFhZLng7XG4gICAgdGFyZ2V0T2JqLnBhZ2UueSA9IHRtcFhZLnk7XG5cbiAgICBwb2ludGVyVXRpbHMuZ2V0Q2xpZW50WFkocG9pbnRlciwgdG1wWFkpO1xuICAgIHRhcmdldE9iai5jbGllbnQueCA9IHRtcFhZLng7XG4gICAgdGFyZ2V0T2JqLmNsaWVudC55ID0gdG1wWFkueTtcblxuICAgIHRhcmdldE9iai50aW1lU3RhbXAgPSBpcy5udW1iZXIodGltZVN0YW1wKSA/IHRpbWVTdGFtcCA6IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICB9LFxuXG4gIHBvaW50ZXJFeHRlbmQ6IHBvaW50ZXJFeHRlbmQsXG5cbiAgZ2V0VG91Y2hQYWlyOiBmdW5jdGlvbiBnZXRUb3VjaFBhaXIoZXZlbnQpIHtcbiAgICB2YXIgdG91Y2hlcyA9IFtdO1xuXG4gICAgLy8gYXJyYXkgb2YgdG91Y2hlcyBpcyBzdXBwbGllZFxuICAgIGlmIChpcy5hcnJheShldmVudCkpIHtcbiAgICAgIHRvdWNoZXNbMF0gPSBldmVudFswXTtcbiAgICAgIHRvdWNoZXNbMV0gPSBldmVudFsxXTtcbiAgICB9XG4gICAgLy8gYW4gZXZlbnRcbiAgICBlbHNlIHtcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICd0b3VjaGVuZCcpIHtcbiAgICAgICAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHRvdWNoZXNbMF0gPSBldmVudC50b3VjaGVzWzBdO1xuICAgICAgICAgICAgdG91Y2hlc1sxXSA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRvdWNoZXNbMF0gPSBldmVudC5jaGFuZ2VkVG91Y2hlc1swXTtcbiAgICAgICAgICAgIHRvdWNoZXNbMV0gPSBldmVudC5jaGFuZ2VkVG91Y2hlc1sxXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG91Y2hlc1swXSA9IGV2ZW50LnRvdWNoZXNbMF07XG4gICAgICAgICAgdG91Y2hlc1sxXSA9IGV2ZW50LnRvdWNoZXNbMV07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgIHJldHVybiB0b3VjaGVzO1xuICB9LFxuXG4gIHBvaW50ZXJBdmVyYWdlOiBmdW5jdGlvbiBwb2ludGVyQXZlcmFnZShwb2ludGVycykge1xuICAgIHZhciBhdmVyYWdlID0ge1xuICAgICAgcGFnZVg6IDAsXG4gICAgICBwYWdlWTogMCxcbiAgICAgIGNsaWVudFg6IDAsXG4gICAgICBjbGllbnRZOiAwLFxuICAgICAgc2NyZWVuWDogMCxcbiAgICAgIHNjcmVlblk6IDBcbiAgICB9O1xuXG4gICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gcG9pbnRlcnMsIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IpLCBfaSA9IDAsIF9pdGVyYXRvciA9IF9pc0FycmF5ID8gX2l0ZXJhdG9yIDogX2l0ZXJhdG9yW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICB2YXIgX3JlZjtcblxuICAgICAgaWYgKF9pc0FycmF5KSB7XG4gICAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcbiAgICAgICAgX3JlZiA9IF9pdGVyYXRvcltfaSsrXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9pID0gX2l0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKF9pLmRvbmUpIGJyZWFrO1xuICAgICAgICBfcmVmID0gX2kudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBwb2ludGVyID0gX3JlZjtcblxuICAgICAgZm9yICh2YXIgX3Byb3AgaW4gYXZlcmFnZSkge1xuICAgICAgICBhdmVyYWdlW19wcm9wXSArPSBwb2ludGVyW19wcm9wXTtcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yICh2YXIgcHJvcCBpbiBhdmVyYWdlKSB7XG4gICAgICBhdmVyYWdlW3Byb3BdIC89IHBvaW50ZXJzLmxlbmd0aDtcbiAgICB9XG5cbiAgICByZXR1cm4gYXZlcmFnZTtcbiAgfSxcblxuICB0b3VjaEJCb3g6IGZ1bmN0aW9uIHRvdWNoQkJveChldmVudCkge1xuICAgIGlmICghZXZlbnQubGVuZ3RoICYmICEoZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzLmxlbmd0aCA+IDEpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRvdWNoZXMgPSBwb2ludGVyVXRpbHMuZ2V0VG91Y2hQYWlyKGV2ZW50KTtcbiAgICB2YXIgbWluWCA9IE1hdGgubWluKHRvdWNoZXNbMF0ucGFnZVgsIHRvdWNoZXNbMV0ucGFnZVgpO1xuICAgIHZhciBtaW5ZID0gTWF0aC5taW4odG91Y2hlc1swXS5wYWdlWSwgdG91Y2hlc1sxXS5wYWdlWSk7XG4gICAgdmFyIG1heFggPSBNYXRoLm1heCh0b3VjaGVzWzBdLnBhZ2VYLCB0b3VjaGVzWzFdLnBhZ2VYKTtcbiAgICB2YXIgbWF4WSA9IE1hdGgubWF4KHRvdWNoZXNbMF0ucGFnZVksIHRvdWNoZXNbMV0ucGFnZVkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IG1pblgsXG4gICAgICB5OiBtaW5ZLFxuICAgICAgbGVmdDogbWluWCxcbiAgICAgIHRvcDogbWluWSxcbiAgICAgIHdpZHRoOiBtYXhYIC0gbWluWCxcbiAgICAgIGhlaWdodDogbWF4WSAtIG1pbllcbiAgICB9O1xuICB9LFxuXG4gIHRvdWNoRGlzdGFuY2U6IGZ1bmN0aW9uIHRvdWNoRGlzdGFuY2UoZXZlbnQsIGRlbHRhU291cmNlKSB7XG4gICAgdmFyIHNvdXJjZVggPSBkZWx0YVNvdXJjZSArICdYJztcbiAgICB2YXIgc291cmNlWSA9IGRlbHRhU291cmNlICsgJ1knO1xuICAgIHZhciB0b3VjaGVzID0gcG9pbnRlclV0aWxzLmdldFRvdWNoUGFpcihldmVudCk7XG5cbiAgICB2YXIgZHggPSB0b3VjaGVzWzBdW3NvdXJjZVhdIC0gdG91Y2hlc1sxXVtzb3VyY2VYXTtcbiAgICB2YXIgZHkgPSB0b3VjaGVzWzBdW3NvdXJjZVldIC0gdG91Y2hlc1sxXVtzb3VyY2VZXTtcblxuICAgIHJldHVybiBoeXBvdChkeCwgZHkpO1xuICB9LFxuXG4gIHRvdWNoQW5nbGU6IGZ1bmN0aW9uIHRvdWNoQW5nbGUoZXZlbnQsIHByZXZBbmdsZSwgZGVsdGFTb3VyY2UpIHtcbiAgICB2YXIgc291cmNlWCA9IGRlbHRhU291cmNlICsgJ1gnO1xuICAgIHZhciBzb3VyY2VZID0gZGVsdGFTb3VyY2UgKyAnWSc7XG4gICAgdmFyIHRvdWNoZXMgPSBwb2ludGVyVXRpbHMuZ2V0VG91Y2hQYWlyKGV2ZW50KTtcbiAgICB2YXIgZHggPSB0b3VjaGVzWzFdW3NvdXJjZVhdIC0gdG91Y2hlc1swXVtzb3VyY2VYXTtcbiAgICB2YXIgZHkgPSB0b3VjaGVzWzFdW3NvdXJjZVldIC0gdG91Y2hlc1swXVtzb3VyY2VZXTtcbiAgICB2YXIgYW5nbGUgPSAxODAgKiBNYXRoLmF0YW4yKGR5LCBkeCkgLyBNYXRoLlBJO1xuXG4gICAgcmV0dXJuIGFuZ2xlO1xuICB9LFxuXG4gIGdldFBvaW50ZXJUeXBlOiBmdW5jdGlvbiBnZXRQb2ludGVyVHlwZShwb2ludGVyKSB7XG4gICAgcmV0dXJuIGlzLnN0cmluZyhwb2ludGVyLnBvaW50ZXJUeXBlKSA/IHBvaW50ZXIucG9pbnRlclR5cGUgOiBpcy5udW1iZXIocG9pbnRlci5wb2ludGVyVHlwZSkgPyBbdW5kZWZpbmVkLCB1bmRlZmluZWQsICd0b3VjaCcsICdwZW4nLCAnbW91c2UnXVtwb2ludGVyLnBvaW50ZXJUeXBlXVxuICAgIC8vIGlmIHRoZSBQb2ludGVyRXZlbnQgQVBJIGlzbid0IGF2YWlsYWJsZSwgdGhlbiB0aGUgXCJwb2ludGVyXCIgbXVzdFxuICAgIC8vIGJlIGVpdGhlciBhIE1vdXNlRXZlbnQsIFRvdWNoRXZlbnQsIG9yIFRvdWNoIG9iamVjdFxuICAgIDogL3RvdWNoLy50ZXN0KHBvaW50ZXIudHlwZSkgfHwgcG9pbnRlciBpbnN0YW5jZW9mIGRvbU9iamVjdHMuVG91Y2ggPyAndG91Y2gnIDogJ21vdXNlJztcbiAgfSxcblxuICAvLyBbIGV2ZW50LnRhcmdldCwgZXZlbnQuY3VycmVudFRhcmdldCBdXG4gIGdldEV2ZW50VGFyZ2V0czogZnVuY3Rpb24gZ2V0RXZlbnRUYXJnZXRzKGV2ZW50KSB7XG4gICAgcmV0dXJuIFtkb21VdGlscy5nZXRBY3R1YWxFbGVtZW50KGV2ZW50LnBhdGggPyBldmVudC5wYXRoWzBdIDogZXZlbnQudGFyZ2V0KSwgZG9tVXRpbHMuZ2V0QWN0dWFsRWxlbWVudChldmVudC5jdXJyZW50VGFyZ2V0KV07XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gcG9pbnRlclV0aWxzO1xuXG59LHtcIi4vYnJvd3NlclwiOjM3LFwiLi9kb21PYmplY3RzXCI6MzgsXCIuL2RvbVV0aWxzXCI6MzksXCIuL2h5cG90XCI6NDMsXCIuL2lzXCI6NDYsXCIuL3BvaW50ZXJFeHRlbmRcIjo0OH1dLDUwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnLi93aW5kb3cnKSxcbiAgICB3aW5kb3cgPSBfcmVxdWlyZS53aW5kb3c7XG5cbnZhciB2ZW5kb3JzID0gWydtcycsICdtb3onLCAnd2Via2l0JywgJ28nXTtcbnZhciBsYXN0VGltZSA9IDA7XG52YXIgcmVxdWVzdCA9IHZvaWQgMDtcbnZhciBjYW5jZWwgPSB2b2lkIDA7XG5cbmZvciAodmFyIHggPSAwOyB4IDwgdmVuZG9ycy5sZW5ndGggJiYgIXdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWU7IHgrKykge1xuICByZXF1ZXN0ID0gd2luZG93W3ZlbmRvcnNbeF0gKyAnUmVxdWVzdEFuaW1hdGlvbkZyYW1lJ107XG4gIGNhbmNlbCA9IHdpbmRvd1t2ZW5kb3JzW3hdICsgJ0NhbmNlbEFuaW1hdGlvbkZyYW1lJ10gfHwgd2luZG93W3ZlbmRvcnNbeF0gKyAnQ2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lJ107XG59XG5cbmlmICghcmVxdWVzdCkge1xuICByZXF1ZXN0ID0gZnVuY3Rpb24gcmVxdWVzdChjYWxsYmFjaykge1xuICAgIHZhciBjdXJyVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIHZhciB0aW1lVG9DYWxsID0gTWF0aC5tYXgoMCwgMTYgLSAoY3VyclRpbWUgLSBsYXN0VGltZSkpO1xuICAgIHZhciBpZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgY2FsbGJhY2soY3VyclRpbWUgKyB0aW1lVG9DYWxsKTtcbiAgICB9LCB0aW1lVG9DYWxsKTtcblxuICAgIGxhc3RUaW1lID0gY3VyclRpbWUgKyB0aW1lVG9DYWxsO1xuICAgIHJldHVybiBpZDtcbiAgfTtcbn1cblxuaWYgKCFjYW5jZWwpIHtcbiAgY2FuY2VsID0gZnVuY3Rpb24gY2FuY2VsKGlkKSB7XG4gICAgY2xlYXJUaW1lb3V0KGlkKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJlcXVlc3Q6IHJlcXVlc3QsXG4gIGNhbmNlbDogY2FuY2VsXG59O1xuXG59LHtcIi4vd2luZG93XCI6NTJ9XSw1MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBleHRlbmQgPSByZXF1aXJlKCcuL2V4dGVuZCcpO1xudmFyIGlzID0gcmVxdWlyZSgnLi9pcycpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCcuL2RvbVV0aWxzJyksXG4gICAgY2xvc2VzdCA9IF9yZXF1aXJlLmNsb3Nlc3QsXG4gICAgcGFyZW50Tm9kZSA9IF9yZXF1aXJlLnBhcmVudE5vZGUsXG4gICAgZ2V0RWxlbWVudFJlY3QgPSBfcmVxdWlyZS5nZXRFbGVtZW50UmVjdDtcblxudmFyIHJlY3RVdGlscyA9IHtcbiAgZ2V0U3RyaW5nT3B0aW9uUmVzdWx0OiBmdW5jdGlvbiBnZXRTdHJpbmdPcHRpb25SZXN1bHQodmFsdWUsIGludGVyYWN0YWJsZSwgZWxlbWVudCkge1xuICAgIGlmICghaXMuc3RyaW5nKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlID09PSAncGFyZW50Jykge1xuICAgICAgdmFsdWUgPSBwYXJlbnROb2RlKGVsZW1lbnQpO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICdzZWxmJykge1xuICAgICAgdmFsdWUgPSBpbnRlcmFjdGFibGUuZ2V0UmVjdChlbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgPSBjbG9zZXN0KGVsZW1lbnQsIHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG5cbiAgcmVzb2x2ZVJlY3RMaWtlOiBmdW5jdGlvbiByZXNvbHZlUmVjdExpa2UodmFsdWUsIGludGVyYWN0YWJsZSwgZWxlbWVudCwgZnVuY3Rpb25BcmdzKSB7XG4gICAgdmFsdWUgPSByZWN0VXRpbHMuZ2V0U3RyaW5nT3B0aW9uUmVzdWx0KHZhbHVlLCBpbnRlcmFjdGFibGUsIGVsZW1lbnQpIHx8IHZhbHVlO1xuXG4gICAgaWYgKGlzLmZ1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFsdWUgPSB2YWx1ZS5hcHBseShudWxsLCBmdW5jdGlvbkFyZ3MpO1xuICAgIH1cblxuICAgIGlmIChpcy5lbGVtZW50KHZhbHVlKSkge1xuICAgICAgdmFsdWUgPSBnZXRFbGVtZW50UmVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuXG4gIHJlY3RUb1hZOiBmdW5jdGlvbiByZWN0VG9YWShyZWN0KSB7XG4gICAgcmV0dXJuIHJlY3QgJiYge1xuICAgICAgeDogJ3gnIGluIHJlY3QgPyByZWN0LnggOiByZWN0LmxlZnQsXG4gICAgICB5OiAneScgaW4gcmVjdCA/IHJlY3QueSA6IHJlY3QudG9wXG4gICAgfTtcbiAgfSxcblxuICB4eXdoVG9UbGJyOiBmdW5jdGlvbiB4eXdoVG9UbGJyKHJlY3QpIHtcbiAgICBpZiAocmVjdCAmJiAhKCdsZWZ0JyBpbiByZWN0ICYmICd0b3AnIGluIHJlY3QpKSB7XG4gICAgICByZWN0ID0gZXh0ZW5kKHt9LCByZWN0KTtcblxuICAgICAgcmVjdC5sZWZ0ID0gcmVjdC54IHx8IDA7XG4gICAgICByZWN0LnRvcCA9IHJlY3QueSB8fCAwO1xuICAgICAgcmVjdC5yaWdodCA9IHJlY3QucmlnaHQgfHwgcmVjdC5sZWZ0ICsgcmVjdC53aWR0aDtcbiAgICAgIHJlY3QuYm90dG9tID0gcmVjdC5ib3R0b20gfHwgcmVjdC50b3AgKyByZWN0LmhlaWdodDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVjdDtcbiAgfSxcblxuICB0bGJyVG9YeXdoOiBmdW5jdGlvbiB0bGJyVG9YeXdoKHJlY3QpIHtcbiAgICBpZiAocmVjdCAmJiAhKCd4JyBpbiByZWN0ICYmICd5JyBpbiByZWN0KSkge1xuICAgICAgcmVjdCA9IGV4dGVuZCh7fSwgcmVjdCk7XG5cbiAgICAgIHJlY3QueCA9IHJlY3QubGVmdCB8fCAwO1xuICAgICAgcmVjdC50b3AgPSByZWN0LnRvcCB8fCAwO1xuICAgICAgcmVjdC53aWR0aCA9IHJlY3Qud2lkdGggfHwgcmVjdC5yaWdodCAtIHJlY3QueDtcbiAgICAgIHJlY3QuaGVpZ2h0ID0gcmVjdC5oZWlnaHQgfHwgcmVjdC5ib3R0b20gLSByZWN0Lnk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlY3Q7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gcmVjdFV0aWxzO1xuXG59LHtcIi4vZG9tVXRpbHNcIjozOSxcIi4vZXh0ZW5kXCI6NDEsXCIuL2lzXCI6NDZ9XSw1MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciB3aW4gPSBtb2R1bGUuZXhwb3J0cztcbnZhciBpc1dpbmRvdyA9IHJlcXVpcmUoJy4vaXNXaW5kb3cnKTtcblxuZnVuY3Rpb24gaW5pdCh3aW5kb3cpIHtcbiAgLy8gZ2V0IHdyYXBwZWQgd2luZG93IGlmIHVzaW5nIFNoYWRvdyBET00gcG9seWZpbGxcblxuICB3aW4ucmVhbFdpbmRvdyA9IHdpbmRvdztcblxuICAvLyBjcmVhdGUgYSBUZXh0Tm9kZVxuICB2YXIgZWwgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuXG4gIC8vIGNoZWNrIGlmIGl0J3Mgd3JhcHBlZCBieSBhIHBvbHlmaWxsXG4gIGlmIChlbC5vd25lckRvY3VtZW50ICE9PSB3aW5kb3cuZG9jdW1lbnQgJiYgdHlwZW9mIHdpbmRvdy53cmFwID09PSAnZnVuY3Rpb24nICYmIHdpbmRvdy53cmFwKGVsKSA9PT0gZWwpIHtcbiAgICAvLyB1c2Ugd3JhcHBlZCB3aW5kb3dcbiAgICB3aW5kb3cgPSB3aW5kb3cud3JhcCh3aW5kb3cpO1xuICB9XG5cbiAgd2luLndpbmRvdyA9IHdpbmRvdztcbn1cblxuaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gIHdpbi53aW5kb3cgPSB1bmRlZmluZWQ7XG4gIHdpbi5yZWFsV2luZG93ID0gdW5kZWZpbmVkO1xufSBlbHNlIHtcbiAgaW5pdCh3aW5kb3cpO1xufVxuXG53aW4uZ2V0V2luZG93ID0gZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHtcbiAgaWYgKGlzV2luZG93KG5vZGUpKSB7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICB2YXIgcm9vdE5vZGUgPSBub2RlLm93bmVyRG9jdW1lbnQgfHwgbm9kZTtcblxuICByZXR1cm4gcm9vdE5vZGUuZGVmYXVsdFZpZXcgfHwgcm9vdE5vZGUucGFyZW50V2luZG93IHx8IHdpbi53aW5kb3c7XG59O1xuXG53aW4uaW5pdCA9IGluaXQ7XG5cbn0se1wiLi9pc1dpbmRvd1wiOjQ3fV19LHt9LFsxXSkoMSlcbn0pO1xuXG5cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludGVyYWN0LmpzLm1hcFxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvaW50ZXJhY3Rqcy9kaXN0L2ludGVyYWN0LmpzXG4vLyBtb2R1bGUgaWQgPSAxNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///16\n"); +eval("module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n ref: \"item\",\n staticClass: \"vue-grid-item\",\n class: {\n 'vue-resizable': _vm.resizable, 'resizing': _vm.isResizing, 'vue-draggable-dragging': _vm.isDragging, 'cssTransforms': _vm.useCssTransforms, 'render-rtl': _vm.renderRtl\n },\n style: (_vm.style)\n }, [_vm._t(\"default\"), _vm._v(\" \"), (_vm.resizable) ? _c('span', {\n ref: \"handle\",\n class: _vm.resizableHandleClass\n }) : _vm._e()], 2)\n},staticRenderFns: []}\nmodule.exports.render._withStripped = true\nif (false) {\n module.hot.accept()\n if (module.hot.data) {\n require(\"vue-hot-reload-api\").rerender(\"data-v-f2ef9cd2\", module.exports)\n }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlPzEyMDIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZ0JBQWdCLG1CQUFtQixhQUFhLDBCQUEwQjtBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjE2LmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCdkaXYnLCB7XG4gICAgcmVmOiBcIml0ZW1cIixcbiAgICBzdGF0aWNDbGFzczogXCJ2dWUtZ3JpZC1pdGVtXCIsXG4gICAgY2xhc3M6IHtcbiAgICAgICd2dWUtcmVzaXphYmxlJzogX3ZtLnJlc2l6YWJsZSwgJ3Jlc2l6aW5nJzogX3ZtLmlzUmVzaXppbmcsICd2dWUtZHJhZ2dhYmxlLWRyYWdnaW5nJzogX3ZtLmlzRHJhZ2dpbmcsICdjc3NUcmFuc2Zvcm1zJzogX3ZtLnVzZUNzc1RyYW5zZm9ybXMsICdyZW5kZXItcnRsJzogX3ZtLnJlbmRlclJ0bFxuICAgIH0sXG4gICAgc3R5bGU6IChfdm0uc3R5bGUpXG4gIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLnJlc2l6YWJsZSkgPyBfYygnc3BhbicsIHtcbiAgICByZWY6IFwiaGFuZGxlXCIsXG4gICAgY2xhc3M6IF92bS5yZXNpemFibGVIYW5kbGVDbGFzc1xuICB9KSA6IF92bS5fZSgpXSwgMilcbn0sc3RhdGljUmVuZGVyRm5zOiBbXX1cbm1vZHVsZS5leHBvcnRzLnJlbmRlci5fd2l0aFN0cmlwcGVkID0gdHJ1ZVxuaWYgKG1vZHVsZS5ob3QpIHtcbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtZjJlZjljZDJcIiwgbW9kdWxlLmV4cG9ydHMpXG4gIH1cbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlcj97XCJpZFwiOlwiZGF0YS12LWYyZWY5Y2QyXCJ9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDE2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///16\n"); /***/ }), /* 17 */ /***/ (function(module, exports, __webpack_require__) { -eval("module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n ref: \"item\",\n staticClass: \"vue-grid-item\",\n class: {\n 'vue-resizable': _vm.resizable, 'resizing': _vm.isResizing, 'vue-draggable-dragging': _vm.isDragging, 'cssTransforms': _vm.useCssTransforms, 'render-rtl': _vm.renderRtl\n },\n style: (_vm.style)\n }, [_vm._t(\"default\"), _vm._v(\" \"), (_vm.resizable) ? _c('span', {\n ref: \"handle\",\n class: _vm.resizableHandleClass\n }) : _vm._e()], 2)\n},staticRenderFns: []}\nmodule.exports.render._withStripped = true\nif (false) {\n module.hot.accept()\n if (module.hot.data) {\n require(\"vue-hot-reload-api\").rerender(\"data-v-f2ef9cd2\", module.exports)\n }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZEl0ZW0udnVlPzEyMDIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZ0JBQWdCLG1CQUFtQixhQUFhLDBCQUEwQjtBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjE3LmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt2YXIgX3ZtPXRoaXM7dmFyIF9oPV92bS4kY3JlYXRlRWxlbWVudDt2YXIgX2M9X3ZtLl9zZWxmLl9jfHxfaDtcbiAgcmV0dXJuIF9jKCdkaXYnLCB7XG4gICAgcmVmOiBcIml0ZW1cIixcbiAgICBzdGF0aWNDbGFzczogXCJ2dWUtZ3JpZC1pdGVtXCIsXG4gICAgY2xhc3M6IHtcbiAgICAgICd2dWUtcmVzaXphYmxlJzogX3ZtLnJlc2l6YWJsZSwgJ3Jlc2l6aW5nJzogX3ZtLmlzUmVzaXppbmcsICd2dWUtZHJhZ2dhYmxlLWRyYWdnaW5nJzogX3ZtLmlzRHJhZ2dpbmcsICdjc3NUcmFuc2Zvcm1zJzogX3ZtLnVzZUNzc1RyYW5zZm9ybXMsICdyZW5kZXItcnRsJzogX3ZtLnJlbmRlclJ0bFxuICAgIH0sXG4gICAgc3R5bGU6IChfdm0uc3R5bGUpXG4gIH0sIFtfdm0uX3QoXCJkZWZhdWx0XCIpLCBfdm0uX3YoXCIgXCIpLCAoX3ZtLnJlc2l6YWJsZSkgPyBfYygnc3BhbicsIHtcbiAgICByZWY6IFwiaGFuZGxlXCIsXG4gICAgY2xhc3M6IF92bS5yZXNpemFibGVIYW5kbGVDbGFzc1xuICB9KSA6IF92bS5fZSgpXSwgMilcbn0sc3RhdGljUmVuZGVyRm5zOiBbXX1cbm1vZHVsZS5leHBvcnRzLnJlbmRlci5fd2l0aFN0cmlwcGVkID0gdHJ1ZVxuaWYgKG1vZHVsZS5ob3QpIHtcbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtZjJlZjljZDJcIiwgbW9kdWxlLmV4cG9ydHMpXG4gIH1cbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlcj97XCJpZFwiOlwiZGF0YS12LWYyZWY5Y2QyXCJ9IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3NyYy9HcmlkSXRlbS52dWVcbi8vIG1vZHVsZSBpZCA9IDE3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///17\n"); +eval("\n/* styles */\n__webpack_require__(18)\n\nvar Component = __webpack_require__(4)(\n /* script */\n __webpack_require__(20),\n /* template */\n __webpack_require__(33),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\nComponent.options.__file = \"C:\\\\projects\\\\JBAY\\\\vue-grid-layout\\\\src\\\\GridLayout.vue\"\nif (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== \"default\" && key !== \"__esModule\"})) {console.error(\"named exports are not supported in *.vue files.\")}\nif (Component.options.functional) {console.error(\"[vue-loader] GridLayout.vue: functional components are not supported with templates, they should use render functions.\")}\n\n/* hot reload */\nif (false) {(function () {\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), false)\n if (!hotAPI.compatible) return\n module.hot.accept()\n if (!module.hot.data) {\n hotAPI.createRecord(\"data-v-3d4bb9a4\", Component.options)\n } else {\n hotAPI.reload(\"data-v-3d4bb9a4\", Component.options)\n }\n})()}\n\nmodule.exports = Component.exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZExheW91dC52dWU/OGFiMCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0E7QUFDQSxzQkFBNEs7O0FBRTVLO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQWdHO0FBQ2hHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtFQUErRSxpREFBaUQsSUFBSTtBQUNwSSxtQ0FBbUM7O0FBRW5DO0FBQ0EsWUFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxDQUFDOztBQUVEIiwiZmlsZSI6IjE3LmpzIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4P3tcXFwiaWRcXFwiOlxcXCJkYXRhLXYtM2Q0YmI5YTRcXFwiLFxcXCJzY29wZWRcXFwiOmZhbHNlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOmZhbHNlfSEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0dyaWRMYXlvdXQudnVlXCIpXG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKFwiIS4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9jb21wb25lbnQtbm9ybWFsaXplclwiKShcbiAgLyogc2NyaXB0ICovXG4gIHJlcXVpcmUoXCIhIWJhYmVsLWxvYWRlciEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zY3JpcHQmaW5kZXg9MCEuL0dyaWRMYXlvdXQudnVlXCIpLFxuICAvKiB0ZW1wbGF0ZSAqL1xuICByZXF1aXJlKFwiISEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXIvaW5kZXg/e1xcXCJpZFxcXCI6XFxcImRhdGEtdi0zZDRiYjlhNFxcXCJ9IS4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXRlbXBsYXRlJmluZGV4PTAhLi9HcmlkTGF5b3V0LnZ1ZVwiKSxcbiAgLyogc2NvcGVJZCAqL1xuICBudWxsLFxuICAvKiBjc3NNb2R1bGVzICovXG4gIG51bGxcbilcbkNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwiQzpcXFxccHJvamVjdHNcXFxcSkJBWVxcXFx2dWUtZ3JpZC1sYXlvdXRcXFxcc3JjXFxcXEdyaWRMYXlvdXQudnVlXCJcbmlmIChDb21wb25lbnQuZXNNb2R1bGUgJiYgT2JqZWN0LmtleXMoQ29tcG9uZW50LmVzTW9kdWxlKS5zb21lKGZ1bmN0aW9uIChrZXkpIHtyZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwifSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5pZiAoQ29tcG9uZW50Lm9wdGlvbnMuZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gR3JpZExheW91dC52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCB3aXRoIHRlbXBsYXRlcywgdGhleSBzaG91bGQgdXNlIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtM2Q0YmI5YTRcIiwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi0zZDRiYjlhNFwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfVxufSkoKX1cblxubW9kdWxlLmV4cG9ydHMgPSBDb21wb25lbnQuZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvR3JpZExheW91dC52dWVcbi8vIG1vZHVsZSBpZCA9IDE3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///17\n"); /***/ }), /* 18 */ /***/ (function(module, exports, __webpack_require__) { -eval("\n/* styles */\n__webpack_require__(19)\n\nvar Component = __webpack_require__(4)(\n /* script */\n __webpack_require__(21),\n /* template */\n __webpack_require__(35),\n /* scopeId */\n null,\n /* cssModules */\n null\n)\nComponent.options.__file = \"/Users/sunzongzheng/work/vue-grid-layout/src/GridLayout.vue\"\nif (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== \"default\" && key !== \"__esModule\"})) {console.error(\"named exports are not supported in *.vue files.\")}\nif (Component.options.functional) {console.error(\"[vue-loader] GridLayout.vue: functional components are not supported with templates, they should use render functions.\")}\n\n/* hot reload */\nif (false) {(function () {\n var hotAPI = require(\"vue-hot-reload-api\")\n hotAPI.install(require(\"vue\"), false)\n if (!hotAPI.compatible) return\n module.hot.accept()\n if (!module.hot.data) {\n hotAPI.createRecord(\"data-v-3d4bb9a4\", Component.options)\n } else {\n hotAPI.reload(\"data-v-3d4bb9a4\", Component.options)\n }\n})()}\n\nmodule.exports = Component.exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZExheW91dC52dWU/OGFiMCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0E7QUFDQSxzQkFBNEs7O0FBRTVLO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQWdHO0FBQ2hHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtFQUErRSxpREFBaUQsSUFBSTtBQUNwSSxtQ0FBbUM7O0FBRW5DO0FBQ0EsWUFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxDQUFDOztBQUVEIiwiZmlsZSI6IjE4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLWNvbXBpbGVyL2luZGV4P3tcXFwiaWRcXFwiOlxcXCJkYXRhLXYtM2Q0YmI5YTRcXFwiLFxcXCJzY29wZWRcXFwiOmZhbHNlLFxcXCJoYXNJbmxpbmVDb25maWdcXFwiOmZhbHNlfSEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0dyaWRMYXlvdXQudnVlXCIpXG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKFwiIS4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9jb21wb25lbnQtbm9ybWFsaXplclwiKShcbiAgLyogc2NyaXB0ICovXG4gIHJlcXVpcmUoXCIhIWJhYmVsLWxvYWRlciEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zY3JpcHQmaW5kZXg9MCEuL0dyaWRMYXlvdXQudnVlXCIpLFxuICAvKiB0ZW1wbGF0ZSAqL1xuICByZXF1aXJlKFwiISEuLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXIvaW5kZXg/e1xcXCJpZFxcXCI6XFxcImRhdGEtdi0zZDRiYjlhNFxcXCJ9IS4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXRlbXBsYXRlJmluZGV4PTAhLi9HcmlkTGF5b3V0LnZ1ZVwiKSxcbiAgLyogc2NvcGVJZCAqL1xuICBudWxsLFxuICAvKiBjc3NNb2R1bGVzICovXG4gIG51bGxcbilcbkNvbXBvbmVudC5vcHRpb25zLl9fZmlsZSA9IFwiL1VzZXJzL3N1bnpvbmd6aGVuZy93b3JrL3Z1ZS1ncmlkLWxheW91dC9zcmMvR3JpZExheW91dC52dWVcIlxuaWYgKENvbXBvbmVudC5lc01vZHVsZSAmJiBPYmplY3Qua2V5cyhDb21wb25lbnQuZXNNb2R1bGUpLnNvbWUoZnVuY3Rpb24gKGtleSkge3JldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCJ9KSkge2NvbnNvbGUuZXJyb3IoXCJuYW1lZCBleHBvcnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluICoudnVlIGZpbGVzLlwiKX1cbmlmIChDb21wb25lbnQub3B0aW9ucy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBHcmlkTGF5b3V0LnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIHdpdGggdGVtcGxhdGVzLCB0aGV5IHNob3VsZCB1c2UgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cbi8qIGhvdCByZWxvYWQgKi9cbmlmIChtb2R1bGUuaG90KSB7KGZ1bmN0aW9uICgpIHtcbiAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcbiAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG4gIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi0zZDRiYjlhNFwiLCBDb21wb25lbnQub3B0aW9ucylcbiAgfSBlbHNlIHtcbiAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTNkNGJiOWE0XCIsIENvbXBvbmVudC5vcHRpb25zKVxuICB9XG59KSgpfVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBvbmVudC5leHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9HcmlkTGF5b3V0LnZ1ZVxuLy8gbW9kdWxlIGlkID0gMThcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///18\n"); +eval("// style-loader: Adds some css to the DOM by adding a \\r\\n\\r\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZExheW91dC52dWU/OWEyYSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOzs7QUFHQTtBQUNBLDZDQUE4Qyx5QkFBeUIsb0NBQW9DLEdBQUcsVUFBVSxpRkFBaUYsS0FBSyxXQUFXLFdBQVcsc2lCQUFzaUIsK0JBQStCLDBDQUEwQyxTQUFTLHNEQUFzRCw4RUFBOEUsb0JBQW9CLDREQUE0RCxnQkFBZ0IsK0NBQStDLHlFQUF5RSx3REFBd0Qsd0JBQXdCLG1EQUFtRCxhQUFhLDBCQUEwQixzQ0FBc0MscUJBQXFCLGdIQUFnSCxvRkFBb0YsMEJBQTBCLGlGQUFpRiw2QkFBNkIsa0ZBQWtGLDJCQUEyQix1RkFBdUYsMEJBQTBCLDBFQUEwRSx3Q0FBd0MscUJBQXFCLGlCQUFpQiwrQkFBK0Isb0ZBQW9GLCtCQUErQixvRkFBb0YsOEJBQThCLHFGQUFxRixvQ0FBb0Msb0ZBQW9GLG1DQUFtQyxvRkFBb0YsMEJBQTBCLG9GQUFvRixjQUFjLGdDQUFnQyx3QkFBd0IsbUVBQW1FLGlIQUFpSCxzS0FBc0ssbUJBQW1CLGFBQWEseUJBQXlCLGdDQUFnQyxvS0FBb0ssK0RBQStELGtCQUFrQixnRkFBZ0YsNkRBQTZELGtCQUFrQix5REFBeUQsd0RBQXdELDBFQUEwRSxzRUFBc0UsYUFBYSx1Q0FBdUMsNkdBQTZHLHVFQUF1RSx3RkFBd0Ysa0NBQWtDLDRDQUE0QyxnREFBZ0Qsb0NBQW9DLCtDQUErQyxrREFBa0Qsa0RBQWtELGdFQUFnRSxtRkFBbUYseUJBQXlCLG1FQUFtRSxnREFBZ0Qsb0RBQW9ELGtFQUFrRSw2R0FBNkcsRUFBRSw4RUFBOEUsc0RBQXNELDZCQUE2QixFQUFFLHlCQUF5QixFQUFFLHFCQUFxQixFQUFFLGdEQUFnRCxrREFBa0Qsa0RBQWtELGdFQUFnRSxtRkFBbUYseUJBQXlCLG1FQUFtRSxnREFBZ0Qsb0RBQW9ELGtFQUFrRSw2R0FBNkcsRUFBRSw4RUFBOEUsc0RBQXNELDZCQUE2QixFQUFFLHlCQUF5QixFQUFFLDBCQUEwQixpQkFBaUIsRUFBRSxhQUFhLHFCQUFxQixvQ0FBb0MsZ0RBQWdELHVFQUF1RSx5RUFBeUUsNENBQTRDLHFCQUFxQixFQUFFLGlCQUFpQixzQ0FBc0Msd0NBQXdDLGlCQUFpQix3Q0FBd0MsMEVBQTBFLGlCQUFpQiwwQ0FBMEMsNEVBQTRFLGlCQUFpQiwwQ0FBMEMsNEVBQTRFLGlCQUFpQixhQUFhLHVCQUF1QixnQ0FBZ0Msb0RBQW9ELDJFQUEyRSxrRUFBa0UsdUVBQXVFLHlCQUF5QixtRUFBbUUseUVBQXlFLDRDQUE0QyxxQkFBcUIsaUJBQWlCLDRDQUE0Qyx3Q0FBd0MsNEVBQTRFLGlCQUFpQiw4Q0FBOEMsMkdBQTJHLGlFQUFpRSxxQkFBcUIsaUJBQWlCLCtDQUErQywrQ0FBK0MsMkdBQTJHLGlCQUFpQixrRUFBa0Usb0ZBQW9GLGdEQUFnRCwrQ0FBK0MsK0NBQStDLCtDQUErQywrQ0FBK0MsbURBQW1ELG1EQUFtRCx5QkFBeUIsRUFBRSx1RUFBdUUseUVBQXlFLHFCQUFxQixPQUFPLG1EQUFtRCxvREFBb0QseUJBQXlCLEVBQUUscUJBQXFCLDJGQUEyRiwyREFBMkQsd0hBQXdILDZCQUE2QixTQUFTLHFCQUFxQiw0QkFBNEIsNEJBQTRCLDBJQUEwSSwrREFBK0QsK0lBQStJLHdDQUF3QywyRkFBMkYsaUJBQWlCLG9FQUFvRSx3RkFBd0YsZ0RBQWdELCtDQUErQywrQ0FBK0MsK0NBQStDLCtDQUErQyxtREFBbUQsbURBQW1ELHlCQUF5QixFQUFFLHVFQUF1RSx5RUFBeUUseUJBQXlCLE9BQU8sbURBQW1ELG9EQUFvRCx5QkFBeUIsRUFBRSxxQkFBcUIsMkRBQTJELHVIQUF1SCw2QkFBNkIsU0FBUyxxQkFBcUIsNEJBQTRCLDRCQUE0QiwrREFBK0QscURBQXFELHdDQUF3Qyw2RkFBNkYsaUJBQWlCLGNBQWMsVUFBVSw4Q0FBOEM7O0FBRXB3VyIsImZpbGUiOiIxOS5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi52dWUtZ3JpZC1sYXlvdXQge1xcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgIHRyYW5zaXRpb246IGhlaWdodCAyMDBtcyBlYXNlO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL0dyaWRMYXlvdXQudnVlPzM0NzBmMzMyXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFhQTtJQUNBLG1CQUFBO0lBQ0EsOEJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiR3JpZExheW91dC52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHRlbXBsYXRlPlxcclxcbiAgICA8ZGl2IHJlZj1cXFwiaXRlbVxcXCIgY2xhc3M9XFxcInZ1ZS1ncmlkLWxheW91dFxcXCIgOnN0eWxlPVxcXCJtZXJnZWRTdHlsZVxcXCI+XFxyXFxuICAgICAgICA8c2xvdD48L3Nsb3Q+XFxyXFxuICAgICAgICA8Z3JpZC1pdGVtIGNsYXNzPVxcXCJ2dWUtZ3JpZC1wbGFjZWhvbGRlclxcXCJcXHJcXG4gICAgICAgICAgICAgICAgICAgdi1zaG93PVxcXCJpc0RyYWdnaW5nXFxcIlxcclxcbiAgICAgICAgICAgICAgICAgICA6eD1cXFwicGxhY2Vob2xkZXIueFxcXCJcXHJcXG4gICAgICAgICAgICAgICAgICAgOnk9XFxcInBsYWNlaG9sZGVyLnlcXFwiXFxyXFxuICAgICAgICAgICAgICAgICAgIDp3PVxcXCJwbGFjZWhvbGRlci53XFxcIlxcclxcbiAgICAgICAgICAgICAgICAgICA6aD1cXFwicGxhY2Vob2xkZXIuaFxcXCJcXHJcXG4gICAgICAgICAgICAgICAgICAgOmk9XFxcInBsYWNlaG9sZGVyLmlcXFwiPjwvZ3JpZC1pdGVtPlxcclxcbiAgICA8L2Rpdj5cXHJcXG48L3RlbXBsYXRlPlxcclxcbjxzdHlsZT5cXHJcXG4gICAgLnZ1ZS1ncmlkLWxheW91dCB7XFxyXFxuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxyXFxuICAgICAgICB0cmFuc2l0aW9uOiBoZWlnaHQgMjAwbXMgZWFzZTtcXHJcXG4gICAgfVxcclxcbjwvc3R5bGU+XFxyXFxuPHNjcmlwdD5cXHJcXG4gICAgaW1wb3J0IFZ1ZSBmcm9tICd2dWUnO1xcclxcbiAgICB2YXIgZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIgPSByZXF1aXJlKFxcXCJlbGVtZW50LXJlc2l6ZS1kZXRlY3RvclxcXCIpO1xcclxcblxcclxcbiAgICBpbXBvcnQge2JvdHRvbSwgY29tcGFjdCwgZ2V0TGF5b3V0SXRlbSwgbW92ZUVsZW1lbnQsIHZhbGlkYXRlTGF5b3V0fSBmcm9tICcuL3V0aWxzJztcXHJcXG4gICAgLy92YXIgZXZlbnRCdXMgPSByZXF1aXJlKCcuL2V2ZW50QnVzJyk7XFxyXFxuICAgIGltcG9ydCBHcmlkSXRlbSBmcm9tICcuL0dyaWRJdGVtLnZ1ZSdcXHJcXG5cXHJcXG4gICAgZXhwb3J0IGRlZmF1bHQge1xcclxcbiAgICAgICAgbmFtZTogXFxcIkdyaWRMYXlvdXRcXFwiLFxcclxcbiAgICAgICAgcHJvdmlkZSgpIHtcXHJcXG4gICAgICAgICAgICByZXR1cm4ge1xcclxcbiAgICAgICAgICAgICAgICBldmVudEJ1czogbnVsbFxcclxcbiAgICAgICAgICAgIH1cXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBjb21wb25lbnRzOiB7XFxyXFxuICAgICAgICAgICAgR3JpZEl0ZW0sXFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgcHJvcHM6IHtcXHJcXG4gICAgICAgICAgICAvLyBJZiB0cnVlLCB0aGUgY29udGFpbmVyIGhlaWdodCBzd2VsbHMgYW5kIGNvbnRyYWN0cyB0byBmaXQgY29udGVudHNcXHJcXG4gICAgICAgICAgICBhdXRvU2l6ZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBjb2xOdW06IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAxMlxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgcm93SGVpZ2h0OiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMTUwXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBtYXhSb3dzOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIG1hcmdpbjoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheSxcXHJcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsxMCwgMTBdO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc1Jlc2l6YWJsZToge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc01pcnJvcmVkOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB1c2VDc3NUcmFuc2Zvcm1zOiB7XFxyXFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxyXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHZlcnRpY2FsQ29tcGFjdDoge1xcclxcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcclxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBsYXlvdXQ6IHtcXHJcXG4gICAgICAgICAgICAgICAgdHlwZTogQXJyYXksXFxyXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgIHJldHVybiB7XFxyXFxuICAgICAgICAgICAgICAgIHdpZHRoOiBudWxsLFxcclxcbiAgICAgICAgICAgICAgICBtZXJnZWRTdHlsZToge30sXFxyXFxuICAgICAgICAgICAgICAgIGxhc3RMYXlvdXRMZW5ndGg6IDAsXFxyXFxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmc6IGZhbHNlLFxcclxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjoge1xcclxcbiAgICAgICAgICAgICAgICAgICAgeDogMCxcXHJcXG4gICAgICAgICAgICAgICAgICAgIHk6IDAsXFxyXFxuICAgICAgICAgICAgICAgICAgICB3OiAwLFxcclxcbiAgICAgICAgICAgICAgICAgICAgaDogMCxcXHJcXG4gICAgICAgICAgICAgICAgICAgIGk6IC0xXFxyXFxuICAgICAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBjcmVhdGVkICgpIHtcXHJcXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuXFxyXFxuICAgICAgICAgICAgLy8gQWNjZXNzaWJsZSByZWZlcm5jZXMgb2YgZnVuY3Rpb25zIGZvciByZW1vdmluZyBpbiBiZWZvcmVEZXN0cm95XFxyXFxuICAgICAgICAgICAgc2VsZi5yZXNpemVFdmVudEhhbmRsZXIgPSBmdW5jdGlvbihldmVudFR5cGUsIGksIHgsIHksIGgsIHcpIHtcXHJcXG4gICAgICAgICAgICAgICAgc2VsZi5yZXNpemVFdmVudChldmVudFR5cGUsIGksIHgsIHksIGgsIHcpO1xcclxcbiAgICAgICAgICAgIH07XFxyXFxuXFxyXFxuICAgICAgICAgICAgc2VsZi5kcmFnRXZlbnRIYW5kbGVyID0gZnVuY3Rpb24oZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KSB7XFxyXFxuICAgICAgICAgICAgICAgIHNlbGYuZHJhZ0V2ZW50KGV2ZW50VHlwZSwgaSwgeCwgeSwgaCwgdyk7XFxyXFxuICAgICAgICAgICAgfTtcXHJcXG5cXHJcXG4gICAgICAgICAgICBzZWxmLl9wcm92aWRlZC5ldmVudEJ1cyA9ICBuZXcgVnVlKCk7XFxyXFxuICAgICAgICAgICAgc2VsZi5ldmVudEJ1cyA9IHNlbGYuX3Byb3ZpZGVkLmV2ZW50QnVzO1xcclxcbiAgICAgICAgICAgIHNlbGYuZXZlbnRCdXMuJG9uKCdyZXNpemVFdmVudCcsIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyKTtcXHJcXG4gICAgICAgICAgICBzZWxmLmV2ZW50QnVzLiRvbignZHJhZ0V2ZW50Jywgc2VsZi5kcmFnRXZlbnRIYW5kbGVyKTtcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICBiZWZvcmVEZXN0cm95OiBmdW5jdGlvbigpe1xcclxcbiAgICAgICAgICAgIC8vUmVtb3ZlIGxpc3RlbmVyc1xcclxcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZigncmVzaXplRXZlbnQnLCBzZWxmLnJlc2l6ZUV2ZW50SGFuZGxlcik7XFxyXFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCdkcmFnRXZlbnQnLCBzZWxmLmRyYWdFdmVudEhhbmRsZXIpO1xcclxcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxcXCJyZXNpemVcXFwiLCBzZWxmLm9uV2luZG93UmVzaXplKVxcclxcbiAgICAgICAgfSxcXHJcXG4gICAgICAgIG1vdW50ZWQ6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdmFsaWRhdGVMYXlvdXQodGhpcy5sYXlvdXQpO1xcclxcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYud2lkdGggPT09IG51bGwpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zZWxmLndpZHRoID0gc2VsZi4kZWwub2Zmc2V0V2lkdGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHNlbGYub25XaW5kb3dSZXNpemUpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdChzZWxmLmxheW91dCwgc2VsZi52ZXJ0aWNhbENvbXBhY3QpO1xcclxcblxcclxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi51cGRhdGVIZWlnaHQoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJkID0gZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIoe1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhdGVneTogXFxcInNjcm9sbFxcXCIgLy88LSBGb3IgdWx0cmEgcGVyZm9ybWFuY2UuXFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJkLmxpc3RlblRvKHNlbGYuJHJlZnMuaXRlbSwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vbldpbmRvd1Jlc2l6ZSgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICB3aW5kb3cub25sb2FkID0gZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi53aWR0aCA9PT0gbnVsbCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NlbGYud2lkdGggPSBzZWxmLiRlbC5vZmZzZXRXaWR0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgc2VsZi5vbldpbmRvd1Jlc2l6ZSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHNlbGYubGF5b3V0LCBzZWxmLnZlcnRpY2FsQ29tcGFjdCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZUhlaWdodCgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlcmQgPSBlbGVtZW50UmVzaXplRGV0ZWN0b3JNYWtlcih7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiBcXFwic2Nyb2xsXFxcIiAvLzwtIEZvciB1bHRyYSBwZXJmb3JtYW5jZS5cXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICBlcmQubGlzdGVuVG8oc2VsZi4kcmVmcy5pdGVtLCBmdW5jdGlvbiAoZWxlbWVudCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG5cXHJcXG4gICAgICAgICAgICAgICAgfTtcXHJcXG4gICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgIH0sXFxyXFxuICAgICAgICB3YXRjaDoge1xcclxcbiAgICAgICAgICAgIHdpZHRoOiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XFxyXFxuICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgbGF5b3V0OiBmdW5jdGlvbiAoKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VXBkYXRlKCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJzZXRSb3dIZWlnaHRcXFwiLCB0aGlzLnJvd0hlaWdodCk7XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBpc0RyYWdnYWJsZTogZnVuY3Rpb24oKSB7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInNldERyYWdnYWJsZVxcXCIsIHRoaXMuaXNEcmFnZ2FibGUpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJzZXRSZXNpemFibGVcXFwiLCB0aGlzLmlzUmVzaXphYmxlKTtcXHJcXG4gICAgICAgICAgICB9XFxyXFxuICAgICAgICB9LFxcclxcbiAgICAgICAgbWV0aG9kczoge1xcclxcbiAgICAgICAgICAgIGxheW91dFVwZGF0ZSgpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubGF5b3V0ICE9PSB1bmRlZmluZWQpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxheW91dC5sZW5ndGggIT09IHRoaXMubGFzdExheW91dExlbmd0aCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coXFxcIiMjIyBMQVlPVVQgVVBEQVRFIVxcXCIpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGFzdExheW91dExlbmd0aCA9IHRoaXMubGF5b3V0Lmxlbmd0aDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgICAgIGNvbXBhY3QodGhpcy5sYXlvdXQsIHRoaXMudmVydGljYWxDb21wYWN0KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICB1cGRhdGVIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy5tZXJnZWRTdHlsZSA9IHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5jb250YWluZXJIZWlnaHQoKVxcclxcbiAgICAgICAgICAgICAgICB9O1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgb25XaW5kb3dSZXNpemU6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuJHJlZnMgIT09IG51bGwgJiYgdGhpcy4kcmVmcy5pdGVtICE9PSBudWxsICYmIHRoaXMuJHJlZnMuaXRlbSAhPT0gdW5kZWZpbmVkKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy4kcmVmcy5pdGVtLm9mZnNldFdpZHRoO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgfSxcXHJcXG4gICAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmF1dG9TaXplKSByZXR1cm47XFxyXFxuICAgICAgICAgICAgICAgIHJldHVybiBib3R0b20odGhpcy5sYXlvdXQpICogKHRoaXMucm93SGVpZ2h0ICsgdGhpcy5tYXJnaW5bMV0pICsgdGhpcy5tYXJnaW5bMV0gKyAncHgnO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICAgICAgZHJhZ0V2ZW50OiBmdW5jdGlvbiAoZXZlbnROYW1lLCBpZCwgeCwgeSwgaCwgdykge1xcclxcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnROYW1lID09PSBcXFwiZHJhZ21vdmVcXFwiIHx8IGV2ZW50TmFtZSA9PT0gXFxcImRyYWdzdGFydFxcXCIpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaSA9IGlkO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci54ID0geDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueSA9IHk7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLncgPSB3O1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci5oID0gaDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XFxyXFxuICAgICAgICAgICAgICAgICAgICB9KTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xcclxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgIH1cXHJcXG4gICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhldmVudE5hbWUgKyBcXFwiIGlkPVxcXCIgKyBpZCArIFxcXCIsIHg9XFxcIiArIHggKyBcXFwiLCB5PVxcXCIgKyB5KTtcXHJcXG4gICAgICAgICAgICAgICAgdmFyIGwgPSBnZXRMYXlvdXRJdGVtKHRoaXMubGF5b3V0LCBpZCk7XFxyXFxuICAgICAgICAgICAgICAgIC8vR2V0TGF5b3V0SXRlbSBzb21ldGltZXMgcmV0dXJucyBudWxsIG9iamVjdFxcclxcbiAgICAgICAgICAgICAgICBpZiAobCA9PT0gdW5kZWZpbmVkIHx8IGwgPT09IG51bGwpe1xcclxcbiAgICAgICAgICAgICAgICAgICAgbCA9IHt4OjAsIHk6MH1cXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBsLnggPSB4O1xcclxcbiAgICAgICAgICAgICAgICBsLnkgPSB5O1xcclxcbiAgICAgICAgICAgICAgICAvLyBNb3ZlIHRoZSBlbGVtZW50IHRvIHRoZSBkcmFnZ2VkIGxvY2F0aW9uLlxcclxcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dCA9IG1vdmVFbGVtZW50KHRoaXMubGF5b3V0LCBsLCB4LCB5LCB0cnVlKTtcXHJcXG4gICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xcclxcbiAgICAgICAgICAgICAgICAvLyBuZWVkZWQgYmVjYXVzZSB2dWUgY2FuJ3QgZGV0ZWN0IGNoYW5nZXMgb24gYXJyYXkgZWxlbWVudCBwcm9wZXJ0aWVzXFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcImNvbXBhY3RcXFwiKTtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ2RyYWdlbmQnKSB0aGlzLiRlbWl0KCdsYXlvdXQtdXBkYXRlZCcsIHRoaXMubGF5b3V0KTtcXHJcXG4gICAgICAgICAgICB9LFxcclxcbiAgICAgICAgICAgIHJlc2l6ZUV2ZW50OiBmdW5jdGlvbiAoZXZlbnROYW1lLCBpZCwgeCwgeSwgaCwgdykge1xcclxcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnROYW1lID09PSBcXFwicmVzaXplc3RhcnRcXFwiIHx8IGV2ZW50TmFtZSA9PT0gXFxcInJlc2l6ZW1vdmVcXFwiKSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmkgPSBpZDtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueCA9IHg7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnkgPSB5O1xcclxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci53ID0gdztcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaCA9IGg7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xcclxcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxyXFxuICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJGJyb2FkY2FzdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxyXFxuXFxyXFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxyXFxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcXHJcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcXHJcXG4gICAgICAgICAgICAgICAgICAgIH0pO1xcclxcbiAgICAgICAgICAgICAgICB9XFxyXFxuICAgICAgICAgICAgICAgIHZhciBsID0gZ2V0TGF5b3V0SXRlbSh0aGlzLmxheW91dCwgaWQpO1xcclxcbiAgICAgICAgICAgICAgICAvL0dldExheW91dEl0ZW0gc29tZXRpbWVzIHJldHVybiBudWxsIG9iamVjdFxcclxcbiAgICAgICAgICAgICAgICBpZiAobCA9PT0gdW5kZWZpbmVkIHx8IGwgPT09IG51bGwpe1xcclxcbiAgICAgICAgICAgICAgICAgICAgbCA9IHtoOjAsIHc6MH1cXHJcXG4gICAgICAgICAgICAgICAgfVxcclxcbiAgICAgICAgICAgICAgICBsLmggPSBoO1xcclxcbiAgICAgICAgICAgICAgICBsLncgPSB3O1xcclxcbiAgICAgICAgICAgICAgICBjb21wYWN0KHRoaXMubGF5b3V0LCB0aGlzLnZlcnRpY2FsQ29tcGFjdCk7XFxyXFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcImNvbXBhY3RcXFwiKTtcXHJcXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcXHJcXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ3Jlc2l6ZWVuZCcpIHRoaXMuJGVtaXQoJ2xheW91dC11cGRhdGVkJywgdGhpcy5sYXlvdXQpO1xcclxcbiAgICAgICAgICAgIH0sXFxyXFxuICAgICAgICB9LFxcclxcbiAgICB9XFxyXFxuPC9zY3JpcHQ+XFxyXFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1jb21waWxlcj97XCJpZFwiOlwiZGF0YS12LTNkNGJiOWE0XCIsXCJzY29wZWRcIjpmYWxzZSxcImhhc0lubGluZUNvbmZpZ1wiOmZhbHNlfSEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vc3JjL0dyaWRMYXlvdXQudnVlXG4vLyBtb2R1bGUgaWQgPSAxOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///19\n"); /***/ }), /* 20 */ /***/ (function(module, exports, __webpack_require__) { -eval("exports = module.exports = __webpack_require__(2)();\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.vue-grid-layout {\\n position: relative;\\n transition: height 200ms ease;\\n}\\n\", \"\", {\"version\":3,\"sources\":[\"/./src/GridLayout.vue?6c736e29\"],\"names\":[],\"mappings\":\";AAaA;IACA,mBAAA;IACA,8BAAA;CACA\",\"file\":\"GridLayout.vue\",\"sourcesContent\":[\"\\n\\n\\n\"],\"sourceRoot\":\"webpack://\"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvR3JpZExheW91dC52dWU/OWEyYSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOzs7QUFHQTtBQUNBLDZDQUE4Qyx5QkFBeUIsb0NBQW9DLEdBQUcsVUFBVSxpRkFBaUYsS0FBSyxXQUFXLFdBQVcsNGdCQUE0Z0IsNkJBQTZCLHdDQUF3QyxPQUFPLGdEQUFnRCw0RUFBNEUsZ0JBQWdCLDREQUE0RCxnQkFBZ0IsNkNBQTZDLG1FQUFtRSxvREFBb0Qsc0JBQXNCLCtDQUErQyxXQUFXLHdCQUF3QixrQ0FBa0MsbUJBQW1CLDRHQUE0Ryw4RUFBOEUsd0JBQXdCLDJFQUEyRSwyQkFBMkIsNEVBQTRFLHlCQUF5QixpRkFBaUYsd0JBQXdCLHNFQUFzRSxzQ0FBc0MsbUJBQW1CLGVBQWUsNkJBQTZCLDhFQUE4RSw2QkFBNkIsOEVBQThFLDRCQUE0QiwrRUFBK0Usa0NBQWtDLDhFQUE4RSxpQ0FBaUMsOEVBQThFLHdCQUF3Qiw4RUFBOEUsWUFBWSw4QkFBOEIsc0JBQXNCLCtEQUErRCwyR0FBMkcsMEpBQTBKLGlCQUFpQixXQUFXLHVCQUF1Qiw4QkFBOEIsOEpBQThKLDZEQUE2RCxnQkFBZ0IsNEVBQTRFLDJEQUEyRCxnQkFBZ0IscURBQXFELHNEQUFzRCx3RUFBd0Usb0VBQW9FLFdBQVcscUNBQXFDLHlHQUF5RyxxRUFBcUUsb0ZBQW9GLGdDQUFnQywwQ0FBMEMsOENBQThDLGtDQUFrQyw2Q0FBNkMsZ0RBQWdELGdEQUFnRCw4REFBOEQsaUZBQWlGLHVCQUF1QixpRUFBaUUsNENBQTRDLGtEQUFrRCxnRUFBZ0UseUdBQXlHLEVBQUUsNEVBQTRFLG9EQUFvRCwyQkFBMkIsRUFBRSx1QkFBdUIsRUFBRSxtQkFBbUIsRUFBRSw4Q0FBOEMsZ0RBQWdELGdEQUFnRCw4REFBOEQsaUZBQWlGLHVCQUF1QixpRUFBaUUsNENBQTRDLGtEQUFrRCxnRUFBZ0UseUdBQXlHLEVBQUUsNEVBQTRFLG9EQUFvRCwyQkFBMkIsRUFBRSx1QkFBdUIsRUFBRSxzQkFBc0IsZUFBZSxFQUFFLFdBQVcsbUJBQW1CLGtDQUFrQyw4Q0FBOEMscUVBQXFFLHVFQUF1RSwwQ0FBMEMsbUJBQW1CLEVBQUUsZUFBZSxvQ0FBb0Msc0NBQXNDLGVBQWUsc0NBQXNDLHdFQUF3RSxlQUFlLHdDQUF3QywwRUFBMEUsZUFBZSx3Q0FBd0MsMEVBQTBFLGVBQWUsV0FBVyxxQkFBcUIsOEJBQThCLGtHQUFrRyw0REFBNEQsaUVBQWlFLGlFQUFpRSx1RUFBdUUsdUVBQXVFLDBDQUEwQyxtQkFBbUIsZUFBZSwwQ0FBMEMsc0NBQXNDLHdFQUF3RSxlQUFlLDRDQUE0Qyx5R0FBeUcsK0RBQStELG1CQUFtQixlQUFlLDZDQUE2Qyw2Q0FBNkMseUdBQXlHLGVBQWUsZ0VBQWdFLGtGQUFrRiw4Q0FBOEMsNkNBQTZDLDZDQUE2Qyw2Q0FBNkMsNkNBQTZDLGlEQUFpRCxpREFBaUQsdUJBQXVCLEVBQUUscUVBQXFFLHVFQUF1RSxtQkFBbUIsT0FBTyxpREFBaUQsa0RBQWtELHVCQUF1QixFQUFFLG1CQUFtQix5RkFBeUYseURBQXlELG9IQUFvSCwyQkFBMkIsU0FBUyxtQkFBbUIsMEJBQTBCLDBCQUEwQixzSUFBc0ksNkRBQTZELDJJQUEySSxzQ0FBc0MseUZBQXlGLGVBQWUsa0VBQWtFLHNGQUFzRiw4Q0FBOEMsNkNBQTZDLDZDQUE2Qyw2Q0FBNkMsNkNBQTZDLGlEQUFpRCxpREFBaUQsdUJBQXVCLEVBQUUscUVBQXFFLHVFQUF1RSxxQkFBcUIsT0FBTyxpREFBaUQsa0RBQWtELHVCQUF1QixFQUFFLG1CQUFtQix5REFBeUQsbUhBQW1ILDJCQUEyQixTQUFTLG1CQUFtQiwwQkFBMEIsMEJBQTBCLDZEQUE2RCxtREFBbUQsc0NBQXNDLDJGQUEyRixlQUFlLFlBQVksUUFBUSwwQ0FBMEM7O0FBRXJ1ViIsImZpbGUiOiIyMC5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi52dWUtZ3JpZC1sYXlvdXQge1xcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgIHRyYW5zaXRpb246IGhlaWdodCAyMDBtcyBlYXNlO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL0dyaWRMYXlvdXQudnVlPzZjNzM2ZTI5XCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFhQTtJQUNBLG1CQUFBO0lBQ0EsOEJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiR3JpZExheW91dC52dWVcIixcInNvdXJjZXNDb250ZW50XCI6W1wiPHRlbXBsYXRlPlxcbiAgICA8ZGl2IHJlZj1cXFwiaXRlbVxcXCIgY2xhc3M9XFxcInZ1ZS1ncmlkLWxheW91dFxcXCIgOnN0eWxlPVxcXCJtZXJnZWRTdHlsZVxcXCI+XFxuICAgICAgICA8c2xvdD48L3Nsb3Q+XFxuICAgICAgICA8Z3JpZC1pdGVtIGNsYXNzPVxcXCJ2dWUtZ3JpZC1wbGFjZWhvbGRlclxcXCJcXG4gICAgICAgICAgICAgICAgICAgdi1zaG93PVxcXCJpc0RyYWdnaW5nXFxcIlxcbiAgICAgICAgICAgICAgICAgICA6eD1cXFwicGxhY2Vob2xkZXIueFxcXCJcXG4gICAgICAgICAgICAgICAgICAgOnk9XFxcInBsYWNlaG9sZGVyLnlcXFwiXFxuICAgICAgICAgICAgICAgICAgIDp3PVxcXCJwbGFjZWhvbGRlci53XFxcIlxcbiAgICAgICAgICAgICAgICAgICA6aD1cXFwicGxhY2Vob2xkZXIuaFxcXCJcXG4gICAgICAgICAgICAgICAgICAgOmk9XFxcInBsYWNlaG9sZGVyLmlcXFwiPjwvZ3JpZC1pdGVtPlxcbiAgICA8L2Rpdj5cXG48L3RlbXBsYXRlPlxcbjxzdHlsZT5cXG4gICAgLnZ1ZS1ncmlkLWxheW91dCB7XFxuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICAgICAgICB0cmFuc2l0aW9uOiBoZWlnaHQgMjAwbXMgZWFzZTtcXG4gICAgfVxcbjwvc3R5bGU+XFxuPHNjcmlwdD5cXG4gICAgaW1wb3J0IFZ1ZSBmcm9tICd2dWUnO1xcbiAgICB2YXIgZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIgPSByZXF1aXJlKFxcXCJlbGVtZW50LXJlc2l6ZS1kZXRlY3RvclxcXCIpO1xcblxcbiAgICBpbXBvcnQge2JvdHRvbSwgY29tcGFjdCwgZ2V0TGF5b3V0SXRlbSwgbW92ZUVsZW1lbnQsIHZhbGlkYXRlTGF5b3V0fSBmcm9tICcuL3V0aWxzJztcXG4gICAgLy92YXIgZXZlbnRCdXMgPSByZXF1aXJlKCcuL2V2ZW50QnVzJyk7XFxuICAgIGltcG9ydCBHcmlkSXRlbSBmcm9tICcuL0dyaWRJdGVtLnZ1ZSdcXG5cXG4gICAgZXhwb3J0IGRlZmF1bHQge1xcbiAgICAgICAgbmFtZTogXFxcIkdyaWRMYXlvdXRcXFwiLFxcbiAgICAgICAgcHJvdmlkZSgpIHtcXG4gICAgICAgICAgICByZXR1cm4ge1xcbiAgICAgICAgICAgICAgICBldmVudEJ1czogbnVsbFxcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH0sXFxuICAgICAgICBjb21wb25lbnRzOiB7XFxuICAgICAgICAgICAgR3JpZEl0ZW0sXFxuICAgICAgICB9LFxcbiAgICAgICAgcHJvcHM6IHtcXG4gICAgICAgICAgICAvLyBJZiB0cnVlLCB0aGUgY29udGFpbmVyIGhlaWdodCBzd2VsbHMgYW5kIGNvbnRyYWN0cyB0byBmaXQgY29udGVudHNcXG4gICAgICAgICAgICBhdXRvU2l6ZToge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBjb2xOdW06IHtcXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAxMlxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgcm93SGVpZ2h0OiB7XFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMTUwXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBtYXhSb3dzOiB7XFxuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIG1hcmdpbjoge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheSxcXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsxMCwgMTBdO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBpc1Jlc2l6YWJsZToge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBpc01pcnJvcmVkOiB7XFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICB1c2VDc3NUcmFuc2Zvcm1zOiB7XFxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIHZlcnRpY2FsQ29tcGFjdDoge1xcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBsYXlvdXQ6IHtcXG4gICAgICAgICAgICAgICAgdHlwZTogQXJyYXksXFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICB9LFxcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgIHJldHVybiB7XFxuICAgICAgICAgICAgICAgIHdpZHRoOiBudWxsLFxcbiAgICAgICAgICAgICAgICBtZXJnZWRTdHlsZToge30sXFxuICAgICAgICAgICAgICAgIGxhc3RMYXlvdXRMZW5ndGg6IDAsXFxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmc6IGZhbHNlLFxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjoge1xcbiAgICAgICAgICAgICAgICAgICAgeDogMCxcXG4gICAgICAgICAgICAgICAgICAgIHk6IDAsXFxuICAgICAgICAgICAgICAgICAgICB3OiAwLFxcbiAgICAgICAgICAgICAgICAgICAgaDogMCxcXG4gICAgICAgICAgICAgICAgICAgIGk6IC0xXFxuICAgICAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgfTtcXG4gICAgICAgIH0sXFxuICAgICAgICBjcmVhdGVkICgpIHtcXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxuXFxuICAgICAgICAgICAgLy8gQWNjZXNzaWJsZSByZWZlcm5jZXMgb2YgZnVuY3Rpb25zIGZvciByZW1vdmluZyBpbiBiZWZvcmVEZXN0cm95XFxuICAgICAgICAgICAgc2VsZi5yZXNpemVFdmVudEhhbmRsZXIgPSBmdW5jdGlvbihldmVudFR5cGUsIGksIHgsIHksIGgsIHcpIHtcXG4gICAgICAgICAgICAgICAgc2VsZi5yZXNpemVFdmVudChldmVudFR5cGUsIGksIHgsIHksIGgsIHcpO1xcbiAgICAgICAgICAgIH07XFxuXFxuICAgICAgICAgICAgc2VsZi5kcmFnRXZlbnRIYW5kbGVyID0gZnVuY3Rpb24oZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KSB7XFxuICAgICAgICAgICAgICAgIHNlbGYuZHJhZ0V2ZW50KGV2ZW50VHlwZSwgaSwgeCwgeSwgaCwgdyk7XFxuICAgICAgICAgICAgfTtcXG5cXG4gICAgICAgICAgICBzZWxmLl9wcm92aWRlZC5ldmVudEJ1cyA9ICBuZXcgVnVlKCk7XFxuICAgICAgICAgICAgc2VsZi5ldmVudEJ1cyA9IHNlbGYuX3Byb3ZpZGVkLmV2ZW50QnVzO1xcbiAgICAgICAgICAgIHNlbGYuZXZlbnRCdXMuJG9uKCdyZXNpemVFdmVudCcsIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyKTtcXG4gICAgICAgICAgICBzZWxmLmV2ZW50QnVzLiRvbignZHJhZ0V2ZW50Jywgc2VsZi5kcmFnRXZlbnRIYW5kbGVyKTtcXG4gICAgICAgIH0sXFxuICAgICAgICBiZWZvcmVEZXN0cm95OiBmdW5jdGlvbigpe1xcbiAgICAgICAgICAgIC8vUmVtb3ZlIGxpc3RlbmVyc1xcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJG9mZigncmVzaXplRXZlbnQnLCBzZWxmLnJlc2l6ZUV2ZW50SGFuZGxlcik7XFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCdkcmFnRXZlbnQnLCBzZWxmLmRyYWdFdmVudEhhbmRsZXIpO1xcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFxcXCJyZXNpemVcXFwiLCBzZWxmLm9uV2luZG93UmVzaXplKVxcbiAgICAgICAgfSxcXG4gICAgICAgIG1vdW50ZWQ6IGZ1bmN0aW9uKCkge1xcbiAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXG4gICAgICAgICAgICAgICAgdmFsaWRhdGVMYXlvdXQodGhpcy5sYXlvdXQpO1xcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XFxuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYud2lkdGggPT09IG51bGwpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zZWxmLndpZHRoID0gc2VsZi4kZWwub2Zmc2V0V2lkdGg7XFxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHNlbGYub25XaW5kb3dSZXNpemUpO1xcbiAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdChzZWxmLmxheW91dCwgc2VsZi52ZXJ0aWNhbENvbXBhY3QpO1xcblxcbiAgICAgICAgICAgICAgICAgICAgc2VsZi51cGRhdGVIZWlnaHQoKTtcXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJkID0gZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIoe1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhdGVneTogXFxcInNjcm9sbFxcXCIgLy88LSBGb3IgdWx0cmEgcGVyZm9ybWFuY2UuXFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJkLmxpc3RlblRvKHNlbGYuJHJlZnMuaXRlbSwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vbldpbmRvd1Jlc2l6ZSgpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgICAgICB3aW5kb3cub25sb2FkID0gZnVuY3Rpb24oKSB7XFxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi53aWR0aCA9PT0gbnVsbCkge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NlbGYud2lkdGggPSBzZWxmLiRlbC5vZmZzZXRXaWR0aDtcXG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgc2VsZi5vbldpbmRvd1Jlc2l6ZSk7XFxuICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHNlbGYubGF5b3V0LCBzZWxmLnZlcnRpY2FsQ29tcGFjdCk7XFxuXFxuICAgICAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZUhlaWdodCgpO1xcbiAgICAgICAgICAgICAgICAgICAgc2VsZi4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlcmQgPSBlbGVtZW50UmVzaXplRGV0ZWN0b3JNYWtlcih7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiBcXFwic2Nyb2xsXFxcIiAvLzwtIEZvciB1bHRyYSBwZXJmb3JtYW5jZS5cXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBlcmQubGlzdGVuVG8oc2VsZi4kcmVmcy5pdGVtLCBmdW5jdGlvbiAoZWxlbWVudCkge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgICAgICAgICB9KTtcXG5cXG4gICAgICAgICAgICAgICAgfTtcXG4gICAgICAgICAgICB9KTtcXG4gICAgICAgIH0sXFxuICAgICAgICB3YXRjaDoge1xcbiAgICAgICAgICAgIHdpZHRoOiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XFxuICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgbGF5b3V0OiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VXBkYXRlKCk7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJzZXRSb3dIZWlnaHRcXFwiLCB0aGlzLnJvd0hlaWdodCk7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICBpc0RyYWdnYWJsZTogZnVuY3Rpb24oKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInNldERyYWdnYWJsZVxcXCIsIHRoaXMuaXNEcmFnZ2FibGUpO1xcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IGZ1bmN0aW9uKCkge1xcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJzZXRSZXNpemFibGVcXFwiLCB0aGlzLmlzUmVzaXphYmxlKTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9LFxcbiAgICAgICAgbWV0aG9kczoge1xcbiAgICAgICAgICAgIGxheW91dFVwZGF0ZSgpIHtcXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubGF5b3V0ICE9PSB1bmRlZmluZWQgJiYgdGhpcy5sYXlvdXQubGVuZ3RoICE9PSB0aGlzLmxhc3RMYXlvdXRMZW5ndGgpIHtcXG4vLyAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXFxcIiMjIyBMQVlPVVQgVVBEQVRFIVxcXCIpO1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXN0TGF5b3V0TGVuZ3RoID0gdGhpcy5sYXlvdXQubGVuZ3RoO1xcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xcblxcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLiRicm9hZGNhc3QoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgdXBkYXRlSGVpZ2h0OiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIHRoaXMubWVyZ2VkU3R5bGUgPSB7XFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuY29udGFpbmVySGVpZ2h0KClcXG4gICAgICAgICAgICAgICAgfTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIG9uV2luZG93UmVzaXplOiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLiRyZWZzICE9PSBudWxsICYmIHRoaXMuJHJlZnMuaXRlbSAhPT0gbnVsbCAmJiB0aGlzLiRyZWZzLml0ZW0gIT09IHVuZGVmaW5lZCkge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy53aWR0aCA9IHRoaXMuJHJlZnMuaXRlbS5vZmZzZXRXaWR0aDtcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIH0sXFxuICAgICAgICAgICAgY29udGFpbmVySGVpZ2h0OiBmdW5jdGlvbiAoKSB7XFxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5hdXRvU2l6ZSkgcmV0dXJuO1xcbiAgICAgICAgICAgICAgICByZXR1cm4gYm90dG9tKHRoaXMubGF5b3V0KSAqICh0aGlzLnJvd0hlaWdodCArIHRoaXMubWFyZ2luWzFdKSArIHRoaXMubWFyZ2luWzFdICsgJ3B4JztcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgICAgIGRyYWdFdmVudDogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaWQsIHgsIHksIGgsIHcpIHtcXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gXFxcImRyYWdtb3ZlXFxcIiB8fCBldmVudE5hbWUgPT09IFxcXCJkcmFnc3RhcnRcXFwiKSB7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmkgPSBpZDtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueCA9IHg7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnkgPSB5O1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci53ID0gdztcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaCA9IGg7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xcbiAgICAgICAgICAgICAgICAgICAgfSk7XFxuICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJGJyb2FkY2FzdChcXFwidXBkYXRlV2lkdGhcXFwiLCB0aGlzLndpZHRoKTtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcXG4gICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coZXZlbnROYW1lICsgXFxcIiBpZD1cXFwiICsgaWQgKyBcXFwiLCB4PVxcXCIgKyB4ICsgXFxcIiwgeT1cXFwiICsgeSk7XFxuICAgICAgICAgICAgICAgIHZhciBsID0gZ2V0TGF5b3V0SXRlbSh0aGlzLmxheW91dCwgaWQpO1xcbiAgICAgICAgICAgICAgICAvL0dldExheW91dEl0ZW0gc29tZXRpbWVzIHJldHVybnMgbnVsbCBvYmplY3RcXG4gICAgICAgICAgICAgICAgaWYgKGwgPT09IHVuZGVmaW5lZCB8fCBsID09PSBudWxsKXtcXG4gICAgICAgICAgICAgICAgICAgIGwgPSB7eDowLCB5OjB9XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgbC54ID0geDtcXG4gICAgICAgICAgICAgICAgbC55ID0geTtcXG4gICAgICAgICAgICAgICAgLy8gTW92ZSB0aGUgZWxlbWVudCB0byB0aGUgZHJhZ2dlZCBsb2NhdGlvbi5cXG4gICAgICAgICAgICAgICAgdGhpcy5sYXlvdXQgPSBtb3ZlRWxlbWVudCh0aGlzLmxheW91dCwgbCwgeCwgeSwgdHJ1ZSk7XFxuICAgICAgICAgICAgICAgIGNvbXBhY3QodGhpcy5sYXlvdXQsIHRoaXMudmVydGljYWxDb21wYWN0KTtcXG4gICAgICAgICAgICAgICAgLy8gbmVlZGVkIGJlY2F1c2UgdnVlIGNhbid0IGRldGVjdCBjaGFuZ2VzIG9uIGFycmF5IGVsZW1lbnQgcHJvcGVydGllc1xcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJjb21wYWN0XFxcIik7XFxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XFxuICAgICAgICAgICAgICAgIGlmIChldmVudE5hbWUgPT09ICdkcmFnZW5kJykgdGhpcy4kZW1pdCgnbGF5b3V0LXVwZGF0ZWQnLCB0aGlzLmxheW91dCk7XFxuICAgICAgICAgICAgfSxcXG4gICAgICAgICAgICByZXNpemVFdmVudDogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaWQsIHgsIHksIGgsIHcpIHtcXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gXFxcInJlc2l6ZXN0YXJ0XFxcIiB8fCBldmVudE5hbWUgPT09IFxcXCJyZXNpemVtb3ZlXFxcIikge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci5pID0gaWQ7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnggPSB4O1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci55ID0geTtcXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIudyA9IHc7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmggPSBoO1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24oKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZTtcXG4gICAgICAgICAgICAgICAgICAgIH0pO1xcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLiRicm9hZGNhc3QoXFxcInVwZGF0ZVdpZHRoXFxcIiwgdGhpcy53aWR0aCk7XFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJ1cGRhdGVXaWR0aFxcXCIsIHRoaXMud2lkdGgpO1xcblxcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24oKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XFxuICAgICAgICAgICAgICAgICAgICB9KTtcXG4gICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICB2YXIgbCA9IGdldExheW91dEl0ZW0odGhpcy5sYXlvdXQsIGlkKTtcXG4gICAgICAgICAgICAgICAgLy9HZXRMYXlvdXRJdGVtIHNvbWV0aW1lcyByZXR1cm4gbnVsbCBvYmplY3RcXG4gICAgICAgICAgICAgICAgaWYgKGwgPT09IHVuZGVmaW5lZCB8fCBsID09PSBudWxsKXtcXG4gICAgICAgICAgICAgICAgICAgIGwgPSB7aDowLCB3OjB9XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgbC5oID0gaDtcXG4gICAgICAgICAgICAgICAgbC53ID0gdztcXG4gICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFxcXCJjb21wYWN0XFxcIik7XFxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XFxuICAgICAgICAgICAgICAgIGlmIChldmVudE5hbWUgPT09ICdyZXNpemVlbmQnKSB0aGlzLiRlbWl0KCdsYXlvdXQtdXBkYXRlZCcsIHRoaXMubGF5b3V0KTtcXG4gICAgICAgICAgICB9LFxcbiAgICAgICAgfSxcXG4gICAgfVxcbjwvc2NyaXB0PlxcblwiXSxcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi0zZDRiYjlhNFwiLFwic2NvcGVkXCI6ZmFsc2UsXCJoYXNJbmxpbmVDb25maWdcIjpmYWxzZX0hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9HcmlkTGF5b3V0LnZ1ZVxuLy8gbW9kdWxlIGlkID0gMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///20\n"); +"use strict"; +eval("\n\nexports.__esModule = true;\n\nvar _vue = __webpack_require__(21);\n\nvar _vue2 = _interopRequireDefault(_vue);\n\nvar _utils = __webpack_require__(0);\n\nvar _GridItem = __webpack_require__(1);\n\nvar _GridItem2 = _interopRequireDefault(_GridItem);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar elementResizeDetectorMaker = __webpack_require__(6); //\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n//var eventBus = require('./eventBus');\nexports.default = {\n name: \"GridLayout\",\n provide: function provide() {\n return {\n eventBus: null\n };\n },\n\n components: {\n GridItem: _GridItem2.default\n },\n props: {\n // If true, the container height swells and contracts to fit contents\n autoSize: {\n type: Boolean,\n default: true\n },\n colNum: {\n type: Number,\n default: 12\n },\n rowHeight: {\n type: Number,\n default: 150\n },\n maxRows: {\n type: Number,\n default: Infinity\n },\n margin: {\n type: Array,\n default: function _default() {\n return [10, 10];\n }\n },\n isDraggable: {\n type: Boolean,\n default: true\n },\n isResizable: {\n type: Boolean,\n default: true\n },\n isMirrored: {\n type: Boolean,\n default: false\n },\n useCssTransforms: {\n type: Boolean,\n default: true\n },\n verticalCompact: {\n type: Boolean,\n default: true\n },\n layout: {\n type: Array,\n required: true\n }\n },\n data: function data() {\n return {\n width: null,\n mergedStyle: {},\n lastLayoutLength: 0,\n isDragging: false,\n placeholder: {\n x: 0,\n y: 0,\n w: 0,\n h: 0,\n i: -1\n }\n };\n },\n created: function created() {\n var self = this;\n\n // Accessible refernces of functions for removing in beforeDestroy\n self.resizeEventHandler = function (eventType, i, x, y, h, w) {\n self.resizeEvent(eventType, i, x, y, h, w);\n };\n\n self.dragEventHandler = function (eventType, i, x, y, h, w) {\n self.dragEvent(eventType, i, x, y, h, w);\n };\n\n self._provided.eventBus = new _vue2.default();\n self.eventBus = self._provided.eventBus;\n self.eventBus.$on('resizeEvent', self.resizeEventHandler);\n self.eventBus.$on('dragEvent', self.dragEventHandler);\n },\n\n beforeDestroy: function beforeDestroy() {\n //Remove listeners\n this.eventBus.$off('resizeEvent', self.resizeEventHandler);\n this.eventBus.$off('dragEvent', self.dragEventHandler);\n window.removeEventListener(\"resize\", self.onWindowResize);\n },\n mounted: function mounted() {\n this.$nextTick(function () {\n (0, _utils.validateLayout)(this.layout);\n var self = this;\n this.$nextTick(function () {\n if (self.width === null) {\n self.onWindowResize();\n //self.width = self.$el.offsetWidth;\n window.addEventListener('resize', self.onWindowResize);\n }\n (0, _utils.compact)(self.layout, self.verticalCompact);\n\n self.updateHeight();\n self.$nextTick(function () {\n var erd = elementResizeDetectorMaker({\n strategy: \"scroll\" //<- For ultra performance.\n });\n erd.listenTo(self.$refs.item, function (element) {\n self.onWindowResize();\n });\n });\n });\n window.onload = function () {\n if (self.width === null) {\n self.onWindowResize();\n //self.width = self.$el.offsetWidth;\n window.addEventListener('resize', self.onWindowResize);\n }\n (0, _utils.compact)(self.layout, self.verticalCompact);\n\n self.updateHeight();\n self.$nextTick(function () {\n var erd = elementResizeDetectorMaker({\n strategy: \"scroll\" //<- For ultra performance.\n });\n erd.listenTo(self.$refs.item, function (element) {\n self.onWindowResize();\n });\n });\n };\n });\n },\n watch: {\n width: function width() {\n this.$nextTick(function () {\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n this.updateHeight();\n });\n },\n layout: function layout() {\n this.layoutUpdate();\n },\n rowHeight: function rowHeight() {\n this.eventBus.$emit(\"setRowHeight\", this.rowHeight);\n },\n isDraggable: function isDraggable() {\n this.eventBus.$emit(\"setDraggable\", this.isDraggable);\n },\n isResizable: function isResizable() {\n this.eventBus.$emit(\"setResizable\", this.isResizable);\n }\n },\n methods: {\n layoutUpdate: function layoutUpdate() {\n if (this.layout !== undefined) {\n if (this.layout.length !== this.lastLayoutLength) {\n //console.log(\"### LAYOUT UPDATE!\");\n this.lastLayoutLength = this.layout.length;\n }\n (0, _utils.compact)(this.layout, this.verticalCompact);\n this.eventBus.$emit(\"updateWidth\", this.width);\n this.updateHeight();\n }\n },\n\n updateHeight: function updateHeight() {\n this.mergedStyle = {\n height: this.containerHeight()\n };\n },\n onWindowResize: function onWindowResize() {\n if (this.$refs !== null && this.$refs.item !== null && this.$refs.item !== undefined) {\n this.width = this.$refs.item.offsetWidth;\n }\n },\n containerHeight: function containerHeight() {\n if (!this.autoSize) return;\n return (0, _utils.bottom)(this.layout) * (this.rowHeight + this.margin[1]) + this.margin[1] + 'px';\n },\n dragEvent: function dragEvent(eventName, id, x, y, h, w) {\n if (eventName === \"dragmove\" || eventName === \"dragstart\") {\n this.placeholder.i = id;\n this.placeholder.x = x;\n this.placeholder.y = y;\n this.placeholder.w = w;\n this.placeholder.h = h;\n this.$nextTick(function () {\n this.isDragging = true;\n });\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n } else {\n this.$nextTick(function () {\n this.isDragging = false;\n });\n }\n //console.log(eventName + \" id=\" + id + \", x=\" + x + \", y=\" + y);\n var l = (0, _utils.getLayoutItem)(this.layout, id);\n //GetLayoutItem sometimes returns null object\n if (l === undefined || l === null) {\n l = { x: 0, y: 0 };\n }\n l.x = x;\n l.y = y;\n // Move the element to the dragged location.\n this.layout = (0, _utils.moveElement)(this.layout, l, x, y, true);\n (0, _utils.compact)(this.layout, this.verticalCompact);\n // needed because vue can't detect changes on array element properties\n this.eventBus.$emit(\"compact\");\n this.updateHeight();\n if (eventName === 'dragend') this.$emit('layout-updated', this.layout);\n },\n resizeEvent: function resizeEvent(eventName, id, x, y, h, w) {\n if (eventName === \"resizestart\" || eventName === \"resizemove\") {\n this.placeholder.i = id;\n this.placeholder.x = x;\n this.placeholder.y = y;\n this.placeholder.w = w;\n this.placeholder.h = h;\n this.$nextTick(function () {\n this.isDragging = true;\n });\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n } else {\n this.$nextTick(function () {\n this.isDragging = false;\n });\n }\n var l = (0, _utils.getLayoutItem)(this.layout, id);\n //GetLayoutItem sometimes return null object\n if (l === undefined || l === null) {\n l = { h: 0, w: 0 };\n }\n l.h = h;\n l.w = w;\n (0, _utils.compact)(this.layout, this.verticalCompact);\n this.eventBus.$emit(\"compact\");\n this.updateHeight();\n if (eventName === 'resizeend') this.$emit('layout-updated', this.layout);\n }\n }\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vR3JpZExheW91dC52dWU/MTE1NyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBbUJBOzs7O0FBR0E7O0FBSUE7Ozs7OztBQU5BOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0E7O1VBS0E7Z0NBQ0E7O3NCQUdBO0FBRkE7QUFHQTs7O0FBR0E7QUFGQTs7QUFJQTs7a0JBRUE7cUJBRUE7QUFIQTs7a0JBS0E7cUJBRUE7QUFIQTs7a0JBS0E7cUJBRUE7QUFIQTs7a0JBS0E7cUJBRUE7QUFIQTs7a0JBS0E7eUNBQ0E7NEJBQ0E7QUFFQTtBQUxBOztrQkFPQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtzQkFHQTtBQUpBO0FBNUNBOzBCQWlEQTs7bUJBRUE7eUJBQ0E7OEJBQ0E7d0JBQ0E7O21CQUVBO21CQUNBO21CQUNBO21CQUNBO29CQUdBO0FBUEE7QUFMQTtBQWFBO2dDQUNBO21CQUVBOztBQUNBO3NFQUNBO29EQUNBO0FBRUE7O29FQUNBO2tEQUNBO0FBRUE7O2tDQUNBO3VDQUNBOzhDQUNBOzRDQUNBO0FBQ0E7OzRDQUNBO0FBQ0E7K0NBQ0E7NkNBQ0E7a0RBQ0E7QUFDQTtnQ0FDQTttQ0FDQTs0Q0FDQTt1QkFDQTt1Q0FDQTt5Q0FDQTt5QkFDQTtBQUNBOzJEQUNBO0FBQ0E7c0RBRUE7O3FCQUNBOzJDQUNBOzsyQ0FHQTtBQUZBO3FFQUdBOzZCQUNBO0FBQ0E7QUFDQTtBQUNBO3dDQUNBO3lDQUNBO3lCQUNBO0FBQ0E7MkRBQ0E7QUFDQTtzREFFQTs7cUJBQ0E7MkNBQ0E7OzJDQUdBO0FBRkE7cUVBR0E7NkJBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBOztnQ0FFQTt1Q0FDQTtBQUNBO3dEQUNBO3FCQUNBO0FBQ0E7QUFDQTtrQ0FDQTtpQkFDQTtBQUNBO3dDQUNBO3FEQUNBO0FBQ0E7NENBQ0E7cURBQ0E7QUFDQTs0Q0FDQTtxREFDQTtBQUVBO0FBcEJBOzs4Q0FzQkE7MkNBQ0E7a0VBQ0E7QUFDQTt3REFDQTtBQUNBO3NEQUNBO3dEQUNBO3FCQUNBO0FBQ0E7QUFDQTs7OENBQ0E7OzZCQUdBO0FBRkE7QUFHQTtrREFDQTtrR0FDQTs2Q0FDQTtBQUNBO0FBQ0E7b0RBQ0E7Z0NBQ0E7MEdBQ0E7QUFDQTtpRUFDQTt1RUFDQTtxQ0FDQTtxQ0FDQTtxQ0FDQTtxQ0FDQTtxQ0FDQTsyQ0FDQTtzQ0FDQTtBQUNBO0FBQ0E7d0RBQ0E7bUJBQ0E7MkNBQ0E7c0NBQ0E7QUFDQTtBQUNBO0FBQ0E7MkRBQ0E7QUFDQTsrQ0FDQTsrQkFDQTtBQUNBO2tCQUNBO2tCQUNBO0FBQ0E7d0VBQ0E7a0RBQ0E7QUFDQTtnQ0FDQTtpQkFDQTsyRUFDQTtBQUNBO3FFQUNBOzJFQUNBO3FDQUNBO3FDQUNBO3FDQUNBO3FDQUNBO3FDQUNBOzJDQUNBO3NDQUNBO0FBQ0E7QUFDQTt3REFFQTttQkFDQTsyQ0FDQTtzQ0FDQTtBQUNBO0FBQ0E7MkRBQ0E7QUFDQTsrQ0FDQTsrQkFDQTtBQUNBO2tCQUNBO2tCQUNBO2tEQUNBO2dDQUNBO2lCQUNBOzZFQUNBO0FBRUE7QUF6RkE7QUFqS0EiLCJmaWxlIjoiMjAuanMiLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XHJcbiAgICA8ZGl2IHJlZj1cIml0ZW1cIiBjbGFzcz1cInZ1ZS1ncmlkLWxheW91dFwiIDpzdHlsZT1cIm1lcmdlZFN0eWxlXCI+XHJcbiAgICAgICAgPHNsb3Q+PC9zbG90PlxyXG4gICAgICAgIDxncmlkLWl0ZW0gY2xhc3M9XCJ2dWUtZ3JpZC1wbGFjZWhvbGRlclwiXHJcbiAgICAgICAgICAgICAgICAgICB2LXNob3c9XCJpc0RyYWdnaW5nXCJcclxuICAgICAgICAgICAgICAgICAgIDp4PVwicGxhY2Vob2xkZXIueFwiXHJcbiAgICAgICAgICAgICAgICAgICA6eT1cInBsYWNlaG9sZGVyLnlcIlxyXG4gICAgICAgICAgICAgICAgICAgOnc9XCJwbGFjZWhvbGRlci53XCJcclxuICAgICAgICAgICAgICAgICAgIDpoPVwicGxhY2Vob2xkZXIuaFwiXHJcbiAgICAgICAgICAgICAgICAgICA6aT1cInBsYWNlaG9sZGVyLmlcIj48L2dyaWQtaXRlbT5cclxuICAgIDwvZGl2PlxyXG48L3RlbXBsYXRlPlxyXG48c3R5bGU+XHJcbiAgICAudnVlLWdyaWQtbGF5b3V0IHtcclxuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XHJcbiAgICAgICAgdHJhbnNpdGlvbjogaGVpZ2h0IDIwMG1zIGVhc2U7XHJcbiAgICB9XHJcbjwvc3R5bGU+XHJcbjxzY3JpcHQ+XHJcbiAgICBpbXBvcnQgVnVlIGZyb20gJ3Z1ZSc7XHJcbiAgICB2YXIgZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIgPSByZXF1aXJlKFwiZWxlbWVudC1yZXNpemUtZGV0ZWN0b3JcIik7XHJcblxyXG4gICAgaW1wb3J0IHtib3R0b20sIGNvbXBhY3QsIGdldExheW91dEl0ZW0sIG1vdmVFbGVtZW50LCB2YWxpZGF0ZUxheW91dH0gZnJvbSAnLi91dGlscyc7XHJcbiAgICAvL3ZhciBldmVudEJ1cyA9IHJlcXVpcmUoJy4vZXZlbnRCdXMnKTtcclxuICAgIGltcG9ydCBHcmlkSXRlbSBmcm9tICcuL0dyaWRJdGVtLnZ1ZSdcclxuXHJcbiAgICBleHBvcnQgZGVmYXVsdCB7XHJcbiAgICAgICAgbmFtZTogXCJHcmlkTGF5b3V0XCIsXHJcbiAgICAgICAgcHJvdmlkZSgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGV2ZW50QnVzOiBudWxsXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIGNvbXBvbmVudHM6IHtcclxuICAgICAgICAgICAgR3JpZEl0ZW0sXHJcbiAgICAgICAgfSxcclxuICAgICAgICBwcm9wczoge1xyXG4gICAgICAgICAgICAvLyBJZiB0cnVlLCB0aGUgY29udGFpbmVyIGhlaWdodCBzd2VsbHMgYW5kIGNvbnRyYWN0cyB0byBmaXQgY29udGVudHNcclxuICAgICAgICAgICAgYXV0b1NpemU6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGNvbE51bToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMTJcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcm93SGVpZ2h0OiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAxNTBcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWF4Um93czoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogSW5maW5pdHlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWFyZ2luOiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheSxcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWzEwLCAxMF07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBpc1Jlc2l6YWJsZToge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaXNNaXJyb3JlZDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHVzZUNzc1RyYW5zZm9ybXM6IHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHZlcnRpY2FsQ29tcGFjdDoge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbGF5b3V0OiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBBcnJheSxcclxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZGF0YTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgd2lkdGg6IG51bGwsXHJcbiAgICAgICAgICAgICAgICBtZXJnZWRTdHlsZToge30sXHJcbiAgICAgICAgICAgICAgICBsYXN0TGF5b3V0TGVuZ3RoOiAwLFxyXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2luZzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjoge1xyXG4gICAgICAgICAgICAgICAgICAgIHg6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgeTogMCxcclxuICAgICAgICAgICAgICAgICAgICB3OiAwLFxyXG4gICAgICAgICAgICAgICAgICAgIGg6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgaTogLTFcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjcmVhdGVkICgpIHtcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICAgICAgICAgICAgLy8gQWNjZXNzaWJsZSByZWZlcm5jZXMgb2YgZnVuY3Rpb25zIGZvciByZW1vdmluZyBpbiBiZWZvcmVEZXN0cm95XHJcbiAgICAgICAgICAgIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyID0gZnVuY3Rpb24oZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnJlc2l6ZUV2ZW50KGV2ZW50VHlwZSwgaSwgeCwgeSwgaCwgdyk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBzZWxmLmRyYWdFdmVudEhhbmRsZXIgPSBmdW5jdGlvbihldmVudFR5cGUsIGksIHgsIHksIGgsIHcpIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuZHJhZ0V2ZW50KGV2ZW50VHlwZSwgaSwgeCwgeSwgaCwgdyk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBzZWxmLl9wcm92aWRlZC5ldmVudEJ1cyA9ICBuZXcgVnVlKCk7XHJcbiAgICAgICAgICAgIHNlbGYuZXZlbnRCdXMgPSBzZWxmLl9wcm92aWRlZC5ldmVudEJ1cztcclxuICAgICAgICAgICAgc2VsZi5ldmVudEJ1cy4kb24oJ3Jlc2l6ZUV2ZW50Jywgc2VsZi5yZXNpemVFdmVudEhhbmRsZXIpO1xyXG4gICAgICAgICAgICBzZWxmLmV2ZW50QnVzLiRvbignZHJhZ0V2ZW50Jywgc2VsZi5kcmFnRXZlbnRIYW5kbGVyKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGJlZm9yZURlc3Ryb3k6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgIC8vUmVtb3ZlIGxpc3RlbmVyc1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ3Jlc2l6ZUV2ZW50Jywgc2VsZi5yZXNpemVFdmVudEhhbmRsZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ2RyYWdFdmVudCcsIHNlbGYuZHJhZ0V2ZW50SGFuZGxlcik7XHJcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwicmVzaXplXCIsIHNlbGYub25XaW5kb3dSZXNpemUpXHJcbiAgICAgICAgfSxcclxuICAgICAgICBtb3VudGVkOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdmFsaWRhdGVMYXlvdXQodGhpcy5sYXlvdXQpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYud2lkdGggPT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vbldpbmRvd1Jlc2l6ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NlbGYud2lkdGggPSBzZWxmLiRlbC5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHNlbGYub25XaW5kb3dSZXNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHNlbGYubGF5b3V0LCBzZWxmLnZlcnRpY2FsQ29tcGFjdCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYudXBkYXRlSGVpZ2h0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZi4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJkID0gZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyYXRlZ3k6IFwic2Nyb2xsXCIgLy88LSBGb3IgdWx0cmEgcGVyZm9ybWFuY2UuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcmQubGlzdGVuVG8oc2VsZi4kcmVmcy5pdGVtLCBmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5vbldpbmRvd1Jlc2l6ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgd2luZG93Lm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLndpZHRoID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zZWxmLndpZHRoID0gc2VsZi4kZWwub2Zmc2V0V2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBzZWxmLm9uV2luZG93UmVzaXplKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdChzZWxmLmxheW91dCwgc2VsZi52ZXJ0aWNhbENvbXBhY3QpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZUhlaWdodCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVyZCA9IGVsZW1lbnRSZXNpemVEZXRlY3Rvck1ha2VyKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiBcInNjcm9sbFwiIC8vPC0gRm9yIHVsdHJhIHBlcmZvcm1hbmNlLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJkLmxpc3RlblRvKHNlbGYuJHJlZnMuaXRlbSwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICB3YXRjaDoge1xyXG4gICAgICAgICAgICB3aWR0aDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFwidXBkYXRlV2lkdGhcIiwgdGhpcy53aWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInVwZGF0ZVdpZHRoXCIsIHRoaXMud2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbGF5b3V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxheW91dFVwZGF0ZSgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICByb3dIZWlnaHQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInNldFJvd0hlaWdodFwiLCB0aGlzLnJvd0hlaWdodCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXCJzZXREcmFnZ2FibGVcIiwgdGhpcy5pc0RyYWdnYWJsZSk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXCJzZXRSZXNpemFibGVcIiwgdGhpcy5pc1Jlc2l6YWJsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIG1ldGhvZHM6IHtcclxuICAgICAgICAgICAgbGF5b3V0VXBkYXRlKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubGF5b3V0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5sYXlvdXQubGVuZ3RoICE9PSB0aGlzLmxhc3RMYXlvdXRMZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIiMjIyBMQVlPVVQgVVBEQVRFIVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXN0TGF5b3V0TGVuZ3RoID0gdGhpcy5sYXlvdXQubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHRoaXMubGF5b3V0LCB0aGlzLnZlcnRpY2FsQ29tcGFjdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInVwZGF0ZVdpZHRoXCIsIHRoaXMud2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHVwZGF0ZUhlaWdodDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tZXJnZWRTdHlsZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuY29udGFpbmVySGVpZ2h0KClcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG9uV2luZG93UmVzaXplOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4kcmVmcyAhPT0gbnVsbCAmJiB0aGlzLiRyZWZzLml0ZW0gIT09IG51bGwgJiYgdGhpcy4kcmVmcy5pdGVtICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy4kcmVmcy5pdGVtLm9mZnNldFdpZHRoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5hdXRvU2l6ZSkgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJvdHRvbSh0aGlzLmxheW91dCkgKiAodGhpcy5yb3dIZWlnaHQgKyB0aGlzLm1hcmdpblsxXSkgKyB0aGlzLm1hcmdpblsxXSArICdweCc7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGRyYWdFdmVudDogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaWQsIHgsIHksIGgsIHcpIHtcclxuICAgICAgICAgICAgICAgIGlmIChldmVudE5hbWUgPT09IFwiZHJhZ21vdmVcIiB8fCBldmVudE5hbWUgPT09IFwiZHJhZ3N0YXJ0XCIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmkgPSBpZDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnggPSB4O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueSA9IHk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci53ID0gdztcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmggPSBoO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFwidXBkYXRlV2lkdGhcIiwgdGhpcy53aWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInVwZGF0ZVdpZHRoXCIsIHRoaXMud2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKGV2ZW50TmFtZSArIFwiIGlkPVwiICsgaWQgKyBcIiwgeD1cIiArIHggKyBcIiwgeT1cIiArIHkpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGwgPSBnZXRMYXlvdXRJdGVtKHRoaXMubGF5b3V0LCBpZCk7XHJcbiAgICAgICAgICAgICAgICAvL0dldExheW91dEl0ZW0gc29tZXRpbWVzIHJldHVybnMgbnVsbCBvYmplY3RcclxuICAgICAgICAgICAgICAgIGlmIChsID09PSB1bmRlZmluZWQgfHwgbCA9PT0gbnVsbCl7XHJcbiAgICAgICAgICAgICAgICAgICAgbCA9IHt4OjAsIHk6MH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGwueCA9IHg7XHJcbiAgICAgICAgICAgICAgICBsLnkgPSB5O1xyXG4gICAgICAgICAgICAgICAgLy8gTW92ZSB0aGUgZWxlbWVudCB0byB0aGUgZHJhZ2dlZCBsb2NhdGlvbi5cclxuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0ID0gbW92ZUVsZW1lbnQodGhpcy5sYXlvdXQsIGwsIHgsIHksIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xyXG4gICAgICAgICAgICAgICAgLy8gbmVlZGVkIGJlY2F1c2UgdnVlIGNhbid0IGRldGVjdCBjaGFuZ2VzIG9uIGFycmF5IGVsZW1lbnQgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcImNvbXBhY3RcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ2RyYWdlbmQnKSB0aGlzLiRlbWl0KCdsYXlvdXQtdXBkYXRlZCcsIHRoaXMubGF5b3V0KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcmVzaXplRXZlbnQ6IGZ1bmN0aW9uIChldmVudE5hbWUsIGlkLCB4LCB5LCBoLCB3KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnROYW1lID09PSBcInJlc2l6ZXN0YXJ0XCIgfHwgZXZlbnROYW1lID09PSBcInJlc2l6ZW1vdmVcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaSA9IGlkO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIueCA9IHg7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci55ID0geTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLncgPSB3O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaCA9IGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLiRicm9hZGNhc3QoXCJ1cGRhdGVXaWR0aFwiLCB0aGlzLndpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFwidXBkYXRlV2lkdGhcIiwgdGhpcy53aWR0aCk7XHJcblxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgbCA9IGdldExheW91dEl0ZW0odGhpcy5sYXlvdXQsIGlkKTtcclxuICAgICAgICAgICAgICAgIC8vR2V0TGF5b3V0SXRlbSBzb21ldGltZXMgcmV0dXJuIG51bGwgb2JqZWN0XHJcbiAgICAgICAgICAgICAgICBpZiAobCA9PT0gdW5kZWZpbmVkIHx8IGwgPT09IG51bGwpe1xyXG4gICAgICAgICAgICAgICAgICAgIGwgPSB7aDowLCB3OjB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBsLmggPSBoO1xyXG4gICAgICAgICAgICAgICAgbC53ID0gdztcclxuICAgICAgICAgICAgICAgIGNvbXBhY3QodGhpcy5sYXlvdXQsIHRoaXMudmVydGljYWxDb21wYWN0KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXCJjb21wYWN0XCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcclxuICAgICAgICAgICAgICAgIGlmIChldmVudE5hbWUgPT09ICdyZXNpemVlbmQnKSB0aGlzLiRlbWl0KCdsYXlvdXQtdXBkYXRlZCcsIHRoaXMubGF5b3V0KTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9LFxyXG4gICAgfVxyXG48L3NjcmlwdD5cclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIEdyaWRMYXlvdXQudnVlPzM0NzBmMzMyIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///20\n"); /***/ }), /* 21 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nexports.__esModule = true;\n\nvar _vue = __webpack_require__(22);\n\nvar _vue2 = _interopRequireDefault(_vue);\n\nvar _utils = __webpack_require__(0);\n\nvar _GridItem = __webpack_require__(1);\n\nvar _GridItem2 = _interopRequireDefault(_GridItem);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar elementResizeDetectorMaker = __webpack_require__(7); //\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n//var eventBus = require('./eventBus');\nexports.default = {\n name: \"GridLayout\",\n provide: function provide() {\n return {\n eventBus: null\n };\n },\n\n components: {\n GridItem: _GridItem2.default\n },\n props: {\n // If true, the container height swells and contracts to fit contents\n autoSize: {\n type: Boolean,\n default: true\n },\n colNum: {\n type: Number,\n default: 12\n },\n rowHeight: {\n type: Number,\n default: 150\n },\n maxRows: {\n type: Number,\n default: Infinity\n },\n margin: {\n type: Array,\n default: function _default() {\n return [10, 10];\n }\n },\n isDraggable: {\n type: Boolean,\n default: true\n },\n isResizable: {\n type: Boolean,\n default: true\n },\n isMirrored: {\n type: Boolean,\n default: false\n },\n useCssTransforms: {\n type: Boolean,\n default: true\n },\n verticalCompact: {\n type: Boolean,\n default: true\n },\n layout: {\n type: Array,\n required: true\n }\n },\n data: function data() {\n return {\n width: null,\n mergedStyle: {},\n lastLayoutLength: 0,\n isDragging: false,\n placeholder: {\n x: 0,\n y: 0,\n w: 0,\n h: 0,\n i: -1\n }\n };\n },\n created: function created() {\n var self = this;\n\n // Accessible refernces of functions for removing in beforeDestroy\n self.resizeEventHandler = function (eventType, i, x, y, h, w) {\n self.resizeEvent(eventType, i, x, y, h, w);\n };\n\n self.dragEventHandler = function (eventType, i, x, y, h, w) {\n self.dragEvent(eventType, i, x, y, h, w);\n };\n\n self._provided.eventBus = new _vue2.default();\n self.eventBus = self._provided.eventBus;\n self.eventBus.$on('resizeEvent', self.resizeEventHandler);\n self.eventBus.$on('dragEvent', self.dragEventHandler);\n },\n\n beforeDestroy: function beforeDestroy() {\n //Remove listeners\n this.eventBus.$off('resizeEvent', self.resizeEventHandler);\n this.eventBus.$off('dragEvent', self.dragEventHandler);\n window.removeEventListener(\"resize\", self.onWindowResize);\n },\n mounted: function mounted() {\n this.$nextTick(function () {\n (0, _utils.validateLayout)(this.layout);\n var self = this;\n this.$nextTick(function () {\n if (self.width === null) {\n self.onWindowResize();\n //self.width = self.$el.offsetWidth;\n window.addEventListener('resize', self.onWindowResize);\n }\n (0, _utils.compact)(self.layout, self.verticalCompact);\n\n self.updateHeight();\n self.$nextTick(function () {\n var erd = elementResizeDetectorMaker({\n strategy: \"scroll\" //<- For ultra performance.\n });\n erd.listenTo(self.$refs.item, function (element) {\n self.onWindowResize();\n });\n });\n });\n window.onload = function () {\n if (self.width === null) {\n self.onWindowResize();\n //self.width = self.$el.offsetWidth;\n window.addEventListener('resize', self.onWindowResize);\n }\n (0, _utils.compact)(self.layout, self.verticalCompact);\n\n self.updateHeight();\n self.$nextTick(function () {\n var erd = elementResizeDetectorMaker({\n strategy: \"scroll\" //<- For ultra performance.\n });\n erd.listenTo(self.$refs.item, function (element) {\n self.onWindowResize();\n });\n });\n };\n });\n },\n watch: {\n width: function width() {\n this.$nextTick(function () {\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n this.updateHeight();\n });\n },\n layout: function layout() {\n this.layoutUpdate();\n },\n rowHeight: function rowHeight() {\n this.eventBus.$emit(\"setRowHeight\", this.rowHeight);\n },\n isDraggable: function isDraggable() {\n this.eventBus.$emit(\"setDraggable\", this.isDraggable);\n },\n isResizable: function isResizable() {\n this.eventBus.$emit(\"setResizable\", this.isResizable);\n }\n },\n methods: {\n layoutUpdate: function layoutUpdate() {\n if (this.layout !== undefined && this.layout.length !== this.lastLayoutLength) {\n // console.log(\"### LAYOUT UPDATE!\");\n this.lastLayoutLength = this.layout.length;\n (0, _utils.compact)(this.layout, this.verticalCompact);\n\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n this.updateHeight();\n }\n },\n\n updateHeight: function updateHeight() {\n this.mergedStyle = {\n height: this.containerHeight()\n };\n },\n onWindowResize: function onWindowResize() {\n if (this.$refs !== null && this.$refs.item !== null && this.$refs.item !== undefined) {\n this.width = this.$refs.item.offsetWidth;\n }\n },\n containerHeight: function containerHeight() {\n if (!this.autoSize) return;\n return (0, _utils.bottom)(this.layout) * (this.rowHeight + this.margin[1]) + this.margin[1] + 'px';\n },\n dragEvent: function dragEvent(eventName, id, x, y, h, w) {\n if (eventName === \"dragmove\" || eventName === \"dragstart\") {\n this.placeholder.i = id;\n this.placeholder.x = x;\n this.placeholder.y = y;\n this.placeholder.w = w;\n this.placeholder.h = h;\n this.$nextTick(function () {\n this.isDragging = true;\n });\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n } else {\n this.$nextTick(function () {\n this.isDragging = false;\n });\n }\n //console.log(eventName + \" id=\" + id + \", x=\" + x + \", y=\" + y);\n var l = (0, _utils.getLayoutItem)(this.layout, id);\n //GetLayoutItem sometimes returns null object\n if (l === undefined || l === null) {\n l = { x: 0, y: 0 };\n }\n l.x = x;\n l.y = y;\n // Move the element to the dragged location.\n this.layout = (0, _utils.moveElement)(this.layout, l, x, y, true);\n (0, _utils.compact)(this.layout, this.verticalCompact);\n // needed because vue can't detect changes on array element properties\n this.eventBus.$emit(\"compact\");\n this.updateHeight();\n if (eventName === 'dragend') this.$emit('layout-updated', this.layout);\n },\n resizeEvent: function resizeEvent(eventName, id, x, y, h, w) {\n if (eventName === \"resizestart\" || eventName === \"resizemove\") {\n this.placeholder.i = id;\n this.placeholder.x = x;\n this.placeholder.y = y;\n this.placeholder.w = w;\n this.placeholder.h = h;\n this.$nextTick(function () {\n this.isDragging = true;\n });\n //this.$broadcast(\"updateWidth\", this.width);\n this.eventBus.$emit(\"updateWidth\", this.width);\n } else {\n this.$nextTick(function () {\n this.isDragging = false;\n });\n }\n var l = (0, _utils.getLayoutItem)(this.layout, id);\n //GetLayoutItem sometimes return null object\n if (l === undefined || l === null) {\n l = { h: 0, w: 0 };\n }\n l.h = h;\n l.w = w;\n (0, _utils.compact)(this.layout, this.verticalCompact);\n this.eventBus.$emit(\"compact\");\n this.updateHeight();\n if (eventName === 'resizeend') this.$emit('layout-updated', this.layout);\n }\n }\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vR3JpZExheW91dC52dWU/MTBjMyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBb0JBOzs7O0FBR0E7O0FBR0E7Ozs7OztxREFKQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFIQTs7QUFLQTs7VUFJQTtnQ0FDQTs7c0JBR0E7QUFGQTtBQUdBOzs7QUFHQTtBQUZBOztBQUlBOztrQkFFQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTtxQkFFQTtBQUhBOztrQkFLQTt5Q0FDQTs0QkFDQTtBQUVBO0FBTEE7O2tCQU9BO3FCQUVBO0FBSEE7O2tCQUtBO3FCQUVBO0FBSEE7O2tCQUtBO3FCQUVBO0FBSEE7O2tCQUtBO3FCQUVBO0FBSEE7O2tCQUtBO3FCQUVBO0FBSEE7O2tCQUtBO3NCQUdBO0FBSkE7QUE1Q0E7MEJBaURBOzttQkFFQTt5QkFDQTs4QkFDQTt3QkFDQTs7bUJBRUE7bUJBQ0E7bUJBQ0E7bUJBQ0E7b0JBR0E7QUFQQTtBQUxBO0FBYUE7Z0NBQ0E7bUJBRUE7O0FBQ0E7c0VBQ0E7b0RBQ0E7QUFFQTs7b0VBQ0E7a0RBQ0E7QUFFQTs7a0NBQ0E7dUNBQ0E7OENBQ0E7NENBQ0E7QUFDQTs7NENBQ0E7QUFDQTsrQ0FDQTs2Q0FDQTtrREFDQTtBQUNBO2dDQUNBO21DQUNBOzRDQUNBO3VCQUNBO3VDQUNBO3lDQUNBO3lCQUNBO0FBQ0E7MkRBQ0E7QUFDQTtzREFFQTs7cUJBQ0E7MkNBQ0E7OzJDQUdBO0FBRkE7cUVBR0E7NkJBQ0E7QUFDQTtBQUNBO0FBQ0E7d0NBQ0E7eUNBQ0E7eUJBQ0E7QUFDQTsyREFDQTtBQUNBO3NEQUVBOztxQkFDQTsyQ0FDQTs7MkNBR0E7QUFGQTtxRUFHQTs2QkFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7O2dDQUVBO3VDQUNBO0FBQ0E7d0RBQ0E7cUJBQ0E7QUFDQTtBQUNBO2tDQUNBO2lCQUNBO0FBQ0E7d0NBQ0E7cURBQ0E7QUFDQTs0Q0FDQTtxREFDQTtBQUNBOzRDQUNBO3FEQUNBO0FBRUE7QUFwQkE7OzhDQXNCQTs7QUFFQTtvREFDQTtzREFFQTs7QUFDQTt3REFDQTtxQkFDQTtBQUNBO0FBQ0E7OzhDQUNBOzs2QkFHQTtBQUZBO0FBR0E7a0RBQ0E7a0dBQ0E7NkNBQ0E7QUFDQTtBQUNBO29EQUNBO2dDQUNBOzBHQUNBO0FBQ0E7aUVBQ0E7dUVBQ0E7cUNBQ0E7cUNBQ0E7cUNBQ0E7cUNBQ0E7cUNBQ0E7MkNBQ0E7c0NBQ0E7QUFDQTtBQUNBO3dEQUNBO21CQUNBOzJDQUNBO3NDQUNBO0FBQ0E7QUFDQTtBQUNBOzJEQUNBO0FBQ0E7K0NBQ0E7K0JBQ0E7QUFDQTtrQkFDQTtrQkFDQTtBQUNBO3dFQUNBO2tEQUNBO0FBQ0E7Z0NBQ0E7aUJBQ0E7MkVBQ0E7QUFDQTtxRUFDQTsyRUFDQTtxQ0FDQTtxQ0FDQTtxQ0FDQTtxQ0FDQTtxQ0FDQTsyQ0FDQTtzQ0FDQTtBQUNBO0FBQ0E7d0RBRUE7bUJBQ0E7MkNBQ0E7c0NBQ0E7QUFDQTtBQUNBOzJEQUNBO0FBQ0E7K0NBQ0E7K0JBQ0E7QUFDQTtrQkFDQTtrQkFDQTtrREFDQTtnQ0FDQTtpQkFDQTs2RUFDQTtBQUVBO0FBekZBO0FBaktBIiwiZmlsZSI6IjIxLmpzIiwic291cmNlc0NvbnRlbnQiOlsiPHRlbXBsYXRlPlxuICAgIDxkaXYgcmVmPVwiaXRlbVwiIGNsYXNzPVwidnVlLWdyaWQtbGF5b3V0XCIgOnN0eWxlPVwibWVyZ2VkU3R5bGVcIj5cbiAgICAgICAgPHNsb3Q+PC9zbG90PlxuICAgICAgICA8Z3JpZC1pdGVtIGNsYXNzPVwidnVlLWdyaWQtcGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICAgICAgIHYtc2hvdz1cImlzRHJhZ2dpbmdcIlxuICAgICAgICAgICAgICAgICAgIDp4PVwicGxhY2Vob2xkZXIueFwiXG4gICAgICAgICAgICAgICAgICAgOnk9XCJwbGFjZWhvbGRlci55XCJcbiAgICAgICAgICAgICAgICAgICA6dz1cInBsYWNlaG9sZGVyLndcIlxuICAgICAgICAgICAgICAgICAgIDpoPVwicGxhY2Vob2xkZXIuaFwiXG4gICAgICAgICAgICAgICAgICAgOmk9XCJwbGFjZWhvbGRlci5pXCI+PC9ncmlkLWl0ZW0+XG4gICAgPC9kaXY+XG48L3RlbXBsYXRlPlxuPHN0eWxlPlxuICAgIC52dWUtZ3JpZC1sYXlvdXQge1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIHRyYW5zaXRpb246IGhlaWdodCAyMDBtcyBlYXNlO1xuICAgIH1cbjwvc3R5bGU+XG48c2NyaXB0PlxuICAgIGltcG9ydCBWdWUgZnJvbSAndnVlJztcbiAgICB2YXIgZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIgPSByZXF1aXJlKFwiZWxlbWVudC1yZXNpemUtZGV0ZWN0b3JcIik7XG5cbiAgICBpbXBvcnQge2JvdHRvbSwgY29tcGFjdCwgZ2V0TGF5b3V0SXRlbSwgbW92ZUVsZW1lbnQsIHZhbGlkYXRlTGF5b3V0fSBmcm9tICcuL3V0aWxzJztcbiAgICAvL3ZhciBldmVudEJ1cyA9IHJlcXVpcmUoJy4vZXZlbnRCdXMnKTtcbiAgICBpbXBvcnQgR3JpZEl0ZW0gZnJvbSAnLi9HcmlkSXRlbS52dWUnXG5cbiAgICBleHBvcnQgZGVmYXVsdCB7XG4gICAgICAgIG5hbWU6IFwiR3JpZExheW91dFwiLFxuICAgICAgICBwcm92aWRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBldmVudEJ1czogbnVsbFxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjb21wb25lbnRzOiB7XG4gICAgICAgICAgICBHcmlkSXRlbSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICAgIC8vIElmIHRydWUsIHRoZSBjb250YWluZXIgaGVpZ2h0IHN3ZWxscyBhbmQgY29udHJhY3RzIHRvIGZpdCBjb250ZW50c1xuICAgICAgICAgICAgYXV0b1NpemU6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBCb29sZWFuLFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb2xOdW06IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMTJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByb3dIZWlnaHQ6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBOdW1iZXIsXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogMTUwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbWF4Um93czoge1xuICAgICAgICAgICAgICAgIHR5cGU6IE51bWJlcixcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBJbmZpbml0eVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG1hcmdpbjoge1xuICAgICAgICAgICAgICAgIHR5cGU6IEFycmF5LFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFsxMCwgMTBdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpc0RyYWdnYWJsZToge1xuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaXNNaXJyb3JlZDoge1xuICAgICAgICAgICAgICAgIHR5cGU6IEJvb2xlYW4sXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogZmFsc2VcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB1c2VDc3NUcmFuc2Zvcm1zOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdmVydGljYWxDb21wYWN0OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogQm9vbGVhbixcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGF5b3V0OiB7XG4gICAgICAgICAgICAgICAgdHlwZTogQXJyYXksXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBkYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHdpZHRoOiBudWxsLFxuICAgICAgICAgICAgICAgIG1lcmdlZFN0eWxlOiB7fSxcbiAgICAgICAgICAgICAgICBsYXN0TGF5b3V0TGVuZ3RoOiAwLFxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB7XG4gICAgICAgICAgICAgICAgICAgIHg6IDAsXG4gICAgICAgICAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICAgICAgICAgIHc6IDAsXG4gICAgICAgICAgICAgICAgICAgIGg6IDAsXG4gICAgICAgICAgICAgICAgICAgIGk6IC0xXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgICAgIGNyZWF0ZWQgKCkge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgICAgICAgICAvLyBBY2Nlc3NpYmxlIHJlZmVybmNlcyBvZiBmdW5jdGlvbnMgZm9yIHJlbW92aW5nIGluIGJlZm9yZURlc3Ryb3lcbiAgICAgICAgICAgIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyID0gZnVuY3Rpb24oZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KSB7XG4gICAgICAgICAgICAgICAgc2VsZi5yZXNpemVFdmVudChldmVudFR5cGUsIGksIHgsIHksIGgsIHcpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgc2VsZi5kcmFnRXZlbnRIYW5kbGVyID0gZnVuY3Rpb24oZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KSB7XG4gICAgICAgICAgICAgICAgc2VsZi5kcmFnRXZlbnQoZXZlbnRUeXBlLCBpLCB4LCB5LCBoLCB3KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHNlbGYuX3Byb3ZpZGVkLmV2ZW50QnVzID0gIG5ldyBWdWUoKTtcbiAgICAgICAgICAgIHNlbGYuZXZlbnRCdXMgPSBzZWxmLl9wcm92aWRlZC5ldmVudEJ1cztcbiAgICAgICAgICAgIHNlbGYuZXZlbnRCdXMuJG9uKCdyZXNpemVFdmVudCcsIHNlbGYucmVzaXplRXZlbnRIYW5kbGVyKTtcbiAgICAgICAgICAgIHNlbGYuZXZlbnRCdXMuJG9uKCdkcmFnRXZlbnQnLCBzZWxmLmRyYWdFdmVudEhhbmRsZXIpO1xuICAgICAgICB9LFxuICAgICAgICBiZWZvcmVEZXN0cm95OiBmdW5jdGlvbigpe1xuICAgICAgICAgICAgLy9SZW1vdmUgbGlzdGVuZXJzXG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRvZmYoJ3Jlc2l6ZUV2ZW50Jywgc2VsZi5yZXNpemVFdmVudEhhbmRsZXIpO1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kb2ZmKCdkcmFnRXZlbnQnLCBzZWxmLmRyYWdFdmVudEhhbmRsZXIpO1xuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwgc2VsZi5vbldpbmRvd1Jlc2l6ZSlcbiAgICAgICAgfSxcbiAgICAgICAgbW91bnRlZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGVMYXlvdXQodGhpcy5sYXlvdXQpO1xuICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYud2lkdGggPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vc2VsZi53aWR0aCA9IHNlbGYuJGVsLm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHNlbGYub25XaW5kb3dSZXNpemUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbXBhY3Qoc2VsZi5sYXlvdXQsIHNlbGYudmVydGljYWxDb21wYWN0KTtcblxuICAgICAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLiRuZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJkID0gZWxlbWVudFJlc2l6ZURldGVjdG9yTWFrZXIoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiBcInNjcm9sbFwiIC8vPC0gRm9yIHVsdHJhIHBlcmZvcm1hbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcmQubGlzdGVuVG8oc2VsZi4kcmVmcy5pdGVtLCBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub25XaW5kb3dSZXNpemUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB3aW5kb3cub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLndpZHRoID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NlbGYud2lkdGggPSBzZWxmLiRlbC5vZmZzZXRXaWR0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBzZWxmLm9uV2luZG93UmVzaXplKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb21wYWN0KHNlbGYubGF5b3V0LCBzZWxmLnZlcnRpY2FsQ29tcGFjdCk7XG5cbiAgICAgICAgICAgICAgICAgICAgc2VsZi51cGRhdGVIZWlnaHQoKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi4kbmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVyZCA9IGVsZW1lbnRSZXNpemVEZXRlY3Rvck1ha2VyKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhdGVneTogXCJzY3JvbGxcIiAvLzwtIEZvciB1bHRyYSBwZXJmb3JtYW5jZS5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJkLmxpc3RlblRvKHNlbGYuJHJlZnMuaXRlbSwgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uV2luZG93UmVzaXplKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICAgIHdhdGNoOiB7XG4gICAgICAgICAgICB3aWR0aDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLiRicm9hZGNhc3QoXCJ1cGRhdGVXaWR0aFwiLCB0aGlzLndpZHRoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInVwZGF0ZVdpZHRoXCIsIHRoaXMud2lkdGgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxheW91dDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VXBkYXRlKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcm93SGVpZ2h0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFwic2V0Um93SGVpZ2h0XCIsIHRoaXMucm93SGVpZ2h0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpc0RyYWdnYWJsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInNldERyYWdnYWJsZVwiLCB0aGlzLmlzRHJhZ2dhYmxlKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpc1Jlc2l6YWJsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInNldFJlc2l6YWJsZVwiLCB0aGlzLmlzUmVzaXphYmxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgbWV0aG9kczoge1xuICAgICAgICAgICAgbGF5b3V0VXBkYXRlKCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxheW91dCAhPT0gdW5kZWZpbmVkICYmIHRoaXMubGF5b3V0Lmxlbmd0aCAhPT0gdGhpcy5sYXN0TGF5b3V0TGVuZ3RoKSB7XG4vLyAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCIjIyMgTEFZT1VUIFVQREFURSFcIik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGFzdExheW91dExlbmd0aCA9IHRoaXMubGF5b3V0Lmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vdGhpcy4kYnJvYWRjYXN0KFwidXBkYXRlV2lkdGhcIiwgdGhpcy53aWR0aCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXCJ1cGRhdGVXaWR0aFwiLCB0aGlzLndpZHRoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdXBkYXRlSGVpZ2h0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXJnZWRTdHlsZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmNvbnRhaW5lckhlaWdodCgpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbldpbmRvd1Jlc2l6ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLiRyZWZzICE9PSBudWxsICYmIHRoaXMuJHJlZnMuaXRlbSAhPT0gbnVsbCAmJiB0aGlzLiRyZWZzLml0ZW0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy4kcmVmcy5pdGVtLm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYXV0b1NpemUpIHJldHVybjtcbiAgICAgICAgICAgICAgICByZXR1cm4gYm90dG9tKHRoaXMubGF5b3V0KSAqICh0aGlzLnJvd0hlaWdodCArIHRoaXMubWFyZ2luWzFdKSArIHRoaXMubWFyZ2luWzFdICsgJ3B4JztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkcmFnRXZlbnQ6IGZ1bmN0aW9uIChldmVudE5hbWUsIGlkLCB4LCB5LCBoLCB3KSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gXCJkcmFnbW92ZVwiIHx8IGV2ZW50TmFtZSA9PT0gXCJkcmFnc3RhcnRcIikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmkgPSBpZDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci54ID0geDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci55ID0geTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci53ID0gdztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbGFjZWhvbGRlci5oID0gaDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgLy90aGlzLiRicm9hZGNhc3QoXCJ1cGRhdGVXaWR0aFwiLCB0aGlzLndpZHRoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcInVwZGF0ZVdpZHRoXCIsIHRoaXMud2lkdGgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKGV2ZW50TmFtZSArIFwiIGlkPVwiICsgaWQgKyBcIiwgeD1cIiArIHggKyBcIiwgeT1cIiArIHkpO1xuICAgICAgICAgICAgICAgIHZhciBsID0gZ2V0TGF5b3V0SXRlbSh0aGlzLmxheW91dCwgaWQpO1xuICAgICAgICAgICAgICAgIC8vR2V0TGF5b3V0SXRlbSBzb21ldGltZXMgcmV0dXJucyBudWxsIG9iamVjdFxuICAgICAgICAgICAgICAgIGlmIChsID09PSB1bmRlZmluZWQgfHwgbCA9PT0gbnVsbCl7XG4gICAgICAgICAgICAgICAgICAgIGwgPSB7eDowLCB5OjB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGwueCA9IHg7XG4gICAgICAgICAgICAgICAgbC55ID0geTtcbiAgICAgICAgICAgICAgICAvLyBNb3ZlIHRoZSBlbGVtZW50IHRvIHRoZSBkcmFnZ2VkIGxvY2F0aW9uLlxuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0ID0gbW92ZUVsZW1lbnQodGhpcy5sYXlvdXQsIGwsIHgsIHksIHRydWUpO1xuICAgICAgICAgICAgICAgIGNvbXBhY3QodGhpcy5sYXlvdXQsIHRoaXMudmVydGljYWxDb21wYWN0KTtcbiAgICAgICAgICAgICAgICAvLyBuZWVkZWQgYmVjYXVzZSB2dWUgY2FuJ3QgZGV0ZWN0IGNoYW5nZXMgb24gYXJyYXkgZWxlbWVudCBwcm9wZXJ0aWVzXG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy4kZW1pdChcImNvbXBhY3RcIik7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnROYW1lID09PSAnZHJhZ2VuZCcpIHRoaXMuJGVtaXQoJ2xheW91dC11cGRhdGVkJywgdGhpcy5sYXlvdXQpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlc2l6ZUV2ZW50OiBmdW5jdGlvbiAoZXZlbnROYW1lLCBpZCwgeCwgeSwgaCwgdykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudE5hbWUgPT09IFwicmVzaXplc3RhcnRcIiB8fCBldmVudE5hbWUgPT09IFwicmVzaXplbW92ZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGxhY2Vob2xkZXIuaSA9IGlkO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnggPSB4O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLnkgPSB5O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLncgPSB3O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyLmggPSBoO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJGJyb2FkY2FzdChcInVwZGF0ZVdpZHRoXCIsIHRoaXMud2lkdGgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLiRlbWl0KFwidXBkYXRlV2lkdGhcIiwgdGhpcy53aWR0aCk7XG5cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRuZXh0VGljayhmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGwgPSBnZXRMYXlvdXRJdGVtKHRoaXMubGF5b3V0LCBpZCk7XG4gICAgICAgICAgICAgICAgLy9HZXRMYXlvdXRJdGVtIHNvbWV0aW1lcyByZXR1cm4gbnVsbCBvYmplY3RcbiAgICAgICAgICAgICAgICBpZiAobCA9PT0gdW5kZWZpbmVkIHx8IGwgPT09IG51bGwpe1xuICAgICAgICAgICAgICAgICAgICBsID0ge2g6MCwgdzowfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsLmggPSBoO1xuICAgICAgICAgICAgICAgIGwudyA9IHc7XG4gICAgICAgICAgICAgICAgY29tcGFjdCh0aGlzLmxheW91dCwgdGhpcy52ZXJ0aWNhbENvbXBhY3QpO1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuJGVtaXQoXCJjb21wYWN0XCIpO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSA9PT0gJ3Jlc2l6ZWVuZCcpIHRoaXMuJGVtaXQoJ2xheW91dC11cGRhdGVkJywgdGhpcy5sYXlvdXQpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICB9XG48L3NjcmlwdD5cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBHcmlkTGF5b3V0LnZ1ZT82YzczNmUyOSJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///21\n"); +eval("/* WEBPACK VAR INJECTION */(function(process, global) {/*!\n * Vue.js v2.4.2\n * (c) 2014-2017 Evan You\n * Released under the MIT License.\n */\n\n\n/* */\n\n// these helpers produces better vm code in JS engines due to their\n// explicitness and function inlining\nfunction isUndef (v) {\n return v === undefined || v === null\n}\n\nfunction isDef (v) {\n return v !== undefined && v !== null\n}\n\nfunction isTrue (v) {\n return v === true\n}\n\nfunction isFalse (v) {\n return v === false\n}\n\n/**\n * Check if value is primitive\n */\nfunction isPrimitive (value) {\n return (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n )\n}\n\n/**\n * Quick object check - this is primarily used to tell\n * Objects from primitive values when we know the value\n * is a JSON-compliant type.\n */\nfunction isObject (obj) {\n return obj !== null && typeof obj === 'object'\n}\n\nvar _toString = Object.prototype.toString;\n\n/**\n * Strict object type check. Only returns true\n * for plain JavaScript objects.\n */\nfunction isPlainObject (obj) {\n return _toString.call(obj) === '[object Object]'\n}\n\nfunction isRegExp (v) {\n return _toString.call(v) === '[object RegExp]'\n}\n\n/**\n * Check if val is a valid array index.\n */\nfunction isValidArrayIndex (val) {\n var n = parseFloat(val);\n return n >= 0 && Math.floor(n) === n && isFinite(val)\n}\n\n/**\n * Convert a value to a string that is actually rendered.\n */\nfunction toString (val) {\n return val == null\n ? ''\n : typeof val === 'object'\n ? JSON.stringify(val, null, 2)\n : String(val)\n}\n\n/**\n * Convert a input value to a number for persistence.\n * If the conversion fails, return original string.\n */\nfunction toNumber (val) {\n var n = parseFloat(val);\n return isNaN(n) ? val : n\n}\n\n/**\n * Make a map and return a function for checking if a key\n * is in that map.\n */\nfunction makeMap (\n str,\n expectsLowerCase\n) {\n var map = Object.create(null);\n var list = str.split(',');\n for (var i = 0; i < list.length; i++) {\n map[list[i]] = true;\n }\n return expectsLowerCase\n ? function (val) { return map[val.toLowerCase()]; }\n : function (val) { return map[val]; }\n}\n\n/**\n * Check if a tag is a built-in tag.\n */\nvar isBuiltInTag = makeMap('slot,component', true);\n\n/**\n * Check if a attribute is a reserved attribute.\n */\nvar isReservedAttribute = makeMap('key,ref,slot,is');\n\n/**\n * Remove an item from an array\n */\nfunction remove (arr, item) {\n if (arr.length) {\n var index = arr.indexOf(item);\n if (index > -1) {\n return arr.splice(index, 1)\n }\n }\n}\n\n/**\n * Check whether the object has the property.\n */\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction hasOwn (obj, key) {\n return hasOwnProperty.call(obj, key)\n}\n\n/**\n * Create a cached version of a pure function.\n */\nfunction cached (fn) {\n var cache = Object.create(null);\n return (function cachedFn (str) {\n var hit = cache[str];\n return hit || (cache[str] = fn(str))\n })\n}\n\n/**\n * Camelize a hyphen-delimited string.\n */\nvar camelizeRE = /-(\\w)/g;\nvar camelize = cached(function (str) {\n return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })\n});\n\n/**\n * Capitalize a string.\n */\nvar capitalize = cached(function (str) {\n return str.charAt(0).toUpperCase() + str.slice(1)\n});\n\n/**\n * Hyphenate a camelCase string.\n */\nvar hyphenateRE = /([^-])([A-Z])/g;\nvar hyphenate = cached(function (str) {\n return str\n .replace(hyphenateRE, '$1-$2')\n .replace(hyphenateRE, '$1-$2')\n .toLowerCase()\n});\n\n/**\n * Simple bind, faster than native\n */\nfunction bind (fn, ctx) {\n function boundFn (a) {\n var l = arguments.length;\n return l\n ? l > 1\n ? fn.apply(ctx, arguments)\n : fn.call(ctx, a)\n : fn.call(ctx)\n }\n // record original fn length\n boundFn._length = fn.length;\n return boundFn\n}\n\n/**\n * Convert an Array-like object to a real Array.\n */\nfunction toArray (list, start) {\n start = start || 0;\n var i = list.length - start;\n var ret = new Array(i);\n while (i--) {\n ret[i] = list[i + start];\n }\n return ret\n}\n\n/**\n * Mix properties into target object.\n */\nfunction extend (to, _from) {\n for (var key in _from) {\n to[key] = _from[key];\n }\n return to\n}\n\n/**\n * Merge an Array of Objects into a single Object.\n */\nfunction toObject (arr) {\n var res = {};\n for (var i = 0; i < arr.length; i++) {\n if (arr[i]) {\n extend(res, arr[i]);\n }\n }\n return res\n}\n\n/**\n * Perform no operation.\n * Stubbing args to make Flow happy without leaving useless transpiled code\n * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)\n */\nfunction noop (a, b, c) {}\n\n/**\n * Always return false.\n */\nvar no = function (a, b, c) { return false; };\n\n/**\n * Return same value\n */\nvar identity = function (_) { return _; };\n\n/**\n * Generate a static keys string from compiler modules.\n */\nfunction genStaticKeys (modules) {\n return modules.reduce(function (keys, m) {\n return keys.concat(m.staticKeys || [])\n }, []).join(',')\n}\n\n/**\n * Check if two values are loosely equal - that is,\n * if they are plain objects, do they have the same shape?\n */\nfunction looseEqual (a, b) {\n if (a === b) { return true }\n var isObjectA = isObject(a);\n var isObjectB = isObject(b);\n if (isObjectA && isObjectB) {\n try {\n var isArrayA = Array.isArray(a);\n var isArrayB = Array.isArray(b);\n if (isArrayA && isArrayB) {\n return a.length === b.length && a.every(function (e, i) {\n return looseEqual(e, b[i])\n })\n } else if (!isArrayA && !isArrayB) {\n var keysA = Object.keys(a);\n var keysB = Object.keys(b);\n return keysA.length === keysB.length && keysA.every(function (key) {\n return looseEqual(a[key], b[key])\n })\n } else {\n /* istanbul ignore next */\n return false\n }\n } catch (e) {\n /* istanbul ignore next */\n return false\n }\n } else if (!isObjectA && !isObjectB) {\n return String(a) === String(b)\n } else {\n return false\n }\n}\n\nfunction looseIndexOf (arr, val) {\n for (var i = 0; i < arr.length; i++) {\n if (looseEqual(arr[i], val)) { return i }\n }\n return -1\n}\n\n/**\n * Ensure a function is called only once.\n */\nfunction once (fn) {\n var called = false;\n return function () {\n if (!called) {\n called = true;\n fn.apply(this, arguments);\n }\n }\n}\n\nvar SSR_ATTR = 'data-server-rendered';\n\nvar ASSET_TYPES = [\n 'component',\n 'directive',\n 'filter'\n];\n\nvar LIFECYCLE_HOOKS = [\n 'beforeCreate',\n 'created',\n 'beforeMount',\n 'mounted',\n 'beforeUpdate',\n 'updated',\n 'beforeDestroy',\n 'destroyed',\n 'activated',\n 'deactivated'\n];\n\n/* */\n\nvar config = ({\n /**\n * Option merge strategies (used in core/util/options)\n */\n optionMergeStrategies: Object.create(null),\n\n /**\n * Whether to suppress warnings.\n */\n silent: false,\n\n /**\n * Show production mode tip message on boot?\n */\n productionTip: process.env.NODE_ENV !== 'production',\n\n /**\n * Whether to enable devtools\n */\n devtools: process.env.NODE_ENV !== 'production',\n\n /**\n * Whether to record perf\n */\n performance: false,\n\n /**\n * Error handler for watcher errors\n */\n errorHandler: null,\n\n /**\n * Warn handler for watcher warns\n */\n warnHandler: null,\n\n /**\n * Ignore certain custom elements\n */\n ignoredElements: [],\n\n /**\n * Custom user key aliases for v-on\n */\n keyCodes: Object.create(null),\n\n /**\n * Check if a tag is reserved so that it cannot be registered as a\n * component. This is platform-dependent and may be overwritten.\n */\n isReservedTag: no,\n\n /**\n * Check if an attribute is reserved so that it cannot be used as a component\n * prop. This is platform-dependent and may be overwritten.\n */\n isReservedAttr: no,\n\n /**\n * Check if a tag is an unknown element.\n * Platform-dependent.\n */\n isUnknownElement: no,\n\n /**\n * Get the namespace of an element\n */\n getTagNamespace: noop,\n\n /**\n * Parse the real tag name for the specific platform.\n */\n parsePlatformTagName: identity,\n\n /**\n * Check if an attribute must be bound using property, e.g. value\n * Platform-dependent.\n */\n mustUseProp: no,\n\n /**\n * Exposed for legacy reasons\n */\n _lifecycleHooks: LIFECYCLE_HOOKS\n});\n\n/* */\n\nvar emptyObject = Object.freeze({});\n\n/**\n * Check if a string starts with $ or _\n */\nfunction isReserved (str) {\n var c = (str + '').charCodeAt(0);\n return c === 0x24 || c === 0x5F\n}\n\n/**\n * Define a property.\n */\nfunction def (obj, key, val, enumerable) {\n Object.defineProperty(obj, key, {\n value: val,\n enumerable: !!enumerable,\n writable: true,\n configurable: true\n });\n}\n\n/**\n * Parse simple path.\n */\nvar bailRE = /[^\\w.$]/;\nfunction parsePath (path) {\n if (bailRE.test(path)) {\n return\n }\n var segments = path.split('.');\n return function (obj) {\n for (var i = 0; i < segments.length; i++) {\n if (!obj) { return }\n obj = obj[segments[i]];\n }\n return obj\n }\n}\n\n/* */\n\nvar warn = noop;\nvar tip = noop;\nvar formatComponentName = (null); // work around flow check\n\nif (process.env.NODE_ENV !== 'production') {\n var hasConsole = typeof console !== 'undefined';\n var classifyRE = /(?:^|[-_])(\\w)/g;\n var classify = function (str) { return str\n .replace(classifyRE, function (c) { return c.toUpperCase(); })\n .replace(/[-_]/g, ''); };\n\n warn = function (msg, vm) {\n var trace = vm ? generateComponentTrace(vm) : '';\n\n if (config.warnHandler) {\n config.warnHandler.call(null, msg, vm, trace);\n } else if (hasConsole && (!config.silent)) {\n console.error((\"[Vue warn]: \" + msg + trace));\n }\n };\n\n tip = function (msg, vm) {\n if (hasConsole && (!config.silent)) {\n console.warn(\"[Vue tip]: \" + msg + (\n vm ? generateComponentTrace(vm) : ''\n ));\n }\n };\n\n formatComponentName = function (vm, includeFile) {\n if (vm.$root === vm) {\n return ''\n }\n var name = typeof vm === 'string'\n ? vm\n : typeof vm === 'function' && vm.options\n ? vm.options.name\n : vm._isVue\n ? vm.$options.name || vm.$options._componentTag\n : vm.name;\n\n var file = vm._isVue && vm.$options.__file;\n if (!name && file) {\n var match = file.match(/([^/\\\\]+)\\.vue$/);\n name = match && match[1];\n }\n\n return (\n (name ? (\"<\" + (classify(name)) + \">\") : \"\") +\n (file && includeFile !== false ? (\" at \" + file) : '')\n )\n };\n\n var repeat = function (str, n) {\n var res = '';\n while (n) {\n if (n % 2 === 1) { res += str; }\n if (n > 1) { str += str; }\n n >>= 1;\n }\n return res\n };\n\n var generateComponentTrace = function (vm) {\n if (vm._isVue && vm.$parent) {\n var tree = [];\n var currentRecursiveSequence = 0;\n while (vm) {\n if (tree.length > 0) {\n var last = tree[tree.length - 1];\n if (last.constructor === vm.constructor) {\n currentRecursiveSequence++;\n vm = vm.$parent;\n continue\n } else if (currentRecursiveSequence > 0) {\n tree[tree.length - 1] = [last, currentRecursiveSequence];\n currentRecursiveSequence = 0;\n }\n }\n tree.push(vm);\n vm = vm.$parent;\n }\n return '\\n\\nfound in\\n\\n' + tree\n .map(function (vm, i) { return (\"\" + (i === 0 ? '---> ' : repeat(' ', 5 + i * 2)) + (Array.isArray(vm)\n ? ((formatComponentName(vm[0])) + \"... (\" + (vm[1]) + \" recursive calls)\")\n : formatComponentName(vm))); })\n .join('\\n')\n } else {\n return (\"\\n\\n(found in \" + (formatComponentName(vm)) + \")\")\n }\n };\n}\n\n/* */\n\nfunction handleError (err, vm, info) {\n if (config.errorHandler) {\n config.errorHandler.call(null, err, vm, info);\n } else {\n if (process.env.NODE_ENV !== 'production') {\n warn((\"Error in \" + info + \": \\\"\" + (err.toString()) + \"\\\"\"), vm);\n }\n /* istanbul ignore else */\n if (inBrowser && typeof console !== 'undefined') {\n console.error(err);\n } else {\n throw err\n }\n }\n}\n\n/* */\n/* globals MutationObserver */\n\n// can we use __proto__?\nvar hasProto = '__proto__' in {};\n\n// Browser environment sniffing\nvar inBrowser = typeof window !== 'undefined';\nvar UA = inBrowser && window.navigator.userAgent.toLowerCase();\nvar isIE = UA && /msie|trident/.test(UA);\nvar isIE9 = UA && UA.indexOf('msie 9.0') > 0;\nvar isEdge = UA && UA.indexOf('edge/') > 0;\nvar isAndroid = UA && UA.indexOf('android') > 0;\nvar isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);\nvar isChrome = UA && /chrome\\/\\d+/.test(UA) && !isEdge;\n\n// Firefix has a \"watch\" function on Object.prototype...\nvar nativeWatch = ({}).watch;\n\nvar supportsPassive = false;\nif (inBrowser) {\n try {\n var opts = {};\n Object.defineProperty(opts, 'passive', ({\n get: function get () {\n /* istanbul ignore next */\n supportsPassive = true;\n }\n })); // https://github.com/facebook/flow/issues/285\n window.addEventListener('test-passive', null, opts);\n } catch (e) {}\n}\n\n// this needs to be lazy-evaled because vue may be required before\n// vue-server-renderer can set VUE_ENV\nvar _isServer;\nvar isServerRendering = function () {\n if (_isServer === undefined) {\n /* istanbul ignore if */\n if (!inBrowser && typeof global !== 'undefined') {\n // detect presence of vue-server-renderer and avoid\n // Webpack shimming the process\n _isServer = global['process'].env.VUE_ENV === 'server';\n } else {\n _isServer = false;\n }\n }\n return _isServer\n};\n\n// detect devtools\nvar devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;\n\n/* istanbul ignore next */\nfunction isNative (Ctor) {\n return typeof Ctor === 'function' && /native code/.test(Ctor.toString())\n}\n\nvar hasSymbol =\n typeof Symbol !== 'undefined' && isNative(Symbol) &&\n typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys);\n\n/**\n * Defer a task to execute it asynchronously.\n */\nvar nextTick = (function () {\n var callbacks = [];\n var pending = false;\n var timerFunc;\n\n function nextTickHandler () {\n pending = false;\n var copies = callbacks.slice(0);\n callbacks.length = 0;\n for (var i = 0; i < copies.length; i++) {\n copies[i]();\n }\n }\n\n // the nextTick behavior leverages the microtask queue, which can be accessed\n // via either native Promise.then or MutationObserver.\n // MutationObserver has wider support, however it is seriously bugged in\n // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It\n // completely stops working after triggering a few times... so, if native\n // Promise is available, we will use it:\n /* istanbul ignore if */\n if (typeof Promise !== 'undefined' && isNative(Promise)) {\n var p = Promise.resolve();\n var logError = function (err) { console.error(err); };\n timerFunc = function () {\n p.then(nextTickHandler).catch(logError);\n // in problematic UIWebViews, Promise.then doesn't completely break, but\n // it can get stuck in a weird state where callbacks are pushed into the\n // microtask queue but the queue isn't being flushed, until the browser\n // needs to do some other work, e.g. handle a timer. Therefore we can\n // \"force\" the microtask queue to be flushed by adding an empty timer.\n if (isIOS) { setTimeout(noop); }\n };\n } else if (typeof MutationObserver !== 'undefined' && (\n isNative(MutationObserver) ||\n // PhantomJS and iOS 7.x\n MutationObserver.toString() === '[object MutationObserverConstructor]'\n )) {\n // use MutationObserver where native Promise is not available,\n // e.g. PhantomJS IE11, iOS7, Android 4.4\n var counter = 1;\n var observer = new MutationObserver(nextTickHandler);\n var textNode = document.createTextNode(String(counter));\n observer.observe(textNode, {\n characterData: true\n });\n timerFunc = function () {\n counter = (counter + 1) % 2;\n textNode.data = String(counter);\n };\n } else {\n // fallback to setTimeout\n /* istanbul ignore next */\n timerFunc = function () {\n setTimeout(nextTickHandler, 0);\n };\n }\n\n return function queueNextTick (cb, ctx) {\n var _resolve;\n callbacks.push(function () {\n if (cb) {\n try {\n cb.call(ctx);\n } catch (e) {\n handleError(e, ctx, 'nextTick');\n }\n } else if (_resolve) {\n _resolve(ctx);\n }\n });\n if (!pending) {\n pending = true;\n timerFunc();\n }\n if (!cb && typeof Promise !== 'undefined') {\n return new Promise(function (resolve, reject) {\n _resolve = resolve;\n })\n }\n }\n})();\n\nvar _Set;\n/* istanbul ignore if */\nif (typeof Set !== 'undefined' && isNative(Set)) {\n // use native Set when available.\n _Set = Set;\n} else {\n // a non-standard Set polyfill that only works with primitive keys.\n _Set = (function () {\n function Set () {\n this.set = Object.create(null);\n }\n Set.prototype.has = function has (key) {\n return this.set[key] === true\n };\n Set.prototype.add = function add (key) {\n this.set[key] = true;\n };\n Set.prototype.clear = function clear () {\n this.set = Object.create(null);\n };\n\n return Set;\n }());\n}\n\n/* */\n\n\nvar uid = 0;\n\n/**\n * A dep is an observable that can have multiple\n * directives subscribing to it.\n */\nvar Dep = function Dep () {\n this.id = uid++;\n this.subs = [];\n};\n\nDep.prototype.addSub = function addSub (sub) {\n this.subs.push(sub);\n};\n\nDep.prototype.removeSub = function removeSub (sub) {\n remove(this.subs, sub);\n};\n\nDep.prototype.depend = function depend () {\n if (Dep.target) {\n Dep.target.addDep(this);\n }\n};\n\nDep.prototype.notify = function notify () {\n // stabilize the subscriber list first\n var subs = this.subs.slice();\n for (var i = 0, l = subs.length; i < l; i++) {\n subs[i].update();\n }\n};\n\n// the current target watcher being evaluated.\n// this is globally unique because there could be only one\n// watcher being evaluated at any time.\nDep.target = null;\nvar targetStack = [];\n\nfunction pushTarget (_target) {\n if (Dep.target) { targetStack.push(Dep.target); }\n Dep.target = _target;\n}\n\nfunction popTarget () {\n Dep.target = targetStack.pop();\n}\n\n/*\n * not type checking this file because flow doesn't play well with\n * dynamically accessing methods on Array prototype\n */\n\nvar arrayProto = Array.prototype;\nvar arrayMethods = Object.create(arrayProto);[\n 'push',\n 'pop',\n 'shift',\n 'unshift',\n 'splice',\n 'sort',\n 'reverse'\n]\n.forEach(function (method) {\n // cache original method\n var original = arrayProto[method];\n def(arrayMethods, method, function mutator () {\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n\n var result = original.apply(this, args);\n var ob = this.__ob__;\n var inserted;\n switch (method) {\n case 'push':\n case 'unshift':\n inserted = args;\n break\n case 'splice':\n inserted = args.slice(2);\n break\n }\n if (inserted) { ob.observeArray(inserted); }\n // notify change\n ob.dep.notify();\n return result\n });\n});\n\n/* */\n\nvar arrayKeys = Object.getOwnPropertyNames(arrayMethods);\n\n/**\n * By default, when a reactive property is set, the new value is\n * also converted to become reactive. However when passing down props,\n * we don't want to force conversion because the value may be a nested value\n * under a frozen data structure. Converting it would defeat the optimization.\n */\nvar observerState = {\n shouldConvert: true\n};\n\n/**\n * Observer class that are attached to each observed\n * object. Once attached, the observer converts target\n * object's property keys into getter/setters that\n * collect dependencies and dispatches updates.\n */\nvar Observer = function Observer (value) {\n this.value = value;\n this.dep = new Dep();\n this.vmCount = 0;\n def(value, '__ob__', this);\n if (Array.isArray(value)) {\n var augment = hasProto\n ? protoAugment\n : copyAugment;\n augment(value, arrayMethods, arrayKeys);\n this.observeArray(value);\n } else {\n this.walk(value);\n }\n};\n\n/**\n * Walk through each property and convert them into\n * getter/setters. This method should only be called when\n * value type is Object.\n */\nObserver.prototype.walk = function walk (obj) {\n var keys = Object.keys(obj);\n for (var i = 0; i < keys.length; i++) {\n defineReactive$$1(obj, keys[i], obj[keys[i]]);\n }\n};\n\n/**\n * Observe a list of Array items.\n */\nObserver.prototype.observeArray = function observeArray (items) {\n for (var i = 0, l = items.length; i < l; i++) {\n observe(items[i]);\n }\n};\n\n// helpers\n\n/**\n * Augment an target Object or Array by intercepting\n * the prototype chain using __proto__\n */\nfunction protoAugment (target, src, keys) {\n /* eslint-disable no-proto */\n target.__proto__ = src;\n /* eslint-enable no-proto */\n}\n\n/**\n * Augment an target Object or Array by defining\n * hidden properties.\n */\n/* istanbul ignore next */\nfunction copyAugment (target, src, keys) {\n for (var i = 0, l = keys.length; i < l; i++) {\n var key = keys[i];\n def(target, key, src[key]);\n }\n}\n\n/**\n * Attempt to create an observer instance for a value,\n * returns the new observer if successfully observed,\n * or the existing observer if the value already has one.\n */\nfunction observe (value, asRootData) {\n if (!isObject(value)) {\n return\n }\n var ob;\n if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {\n ob = value.__ob__;\n } else if (\n observerState.shouldConvert &&\n !isServerRendering() &&\n (Array.isArray(value) || isPlainObject(value)) &&\n Object.isExtensible(value) &&\n !value._isVue\n ) {\n ob = new Observer(value);\n }\n if (asRootData && ob) {\n ob.vmCount++;\n }\n return ob\n}\n\n/**\n * Define a reactive property on an Object.\n */\nfunction defineReactive$$1 (\n obj,\n key,\n val,\n customSetter,\n shallow\n) {\n var dep = new Dep();\n\n var property = Object.getOwnPropertyDescriptor(obj, key);\n if (property && property.configurable === false) {\n return\n }\n\n // cater for pre-defined getter/setters\n var getter = property && property.get;\n var setter = property && property.set;\n\n var childOb = !shallow && observe(val);\n Object.defineProperty(obj, key, {\n enumerable: true,\n configurable: true,\n get: function reactiveGetter () {\n var value = getter ? getter.call(obj) : val;\n if (Dep.target) {\n dep.depend();\n if (childOb) {\n childOb.dep.depend();\n }\n if (Array.isArray(value)) {\n dependArray(value);\n }\n }\n return value\n },\n set: function reactiveSetter (newVal) {\n var value = getter ? getter.call(obj) : val;\n /* eslint-disable no-self-compare */\n if (newVal === value || (newVal !== newVal && value !== value)) {\n return\n }\n /* eslint-enable no-self-compare */\n if (process.env.NODE_ENV !== 'production' && customSetter) {\n customSetter();\n }\n if (setter) {\n setter.call(obj, newVal);\n } else {\n val = newVal;\n }\n childOb = !shallow && observe(newVal);\n dep.notify();\n }\n });\n}\n\n/**\n * Set a property on an object. Adds the new property and\n * triggers change notification if the property doesn't\n * already exist.\n */\nfunction set (target, key, val) {\n if (Array.isArray(target) && isValidArrayIndex(key)) {\n target.length = Math.max(target.length, key);\n target.splice(key, 1, val);\n return val\n }\n if (hasOwn(target, key)) {\n target[key] = val;\n return val\n }\n var ob = (target).__ob__;\n if (target._isVue || (ob && ob.vmCount)) {\n process.env.NODE_ENV !== 'production' && warn(\n 'Avoid adding reactive properties to a Vue instance or its root $data ' +\n 'at runtime - declare it upfront in the data option.'\n );\n return val\n }\n if (!ob) {\n target[key] = val;\n return val\n }\n defineReactive$$1(ob.value, key, val);\n ob.dep.notify();\n return val\n}\n\n/**\n * Delete a property and trigger change if necessary.\n */\nfunction del (target, key) {\n if (Array.isArray(target) && isValidArrayIndex(key)) {\n target.splice(key, 1);\n return\n }\n var ob = (target).__ob__;\n if (target._isVue || (ob && ob.vmCount)) {\n process.env.NODE_ENV !== 'production' && warn(\n 'Avoid deleting properties on a Vue instance or its root $data ' +\n '- just set it to null.'\n );\n return\n }\n if (!hasOwn(target, key)) {\n return\n }\n delete target[key];\n if (!ob) {\n return\n }\n ob.dep.notify();\n}\n\n/**\n * Collect dependencies on array elements when the array is touched, since\n * we cannot intercept array element access like property getters.\n */\nfunction dependArray (value) {\n for (var e = (void 0), i = 0, l = value.length; i < l; i++) {\n e = value[i];\n e && e.__ob__ && e.__ob__.dep.depend();\n if (Array.isArray(e)) {\n dependArray(e);\n }\n }\n}\n\n/* */\n\n/**\n * Option overwriting strategies are functions that handle\n * how to merge a parent option value and a child option\n * value into the final value.\n */\nvar strats = config.optionMergeStrategies;\n\n/**\n * Options with restrictions\n */\nif (process.env.NODE_ENV !== 'production') {\n strats.el = strats.propsData = function (parent, child, vm, key) {\n if (!vm) {\n warn(\n \"option \\\"\" + key + \"\\\" can only be used during instance \" +\n 'creation with the `new` keyword.'\n );\n }\n return defaultStrat(parent, child)\n };\n}\n\n/**\n * Helper that recursively merges two data objects together.\n */\nfunction mergeData (to, from) {\n if (!from) { return to }\n var key, toVal, fromVal;\n var keys = Object.keys(from);\n for (var i = 0; i < keys.length; i++) {\n key = keys[i];\n toVal = to[key];\n fromVal = from[key];\n if (!hasOwn(to, key)) {\n set(to, key, fromVal);\n } else if (isPlainObject(toVal) && isPlainObject(fromVal)) {\n mergeData(toVal, fromVal);\n }\n }\n return to\n}\n\n/**\n * Data\n */\nfunction mergeDataOrFn (\n parentVal,\n childVal,\n vm\n) {\n if (!vm) {\n // in a Vue.extend merge, both should be functions\n if (!childVal) {\n return parentVal\n }\n if (!parentVal) {\n return childVal\n }\n // when parentVal & childVal are both present,\n // we need to return a function that returns the\n // merged result of both functions... no need to\n // check if parentVal is a function here because\n // it has to be a function to pass previous merges.\n return function mergedDataFn () {\n return mergeData(\n typeof childVal === 'function' ? childVal.call(this) : childVal,\n typeof parentVal === 'function' ? parentVal.call(this) : parentVal\n )\n }\n } else if (parentVal || childVal) {\n return function mergedInstanceDataFn () {\n // instance merge\n var instanceData = typeof childVal === 'function'\n ? childVal.call(vm)\n : childVal;\n var defaultData = typeof parentVal === 'function'\n ? parentVal.call(vm)\n : undefined;\n if (instanceData) {\n return mergeData(instanceData, defaultData)\n } else {\n return defaultData\n }\n }\n }\n}\n\nstrats.data = function (\n parentVal,\n childVal,\n vm\n) {\n if (!vm) {\n if (childVal && typeof childVal !== 'function') {\n process.env.NODE_ENV !== 'production' && warn(\n 'The \"data\" option should be a function ' +\n 'that returns a per-instance value in component ' +\n 'definitions.',\n vm\n );\n\n return parentVal\n }\n return mergeDataOrFn.call(this, parentVal, childVal)\n }\n\n return mergeDataOrFn(parentVal, childVal, vm)\n};\n\n/**\n * Hooks and props are merged as arrays.\n */\nfunction mergeHook (\n parentVal,\n childVal\n) {\n return childVal\n ? parentVal\n ? parentVal.concat(childVal)\n : Array.isArray(childVal)\n ? childVal\n : [childVal]\n : parentVal\n}\n\nLIFECYCLE_HOOKS.forEach(function (hook) {\n strats[hook] = mergeHook;\n});\n\n/**\n * Assets\n *\n * When a vm is present (instance creation), we need to do\n * a three-way merge between constructor options, instance\n * options and parent options.\n */\nfunction mergeAssets (parentVal, childVal) {\n var res = Object.create(parentVal || null);\n return childVal\n ? extend(res, childVal)\n : res\n}\n\nASSET_TYPES.forEach(function (type) {\n strats[type + 's'] = mergeAssets;\n});\n\n/**\n * Watchers.\n *\n * Watchers hashes should not overwrite one\n * another, so we merge them as arrays.\n */\nstrats.watch = function (parentVal, childVal) {\n // work around Firefox's Object.prototype.watch...\n if (parentVal === nativeWatch) { parentVal = undefined; }\n if (childVal === nativeWatch) { childVal = undefined; }\n /* istanbul ignore if */\n if (!childVal) { return Object.create(parentVal || null) }\n if (!parentVal) { return childVal }\n var ret = {};\n extend(ret, parentVal);\n for (var key in childVal) {\n var parent = ret[key];\n var child = childVal[key];\n if (parent && !Array.isArray(parent)) {\n parent = [parent];\n }\n ret[key] = parent\n ? parent.concat(child)\n : Array.isArray(child) ? child : [child];\n }\n return ret\n};\n\n/**\n * Other object hashes.\n */\nstrats.props =\nstrats.methods =\nstrats.inject =\nstrats.computed = function (parentVal, childVal) {\n if (!parentVal) { return childVal }\n var ret = Object.create(null);\n extend(ret, parentVal);\n if (childVal) { extend(ret, childVal); }\n return ret\n};\nstrats.provide = mergeDataOrFn;\n\n/**\n * Default strategy.\n */\nvar defaultStrat = function (parentVal, childVal) {\n return childVal === undefined\n ? parentVal\n : childVal\n};\n\n/**\n * Validate component names\n */\nfunction checkComponents (options) {\n for (var key in options.components) {\n var lower = key.toLowerCase();\n if (isBuiltInTag(lower) || config.isReservedTag(lower)) {\n warn(\n 'Do not use built-in or reserved HTML elements as component ' +\n 'id: ' + key\n );\n }\n }\n}\n\n/**\n * Ensure all props option syntax are normalized into the\n * Object-based format.\n */\nfunction normalizeProps (options) {\n var props = options.props;\n if (!props) { return }\n var res = {};\n var i, val, name;\n if (Array.isArray(props)) {\n i = props.length;\n while (i--) {\n val = props[i];\n if (typeof val === 'string') {\n name = camelize(val);\n res[name] = { type: null };\n } else if (process.env.NODE_ENV !== 'production') {\n warn('props must be strings when using array syntax.');\n }\n }\n } else if (isPlainObject(props)) {\n for (var key in props) {\n val = props[key];\n name = camelize(key);\n res[name] = isPlainObject(val)\n ? val\n : { type: val };\n }\n }\n options.props = res;\n}\n\n/**\n * Normalize all injections into Object-based format\n */\nfunction normalizeInject (options) {\n var inject = options.inject;\n if (Array.isArray(inject)) {\n var normalized = options.inject = {};\n for (var i = 0; i < inject.length; i++) {\n normalized[inject[i]] = inject[i];\n }\n }\n}\n\n/**\n * Normalize raw function directives into object format.\n */\nfunction normalizeDirectives (options) {\n var dirs = options.directives;\n if (dirs) {\n for (var key in dirs) {\n var def = dirs[key];\n if (typeof def === 'function') {\n dirs[key] = { bind: def, update: def };\n }\n }\n }\n}\n\n/**\n * Merge two option objects into a new one.\n * Core utility used in both instantiation and inheritance.\n */\nfunction mergeOptions (\n parent,\n child,\n vm\n) {\n if (process.env.NODE_ENV !== 'production') {\n checkComponents(child);\n }\n\n if (typeof child === 'function') {\n child = child.options;\n }\n\n normalizeProps(child);\n normalizeInject(child);\n normalizeDirectives(child);\n var extendsFrom = child.extends;\n if (extendsFrom) {\n parent = mergeOptions(parent, extendsFrom, vm);\n }\n if (child.mixins) {\n for (var i = 0, l = child.mixins.length; i < l; i++) {\n parent = mergeOptions(parent, child.mixins[i], vm);\n }\n }\n var options = {};\n var key;\n for (key in parent) {\n mergeField(key);\n }\n for (key in child) {\n if (!hasOwn(parent, key)) {\n mergeField(key);\n }\n }\n function mergeField (key) {\n var strat = strats[key] || defaultStrat;\n options[key] = strat(parent[key], child[key], vm, key);\n }\n return options\n}\n\n/**\n * Resolve an asset.\n * This function is used because child instances need access\n * to assets defined in its ancestor chain.\n */\nfunction resolveAsset (\n options,\n type,\n id,\n warnMissing\n) {\n /* istanbul ignore if */\n if (typeof id !== 'string') {\n return\n }\n var assets = options[type];\n // check local registration variations first\n if (hasOwn(assets, id)) { return assets[id] }\n var camelizedId = camelize(id);\n if (hasOwn(assets, camelizedId)) { return assets[camelizedId] }\n var PascalCaseId = capitalize(camelizedId);\n if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] }\n // fallback to prototype chain\n var res = assets[id] || assets[camelizedId] || assets[PascalCaseId];\n if (process.env.NODE_ENV !== 'production' && warnMissing && !res) {\n warn(\n 'Failed to resolve ' + type.slice(0, -1) + ': ' + id,\n options\n );\n }\n return res\n}\n\n/* */\n\nfunction validateProp (\n key,\n propOptions,\n propsData,\n vm\n) {\n var prop = propOptions[key];\n var absent = !hasOwn(propsData, key);\n var value = propsData[key];\n // handle boolean props\n if (isType(Boolean, prop.type)) {\n if (absent && !hasOwn(prop, 'default')) {\n value = false;\n } else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) {\n value = true;\n }\n }\n // check default value\n if (value === undefined) {\n value = getPropDefaultValue(vm, prop, key);\n // since the default value is a fresh copy,\n // make sure to observe it.\n var prevShouldConvert = observerState.shouldConvert;\n observerState.shouldConvert = true;\n observe(value);\n observerState.shouldConvert = prevShouldConvert;\n }\n if (process.env.NODE_ENV !== 'production') {\n assertProp(prop, key, value, vm, absent);\n }\n return value\n}\n\n/**\n * Get the default value of a prop.\n */\nfunction getPropDefaultValue (vm, prop, key) {\n // no default, return undefined\n if (!hasOwn(prop, 'default')) {\n return undefined\n }\n var def = prop.default;\n // warn against non-factory defaults for Object & Array\n if (process.env.NODE_ENV !== 'production' && isObject(def)) {\n warn(\n 'Invalid default value for prop \"' + key + '\": ' +\n 'Props with type Object/Array must use a factory function ' +\n 'to return the default value.',\n vm\n );\n }\n // the raw prop value was also undefined from previous render,\n // return previous default value to avoid unnecessary watcher trigger\n if (vm && vm.$options.propsData &&\n vm.$options.propsData[key] === undefined &&\n vm._props[key] !== undefined\n ) {\n return vm._props[key]\n }\n // call factory function for non-Function types\n // a value is Function if its prototype is function even across different execution context\n return typeof def === 'function' && getType(prop.type) !== 'Function'\n ? def.call(vm)\n : def\n}\n\n/**\n * Assert whether a prop is valid.\n */\nfunction assertProp (\n prop,\n name,\n value,\n vm,\n absent\n) {\n if (prop.required && absent) {\n warn(\n 'Missing required prop: \"' + name + '\"',\n vm\n );\n return\n }\n if (value == null && !prop.required) {\n return\n }\n var type = prop.type;\n var valid = !type || type === true;\n var expectedTypes = [];\n if (type) {\n if (!Array.isArray(type)) {\n type = [type];\n }\n for (var i = 0; i < type.length && !valid; i++) {\n var assertedType = assertType(value, type[i]);\n expectedTypes.push(assertedType.expectedType || '');\n valid = assertedType.valid;\n }\n }\n if (!valid) {\n warn(\n 'Invalid prop: type check failed for prop \"' + name + '\".' +\n ' Expected ' + expectedTypes.map(capitalize).join(', ') +\n ', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.',\n vm\n );\n return\n }\n var validator = prop.validator;\n if (validator) {\n if (!validator(value)) {\n warn(\n 'Invalid prop: custom validator check failed for prop \"' + name + '\".',\n vm\n );\n }\n }\n}\n\nvar simpleCheckRE = /^(String|Number|Boolean|Function|Symbol)$/;\n\nfunction assertType (value, type) {\n var valid;\n var expectedType = getType(type);\n if (simpleCheckRE.test(expectedType)) {\n valid = typeof value === expectedType.toLowerCase();\n } else if (expectedType === 'Object') {\n valid = isPlainObject(value);\n } else if (expectedType === 'Array') {\n valid = Array.isArray(value);\n } else {\n valid = value instanceof type;\n }\n return {\n valid: valid,\n expectedType: expectedType\n }\n}\n\n/**\n * Use function string name to check built-in types,\n * because a simple equality check will fail when running\n * across different vms / iframes.\n */\nfunction getType (fn) {\n var match = fn && fn.toString().match(/^\\s*function (\\w+)/);\n return match ? match[1] : ''\n}\n\nfunction isType (type, fn) {\n if (!Array.isArray(fn)) {\n return getType(fn) === getType(type)\n }\n for (var i = 0, len = fn.length; i < len; i++) {\n if (getType(fn[i]) === getType(type)) {\n return true\n }\n }\n /* istanbul ignore next */\n return false\n}\n\n/* */\n\nvar mark;\nvar measure;\n\nif (process.env.NODE_ENV !== 'production') {\n var perf = inBrowser && window.performance;\n /* istanbul ignore if */\n if (\n perf &&\n perf.mark &&\n perf.measure &&\n perf.clearMarks &&\n perf.clearMeasures\n ) {\n mark = function (tag) { return perf.mark(tag); };\n measure = function (name, startTag, endTag) {\n perf.measure(name, startTag, endTag);\n perf.clearMarks(startTag);\n perf.clearMarks(endTag);\n perf.clearMeasures(name);\n };\n }\n}\n\n/* not type checking this file because flow doesn't play well with Proxy */\n\nvar initProxy;\n\nif (process.env.NODE_ENV !== 'production') {\n var allowedGlobals = makeMap(\n 'Infinity,undefined,NaN,isFinite,isNaN,' +\n 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +\n 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +\n 'require' // for Webpack/Browserify\n );\n\n var warnNonPresent = function (target, key) {\n warn(\n \"Property or method \\\"\" + key + \"\\\" is not defined on the instance but \" +\n \"referenced during render. Make sure to declare reactive data \" +\n \"properties in the data option.\",\n target\n );\n };\n\n var hasProxy =\n typeof Proxy !== 'undefined' &&\n Proxy.toString().match(/native code/);\n\n if (hasProxy) {\n var isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta');\n config.keyCodes = new Proxy(config.keyCodes, {\n set: function set (target, key, value) {\n if (isBuiltInModifier(key)) {\n warn((\"Avoid overwriting built-in modifier in config.keyCodes: .\" + key));\n return false\n } else {\n target[key] = value;\n return true\n }\n }\n });\n }\n\n var hasHandler = {\n has: function has (target, key) {\n var has = key in target;\n var isAllowed = allowedGlobals(key) || key.charAt(0) === '_';\n if (!has && !isAllowed) {\n warnNonPresent(target, key);\n }\n return has || !isAllowed\n }\n };\n\n var getHandler = {\n get: function get (target, key) {\n if (typeof key === 'string' && !(key in target)) {\n warnNonPresent(target, key);\n }\n return target[key]\n }\n };\n\n initProxy = function initProxy (vm) {\n if (hasProxy) {\n // determine which proxy handler to use\n var options = vm.$options;\n var handlers = options.render && options.render._withStripped\n ? getHandler\n : hasHandler;\n vm._renderProxy = new Proxy(vm, handlers);\n } else {\n vm._renderProxy = vm;\n }\n };\n}\n\n/* */\n\nvar VNode = function VNode (\n tag,\n data,\n children,\n text,\n elm,\n context,\n componentOptions,\n asyncFactory\n) {\n this.tag = tag;\n this.data = data;\n this.children = children;\n this.text = text;\n this.elm = elm;\n this.ns = undefined;\n this.context = context;\n this.functionalContext = undefined;\n this.key = data && data.key;\n this.componentOptions = componentOptions;\n this.componentInstance = undefined;\n this.parent = undefined;\n this.raw = false;\n this.isStatic = false;\n this.isRootInsert = true;\n this.isComment = false;\n this.isCloned = false;\n this.isOnce = false;\n this.asyncFactory = asyncFactory;\n this.asyncMeta = undefined;\n this.isAsyncPlaceholder = false;\n};\n\nvar prototypeAccessors = { child: {} };\n\n// DEPRECATED: alias for componentInstance for backwards compat.\n/* istanbul ignore next */\nprototypeAccessors.child.get = function () {\n return this.componentInstance\n};\n\nObject.defineProperties( VNode.prototype, prototypeAccessors );\n\nvar createEmptyVNode = function (text) {\n if ( text === void 0 ) text = '';\n\n var node = new VNode();\n node.text = text;\n node.isComment = true;\n return node\n};\n\nfunction createTextVNode (val) {\n return new VNode(undefined, undefined, undefined, String(val))\n}\n\n// optimized shallow clone\n// used for static nodes and slot nodes because they may be reused across\n// multiple renders, cloning them avoids errors when DOM manipulations rely\n// on their elm reference.\nfunction cloneVNode (vnode) {\n var cloned = new VNode(\n vnode.tag,\n vnode.data,\n vnode.children,\n vnode.text,\n vnode.elm,\n vnode.context,\n vnode.componentOptions,\n vnode.asyncFactory\n );\n cloned.ns = vnode.ns;\n cloned.isStatic = vnode.isStatic;\n cloned.key = vnode.key;\n cloned.isComment = vnode.isComment;\n cloned.isCloned = true;\n return cloned\n}\n\nfunction cloneVNodes (vnodes) {\n var len = vnodes.length;\n var res = new Array(len);\n for (var i = 0; i < len; i++) {\n res[i] = cloneVNode(vnodes[i]);\n }\n return res\n}\n\n/* */\n\nvar normalizeEvent = cached(function (name) {\n var passive = name.charAt(0) === '&';\n name = passive ? name.slice(1) : name;\n var once$$1 = name.charAt(0) === '~'; // Prefixed last, checked first\n name = once$$1 ? name.slice(1) : name;\n var capture = name.charAt(0) === '!';\n name = capture ? name.slice(1) : name;\n return {\n name: name,\n once: once$$1,\n capture: capture,\n passive: passive\n }\n});\n\nfunction createFnInvoker (fns) {\n function invoker () {\n var arguments$1 = arguments;\n\n var fns = invoker.fns;\n if (Array.isArray(fns)) {\n var cloned = fns.slice();\n for (var i = 0; i < cloned.length; i++) {\n cloned[i].apply(null, arguments$1);\n }\n } else {\n // return handler return value for single handlers\n return fns.apply(null, arguments)\n }\n }\n invoker.fns = fns;\n return invoker\n}\n\nfunction updateListeners (\n on,\n oldOn,\n add,\n remove$$1,\n vm\n) {\n var name, cur, old, event;\n for (name in on) {\n cur = on[name];\n old = oldOn[name];\n event = normalizeEvent(name);\n if (isUndef(cur)) {\n process.env.NODE_ENV !== 'production' && warn(\n \"Invalid handler for event \\\"\" + (event.name) + \"\\\": got \" + String(cur),\n vm\n );\n } else if (isUndef(old)) {\n if (isUndef(cur.fns)) {\n cur = on[name] = createFnInvoker(cur);\n }\n add(event.name, cur, event.once, event.capture, event.passive);\n } else if (cur !== old) {\n old.fns = cur;\n on[name] = old;\n }\n }\n for (name in oldOn) {\n if (isUndef(on[name])) {\n event = normalizeEvent(name);\n remove$$1(event.name, oldOn[name], event.capture);\n }\n }\n}\n\n/* */\n\nfunction mergeVNodeHook (def, hookKey, hook) {\n var invoker;\n var oldHook = def[hookKey];\n\n function wrappedHook () {\n hook.apply(this, arguments);\n // important: remove merged hook to ensure it's called only once\n // and prevent memory leak\n remove(invoker.fns, wrappedHook);\n }\n\n if (isUndef(oldHook)) {\n // no existing hook\n invoker = createFnInvoker([wrappedHook]);\n } else {\n /* istanbul ignore if */\n if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {\n // already a merged invoker\n invoker = oldHook;\n invoker.fns.push(wrappedHook);\n } else {\n // existing plain hook\n invoker = createFnInvoker([oldHook, wrappedHook]);\n }\n }\n\n invoker.merged = true;\n def[hookKey] = invoker;\n}\n\n/* */\n\nfunction extractPropsFromVNodeData (\n data,\n Ctor,\n tag\n) {\n // we are only extracting raw values here.\n // validation and default values are handled in the child\n // component itself.\n var propOptions = Ctor.options.props;\n if (isUndef(propOptions)) {\n return\n }\n var res = {};\n var attrs = data.attrs;\n var props = data.props;\n if (isDef(attrs) || isDef(props)) {\n for (var key in propOptions) {\n var altKey = hyphenate(key);\n if (process.env.NODE_ENV !== 'production') {\n var keyInLowerCase = key.toLowerCase();\n if (\n key !== keyInLowerCase &&\n attrs && hasOwn(attrs, keyInLowerCase)\n ) {\n tip(\n \"Prop \\\"\" + keyInLowerCase + \"\\\" is passed to component \" +\n (formatComponentName(tag || Ctor)) + \", but the declared prop name is\" +\n \" \\\"\" + key + \"\\\". \" +\n \"Note that HTML attributes are case-insensitive and camelCased \" +\n \"props need to use their kebab-case equivalents when using in-DOM \" +\n \"templates. You should probably use \\\"\" + altKey + \"\\\" instead of \\\"\" + key + \"\\\".\"\n );\n }\n }\n checkProp(res, props, key, altKey, true) ||\n checkProp(res, attrs, key, altKey, false);\n }\n }\n return res\n}\n\nfunction checkProp (\n res,\n hash,\n key,\n altKey,\n preserve\n) {\n if (isDef(hash)) {\n if (hasOwn(hash, key)) {\n res[key] = hash[key];\n if (!preserve) {\n delete hash[key];\n }\n return true\n } else if (hasOwn(hash, altKey)) {\n res[key] = hash[altKey];\n if (!preserve) {\n delete hash[altKey];\n }\n return true\n }\n }\n return false\n}\n\n/* */\n\n// The template compiler attempts to minimize the need for normalization by\n// statically analyzing the template at compile time.\n//\n// For plain HTML markup, normalization can be completely skipped because the\n// generated render function is guaranteed to return Array. There are\n// two cases where extra normalization is needed:\n\n// 1. When the children contains components - because a functional component\n// may return an Array instead of a single root. In this case, just a simple\n// normalization is needed - if any child is an Array, we flatten the whole\n// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep\n// because functional components already normalize their own children.\nfunction simpleNormalizeChildren (children) {\n for (var i = 0; i < children.length; i++) {\n if (Array.isArray(children[i])) {\n return Array.prototype.concat.apply([], children)\n }\n }\n return children\n}\n\n// 2. When the children contains constructs that always generated nested Arrays,\n// e.g.