made with requirebin
Last active
August 28, 2017 16:53
-
-
Save jtenner/f71a39927ec3bd34d51cee862bae2a0f to your computer and use it in GitHub Desktop.
requirebin sketch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const repatch = require('repatch'); | |
const e2d = require('e2d'); | |
const components = []; | |
const app = { pointer: false, mouseData: null, activeRegions: null }; | |
const ctx = document.createElement('canvas').getContext('2d'); | |
ctx.canvas.width = 400; | |
ctx.canvas.height = 300; | |
document.body.appendChild(ctx.canvas); | |
e2d.raf(() => { | |
app.mouseData = e2d.mouseData(ctx); | |
app.activeRegions = e2d.activeRegions(ctx); | |
app.pointer = false; | |
components.forEach(x => { | |
const region = app.activeRegions[x.id]; | |
const prevActive = x.active; | |
x.hover = !!region; | |
if (region.clicked) { | |
x.active = true; | |
} | |
if (x.active && x.hover && !app.mouseData.state) { | |
x.onClick(app); | |
} | |
if (!app.mouseData.state) { | |
x.active = false; | |
} | |
x.dirty = x.update(app) || x.dirty || (prevActive !== x.active); | |
}); | |
components.sort((x, y) => x.zIndex < y.zIndex ? -1 : x.zIndex > y.zIndex ? 1 : 0); | |
const view = components.map(x => x.dirty ? x._cache = x.render() : x._cache); | |
components.forEach(x => (x.dirty = false, true)); | |
e2d.render( | |
e2d.clearRect(ctx.canvas.width, ctx.canvas.height), | |
view, | |
ctx | |
); | |
}) | |
let id = -1; | |
class Component { | |
constructor({ position = [0, 0], scale = [1, 1], rotation = 0, alpha = 0, center = [0, 0], onClick = x => {} }) { | |
this.id = (++id).toString(36); | |
this.position = position; | |
this.scale = scale; | |
this.center = center; | |
this.rotation = rotaion; | |
this.alpha = alpha; | |
this.dirty = true; | |
this.active = false; | |
this.hover = false; | |
this._cache = []; | |
this.onClick = onClick; | |
} | |
render(...children) { | |
return e2d.translate(this.position[0], this.position[1], | |
e2d.rotate(this.rotation, | |
e2d.scale(this.scale[0], this.scale[1], | |
e2d.translate(-this.center[0], -this.center[1], ...children) | |
) | |
) | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
setTimeout(function(){ | |
;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"repatch":[function(require,module,exports){ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.Repatch = {}))); | |
}(this, (function (exports) { 'use strict'; | |
var thunkFactory = function (extraArgument) { | |
var thunk = (function (store) { return function (next) { return function (reducer) { | |
if (typeof reducer !== 'function') | |
throw new Error('Thunk reducer must return a function'); | |
var result = reducer(store.getState()); | |
if (typeof result === 'function') | |
return result(store.dispatch, store.getState, extraArgument); | |
else | |
return next(function (_) { return result; }); | |
}; }; }); | |
thunk.withExtraArgument = thunkFactory; | |
return thunk; | |
}; | |
var thunk = thunkFactory(); | |
var Store = (function () { | |
function Store(initialState) { | |
var _this = this; | |
this.listeners = []; | |
this.getState = function () { return _this.state; }; | |
this.dispatch = function (reducer) { | |
if (typeof reducer !== 'function') | |
throw new Error('Reducer is not a function: dispatch takes only reducers as functions.'); | |
_this.state = reducer(_this.state); | |
_this.listeners.forEach(function (listener) { return listener(); }); | |
return _this.state; | |
}; | |
this.subscribe = function (listener) { | |
if (typeof listener !== 'function') | |
throw new Error('Listener is not a function: subscribe takes only listeners as functions.'); | |
_this.listeners = _this.listeners.concat([listener]); | |
return function () { return (_this.listeners = _this.listeners.filter(function (lis) { return lis !== listener; })); }; | |
}; | |
this.addMiddleware = function () { | |
var middlewares = []; | |
for (var _i = 0; _i < arguments.length; _i++) { | |
middlewares[_i] = arguments[_i]; | |
} | |
if (middlewares.some(function (middleware) { return typeof middleware !== 'function'; })) | |
throw new Error('Middleware is not a function: addMiddleware takes only middlewares as functions.'); | |
middlewares.forEach(function (middleware) { return (_this.dispatch = middleware(_this)(_this.dispatch)); }); | |
return _this; | |
}; | |
this.state = initialState; | |
} | |
return Store; | |
}()); | |
exports.Store = Store; | |
exports['default'] = Store; | |
exports.thunk = thunk; | |
Object.defineProperty(exports, '__esModule', { value: true }); | |
}))); | |
},{}]},{},[]) | |
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsInJlcGF0Y2giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG5cdHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnXSwgZmFjdG9yeSkgOlxuXHQoZmFjdG9yeSgoZ2xvYmFsLlJlcGF0Y2ggPSB7fSkpKTtcbn0odGhpcywgKGZ1bmN0aW9uIChleHBvcnRzKSB7ICd1c2Ugc3RyaWN0JztcblxudmFyIHRodW5rRmFjdG9yeSA9IGZ1bmN0aW9uIChleHRyYUFyZ3VtZW50KSB7XHJcbiAgICB2YXIgdGh1bmsgPSAoZnVuY3Rpb24gKHN0b3JlKSB7IHJldHVybiBmdW5jdGlvbiAobmV4dCkgeyByZXR1cm4gZnVuY3Rpb24gKHJlZHVjZXIpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHJlZHVjZXIgIT09ICdmdW5jdGlvbicpXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGh1bmsgcmVkdWNlciBtdXN0IHJldHVybiBhIGZ1bmN0aW9uJyk7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlZHVjZXIoc3RvcmUuZ2V0U3RhdGUoKSk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdmdW5jdGlvbicpXHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQoc3RvcmUuZGlzcGF0Y2gsIHN0b3JlLmdldFN0YXRlLCBleHRyYUFyZ3VtZW50KTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHJldHVybiBuZXh0KGZ1bmN0aW9uIChfKSB7IHJldHVybiByZXN1bHQ7IH0pO1xyXG4gICAgfTsgfTsgfSk7XHJcbiAgICB0aHVuay53aXRoRXh0cmFBcmd1bWVudCA9IHRodW5rRmFjdG9yeTtcclxuICAgIHJldHVybiB0aHVuaztcclxufTtcclxudmFyIHRodW5rID0gdGh1bmtGYWN0b3J5KCk7XG5cbnZhciBTdG9yZSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBTdG9yZShpbml0aWFsU3RhdGUpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMubGlzdGVuZXJzID0gW107XHJcbiAgICAgICAgdGhpcy5nZXRTdGF0ZSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIF90aGlzLnN0YXRlOyB9O1xyXG4gICAgICAgIHRoaXMuZGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVkdWNlcikge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHJlZHVjZXIgIT09ICdmdW5jdGlvbicpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlZHVjZXIgaXMgbm90IGEgZnVuY3Rpb246IGRpc3BhdGNoIHRha2VzIG9ubHkgcmVkdWNlcnMgYXMgZnVuY3Rpb25zLicpO1xyXG4gICAgICAgICAgICBfdGhpcy5zdGF0ZSA9IHJlZHVjZXIoX3RoaXMuc3RhdGUpO1xyXG4gICAgICAgICAgICBfdGhpcy5saXN0ZW5lcnMuZm9yRWFjaChmdW5jdGlvbiAobGlzdGVuZXIpIHsgcmV0dXJuIGxpc3RlbmVyKCk7IH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuc3RhdGU7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLnN1YnNjcmliZSA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMaXN0ZW5lciBpcyBub3QgYSBmdW5jdGlvbjogc3Vic2NyaWJlIHRha2VzIG9ubHkgbGlzdGVuZXJzIGFzIGZ1bmN0aW9ucy4nKTtcclxuICAgICAgICAgICAgX3RoaXMubGlzdGVuZXJzID0gX3RoaXMubGlzdGVuZXJzLmNvbmNhdChbbGlzdGVuZXJdKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuIChfdGhpcy5saXN0ZW5lcnMgPSBfdGhpcy5saXN0ZW5lcnMuZmlsdGVyKGZ1bmN0aW9uIChsaXMpIHsgcmV0dXJuIGxpcyAhPT0gbGlzdGVuZXI7IH0pKTsgfTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMuYWRkTWlkZGxld2FyZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIG1pZGRsZXdhcmVzID0gW107XHJcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBtaWRkbGV3YXJlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChtaWRkbGV3YXJlcy5zb21lKGZ1bmN0aW9uIChtaWRkbGV3YXJlKSB7IHJldHVybiB0eXBlb2YgbWlkZGxld2FyZSAhPT0gJ2Z1bmN0aW9uJzsgfSkpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pZGRsZXdhcmUgaXMgbm90IGEgZnVuY3Rpb246IGFkZE1pZGRsZXdhcmUgdGFrZXMgb25seSBtaWRkbGV3YXJlcyBhcyBmdW5jdGlvbnMuJyk7XHJcbiAgICAgICAgICAgIG1pZGRsZXdhcmVzLmZvckVhY2goZnVuY3Rpb24gKG1pZGRsZXdhcmUpIHsgcmV0dXJuIChfdGhpcy5kaXNwYXRjaCA9IG1pZGRsZXdhcmUoX3RoaXMpKF90aGlzLmRpc3BhdGNoKSk7IH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gaW5pdGlhbFN0YXRlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFN0b3JlO1xyXG59KCkpO1xuXG5leHBvcnRzLlN0b3JlID0gU3RvcmU7XG5leHBvcnRzWydkZWZhdWx0J10gPSBTdG9yZTtcbmV4cG9ydHMudGh1bmsgPSB0aHVuaztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcblxufSkpKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlcGF0Y2guanMubWFwXG4iXX0= | |
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"e2d":[function(require,module,exports){ | |
(function webpackUniversalModuleDefinition(root, factory) { | |
if(typeof exports === 'object' && typeof module === 'object') | |
module.exports = factory(); | |
else if(typeof define === 'function' && define.amd) | |
define([], factory); | |
else if(typeof exports === 'object') | |
exports["e2d"] = factory(); | |
else | |
root["e2d"] = factory(); | |
})(this, function() { | |
return /******/ (function(modules) { // webpackBootstrap | |
/******/ // The module cache | |
/******/ var installedModules = {}; | |
/******/ // The require function | |
/******/ function __webpack_require__(moduleId) { | |
/******/ // Check if module is in cache | |
/******/ if(installedModules[moduleId]) | |
/******/ return installedModules[moduleId].exports; | |
/******/ // Create a new module (and put it into the cache) | |
/******/ var module = installedModules[moduleId] = { | |
/******/ i: moduleId, | |
/******/ l: false, | |
/******/ exports: {} | |
/******/ }; | |
/******/ // Execute the module function | |
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | |
/******/ // Flag the module as loaded | |
/******/ module.l = true; | |
/******/ // Return the exports of the module | |
/******/ return module.exports; | |
/******/ } | |
/******/ // expose the modules object (__webpack_modules__) | |
/******/ __webpack_require__.m = modules; | |
/******/ // expose the module cache | |
/******/ __webpack_require__.c = installedModules; | |
/******/ // identity function for calling harmony imports with the correct context | |
/******/ __webpack_require__.i = function(value) { return value; }; | |
/******/ // define getter function for harmony exports | |
/******/ __webpack_require__.d = function(exports, name, getter) { | |
/******/ if(!__webpack_require__.o(exports, name)) { | |
/******/ Object.defineProperty(exports, name, { | |
/******/ configurable: false, | |
/******/ enumerable: true, | |
/******/ get: getter | |
/******/ }); | |
/******/ } | |
/******/ }; | |
/******/ // getDefaultExport function for compatibility with non-harmony modules | |
/******/ __webpack_require__.n = function(module) { | |
/******/ var getter = module && module.__esModule ? | |
/******/ function getDefault() { return module['default']; } : | |
/******/ function getModuleExports() { return module; }; | |
/******/ __webpack_require__.d(getter, 'a', getter); | |
/******/ return getter; | |
/******/ }; | |
/******/ // Object.prototype.hasOwnProperty.call | |
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | |
/******/ // __webpack_public_path__ | |
/******/ __webpack_require__.p = ""; | |
/******/ // Load entry module and return exports | |
/******/ return __webpack_require__(__webpack_require__.s = 58); | |
/******/ }) | |
/************************************************************************/ | |
/******/ ([ | |
/* 0 */ | |
/***/ function(module, exports) { | |
class Instruction { | |
constructor(type, props) { | |
this.type = type; | |
this.props = props; | |
return Object.seal(this); | |
} | |
} | |
Object.seal(Instruction); | |
Object.seal(Instruction.prototype); | |
module.exports = Instruction; | |
/***/ }, | |
/* 1 */ | |
/***/ function(module, exports) { | |
let transformPoints = (points, matrix) => { | |
let result = [], | |
x, y; | |
for(let i = 0; i < points.length; i++) { | |
[x, y] = points[i]; | |
result.push([ | |
matrix[0] * x + matrix[2] * y + matrix[4], | |
matrix[1] * x + matrix[3] * y + matrix[5] | |
]); | |
} | |
return result; | |
}; | |
module.exports = transformPoints; | |
/***/ }, | |
/* 2 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0), | |
cache = new Instruction('beginPath'); | |
let beginPath = () => cache; | |
module.exports = beginPath; | |
/***/ }, | |
/* 3 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let cache = new Instruction('closePath'); | |
let closePath = () => cache; | |
module.exports = closePath; | |
/***/ }, | |
/* 4 */ | |
/***/ function(module, exports) { | |
let cycleMouseData = (ctx) => { | |
let mouseData = ctx.canvas[Symbol.for('mouseData')]; | |
if (mouseData) { | |
mouseData.dx = mouseData.x - mouseData.previousX; | |
mouseData.dy = mouseData.y - mouseData.previousY; | |
mouseData.previousX = mouseData.x; | |
mouseData.previousY = mouseData.y; | |
mouseData.clicked = 0; | |
} | |
}; | |
module.exports = cycleMouseData; | |
/***/ }, | |
/* 5 */ | |
/***/ function(module, exports) { | |
let det = 0; | |
let invertMatrix = ([a, b, c, d, e, f]) => ( | |
det = 1 / (a * d - c * b), | |
[ | |
d * det, | |
-c * det, | |
-b * det, | |
a * det, | |
(b * f - e * d) * det, | |
(e * b - a * f) * det | |
] | |
); | |
module.exports = invertMatrix; | |
/***/ }, | |
/* 6 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let lineTo = (x, y) => new Instruction('lineTo', { x, y }); | |
module.exports = lineTo; | |
/***/ }, | |
/* 7 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let moveTo = (x, y) => new Instruction('moveTo', { x, y }); | |
module.exports = moveTo; | |
/***/ }, | |
/* 8 */ | |
/***/ function(module, exports) { | |
let pointInRect = ([px, py], [[x, y], [width, height]]) => px > x && py > y && px < width && py < height; | |
module.exports = pointInRect; | |
/***/ }, | |
/* 9 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('restore'); | |
let setTransform = (matrix, ...children) => [ | |
new Instruction('setTransform', [ | |
matrix[0], | |
matrix[1], | |
matrix[2], | |
matrix[3], | |
matrix[4], | |
matrix[5] | |
]), | |
children, | |
end | |
]; | |
module.exports = setTransform; | |
/***/ }, | |
/* 10 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let pointInPolygon = __webpack_require__(57); | |
let transformPoints = __webpack_require__(1); | |
let invertMatrix = __webpack_require__(5); | |
let pointInRect = __webpack_require__(8); | |
let matrix = new Float64Array(6); | |
module.exports = (ctx) => { | |
let regions = ctx.canvas[Symbol.for('regions')], | |
mousePoints = ctx.canvas[Symbol.for('mousePoints')], | |
mouseData = ctx.canvas[Symbol.for('mouseData')], | |
results = {}; | |
//the mouse might have held still, add the current mouse position | |
if (mousePoints.length === 0) { | |
mousePoints.push([mouseData.x, mouseData.y, mouseData.state]); | |
} | |
for(let region of regions) { | |
//invert the region matrix and transform the mouse points | |
let transformedMousePoints = transformPoints(mousePoints, invertMatrix(region.matrix)); | |
//the mouse points are now relative to the mouse region | |
if (!region.polygon) { | |
for (let mousePoint of transformedMousePoints) { | |
if (pointInRect(mousePoint, region.points)) { | |
region.hover = true; | |
region.clicked = !!mouseData.clicked; | |
results[region.id] = region; | |
break; | |
} | |
} | |
continue; | |
} | |
//loop over each point until one is matched | |
for(let mousePoint of transformedMousePoints) { | |
if (pointInPolygon(mousePoint, region.points)) { | |
region.hover = true; | |
region.clicked = !!mouseData.clicked; | |
results[region.id] = region; | |
break; | |
} | |
} | |
} | |
return results; | |
}; | |
/***/ }, | |
/* 11 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0), | |
pi2 = Math.PI * 2; | |
let arc = (...args) => { | |
let [x, y, r, startAngle, endAngle, counterclockwise] = args; | |
let props = { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2, counterclockwise: false }; | |
if (args.length > 3) { | |
props.startAngle = startAngle; | |
props.endAngle = endAngle; | |
props.counterclockwise = !!counterclockwise; | |
} | |
if (args.length > 1){ | |
props.x = x; | |
props.y = y; | |
props.r = r; | |
} | |
return new Instruction("arc", props); | |
}; | |
module.exports = arc; | |
/***/ }, | |
/* 12 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let arcTo = (x1, y1, x2, y2, r) => new Instruction('arcTo', { x1, y1, x2, y2, r }); | |
module.exports = arcTo; | |
/***/ }, | |
/* 13 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let bezierCurveTo = (cp1x, cp1y, cp2x, cp2y, x, y) => new Instruction('bezierCurveTo', { | |
cp1x, | |
cp1y, | |
cp2x, | |
cp2y, | |
x, | |
y | |
}); | |
module.exports = bezierCurveTo; | |
/***/ }, | |
/* 14 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let clearRect = (...args) => new Instruction('clearRect', | |
args.length > 2 ? | |
{ x: args[0], y: args[1], width: args[2], height: args[3] } : | |
{ x: 0, y: 0, width: args[0], height: args[1] } | |
); | |
module.exports = clearRect; | |
/***/ }, | |
/* 15 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let begin = new Instruction('beginClip'), | |
performClip = new Instruction('clip'), | |
end = new Instruction('endClip'); | |
let clip = (path, ...children) => [ | |
begin, | |
path, | |
performClip, | |
children, | |
end | |
]; | |
module.exports = clip; | |
/***/ }, | |
/* 16 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let cache = new Instruction('clipPath'); | |
let clipPath = () => cache; | |
module.exports = clipPath; | |
/***/ }, | |
/* 17 */ | |
/***/ function(module, exports) { | |
let createRegularPolygon = (radius = 0, position = [0, 0], sides = 3) => { | |
let polygon = []; | |
for(let i = 0; i < sides; i++) { | |
polygon.push([ | |
position[0] + radius * Math.cos(Math.PI * 2 * i / sides), | |
position[1] + radius * Math.sin(Math.PI * 2 * i / sides) | |
]); | |
} | |
return polygon; | |
}; | |
module.exports = createRegularPolygon; | |
/***/ }, | |
/* 18 */ | |
/***/ function(module, exports) { | |
let concat = [].concat; | |
let createWrapper = (...args) => { | |
for(let i = 0; i < args.length; i++) { | |
//parse and flatten the arguments | |
while (args[i] && args[i].constructor === Array) { | |
args = concat.apply([], args).filter(Boolean); | |
} | |
if (!args[i]) { | |
continue; | |
} | |
let { type } = args[i]; | |
if (type === 'placeholder') { | |
// i is set to the placeholder index now | |
//now grab all the elements to the left of the placeHolder | |
let left = args.splice(0, i); | |
//remove the placeHolder from the array | |
args.shift(); | |
return (...children) => [left, children, args]; | |
} | |
} | |
throw new Error('Could not find placeholder, did you forget the e2d.placeHolder() call?'); | |
}; | |
module.exports = concat; | |
/***/ }, | |
/* 19 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let drawImage = (...args) => { | |
let [img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight] = args; | |
if (args.length === 9) { | |
return new Instruction('drawImageSource', { | |
img, | |
sx, | |
sy, | |
sWidth, | |
sHeight, | |
dx, | |
dy, | |
dWidth, | |
dHeight | |
}); | |
} | |
if (args.length >= 5) { | |
return new Instruction('drawImageSize', { | |
img, | |
dx: sx, | |
dy: sy, | |
dWidth: sWidth, | |
dHeight: sHeight | |
}); | |
} | |
if (args.length >= 3) { | |
return new Instruction('drawImage', { | |
img, | |
dx: sx, | |
dy: sy | |
}); | |
} | |
return new Instruction('drawImage', { | |
img, | |
dx: 0, | |
dy: 0 | |
}); | |
}; | |
module.exports = drawImage; | |
/***/ }, | |
/* 20 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0), | |
pi2 = Math.PI * 2; | |
let ellipse = (...args) => { | |
let [x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise] = args; | |
let props = { x: 0, y: 0, radiusX: x, radiusY: y, rotation: 0, startAngle: 0, endAngle: pi2, anticlockwise: false }; | |
if (args.length > 5) { | |
props.startAngle = startAngle; | |
props.endAngle = endAngle; | |
props.anticlockwise = !!anticlockwise; | |
} | |
if (args.length > 4) { | |
props.rotation = rotation; | |
} | |
if (args.length > 2){ | |
props.x = x; | |
props.y = y; | |
props.radiusX = radiusX; | |
props.radiusY = radiusY; | |
} | |
return new Instruction("ellipse", props); | |
}; | |
module.exports = ellipse; | |
/***/ }, | |
/* 21 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let cache = new Instruction('fill'); | |
let fill = () => cache; | |
module.exports = fill; | |
/***/ }, | |
/* 22 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0), | |
pi2 = Math.PI * 2; | |
let fillArc = (...args) => { | |
let [x, y, r, startAngle, endAngle, counterclockwise] = args; | |
let props = { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2, counterclockwise: false }; | |
if (args.length > 3) { | |
props.startAngle = startAngle; | |
props.endAngle = endAngle; | |
props.counterclockwise = !!counterclockwise; | |
} | |
if (args.length >= 2) { | |
props.x = x; | |
props.y = y; | |
props.r = r; | |
} | |
return new Instruction("fillArc", props); | |
}; | |
module.exports = fillArc; | |
/***/ }, | |
/* 23 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let fillRect = (...args) => new Instruction('fillRect', | |
args.length > 2 ? | |
{ x: args[0], y: args[1], width: args[2], height: args[3] } : | |
{ x: 0, y: 0, width: args[0], height: args[1] } | |
); | |
module.exports = fillRect; | |
/***/ }, | |
/* 24 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('endFillStyle'); | |
let fillStyle = (value, ...children) => [ | |
new Instruction('fillStyle', { value }), | |
children, | |
end | |
]; | |
module.exports = fillStyle; | |
/***/ }, | |
/* 25 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let fillText = (...args) => { | |
let [text, x, y, maxWidth] = args; | |
if (args.length < 4) { | |
maxWidth = null; | |
} | |
if (args.length < 3) { | |
x = 0; | |
y = 0; | |
} | |
return new Instruction('fillText', { text, x, y, maxWidth }); | |
}; | |
module.exports = fillText; | |
/***/ }, | |
/* 26 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('endGlobalAlpha'); | |
let globalAlpha = (value, ...children) => [ | |
new Instruction('globalAlpha', { value }), | |
children, | |
end | |
]; | |
module.exports = globalAlpha; | |
/***/ }, | |
/* 27 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var Instruction = __webpack_require__(0); | |
let end = new Instruction('endGlobalCompositeOperation'); | |
let globalCompositeOperation = (value, ...children) => [ | |
new Instruction('globalCompositeOperation', { value }), | |
children, | |
end | |
]; | |
module.exports = globalCompositeOperation; | |
/***/ }, | |
/* 28 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let hitRect = (id, ...args) => { | |
let [x, y, width, height] = args; | |
if (args.length <= 3) { | |
width = x; | |
height = y; | |
x = 0; | |
y = 0; | |
} | |
return new Instruction('hitRect', { | |
id, | |
points: [ | |
[x, y], | |
[x + width, y + height] | |
] | |
}); | |
}; | |
module.exports = hitRect; | |
/***/ }, | |
/* 29 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let hitRegion = (id, points) => new Instruction('hitRegion', { id, points }); | |
module.exports = hitRegion; | |
/***/ }, | |
/* 30 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('endImageSmoothingEnabled'); | |
let imageSmoothingEnabled = (value, ...children) => [ | |
new Instruction('imageSmoothingEnabled', { value }), | |
children, | |
end | |
]; | |
module.exports = imageSmoothingEnabled; | |
/***/ }, | |
/* 31 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let keycode = __webpack_require__(56); | |
module.exports = (ctx) => { | |
let { canvas } = ctx; | |
//mouseData | |
canvas[Symbol.for('mouseData')] = { | |
x: 0, | |
y: 0, | |
dx: 0, | |
dy: 0, | |
previousX: 0, | |
previousY: 0, | |
state: false, | |
clicked: 0 | |
}; | |
let keys = canvas[Symbol.for('keyData')] = {}; | |
for (let name in keycode.code) { | |
if (keycode.code.hasOwnProperty(name)) { | |
keys[name] = false; | |
} | |
} | |
//mouse regions | |
canvas[Symbol.for('regions')] = []; | |
canvas[Symbol.for('mousePoints')] = []; | |
//make the canvas receive touch and mouse events | |
canvas.tabIndex = 1; | |
let mouseMove = (evt) => { | |
let { clientX, clientY } = evt; | |
//get left and top coordinates | |
let { left, top } = canvas.getBoundingClientRect(); | |
let mouseData = canvas[Symbol.for('mouseData')]; | |
let point = [clientX - left, clientY - top, mouseData.state]; | |
mouseData.x = point[0]; | |
mouseData.y = point[1]; | |
let points = canvas[Symbol.for('mousePoints')]; | |
points.push(point); | |
//store the last 100 stored positions for hover detection | |
if (points.length > 100) { | |
points.splice(0, points.length - 100); | |
} | |
evt.preventDefault(); | |
return false; | |
}; | |
canvas.addEventListener('mousemove', (evt) => mouseMove(evt)); | |
canvas.addEventListener('mousedown', (evt) => { | |
let { target } = evt; | |
if (target === canvas) { | |
let mouseData = canvas[Symbol.for('mouseData')]; | |
if (!mouseData.state) { | |
mouseData.clicked += 1; | |
} | |
mouseData.state = true; | |
return mouseMove(evt); | |
} | |
}); | |
canvas.addEventListener('mouseup', (evt) => { | |
let mouseData = canvas[Symbol.for('mouseData')]; | |
mouseData.state = false; | |
return mouseMove(evt); | |
}); | |
canvas.addEventListener('keydown', (evt) => { | |
canvas[Symbol.for('keyData')][keycode(evt.keyCode)] = true; | |
evt.preventDefault(); | |
return false; | |
}); | |
canvas.addEventListener('keyup', (evt) => { | |
canvas[Symbol.for('keyData')][keycode(evt.keyCode)] = false; | |
evt.preventDefault(); | |
return false; | |
}); | |
}; | |
/***/ }, | |
/* 32 */ | |
/***/ function(module, exports) { | |
module.exports = (ctx) => ctx.canvas[Symbol.for('keyData')]; | |
/***/ }, | |
/* 33 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('endLineStyle'); | |
let lineStyle = (value, ...children) => { | |
value = value || {}; | |
var result = { | |
lineWidth: null, | |
lineCap: null, | |
lineJoin: null, | |
miterLimit: null, | |
lineDash: null, | |
lineDashOffset: null | |
}; | |
if (typeof value.lineWidth !== 'undefined') { | |
result.lineWidth = value.lineWidth; | |
} | |
if (typeof value.lineCap !== 'undefined') { | |
result.lineCap = value.lineCap; | |
} | |
if (typeof value.lineJoin !== 'undefined') { | |
result.lineJoin = value.lineJoin; | |
} | |
if (typeof value.miterLimit !== 'undefined') { | |
result.miterLimit = value.miterLimit; | |
} | |
if (typeof value.lineDash !== 'undefined') { | |
result.lineDash = value.lineDash || []; | |
} | |
if (typeof value.lineDashOffset !== 'undefined') { | |
result.lineDashOffset = value.lineDashOffset; | |
} | |
return [ | |
new Instruction('lineStyle', result), | |
children, | |
end | |
]; | |
}; | |
module.exports = lineStyle; | |
/***/ }, | |
/* 34 */ | |
/***/ function(module, exports) { | |
module.exports = (ctx) => ctx.canvas[Symbol.for('mouseData')]; | |
/***/ }, | |
/* 35 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let moveTo = __webpack_require__(7), lineTo = __webpack_require__(6); | |
let moveToLineTo = (point, index) => index === 0 ? | |
moveTo(point[0], point[1]) : | |
lineTo(point[0], point[1]); | |
module.exports = moveToLineTo; | |
/***/ }, | |
/* 36 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let beginPath = __webpack_require__(2)(), | |
closePath = __webpack_require__(3)(); | |
let path = (...children) => [ | |
beginPath, | |
children, | |
closePath | |
]; | |
module.exports = path; | |
/***/ }, | |
/* 37 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let cache = new Instruction('placeholder'); | |
let placeHolder = () => cache; | |
module.exports = placeHolder; | |
/***/ }, | |
/* 38 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let quadraticCurveTo = (cpx, cpy, x, y) => new Instruction('quadraticCurveTo', { | |
cpx, | |
cpy, | |
x, | |
y | |
}); | |
module.exports = quadraticCurveTo; | |
/***/ }, | |
/* 39 */ | |
/***/ function(module, exports) { | |
let raf = (func) => { | |
requestAnimationFrame(() => raf(func)); | |
return func(); | |
}; | |
module.exports = raf; | |
/***/ }, | |
/* 40 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let rect = (...args) => new Instruction('rect', | |
args.length > 2 ? | |
{ x: args[0], y: args[1], width: args[2], height: args[3] } : | |
{ x: 0, y: 0, width: args[0], height: args[1] } | |
); | |
module.exports = rect; | |
/***/ }, | |
/* 41 */ | |
/***/ function(module, exports, __webpack_require__) { | |
//initialize all the properties | |
let identity = [1, 0, 0, 1, 0, 0], | |
matrix = new Float64Array(identity), | |
fillStyleStack = [], | |
strokeStyleStack = [], | |
lineStyleStack = [], | |
textStyleStack = [], | |
shadowStyleStack = [], | |
globalCompositeOperationStack = [], | |
globalAlphaStack = [], | |
imageSmoothingEnabledStack = [], | |
transformStack = new Float64Array(501 * 6), | |
transformStackIndex = 6, | |
concat = [].concat, | |
supportsEllipse = false; | |
if (typeof CanvasRenderingContext2D !== 'undefined') { | |
supportsEllipse = CanvasRenderingContext2D.prototype.hasOwnProperty('ellipse'); | |
} | |
//transform points function | |
const transformPoints = __webpack_require__(1); | |
const cycleMouseData = __webpack_require__(4); | |
const increaseTransformStackSize = () => { | |
let cache = transformStack; | |
transformStack = new Float64Array(transformStack.length + 600); //add 100 more | |
transformStack.set(cache); | |
return this; | |
}; | |
transformStack.set(identity); | |
const PI2 = Math.PI * 2; | |
let empty = (target) => target && target.splice(0, target.length); | |
module.exports = (...args) => { | |
let children = args.slice(0, -1), | |
ctx = args[args.length - 1]; | |
let regions = ctx.canvas[Symbol.for('regions')], | |
mousePoints = ctx.canvas[Symbol.for('mousePoints')], | |
extensions = ctx.canvas[Symbol.for('extensions')]; | |
let cache; | |
cycleMouseData(ctx); | |
empty(regions); | |
empty(mousePoints); | |
let len = children.length; | |
//flatten children during the loop process to save cpu | |
for (let i = 0; i < len; i++) { | |
let child = children[i]; | |
//flattening algorithm | |
if (child && child.constructor === Array) { | |
children = concat.apply([], children); | |
child = children[i]; | |
//repeat as necessary | |
while (child && child.constructor === Array) { | |
children = concat.apply([], children); | |
child = children[i]; | |
} | |
len = children.length; | |
} | |
//child must be truthy | |
if (!child) { | |
continue; | |
} | |
let { props, type } = child; | |
if (type === 'transform') { | |
//copy transformStack values to matrix | |
matrix[0] = transformStack[transformStackIndex - 6]; | |
matrix[1] = transformStack[transformStackIndex - 5]; | |
matrix[2] = transformStack[transformStackIndex - 4]; | |
matrix[3] = transformStack[transformStackIndex - 3]; | |
matrix[4] = transformStack[transformStackIndex - 2]; | |
matrix[5] = transformStack[transformStackIndex - 1]; | |
//increase the index | |
transformStackIndex += 6; | |
if (transformStackIndex > transformStack.length) { | |
increaseTransformStackSize(); | |
} | |
//perform the transform math | |
transformStack[transformStackIndex - 6] = //d | |
matrix[0] * props[0] + matrix[2] * props[1]; | |
transformStack[transformStackIndex - 5] = //b | |
matrix[1] * props[0] + matrix[3] * props[1]; | |
transformStack[transformStackIndex - 4] = //c | |
matrix[0] * props[2] + matrix[2] * props[3]; | |
transformStack[transformStackIndex - 3] = //d | |
matrix[1] * props[2] + matrix[3] * props[3]; | |
transformStack[transformStackIndex - 2] = //e | |
matrix[0] * props[4] + matrix[2] * props[5] + matrix[4]; | |
transformStack[transformStackIndex - 1] = //f | |
matrix[1] * props[4] + matrix[3] * props[5] + matrix[5]; | |
//modify the ctx | |
ctx.setTransform( | |
transformStack[transformStackIndex - 6], | |
transformStack[transformStackIndex - 5], | |
transformStack[transformStackIndex - 4], | |
transformStack[transformStackIndex - 3], | |
transformStack[transformStackIndex - 2], | |
transformStack[transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'setTransform') { | |
transformStackIndex += 6; | |
if (transformStackIndex > transformStack.length) { | |
increaseTransformStackSize(); | |
} | |
transformStack[transformStackIndex - 6] = props[0];//a | |
transformStack[transformStackIndex - 5] = props[1];//b | |
transformStack[transformStackIndex - 4] = props[2];//c | |
transformStack[transformStackIndex - 3] = props[3];//d | |
transformStack[transformStackIndex - 2] = props[4];//e | |
transformStack[transformStackIndex - 1] = props[5];//f | |
ctx.setTransform(props[0], props[1], props[2], props[3], props[4], props[5]); | |
continue; | |
} | |
if (type === 'scale') { | |
matrix[0] = transformStack[transformStackIndex - 6]; | |
matrix[1] = transformStack[transformStackIndex - 5]; | |
matrix[2] = transformStack[transformStackIndex - 4]; | |
matrix[3] = transformStack[transformStackIndex - 3]; | |
matrix[4] = transformStack[transformStackIndex - 2]; | |
matrix[5] = transformStack[transformStackIndex - 1]; | |
transformStackIndex += 6; | |
if (transformStackIndex > transformStack.length) { | |
increaseTransformStackSize(); | |
} | |
transformStack[transformStackIndex - 6] = matrix[0] * props.x; //a | |
transformStack[transformStackIndex - 5] = matrix[1] * props.x; //b | |
transformStack[transformStackIndex - 4] = matrix[2] * props.y; //c | |
transformStack[transformStackIndex - 3] = matrix[3] * props.y; //d | |
transformStack[transformStackIndex - 2] = matrix[4]; //e | |
transformStack[transformStackIndex - 1] = matrix[5]; //f | |
ctx.setTransform( | |
transformStack[transformStackIndex - 6], | |
transformStack[transformStackIndex - 5], | |
transformStack[transformStackIndex - 4], | |
transformStack[transformStackIndex - 3], | |
transformStack[transformStackIndex - 2], | |
transformStack[transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'translate') { | |
matrix[0] = transformStack[transformStackIndex - 6]; | |
matrix[1] = transformStack[transformStackIndex - 5]; | |
matrix[2] = transformStack[transformStackIndex - 4]; | |
matrix[3] = transformStack[transformStackIndex - 3]; | |
matrix[4] = transformStack[transformStackIndex - 2]; | |
matrix[5] = transformStack[transformStackIndex - 1]; | |
transformStackIndex += 6; | |
if (transformStackIndex > transformStack.length) { | |
increaseTransformStackSize(); | |
} | |
transformStack[transformStackIndex - 6] = matrix[0]; //a | |
transformStack[transformStackIndex - 5] = matrix[1]; //b | |
transformStack[transformStackIndex - 4] = matrix[2]; //c | |
transformStack[transformStackIndex - 3] = matrix[3]; //d | |
transformStack[transformStackIndex - 2] = matrix[4] + matrix[0] * props.x + matrix[2] * props.y; //e | |
transformStack[transformStackIndex - 1] = matrix[5] + matrix[1] * props.x + matrix[3] * props.y; //f | |
ctx.setTransform( | |
transformStack[transformStackIndex - 6], | |
transformStack[transformStackIndex - 5], | |
transformStack[transformStackIndex - 4], | |
transformStack[transformStackIndex - 3], | |
transformStack[transformStackIndex - 2], | |
transformStack[transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'rotate') { | |
matrix[0] = transformStack[transformStackIndex - 6]; | |
matrix[1] = transformStack[transformStackIndex - 5]; | |
matrix[2] = transformStack[transformStackIndex - 4]; | |
matrix[3] = transformStack[transformStackIndex - 3]; | |
matrix[4] = transformStack[transformStackIndex - 2]; | |
matrix[5] = transformStack[transformStackIndex - 1]; | |
transformStackIndex += 6; | |
if (transformStackIndex > transformStack.length) { | |
increaseTransformStackSize(); | |
} | |
transformStack[transformStackIndex - 6] = | |
matrix[0] * props.cos + matrix[2] * props.sin; //a | |
transformStack[transformStackIndex - 5] = | |
matrix[1] * props.cos + matrix[3] * props.sin; //b | |
transformStack[transformStackIndex - 4] = | |
matrix[0] * -props.sin + matrix[2] * props.cos; //c | |
transformStack[transformStackIndex - 3] = | |
matrix[1] * -props.sin + matrix[3] * props.cos; //d | |
transformStack[transformStackIndex - 2] = matrix[4]; //e | |
transformStack[transformStackIndex - 1] = matrix[5];//f | |
ctx.setTransform( | |
transformStack[transformStackIndex - 6], | |
transformStack[transformStackIndex - 5], | |
transformStack[transformStackIndex - 4], | |
transformStack[transformStackIndex - 3], | |
transformStack[transformStackIndex - 2], | |
transformStack[transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'skewX') { | |
matrix[0] = transformStack[transformStackIndex - 6]; | |
matrix[1] = transformStack[transformStackIndex - 5]; | |
matrix[2] = transformStack[transformStackIndex - 4]; | |
matrix[3] = transformStack[transformStackIndex - 3]; | |
matrix[4] = transformStack[transformStackIndex - 2]; | |
matrix[5] = transformStack[transformStackIndex - 1]; | |
transformStackIndex += 6; | |
if (transformStackIndex > transformStack.length) { | |
increaseTransformStackSize(); | |
} | |
transformStack[transformStackIndex - 6] = matrix[0]; //a | |
transformStack[transformStackIndex - 5] = matrix[1]; //b | |
transformStack[transformStackIndex - 4] = //c | |
matrix[0] * props.x + matrix[2]; | |
transformStack[transformStackIndex - 3] = //d | |
matrix[1] * props.x + matrix[3]; | |
transformStack[transformStackIndex - 2] = matrix[4]; //e | |
transformStack[transformStackIndex - 1] = matrix[5]; //f | |
ctx.setTransform( | |
transformStack[transformStackIndex - 6], | |
transformStack[transformStackIndex - 5], | |
transformStack[transformStackIndex - 4], | |
transformStack[transformStackIndex - 3], | |
transformStack[transformStackIndex - 2], | |
transformStack[transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'skewY') { | |
matrix[0] = transformStack[transformStackIndex - 6]; | |
matrix[1] = transformStack[transformStackIndex - 5]; | |
matrix[2] = transformStack[transformStackIndex - 4]; | |
matrix[3] = transformStack[transformStackIndex - 3]; | |
matrix[4] = transformStack[transformStackIndex - 2]; | |
matrix[5] = transformStack[transformStackIndex - 1]; | |
transformStackIndex += 6; | |
if (transformStackIndex > transformStack.length) { | |
increaseTransformStackSize(); | |
} | |
transformStack[transformStackIndex - 6] = | |
matrix[0] * 1 + matrix[2] * props.y; //a | |
transformStack[transformStackIndex - 5] = | |
matrix[1] * 1 + matrix[3] * props.y; //b | |
transformStack[transformStackIndex - 4] = matrix[2]; //c | |
transformStack[transformStackIndex - 3] = matrix[3]; //d | |
transformStack[transformStackIndex - 2] = matrix[4]; //e | |
transformStack[transformStackIndex - 1] = matrix[5]; //f | |
ctx.setTransform( | |
transformStack[transformStackIndex - 6], | |
transformStack[transformStackIndex - 5], | |
transformStack[transformStackIndex - 4], | |
transformStack[transformStackIndex - 3], | |
transformStack[transformStackIndex - 2], | |
transformStack[transformStackIndex - 1] | |
); | |
continue; | |
} | |
if (type === 'restore') { | |
transformStackIndex -= 6; | |
matrix[0] = transformStack[transformStackIndex - 6]; | |
matrix[1] = transformStack[transformStackIndex - 5]; | |
matrix[2] = transformStack[transformStackIndex - 4]; | |
matrix[3] = transformStack[transformStackIndex - 3]; | |
matrix[4] = transformStack[transformStackIndex - 2]; | |
matrix[5] = transformStack[transformStackIndex - 1]; | |
ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); | |
continue; | |
} | |
if (type === 'fillRect') { | |
ctx.fillRect(props.x, props.y, props.width, props.height); | |
continue; | |
} | |
if (type === 'strokeRect') { | |
ctx.strokeRect(props.x, props.y, props.width, props.height); | |
continue; | |
} | |
if (type === 'clearRect') { | |
ctx.clearRect(props.x, props.y, props.width, props.height); | |
continue; | |
} | |
if (type === 'rect') { | |
ctx.rect(props.x, props.y, props.width, props.height); | |
continue; | |
} | |
if (type === 'fillStyle') { | |
fillStyleStack.push(ctx.fillStyle); | |
ctx.fillStyle = props.value; | |
continue; | |
} | |
if (type === 'strokeStyle') { | |
strokeStyleStack.push(ctx.strokeStyle); | |
ctx.strokeStyle = props.value; | |
continue; | |
} | |
if (type === 'endFillStyle') { | |
ctx.fillStyle = fillStyleStack.pop(); | |
continue; | |
} | |
if (type === 'endStrokeStyle') { | |
ctx.strokeStyle = strokeStyleStack.pop(); | |
continue; | |
} | |
if (type === 'lineStyle') { | |
lineStyleStack.push({ | |
lineWidth: ctx.lineWidth, | |
lineCap: ctx.lineCap, | |
lineJoin: ctx.lineJoin, | |
miterLimit: ctx.miterLimit, | |
lineDash: ctx.getLineDash(), | |
lineDashOffset: ctx.lineDashOffset | |
}); | |
if (props.lineWidth !== null) { | |
ctx.lineWidth = props.lineWidth; | |
} | |
if (props.lineCap !== null) { | |
ctx.lineCap = props.lineCap; | |
} | |
if (props.lineJoin !== null) { | |
ctx.lineJoin = props.lineJoin; | |
} | |
if (props.miterLimit !== null) { | |
ctx.miterLimit = props.miterLimit; | |
} | |
if (props.lineDash !== null) { | |
ctx.setLineDash(props.lineDash); | |
} | |
if (props.lineDashOffset !== null) { | |
ctx.lineDashOffset = props.lineDashOffset; | |
} | |
continue; | |
} | |
if (type === 'endLineStyle') { | |
cache = lineStyleStack.pop(); | |
ctx.lineWidth = cache.lineWidth; | |
ctx.lineCap = cache.lineCap; | |
ctx.lineJoin = cache.lineJoin; | |
ctx.miterLimit = cache.miterLimit; | |
ctx.setLineDash(cache.lineDash); | |
ctx.lineDashOffset = cache.lineDashOffset; | |
continue; | |
} | |
if (type === 'textStyle') { | |
textStyleStack.push({ | |
font: ctx.font, | |
textAlign: ctx.textAlign, | |
textBaseline: ctx.textBaseline, | |
direction: ctx.direction | |
}); | |
if (props.font !== null) { | |
ctx.font = props.font; | |
} | |
if (props.textAlign !== null) { | |
ctx.textAlign = props.textAlign; | |
} | |
if (props.textBaseline !== null) { | |
ctx.textBaseline = props.textBaseline; | |
} | |
if (props.direction !== null) { | |
ctx.direction = props.direction; | |
} | |
continue; | |
} | |
if (type === 'endTextStyle') { | |
cache = textStyleStack.pop(); | |
ctx.font = cache.font; | |
ctx.textAlign = cache.textAlign; | |
ctx.textBaseline = cache.textBaseline; | |
ctx.direction = cache.direction; | |
continue; | |
} | |
if (type === 'shadowStyle') { | |
shadowStyleStack.push({ | |
shadowBlur: ctx.shadowBlur, | |
shadowColor: ctx.shadowColor, | |
shadowOffsetX: ctx.shadowOffsetX, | |
shadowOffsetY: ctx.shadowOffsetY | |
}); | |
if (props.shadowBlur !== null) { | |
ctx.shadowBlur = props.shadowBlur; | |
} | |
if (props.shadowColor !== null) { | |
ctx.shadowColor = props.shadowColor; | |
} | |
if (props.shadowOffsetX !== null) { | |
ctx.shadowOffsetX = props.shadowOffsetX; | |
} | |
if (props.shadowOffsetY !== null) { | |
ctx.shadowOffsetY = props.shadowOffsetY; | |
} | |
continue; | |
} | |
if (type === 'endShadowStyle') { | |
cache = shadowStyleStack.pop(); | |
ctx.shadowBlur = cache.shadowBlur; | |
ctx.shadowColor = cache.shadowColor; | |
ctx.shadowOffsetX = cache.shadowOffsetX; | |
ctx.shadowOffsetY = cache.shadowOffsetY; | |
continue; | |
} | |
if (type === 'strokeText') { | |
if (props.maxWidth) { | |
ctx.strokeText(props.text, props.x, props.y, props.maxWidth); | |
continue; | |
} | |
ctx.strokeText(props.text, props.x, props.y); | |
continue; | |
} | |
if (type === 'fillText') { | |
if (props.maxWidth) { | |
ctx.fillText(props.text, props.x, props.y, props.maxWidth); | |
continue; | |
} | |
ctx.fillText(props.text, props.x, props.y); | |
continue; | |
} | |
if (type === 'drawImage') { | |
ctx.drawImage(props.img, props.dx, props.dy); | |
continue; | |
} | |
if (type === 'drawImageSize') { | |
ctx.drawImage(props.img, props.dx, props.dy, props.dWidth, props.dHeight); | |
continue; | |
} | |
if (type === 'drawImageSource') { | |
ctx.drawImage(props.img, props.sx, props.sy, props.sWidth, props.sHeight, props.dx, props.dy, props.dWidth, props.dHeight); | |
continue; | |
} | |
if (type === 'strokeArc') { | |
ctx.beginPath(); | |
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, props.counterclockwise); | |
ctx.closePath(); | |
ctx.stroke(); | |
continue; | |
} | |
if (type === 'fillArc') { | |
ctx.beginPath(); | |
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, props.counterclockwise); | |
ctx.closePath(); | |
ctx.fill(); | |
continue; | |
} | |
if (type === 'moveTo') { | |
ctx.moveTo(props.x, props.y); | |
continue; | |
} | |
if (type === 'lineTo') { | |
ctx.lineTo(props.x, props.y); | |
continue; | |
} | |
if (type === 'bezierCurveTo') { | |
ctx.bezierCurveTo(props.cp1x, props.cp1y, props.cp2x, props.cp2y, props.x, props.y); | |
continue; | |
} | |
if (type === 'quadraticCurveTo') { | |
ctx.quadraticCurveTo(props.cpx, props.cpy, props.x, props.y); | |
continue; | |
} | |
if (type === 'arc') { | |
ctx.arc(props.x, props.y, props.r, props.startAngle, props.endAngle, props.counterclockwise); | |
continue; | |
} | |
if (type === 'arcTo') { | |
ctx.arcTo(props.x1, props.y1, props.x2, props.y2, props.r); | |
continue; | |
} | |
if (type === 'ellipse') { | |
//if the method is provided by the browser | |
if (supportsEllipse) { | |
ctx.ellipse( | |
props.x, | |
props.y, | |
props.radiusX, | |
props.radiusY, | |
props.rotation, | |
props.startAngle, | |
props.endAngle, | |
props.anticlockwise | |
); | |
continue; | |
} | |
ctx.save(); | |
ctx.translate(props.x, props.y); | |
ctx.rotate(props.rotation); | |
ctx.scale(props.radiusX, props.radiusY); | |
ctx.arc(0, 0, 1, props.startAngle, props.endAngle, props.anticlockwise); | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'globalCompositeOperation') { | |
globalCompositeOperationStack.push(ctx.globalCompositeOperation); | |
ctx.globalCompositeOperation = props.value; | |
continue; | |
} | |
if (type === 'endGlobalCompositeOperation') { | |
ctx.globalCompositeOperation = globalCompositeOperationStack.pop(); | |
continue; | |
} | |
if (type === 'fill') { | |
ctx.fill(); | |
continue; | |
} | |
if (type === 'stroke') { | |
ctx.stroke(); | |
continue; | |
} | |
if (type === 'beginClip') { | |
ctx.save(); | |
ctx.beginPath(); | |
continue; | |
} | |
if (type === 'clip') { | |
ctx.clip(); | |
continue; | |
} | |
if (type === 'endClip') { | |
ctx.restore(); | |
continue; | |
} | |
if (type === 'beginPath') { | |
ctx.beginPath(); | |
continue; | |
} | |
if (type === 'closePath') { | |
ctx.closePath(); | |
continue; | |
} | |
if (type === 'globalAlpha') { | |
globalAlphaStack.push(ctx.globalAlpha); | |
ctx.globalAlpha *= props.value; | |
continue; | |
} | |
if (type === 'endGlobalAlpha') { | |
ctx.globalAlpha = globalAlphaStack.pop(); | |
continue; | |
} | |
if (type === 'hitRect' && regions) { | |
cache = [ | |
transformStack[transformStackIndex - 6], | |
transformStack[transformStackIndex - 5], | |
transformStack[transformStackIndex - 4], | |
transformStack[transformStackIndex - 3], | |
transformStack[transformStackIndex - 2], | |
transformStack[transformStackIndex - 1] | |
]; | |
regions.push({ | |
id: props.id, | |
points: props.points, | |
matrix: cache, | |
//rectangle! | |
polygon: false, | |
hover: false, | |
touched: false, | |
clicked: false | |
}); | |
} | |
if (type === 'hitRegion' && regions) { | |
cache = [ | |
transformStack[transformStackIndex - 6], | |
transformStack[transformStackIndex - 5], | |
transformStack[transformStackIndex - 4], | |
transformStack[transformStackIndex - 3], | |
transformStack[transformStackIndex - 2], | |
transformStack[transformStackIndex - 1] | |
]; | |
regions.push({ | |
id: props.id, | |
points: props.points, | |
matrix: cache, | |
polygon: true, | |
hover: false, | |
touched: false, | |
clicked: false | |
}); | |
continue; | |
} | |
if (type === 'imageSmoothingEnabled') { | |
imageSmoothingEnabledStack.push(ctx.imageSmoothingEnabled); | |
ctx.imageSmoothingEnabled = props.value; | |
continue; | |
} | |
if (type === 'endImageSmoothingEnabled') { | |
ctx.imageSmoothingEnabled = imageSmoothingEnabledStack.pop(); | |
continue; | |
} | |
if (extensions && extensions[type]) { | |
extensions[type](props, ctx); | |
continue; | |
} | |
} | |
}; | |
/***/ }, | |
/* 42 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let setTransform = __webpack_require__(9); | |
let resetTransform = (...children) => setTransform([1, 0, 0, 1, 0, 0], children); | |
module.exports = resetTransform; | |
/***/ }, | |
/* 43 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('restore'); | |
let rotate = (r, ...children) => [ | |
new Instruction('rotate', { cos: Math.cos(r), sin: Math.sin(r) }), | |
children, | |
end | |
]; | |
module.exports = rotate; | |
/***/ }, | |
/* 44 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('restore'); | |
let scale = (x, y, ...children) => { | |
if (typeof y !== 'number') { | |
children = [y].concat(children); | |
y = x; | |
} | |
return [ | |
new Instruction('scale', { x, y }), | |
children, | |
end | |
]; | |
}; | |
module.exports = scale; | |
/***/ }, | |
/* 45 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('endShadowStyle'); | |
let shadowStyle = (value, ...children) => { | |
value = value || {}; | |
var result = { | |
shadowBlur: null, | |
shadowColor: null, | |
shadowOffsetX: null, | |
shadowOffsetY: null | |
}; | |
if (typeof value.shadowBlur !== 'undefined') { | |
result.shadowBlur = value.shadowBlur; | |
} | |
if (typeof value.shadowColor !== 'undefined') { | |
result.shadowColor = value.shadowColor; | |
} | |
if (typeof value.shadowOffsetX !== 'undefined') { | |
result.shadowOffsetX = value.shadowOffsetX; | |
} | |
if (typeof value.direction !== 'undefined') { | |
result.shadowOffsetY = value.shadowOffsetY; | |
} | |
return [ | |
new Instruction('shadowStyle', value), | |
children, | |
end | |
]; | |
}; | |
module.exports = shadowStyle; | |
/***/ }, | |
/* 46 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('restore'); | |
let skewX = (x, ...children) => [ | |
new Instruction('skewX', { x: Math.tan(x) }), | |
children, | |
end | |
]; | |
module.exports = skewX; | |
/***/ }, | |
/* 47 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('restore'); | |
let skewY = (x, ...children) => [ | |
new Instruction('skewY', { y: Math.tan(y) }), | |
children, | |
end | |
]; | |
module.exports = skewY; | |
/***/ }, | |
/* 48 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let cache = new Instruction('stroke'); | |
let stroke = () => cache; | |
module.exports = stroke; | |
/***/ }, | |
/* 49 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0), | |
pi2 = Math.PI * 2; | |
let strokeArc = (...args) => { | |
let [x, y, r, startAngle, endAngle, counterclockwise] = args; | |
let props = { x: 0, y: 0, r: x, startAngle: 0, endAngle: pi2, counterclockwise: false }; | |
if (args.length > 3) { | |
props.startAngle = startAngle; | |
props.endAngle = endAngle; | |
props.counterclockwise = !!counterclockwise; | |
} | |
if (args.length > 1){ | |
props.x = x; | |
props.y = y; | |
props.r = r; | |
} | |
return new Instruction("strokeArc", props); | |
}; | |
module.exports = strokeArc; | |
/***/ }, | |
/* 50 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let strokeRect = (...args) => new Instruction('strokeRect', | |
args.length > 2 ? | |
{ x: args[0], y: args[1], width: args[2], height: args[3] } : | |
{ x: 0, y: 0, width: args[0], height: args[1] } | |
); | |
module.exports = strokeRect; | |
/***/ }, | |
/* 51 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('endStrokeStyle'); | |
let strokeStyle = (value, ...children) => [ | |
new Instruction('strokeStyle', { value }), | |
children, | |
end | |
]; | |
module.exports = strokeStyle; | |
/***/ }, | |
/* 52 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let strokeText = (...args) => { | |
let [text, x, y, maxWidth] = args; | |
if (args.length < 4) { | |
maxWidth = null; | |
} | |
if (args.length < 3) { | |
x = 0; | |
y = 0; | |
} | |
return new Instruction('strokeText', { | |
text, | |
x, | |
y, | |
maxWidth | |
}); | |
}; | |
module.exports = strokeText; | |
/***/ }, | |
/* 53 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('endTextStyle'); | |
let textStyle = (value, ...children) => { | |
value = value || {}; | |
var result = { | |
font: null, | |
textAlign: null, | |
textBaseline: null, | |
direction: null | |
}; | |
if (typeof value.font !== 'undefined') { | |
result.font = value.font; | |
} | |
if (typeof value.textAlign !== 'undefined') { | |
result.textAlign = value.textAlign; | |
} | |
if (typeof value.textBaseline !== 'undefined') { | |
result.textBaseline = value.textBaseline; | |
} | |
if (typeof value.direction !== 'undefined') { | |
result.direction = value.direction; | |
} | |
return [ | |
new Instruction('textStyle', result), | |
children, | |
end | |
]; | |
}; | |
module.exports = textStyle; | |
/***/ }, | |
/* 54 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('restore'); | |
let transform = (values, ...children) => { | |
return [ | |
new Instruction('transform',[ | |
values[0], | |
values[1], | |
values[2], | |
values[3], | |
values[4], | |
values[5] | |
]), | |
children, | |
end | |
]; | |
}; | |
module.exports = transform; | |
/***/ }, | |
/* 55 */ | |
/***/ function(module, exports, __webpack_require__) { | |
let Instruction = __webpack_require__(0); | |
let end = new Instruction('restore'); | |
let translate = (x, y, ...children) => [ | |
new Instruction('translate', { x: x, y: y }), | |
children, | |
end | |
]; | |
module.exports = translate; | |
/***/ }, | |
/* 56 */ | |
/***/ function(module, exports) { | |
// Source: http://jsfiddle.net/vWx8V/ | |
// http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes | |
/** | |
* Conenience method returns corresponding value for given keyName or keyCode. | |
* | |
* @param {Mixed} keyCode {Number} or keyName {String} | |
* @return {Mixed} | |
* @api public | |
*/ | |
exports = module.exports = function(searchInput) { | |
// Keyboard Events | |
if (searchInput && 'object' === typeof searchInput) { | |
var hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode | |
if (hasKeyCode) searchInput = hasKeyCode | |
} | |
// Numbers | |
if ('number' === typeof searchInput) return names[searchInput] | |
// Everything else (cast to string) | |
var search = String(searchInput) | |
// check codes | |
var foundNamedKey = codes[search.toLowerCase()] | |
if (foundNamedKey) return foundNamedKey | |
// check aliases | |
var foundNamedKey = aliases[search.toLowerCase()] | |
if (foundNamedKey) return foundNamedKey | |
// weird character? | |
if (search.length === 1) return search.charCodeAt(0) | |
return undefined | |
} | |
/** | |
* Get by name | |
* | |
* exports.code['enter'] // => 13 | |
*/ | |
var codes = exports.code = exports.codes = { | |
'backspace': 8, | |
'tab': 9, | |
'enter': 13, | |
'shift': 16, | |
'ctrl': 17, | |
'alt': 18, | |
'pause/break': 19, | |
'caps lock': 20, | |
'esc': 27, | |
'space': 32, | |
'page up': 33, | |
'page down': 34, | |
'end': 35, | |
'home': 36, | |
'left': 37, | |
'up': 38, | |
'right': 39, | |
'down': 40, | |
'insert': 45, | |
'delete': 46, | |
'command': 91, | |
'left command': 91, | |
'right command': 93, | |
'numpad *': 106, | |
'numpad +': 107, | |
'numpad -': 109, | |
'numpad .': 110, | |
'numpad /': 111, | |
'num lock': 144, | |
'scroll lock': 145, | |
'my computer': 182, | |
'my calculator': 183, | |
';': 186, | |
'=': 187, | |
',': 188, | |
'-': 189, | |
'.': 190, | |
'/': 191, | |
'`': 192, | |
'[': 219, | |
'\\': 220, | |
']': 221, | |
"'": 222 | |
} | |
// Helper aliases | |
var aliases = exports.aliases = { | |
'windows': 91, | |
'⇧': 16, | |
'⌥': 18, | |
'⌃': 17, | |
'⌘': 91, | |
'ctl': 17, | |
'control': 17, | |
'option': 18, | |
'pause': 19, | |
'break': 19, | |
'caps': 20, | |
'return': 13, | |
'escape': 27, | |
'spc': 32, | |
'pgup': 33, | |
'pgdn': 34, | |
'ins': 45, | |
'del': 46, | |
'cmd': 91 | |
} | |
/*! | |
* Programatically add the following | |
*/ | |
// lower case chars | |
for (i = 97; i < 123; i++) codes[String.fromCharCode(i)] = i - 32 | |
// numbers | |
for (var i = 48; i < 58; i++) codes[i - 48] = i | |
// function keys | |
for (i = 1; i < 13; i++) codes['f'+i] = i + 111 | |
// numpad keys | |
for (i = 0; i < 10; i++) codes['numpad '+i] = i + 96 | |
/** | |
* Get by code | |
* | |
* exports.name[13] // => 'Enter' | |
*/ | |
var names = exports.names = exports.title = {} // title for backward compat | |
// Create reverse mapping | |
for (i in codes) names[codes[i]] = i | |
// Add aliases | |
for (var alias in aliases) { | |
codes[alias] = aliases[alias] | |
} | |
/***/ }, | |
/* 57 */ | |
/***/ function(module, exports) { | |
module.exports = function (point, vs) { | |
// ray-casting algorithm based on | |
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html | |
var x = point[0], y = point[1]; | |
var inside = false; | |
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) { | |
var xi = vs[i][0], yi = vs[i][1]; | |
var xj = vs[j][0], yj = vs[j][1]; | |
var intersect = ((yi > y) != (yj > y)) | |
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi); | |
if (intersect) inside = !inside; | |
} | |
return inside; | |
}; | |
/***/ }, | |
/* 58 */ | |
/***/ function(module, exports, __webpack_require__) { | |
module.exports = { | |
'activeRegions': __webpack_require__(10), | |
'arc': __webpack_require__(11), | |
'arcTo': __webpack_require__(12), | |
'beginPath': __webpack_require__(2), | |
'bezierCurveTo': __webpack_require__(13), | |
'clearRect': __webpack_require__(14), | |
'clip': __webpack_require__(15), | |
'clipPath': __webpack_require__(16), | |
'closePath': __webpack_require__(3), | |
'createRegularPolygon': __webpack_require__(17), | |
'createWrapper': __webpack_require__(18), | |
'cycleMouseData': __webpack_require__(4), | |
'drawImage': __webpack_require__(19), | |
'ellipse': __webpack_require__(20), | |
'fill': __webpack_require__(21), | |
'fillArc': __webpack_require__(22), | |
'fillRect': __webpack_require__(23), | |
'fillStyle': __webpack_require__(24), | |
'fillText': __webpack_require__(25), | |
'globalAlpha': __webpack_require__(26), | |
'globalCompositeOperation': __webpack_require__(27), | |
'hitRect': __webpack_require__(28), | |
'hitRegion': __webpack_require__(29), | |
'imageSmoothingEnabled': __webpack_require__(30), | |
'initialize': __webpack_require__(31), | |
'Instruction': __webpack_require__(0), | |
'invertMatrix': __webpack_require__(5), | |
'keyData': __webpack_require__(32), | |
'lineStyle': __webpack_require__(33), | |
'lineTo': __webpack_require__(6), | |
'mouseData': __webpack_require__(34), | |
'moveTo': __webpack_require__(7), | |
'moveToLineTo': __webpack_require__(35), | |
'path': __webpack_require__(36), | |
'placeHolder': __webpack_require__(37), | |
'pointInRect': __webpack_require__(8), | |
'quadraticCurveTo': __webpack_require__(38), | |
'raf': __webpack_require__(39), | |
'rect': __webpack_require__(40), | |
'render': __webpack_require__(41), | |
'resetTransform': __webpack_require__(42), | |
'rotate': __webpack_require__(43), | |
'scale': __webpack_require__(44), | |
'setTransform': __webpack_require__(9), | |
'shadowStyle': __webpack_require__(45), | |
'skewX': __webpack_require__(46), | |
'skewY': __webpack_require__(47), | |
'stroke': __webpack_require__(48), | |
'strokeArc': __webpack_require__(49), | |
'strokeRect': __webpack_require__(50), | |
'strokeStyle': __webpack_require__(51), | |
'strokeText': __webpack_require__(52), | |
'textStyle': __webpack_require__(53), | |
'transform': __webpack_require__(54), | |
'transformPoints': __webpack_require__(1), | |
'translate': __webpack_require__(55) | |
}; | |
/***/ } | |
/******/ ]); | |
}); | |
},{}]},{},[]) | |
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImUyZCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcImUyZFwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJlMmRcIl0gPSBmYWN0b3J5KCk7XG59KSh0aGlzLCBmdW5jdGlvbigpIHtcbnJldHVybiAvKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwXG4vKioqKioqLyBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuLyoqKioqKi8gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuLyoqKioqKi8gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbi8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbi8qKioqKiovIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuXG4vKioqKioqLyBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbi8qKioqKiovIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4vKioqKioqLyBcdFx0XHRpOiBtb2R1bGVJZCxcbi8qKioqKiovIFx0XHRcdGw6IGZhbHNlLFxuLyoqKioqKi8gXHRcdFx0ZXhwb3J0czoge31cbi8qKioqKiovIFx0XHR9O1xuXG4vKioqKioqLyBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4vKioqKioqLyBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbi8qKioqKiovIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4vKioqKioqLyBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4vKioqKioqLyBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbi8qKioqKiovIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4vKioqKioqLyBcdH1cblxuXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuLyoqKioqKi8gXHQvLyBpZGVudGl0eSBmdW5jdGlvbiBmb3IgY2FsbGluZyBoYXJtb255IGltcG9ydHMgd2l0aCB0aGUgY29ycmVjdCBjb250ZXh0XG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uaSA9IGZ1bmN0aW9uKHZhbHVlKSB7IHJldHVybiB2YWx1ZTsgfTtcblxuLyoqKioqKi8gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4vKioqKioqLyBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuLyoqKioqKi8gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbi8qKioqKiovIFx0XHRcdFx0Y29uZmlndXJhYmxlOiBmYWxzZSxcbi8qKioqKiovIFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcbi8qKioqKiovIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbi8qKioqKiovIFx0XHRcdH0pO1xuLyoqKioqKi8gXHRcdH1cbi8qKioqKiovIFx0fTtcblxuLyoqKioqKi8gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbi8qKioqKiovIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbi8qKioqKiovIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4vKioqKioqLyBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuLyoqKioqKi8gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbi8qKioqKiovIFx0XHRyZXR1cm4gZ2V0dGVyO1xuLyoqKioqKi8gXHR9O1xuXG4vKioqKioqLyBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuLyoqKioqKi8gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbi8qKioqKiovIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gNTgpO1xuLyoqKioqKi8gfSlcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKioqKioqLyAoW1xuLyogMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmNsYXNzIEluc3RydWN0aW9uIHtcclxuICBjb25zdHJ1Y3Rvcih0eXBlLCBwcm9wcykge1xyXG4gICAgdGhpcy50eXBlID0gdHlwZTtcclxuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcclxuICAgIHJldHVybiBPYmplY3Quc2VhbCh0aGlzKTtcclxuICB9XHJcbn1cclxuXHJcbk9iamVjdC5zZWFsKEluc3RydWN0aW9uKTtcclxuT2JqZWN0LnNlYWwoSW5zdHJ1Y3Rpb24ucHJvdG90eXBlKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gSW5zdHJ1Y3Rpb247XHJcblxuXG4vKioqLyB9LFxuLyogMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmxldCB0cmFuc2Zvcm1Qb2ludHMgPSAocG9pbnRzLCBtYXRyaXgpID0+IHtcclxuICBsZXQgcmVzdWx0ID0gW10sXHJcbiAgICAgIHgsIHk7XHJcblxyXG4gIGZvcihsZXQgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcclxuICAgIFt4LCB5XSA9IHBvaW50c1tpXTtcclxuICAgIHJlc3VsdC5wdXNoKFtcclxuICAgICAgbWF0cml4WzBdICogeCArIG1hdHJpeFsyXSAqIHkgKyBtYXRyaXhbNF0sXHJcbiAgICAgIG1hdHJpeFsxXSAqIHggKyBtYXRyaXhbM10gKiB5ICsgbWF0cml4WzVdXHJcbiAgICBdKTtcclxuICB9XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdHJhbnNmb3JtUG9pbnRzO1xyXG5cblxuLyoqKi8gfSxcbi8qIDIgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApLFxyXG4gIGNhY2hlID0gbmV3IEluc3RydWN0aW9uKCdiZWdpblBhdGgnKTtcclxuXHJcbmxldCBiZWdpblBhdGggPSAoKSA9PiBjYWNoZTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gYmVnaW5QYXRoO1xuXG4vKioqLyB9LFxuLyogMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbignY2xvc2VQYXRoJyk7XHJcblxyXG5sZXQgY2xvc2VQYXRoID0gKCkgPT4gY2FjaGU7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsb3NlUGF0aDtcclxuXG5cbi8qKiovIH0sXG4vKiA0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuXHJcbmxldCBjeWNsZU1vdXNlRGF0YSA9IChjdHgpID0+IHtcclxuICBsZXQgbW91c2VEYXRhID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZURhdGEnKV07XHJcbiAgaWYgKG1vdXNlRGF0YSkge1xyXG4gICAgbW91c2VEYXRhLmR4ID0gbW91c2VEYXRhLnggLSBtb3VzZURhdGEucHJldmlvdXNYO1xyXG4gICAgbW91c2VEYXRhLmR5ID0gbW91c2VEYXRhLnkgLSBtb3VzZURhdGEucHJldmlvdXNZO1xyXG5cclxuICAgIG1vdXNlRGF0YS5wcmV2aW91c1ggPSBtb3VzZURhdGEueDtcclxuICAgIG1vdXNlRGF0YS5wcmV2aW91c1kgPSBtb3VzZURhdGEueTtcclxuXHJcbiAgICBtb3VzZURhdGEuY2xpY2tlZCA9IDA7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjeWNsZU1vdXNlRGF0YTtcblxuLyoqKi8gfSxcbi8qIDUgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5sZXQgZGV0ID0gMDtcclxubGV0IGludmVydE1hdHJpeCA9IChbYSwgYiwgYywgZCwgZSwgZl0pID0+IChcclxuICBkZXQgPSAxIC8gKGEgKiBkIC0gYyAqIGIpLFxyXG4gIFtcclxuICAgIGQgKiBkZXQsXHJcbiAgICAtYyAqIGRldCxcclxuICAgIC1iICogZGV0LFxyXG4gICAgYSAqIGRldCxcclxuICAgIChiICogZiAtIGUgKiBkKSAqIGRldCxcclxuICAgIChlICogYiAtIGEgKiBmKSAqIGRldFxyXG4gIF1cclxuKTtcclxuIG1vZHVsZS5leHBvcnRzID0gaW52ZXJ0TWF0cml4O1xuXG4vKioqLyB9LFxuLyogNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgbGluZVRvID0gKHgsIHkpID0+IG5ldyBJbnN0cnVjdGlvbignbGluZVRvJywgeyB4LCB5IH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBsaW5lVG87XHJcblxuXG4vKioqLyB9LFxuLyogNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgbW92ZVRvID0gKHgsIHkpID0+IG5ldyBJbnN0cnVjdGlvbignbW92ZVRvJywgeyB4LCB5IH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBtb3ZlVG87XHJcblxuXG4vKioqLyB9LFxuLyogOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmxldCBwb2ludEluUmVjdCA9IChbcHgsIHB5XSwgW1t4LCB5XSwgW3dpZHRoLCBoZWlnaHRdXSkgPT4gcHggPiB4ICYmIHB5ID4geSAmJiBweCA8IHdpZHRoICYmIHB5IDwgaGVpZ2h0O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwb2ludEluUmVjdDtcblxuLyoqKi8gfSxcbi8qIDkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5sZXQgZW5kID0gbmV3IEluc3RydWN0aW9uKCdyZXN0b3JlJyk7XHJcblxyXG5sZXQgc2V0VHJhbnNmb3JtID0gKG1hdHJpeCwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ3NldFRyYW5zZm9ybScsIFtcclxuICAgIG1hdHJpeFswXSxcclxuICAgIG1hdHJpeFsxXSxcclxuICAgIG1hdHJpeFsyXSxcclxuICAgIG1hdHJpeFszXSxcclxuICAgIG1hdHJpeFs0XSxcclxuICAgIG1hdHJpeFs1XVxyXG4gIF0pLFxyXG4gIGNoaWxkcmVuLFxyXG4gIGVuZFxyXG5dO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzZXRUcmFuc2Zvcm07XG5cbi8qKiovIH0sXG4vKiAxMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBwb2ludEluUG9seWdvbiA9IF9fd2VicGFja19yZXF1aXJlX18oNTcpO1xyXG5sZXQgdHJhbnNmb3JtUG9pbnRzID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKTtcclxubGV0IGludmVydE1hdHJpeCA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7XHJcbmxldCBwb2ludEluUmVjdCA9IF9fd2VicGFja19yZXF1aXJlX18oOCk7XHJcblxyXG5sZXQgbWF0cml4ID0gbmV3IEZsb2F0NjRBcnJheSg2KTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gKGN0eCkgPT4ge1xyXG4gIGxldCByZWdpb25zID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdyZWdpb25zJyldLFxyXG4gICAgbW91c2VQb2ludHMgPSBjdHguY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlUG9pbnRzJyldLFxyXG4gICAgbW91c2VEYXRhID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZURhdGEnKV0sXHJcbiAgICByZXN1bHRzID0ge307XHJcblxyXG4gIC8vdGhlIG1vdXNlIG1pZ2h0IGhhdmUgaGVsZCBzdGlsbCwgYWRkIHRoZSBjdXJyZW50IG1vdXNlIHBvc2l0aW9uXHJcbiAgaWYgKG1vdXNlUG9pbnRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgbW91c2VQb2ludHMucHVzaChbbW91c2VEYXRhLngsIG1vdXNlRGF0YS55LCBtb3VzZURhdGEuc3RhdGVdKTtcclxuICB9XHJcblxyXG4gIGZvcihsZXQgcmVnaW9uIG9mIHJlZ2lvbnMpIHtcclxuXHJcbiAgICAvL2ludmVydCB0aGUgcmVnaW9uIG1hdHJpeCBhbmQgdHJhbnNmb3JtIHRoZSBtb3VzZSBwb2ludHNcclxuICAgIGxldCB0cmFuc2Zvcm1lZE1vdXNlUG9pbnRzID0gdHJhbnNmb3JtUG9pbnRzKG1vdXNlUG9pbnRzLCBpbnZlcnRNYXRyaXgocmVnaW9uLm1hdHJpeCkpO1xyXG4gICAgLy90aGUgbW91c2UgcG9pbnRzIGFyZSBub3cgcmVsYXRpdmUgdG8gdGhlIG1vdXNlIHJlZ2lvblxyXG5cclxuICAgIGlmICghcmVnaW9uLnBvbHlnb24pIHtcclxuICAgICAgZm9yIChsZXQgbW91c2VQb2ludCBvZiB0cmFuc2Zvcm1lZE1vdXNlUG9pbnRzKSB7XHJcbiAgICAgICAgaWYgKHBvaW50SW5SZWN0KG1vdXNlUG9pbnQsIHJlZ2lvbi5wb2ludHMpKSB7XHJcbiAgICAgICAgICByZWdpb24uaG92ZXIgPSB0cnVlO1xyXG4gICAgICAgICAgcmVnaW9uLmNsaWNrZWQgPSAhIW1vdXNlRGF0YS5jbGlja2VkO1xyXG4gICAgICAgICAgcmVzdWx0c1tyZWdpb24uaWRdID0gcmVnaW9uO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vbG9vcCBvdmVyIGVhY2ggcG9pbnQgdW50aWwgb25lIGlzIG1hdGNoZWRcclxuICAgIGZvcihsZXQgbW91c2VQb2ludCBvZiB0cmFuc2Zvcm1lZE1vdXNlUG9pbnRzKSB7XHJcbiAgICAgIGlmIChwb2ludEluUG9seWdvbihtb3VzZVBvaW50LCByZWdpb24ucG9pbnRzKSkge1xyXG4gICAgICAgIHJlZ2lvbi5ob3ZlciA9IHRydWU7XHJcbiAgICAgICAgcmVnaW9uLmNsaWNrZWQgPSAhIW1vdXNlRGF0YS5jbGlja2VkO1xyXG4gICAgICAgIHJlc3VsdHNbcmVnaW9uLmlkXSA9IHJlZ2lvbjtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gcmVzdWx0cztcclxufTtcblxuLyoqKi8gfSxcbi8qIDExICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKSxcclxuICAgIHBpMiA9IE1hdGguUEkgKiAyO1xyXG5cclxubGV0IGFyYyA9ICguLi5hcmdzKSA9PiB7XHJcbiAgbGV0ICBbeCwgeSwgciwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGNvdW50ZXJjbG9ja3dpc2VdID0gYXJncztcclxuICBsZXQgcHJvcHMgPSB7IHg6IDAsIHk6IDAsIHI6IHgsIHN0YXJ0QW5nbGU6IDAsIGVuZEFuZ2xlOiBwaTIsIGNvdW50ZXJjbG9ja3dpc2U6IGZhbHNlIH07XHJcblxyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPiAzKSB7XHJcbiAgICBwcm9wcy5zdGFydEFuZ2xlID0gc3RhcnRBbmdsZTtcclxuICAgIHByb3BzLmVuZEFuZ2xlID0gZW5kQW5nbGU7XHJcbiAgICBwcm9wcy5jb3VudGVyY2xvY2t3aXNlID0gISFjb3VudGVyY2xvY2t3aXNlO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID4gMSl7XHJcbiAgICBwcm9wcy54ID0geDtcclxuICAgIHByb3BzLnkgPSB5O1xyXG4gICAgcHJvcHMuciA9IHI7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbmV3IEluc3RydWN0aW9uKFwiYXJjXCIsICBwcm9wcyk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGFyYztcclxuXG5cbi8qKiovIH0sXG4vKiAxMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgYXJjVG8gPSAoeDEsIHkxLCB4MiwgeTIsIHIpID0+IG5ldyBJbnN0cnVjdGlvbignYXJjVG8nLCB7IHgxLCB5MSwgeDIsIHkyLCByIH0pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBhcmNUbztcclxuXG5cbi8qKiovIH0sXG4vKiAxMyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgYmV6aWVyQ3VydmVUbyA9IChjcDF4LCBjcDF5LCBjcDJ4LCBjcDJ5LCB4LCB5KSA9PiBuZXcgSW5zdHJ1Y3Rpb24oJ2JlemllckN1cnZlVG8nLCB7XHJcbiAgY3AxeCxcclxuICBjcDF5LFxyXG4gIGNwMngsXHJcbiAgY3AyeSxcclxuICB4LFxyXG4gIHlcclxufSk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBiZXppZXJDdXJ2ZVRvO1xyXG5cblxuLyoqKi8gfSxcbi8qIDE0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBjbGVhclJlY3QgPSAoLi4uYXJncykgPT4gbmV3IEluc3RydWN0aW9uKCdjbGVhclJlY3QnLFxyXG4gIGFyZ3MubGVuZ3RoID4gMiA/XHJcbiAgICB7IHg6IGFyZ3NbMF0sIHk6IGFyZ3NbMV0sIHdpZHRoOiBhcmdzWzJdLCBoZWlnaHQ6IGFyZ3NbM10gfSA6XHJcbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiBhcmdzWzBdLCBoZWlnaHQ6IGFyZ3NbMV0gfVxyXG4pO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xlYXJSZWN0O1xyXG5cblxuLyoqKi8gfSxcbi8qIDE1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBiZWdpbiA9IG5ldyBJbnN0cnVjdGlvbignYmVnaW5DbGlwJyksXHJcbiAgcGVyZm9ybUNsaXAgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2NsaXAnKSxcclxuICBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZENsaXAnKTtcclxuXHJcbmxldCBjbGlwID0gKHBhdGgsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgYmVnaW4sXHJcbiAgcGF0aCxcclxuICBwZXJmb3JtQ2xpcCxcclxuICBjaGlsZHJlbixcclxuICBlbmRcclxuXTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xpcDtcclxuXG5cbi8qKiovIH0sXG4vKiAxNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbignY2xpcFBhdGgnKTtcclxuXHJcbmxldCBjbGlwUGF0aCA9ICgpID0+IGNhY2hlO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjbGlwUGF0aDtcclxuXG5cbi8qKiovIH0sXG4vKiAxNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbmxldCBjcmVhdGVSZWd1bGFyUG9seWdvbiA9IChyYWRpdXMgPSAwLCBwb3NpdGlvbiA9IFswLCAwXSwgc2lkZXMgPSAzKSA9PiB7XHJcbiAgbGV0IHBvbHlnb24gPSBbXTtcclxuICBmb3IobGV0IGkgPSAwOyBpIDwgc2lkZXM7IGkrKykge1xyXG4gICAgcG9seWdvbi5wdXNoKFtcclxuICAgICAgcG9zaXRpb25bMF0gKyByYWRpdXMgKiBNYXRoLmNvcyhNYXRoLlBJICogMiAqIGkgLyBzaWRlcyksXHJcbiAgICAgIHBvc2l0aW9uWzFdICsgcmFkaXVzICogTWF0aC5zaW4oTWF0aC5QSSAqIDIgKiBpIC8gc2lkZXMpXHJcbiAgICBdKTtcclxuICB9XHJcbiAgcmV0dXJuIHBvbHlnb247XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVJlZ3VsYXJQb2x5Z29uO1xyXG5cblxuLyoqKi8gfSxcbi8qIDE4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxubGV0IGNvbmNhdCA9IFtdLmNvbmNhdDtcclxuXHJcbmxldCBjcmVhdGVXcmFwcGVyID0gKC4uLmFyZ3MpID0+IHtcclxuICBmb3IobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xyXG4gICAgLy9wYXJzZSBhbmQgZmxhdHRlbiB0aGUgYXJndW1lbnRzXHJcbiAgICB3aGlsZSAoYXJnc1tpXSAmJiBhcmdzW2ldLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICBhcmdzID0gY29uY2F0LmFwcGx5KFtdLCBhcmdzKS5maWx0ZXIoQm9vbGVhbik7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFhcmdzW2ldKSB7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCB7IHR5cGUgfSA9IGFyZ3NbaV07XHJcbiAgICBpZiAodHlwZSA9PT0gJ3BsYWNlaG9sZGVyJykge1xyXG4gICAgICAvLyBpIGlzIHNldCB0byB0aGUgcGxhY2Vob2xkZXIgaW5kZXggbm93XHJcblxyXG4gICAgICAvL25vdyBncmFiIGFsbCB0aGUgZWxlbWVudHMgdG8gdGhlIGxlZnQgb2YgdGhlIHBsYWNlSG9sZGVyXHJcbiAgICAgIGxldCBsZWZ0ID0gYXJncy5zcGxpY2UoMCwgaSk7XHJcblxyXG4gICAgICAvL3JlbW92ZSB0aGUgcGxhY2VIb2xkZXIgZnJvbSB0aGUgYXJyYXlcclxuICAgICAgYXJncy5zaGlmdCgpO1xyXG5cclxuICAgICAgcmV0dXJuICguLi5jaGlsZHJlbikgPT4gW2xlZnQsIGNoaWxkcmVuLCBhcmdzXTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgcGxhY2Vob2xkZXIsIGRpZCB5b3UgZm9yZ2V0IHRoZSBlMmQucGxhY2VIb2xkZXIoKSBjYWxsPycpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjb25jYXQ7XHJcblxuXG4vKioqLyB9LFxuLyogMTkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5cclxubGV0IGRyYXdJbWFnZSA9ICguLi5hcmdzKSA9PiB7XHJcbiAgbGV0IFtpbWcsIHN4LCBzeSwgc1dpZHRoLCBzSGVpZ2h0LCBkeCwgZHksIGRXaWR0aCwgZEhlaWdodF0gPSBhcmdzO1xyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPT09IDkpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNvdXJjZScsIHtcclxuICAgICAgaW1nLFxyXG4gICAgICBzeCxcclxuICAgICAgc3ksXHJcbiAgICAgIHNXaWR0aCxcclxuICAgICAgc0hlaWdodCxcclxuICAgICAgZHgsXHJcbiAgICAgIGR5LFxyXG4gICAgICBkV2lkdGgsXHJcbiAgICAgIGRIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID49IDUpIHtcclxuICAgIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2RyYXdJbWFnZVNpemUnLCB7XHJcbiAgICAgIGltZyxcclxuICAgICAgZHg6IHN4LFxyXG4gICAgICBkeTogc3ksXHJcbiAgICAgIGRXaWR0aDogc1dpZHRoLFxyXG4gICAgICBkSGVpZ2h0OiBzSGVpZ2h0XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA+PSAzKSB7XHJcbiAgICByZXR1cm4gbmV3IEluc3RydWN0aW9uKCdkcmF3SW1hZ2UnLCB7XHJcbiAgICAgIGltZyxcclxuICAgICAgZHg6IHN4LFxyXG4gICAgICBkeTogc3lcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignZHJhd0ltYWdlJywge1xyXG4gICAgaW1nLFxyXG4gICAgZHg6IDAsXHJcbiAgICBkeTogMFxyXG4gIH0pO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBkcmF3SW1hZ2U7XHJcblxuXG4vKioqLyB9LFxuLyogMjAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApLFxyXG4gICAgcGkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5sZXQgZWxsaXBzZSA9ICguLi5hcmdzKSA9PiB7XHJcbiAgbGV0IFt4LCB5LCByYWRpdXNYLCByYWRpdXNZLCByb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGFudGljbG9ja3dpc2VdID0gYXJncztcclxuXHJcbiAgbGV0IHByb3BzID0geyB4OiAwLCB5OiAwLCByYWRpdXNYOiB4LCByYWRpdXNZOiB5LCByb3RhdGlvbjogMCwgc3RhcnRBbmdsZTogMCwgZW5kQW5nbGU6IHBpMiwgYW50aWNsb2Nrd2lzZTogZmFsc2UgfTtcclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID4gNSkge1xyXG4gICAgcHJvcHMuc3RhcnRBbmdsZSA9IHN0YXJ0QW5nbGU7XHJcbiAgICBwcm9wcy5lbmRBbmdsZSA9IGVuZEFuZ2xlO1xyXG4gICAgcHJvcHMuYW50aWNsb2Nrd2lzZSA9ICEhYW50aWNsb2Nrd2lzZTtcclxuICB9XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA+IDQpIHtcclxuICAgIHByb3BzLnJvdGF0aW9uID0gcm90YXRpb247XHJcbiAgfVxyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPiAyKXtcclxuICAgIHByb3BzLnggPSB4O1xyXG4gICAgcHJvcHMueSA9IHk7XHJcbiAgICBwcm9wcy5yYWRpdXNYID0gcmFkaXVzWDtcclxuICAgIHByb3BzLnJhZGl1c1kgPSByYWRpdXNZO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcImVsbGlwc2VcIiwgIHByb3BzKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZWxsaXBzZTtcclxuXG5cbi8qKiovIH0sXG4vKiAyMSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbignZmlsbCcpO1xyXG5cclxubGV0IGZpbGwgPSAoKSA9PiBjYWNoZTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbDtcclxuXG5cbi8qKiovIH0sXG4vKiAyMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblxyXG5cclxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKSxcclxuICAgIHBpMiA9IE1hdGguUEkgKiAyO1xyXG5cclxubGV0IGZpbGxBcmMgPSAoLi4uYXJncykgPT4ge1xyXG4gIGxldCBbeCwgeSwgciwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGNvdW50ZXJjbG9ja3dpc2VdID0gYXJncztcclxuICBsZXQgcHJvcHMgPSB7IHg6IDAsIHk6IDAsIHI6IHgsIHN0YXJ0QW5nbGU6IDAsIGVuZEFuZ2xlOiBwaTIsIGNvdW50ZXJjbG9ja3dpc2U6IGZhbHNlIH07XHJcblxyXG5cclxuICBpZiAoYXJncy5sZW5ndGggPiAzKSB7XHJcbiAgICBwcm9wcy5zdGFydEFuZ2xlID0gc3RhcnRBbmdsZTtcclxuICAgIHByb3BzLmVuZEFuZ2xlID0gZW5kQW5nbGU7XHJcbiAgICBwcm9wcy5jb3VudGVyY2xvY2t3aXNlID0gISFjb3VudGVyY2xvY2t3aXNlO1xyXG4gIH1cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID49IDIpIHtcclxuICAgIHByb3BzLnggPSB4O1xyXG4gICAgcHJvcHMueSA9IHk7XHJcbiAgICBwcm9wcy5yID0gcjtcclxuICB9XHJcblxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oXCJmaWxsQXJjXCIsICBwcm9wcyk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZpbGxBcmM7XHJcblxuXG4vKioqLyB9LFxuLyogMjMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5cclxubGV0IGZpbGxSZWN0ID0gKC4uLmFyZ3MpID0+IG5ldyBJbnN0cnVjdGlvbignZmlsbFJlY3QnLFxyXG4gIGFyZ3MubGVuZ3RoID4gMiA/XHJcbiAgICB7IHg6IGFyZ3NbMF0sIHk6IGFyZ3NbMV0sIHdpZHRoOiBhcmdzWzJdLCBoZWlnaHQ6IGFyZ3NbM10gfSA6XHJcbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiBhcmdzWzBdLCBoZWlnaHQ6IGFyZ3NbMV0gfVxyXG4pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmaWxsUmVjdDtcclxuXG5cbi8qKiovIH0sXG4vKiAyNCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEZpbGxTdHlsZScpO1xyXG5cclxubGV0IGZpbGxTdHlsZSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignZmlsbFN0eWxlJywgeyB2YWx1ZSB9KSxcclxuICAgIGNoaWxkcmVuLFxyXG4gICAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZpbGxTdHlsZTtcclxuXG5cbi8qKiovIH0sXG4vKiAyNSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgZmlsbFRleHQgPSAoLi4uYXJncykgPT4ge1xyXG4gIGxldCBbdGV4dCwgeCwgeSwgbWF4V2lkdGhdID0gYXJncztcclxuICBpZiAoYXJncy5sZW5ndGggPCA0KSB7XHJcbiAgICBtYXhXaWR0aCA9IG51bGw7XHJcbiAgfVxyXG4gIGlmIChhcmdzLmxlbmd0aCA8IDMpIHtcclxuICAgIHggPSAwO1xyXG4gICAgeSA9IDA7XHJcbiAgfVxyXG4gIHJldHVybiBuZXcgSW5zdHJ1Y3Rpb24oJ2ZpbGxUZXh0JywgeyB0ZXh0LCB4LCB5LCBtYXhXaWR0aCB9KTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsbFRleHQ7XG5cbi8qKiovIH0sXG4vKiAyNiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblxyXG5cclxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbignZW5kR2xvYmFsQWxwaGEnKTtcclxuXHJcbmxldCBnbG9iYWxBbHBoYSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ2dsb2JhbEFscGhhJywgeyB2YWx1ZSB9KSxcclxuICBjaGlsZHJlbixcclxuICBlbmRcclxuXTtcclxubW9kdWxlLmV4cG9ydHMgPSBnbG9iYWxBbHBoYTtcclxuXG5cbi8qKiovIH0sXG4vKiAyNyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblxyXG5cclxudmFyIEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbicpO1xyXG5cclxubGV0IGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ2dsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbicsIHsgdmFsdWUgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbjtcclxuXG5cbi8qKiovIH0sXG4vKiAyOCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgaGl0UmVjdCA9IChpZCwgLi4uYXJncykgPT4ge1xyXG4gIGxldCBbeCwgeSwgd2lkdGgsIGhlaWdodF0gPSBhcmdzO1xyXG4gIGlmIChhcmdzLmxlbmd0aCA8PSAzKSB7XHJcbiAgICB3aWR0aCA9IHg7XHJcbiAgICBoZWlnaHQgPSB5O1xyXG4gICAgeCA9IDA7XHJcbiAgICB5ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignaGl0UmVjdCcsIHtcclxuICAgIGlkLFxyXG4gICAgcG9pbnRzOiBbXHJcbiAgICAgIFt4LCB5XSxcclxuICAgICAgW3ggKyB3aWR0aCwgeSArIGhlaWdodF1cclxuICAgIF1cclxuICB9KTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gaGl0UmVjdDtcblxuLyoqKi8gfSxcbi8qIDI5ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBoaXRSZWdpb24gPSAoaWQsIHBvaW50cykgPT4gbmV3IEluc3RydWN0aW9uKCdoaXRSZWdpb24nLCB7IGlkLCBwb2ludHMgfSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGhpdFJlZ2lvbjtcclxuXG5cbi8qKiovIH0sXG4vKiAzMCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZEltYWdlU21vb3RoaW5nRW5hYmxlZCcpO1xyXG5cclxubGV0IGltYWdlU21vb3RoaW5nRW5hYmxlZCA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ2ltYWdlU21vb3RoaW5nRW5hYmxlZCcsIHsgdmFsdWUgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcbm1vZHVsZS5leHBvcnRzID0gaW1hZ2VTbW9vdGhpbmdFbmFibGVkO1xyXG5cblxuLyoqKi8gfSxcbi8qIDMxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IGtleWNvZGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDU2KTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gKGN0eCkgPT4ge1xyXG4gIGxldCB7IGNhbnZhcyB9ID0gY3R4O1xyXG5cclxuICAvL21vdXNlRGF0YVxyXG4gIGNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZURhdGEnKV0gPSB7XHJcbiAgICB4OiAwLFxyXG4gICAgeTogMCxcclxuICAgIGR4OiAwLFxyXG4gICAgZHk6IDAsXHJcbiAgICBwcmV2aW91c1g6IDAsXHJcbiAgICBwcmV2aW91c1k6IDAsXHJcbiAgICBzdGF0ZTogZmFsc2UsXHJcbiAgICBjbGlja2VkOiAwXHJcbiAgfTtcclxuXHJcbiAgbGV0IGtleXMgPSBjYW52YXNbU3ltYm9sLmZvcigna2V5RGF0YScpXSA9IHt9O1xyXG5cclxuICBmb3IgKGxldCBuYW1lIGluIGtleWNvZGUuY29kZSkge1xyXG4gICAgaWYgKGtleWNvZGUuY29kZS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xyXG4gICAgICBrZXlzW25hbWVdID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvL21vdXNlIHJlZ2lvbnNcclxuICBjYW52YXNbU3ltYm9sLmZvcigncmVnaW9ucycpXSA9IFtdO1xyXG4gIGNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZVBvaW50cycpXSA9IFtdO1xyXG5cclxuICAvL21ha2UgdGhlIGNhbnZhcyByZWNlaXZlIHRvdWNoIGFuZCBtb3VzZSBldmVudHNcclxuICBjYW52YXMudGFiSW5kZXggPSAxO1xyXG5cclxuICBsZXQgbW91c2VNb3ZlID0gKGV2dCkgPT4ge1xyXG4gICAgbGV0IHsgY2xpZW50WCwgY2xpZW50WSB9ID0gZXZ0O1xyXG4gICAgLy9nZXQgbGVmdCBhbmQgdG9wIGNvb3JkaW5hdGVzXHJcbiAgICBsZXQgeyBsZWZ0LCB0b3AgfSA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICBsZXQgbW91c2VEYXRhID0gY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlRGF0YScpXTtcclxuXHJcbiAgICBsZXQgcG9pbnQgPSBbY2xpZW50WCAtIGxlZnQsIGNsaWVudFkgLSB0b3AsIG1vdXNlRGF0YS5zdGF0ZV07XHJcblxyXG4gICAgbW91c2VEYXRhLnggPSBwb2ludFswXTtcclxuICAgIG1vdXNlRGF0YS55ID0gcG9pbnRbMV07XHJcblxyXG4gICAgbGV0IHBvaW50cyA9IGNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZVBvaW50cycpXTtcclxuXHJcbiAgICBwb2ludHMucHVzaChwb2ludCk7XHJcblxyXG4gICAgLy9zdG9yZSB0aGUgbGFzdCAxMDAgc3RvcmVkIHBvc2l0aW9ucyBmb3IgaG92ZXIgZGV0ZWN0aW9uXHJcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA+IDEwMCkge1xyXG4gICAgICBwb2ludHMuc3BsaWNlKDAsIHBvaW50cy5sZW5ndGggLSAxMDApO1xyXG4gICAgfVxyXG5cclxuICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH07XHJcblxyXG4gIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCAoZXZ0KSA9PiBtb3VzZU1vdmUoZXZ0KSk7XHJcbiAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChldnQpID0+IHtcclxuICAgIGxldCB7IHRhcmdldCB9ID0gZXZ0O1xyXG4gICAgaWYgKHRhcmdldCA9PT0gY2FudmFzKSB7XHJcbiAgICAgIGxldCBtb3VzZURhdGEgPSBjYW52YXNbU3ltYm9sLmZvcignbW91c2VEYXRhJyldO1xyXG5cclxuICAgICAgaWYgKCFtb3VzZURhdGEuc3RhdGUpIHtcclxuICAgICAgICBtb3VzZURhdGEuY2xpY2tlZCArPSAxO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBtb3VzZURhdGEuc3RhdGUgPSB0cnVlO1xyXG4gICAgICByZXR1cm4gbW91c2VNb3ZlKGV2dCk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoZXZ0KSA9PiB7XHJcbiAgICBsZXQgbW91c2VEYXRhID0gY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlRGF0YScpXTtcclxuICAgIG1vdXNlRGF0YS5zdGF0ZSA9IGZhbHNlO1xyXG4gICAgcmV0dXJuIG1vdXNlTW92ZShldnQpO1xyXG4gIH0pO1xyXG4gIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGV2dCkgPT4ge1xyXG4gICAgY2FudmFzW1N5bWJvbC5mb3IoJ2tleURhdGEnKV1ba2V5Y29kZShldnQua2V5Q29kZSldID0gdHJ1ZTtcclxuICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH0pO1xyXG4gIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdrZXl1cCcsIChldnQpID0+IHtcclxuICAgIGNhbnZhc1tTeW1ib2wuZm9yKCdrZXlEYXRhJyldW2tleWNvZGUoZXZ0LmtleUNvZGUpXSA9IGZhbHNlO1xyXG4gICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfSk7XHJcbn07XG5cbi8qKiovIH0sXG4vKiAzMiAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7XG5cbm1vZHVsZS5leHBvcnRzID0gKGN0eCkgPT4gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdrZXlEYXRhJyldO1xuXG4vKioqLyB9LFxuLyogMzMgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5sZXQgZW5kID0gbmV3IEluc3RydWN0aW9uKCdlbmRMaW5lU3R5bGUnKTtcclxuXHJcbmxldCBsaW5lU3R5bGUgPSAodmFsdWUsIC4uLmNoaWxkcmVuKSA9PiB7XHJcblxyXG4gIHZhbHVlID0gdmFsdWUgfHwge307XHJcbiAgdmFyIHJlc3VsdCA9IHtcclxuICAgIGxpbmVXaWR0aDogbnVsbCxcclxuICAgIGxpbmVDYXA6IG51bGwsXHJcbiAgICBsaW5lSm9pbjogbnVsbCxcclxuICAgIG1pdGVyTGltaXQ6IG51bGwsXHJcbiAgICBsaW5lRGFzaDogbnVsbCxcclxuICAgIGxpbmVEYXNoT2Zmc2V0OiBudWxsXHJcbiAgfTtcclxuXHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5saW5lV2lkdGggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZVdpZHRoID0gdmFsdWUubGluZVdpZHRoO1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLmxpbmVDYXAgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZUNhcCA9IHZhbHVlLmxpbmVDYXA7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZUpvaW4gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZUpvaW4gPSB2YWx1ZS5saW5lSm9pbjtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5taXRlckxpbWl0ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0Lm1pdGVyTGltaXQgPSB2YWx1ZS5taXRlckxpbWl0O1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLmxpbmVEYXNoICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LmxpbmVEYXNoID0gdmFsdWUubGluZURhc2ggfHwgW107XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUubGluZURhc2hPZmZzZXQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQubGluZURhc2hPZmZzZXQgPSB2YWx1ZS5saW5lRGFzaE9mZnNldDtcclxuICB9XHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignbGluZVN0eWxlJywgcmVzdWx0KSxcclxuICAgIGNoaWxkcmVuLFxyXG4gICAgZW5kXHJcbiAgXTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbGluZVN0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxubW9kdWxlLmV4cG9ydHMgPSAoY3R4KSA9PiBjdHguY2FudmFzW1N5bWJvbC5mb3IoJ21vdXNlRGF0YScpXTtcblxuLyoqKi8gfSxcbi8qIDM1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IG1vdmVUbyA9IF9fd2VicGFja19yZXF1aXJlX18oNyksIGxpbmVUbyA9IF9fd2VicGFja19yZXF1aXJlX18oNik7XHJcblxyXG5sZXQgbW92ZVRvTGluZVRvID0gKHBvaW50LCBpbmRleCkgPT4gaW5kZXggPT09IDAgP1xyXG4gIG1vdmVUbyhwb2ludFswXSwgcG9pbnRbMV0pIDpcclxuICBsaW5lVG8ocG9pbnRbMF0sIHBvaW50WzFdKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbW92ZVRvTGluZVRvO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IGJlZ2luUGF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oMikoKSxcclxuICAgIGNsb3NlUGF0aCA9IF9fd2VicGFja19yZXF1aXJlX18oMykoKTtcclxuXHJcbmxldCBwYXRoID0gKC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgYmVnaW5QYXRoLFxyXG4gIGNoaWxkcmVuLFxyXG4gIGNsb3NlUGF0aFxyXG5dO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwYXRoO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBjYWNoZSA9IG5ldyBJbnN0cnVjdGlvbigncGxhY2Vob2xkZXInKTtcclxubGV0IHBsYWNlSG9sZGVyID0gKCkgPT4gY2FjaGU7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHBsYWNlSG9sZGVyO1xyXG5cblxuLyoqKi8gfSxcbi8qIDM4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBxdWFkcmF0aWNDdXJ2ZVRvID0gKGNweCwgY3B5LCB4LCB5KSA9PiBuZXcgSW5zdHJ1Y3Rpb24oJ3F1YWRyYXRpY0N1cnZlVG8nLCB7XHJcbiAgY3B4LFxyXG4gIGNweSxcclxuICB4LFxyXG4gIHlcclxufSk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHF1YWRyYXRpY0N1cnZlVG87XHJcblxuXG4vKioqLyB9LFxuLyogMzkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5sZXQgcmFmID0gKGZ1bmMpID0+IHtcclxuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gcmFmKGZ1bmMpKTtcclxuICByZXR1cm4gZnVuYygpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByYWY7XG5cbi8qKiovIH0sXG4vKiA0MCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcblxyXG5sZXQgcmVjdCA9ICguLi5hcmdzKSA9PiBuZXcgSW5zdHJ1Y3Rpb24oJ3JlY3QnLFxyXG4gIGFyZ3MubGVuZ3RoID4gMiA/XHJcbiAgICB7IHg6IGFyZ3NbMF0sIHk6IGFyZ3NbMV0sIHdpZHRoOiBhcmdzWzJdLCBoZWlnaHQ6IGFyZ3NbM10gfSA6XHJcbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiBhcmdzWzBdLCBoZWlnaHQ6IGFyZ3NbMV0gfVxyXG4pO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSByZWN0O1xyXG5cblxuLyoqKi8gfSxcbi8qIDQxICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxuXHJcbi8vaW5pdGlhbGl6ZSBhbGwgdGhlIHByb3BlcnRpZXNcclxuXHJcbmxldCBpZGVudGl0eSA9IFsxLCAwLCAwLCAxLCAwLCAwXSxcclxuICBtYXRyaXggPSBuZXcgRmxvYXQ2NEFycmF5KGlkZW50aXR5KSxcclxuICBmaWxsU3R5bGVTdGFjayA9IFtdLFxyXG4gIHN0cm9rZVN0eWxlU3RhY2sgPSBbXSxcclxuICBsaW5lU3R5bGVTdGFjayA9IFtdLFxyXG4gIHRleHRTdHlsZVN0YWNrID0gW10sXHJcbiAgc2hhZG93U3R5bGVTdGFjayA9IFtdLFxyXG4gIGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblN0YWNrID0gW10sXHJcbiAgZ2xvYmFsQWxwaGFTdGFjayA9IFtdLFxyXG4gIGltYWdlU21vb3RoaW5nRW5hYmxlZFN0YWNrID0gW10sXHJcbiAgdHJhbnNmb3JtU3RhY2sgPSBuZXcgRmxvYXQ2NEFycmF5KDUwMSAqIDYpLFxyXG4gIHRyYW5zZm9ybVN0YWNrSW5kZXggPSA2LFxyXG4gIGNvbmNhdCA9IFtdLmNvbmNhdCxcclxuICBzdXBwb3J0c0VsbGlwc2UgPSBmYWxzZTtcclxuXHJcbmlmICh0eXBlb2YgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEICE9PSAndW5kZWZpbmVkJykge1xyXG4gIHN1cHBvcnRzRWxsaXBzZSA9IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkoJ2VsbGlwc2UnKTtcclxufVxyXG5cclxuLy90cmFuc2Zvcm0gcG9pbnRzIGZ1bmN0aW9uXHJcbmNvbnN0IHRyYW5zZm9ybVBvaW50cyA9IF9fd2VicGFja19yZXF1aXJlX18oMSk7XHJcbmNvbnN0IGN5Y2xlTW91c2VEYXRhID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcclxuXHJcbmNvbnN0IGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplID0gKCkgPT4ge1xyXG4gIGxldCBjYWNoZSA9IHRyYW5zZm9ybVN0YWNrO1xyXG4gIHRyYW5zZm9ybVN0YWNrID0gbmV3IEZsb2F0NjRBcnJheSh0cmFuc2Zvcm1TdGFjay5sZW5ndGggKyA2MDApOyAvL2FkZCAxMDAgbW9yZVxyXG4gIHRyYW5zZm9ybVN0YWNrLnNldChjYWNoZSk7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG50cmFuc2Zvcm1TdGFjay5zZXQoaWRlbnRpdHkpO1xyXG5cclxuY29uc3QgUEkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5sZXQgZW1wdHkgPSAodGFyZ2V0KSA9PiB0YXJnZXQgJiYgdGFyZ2V0LnNwbGljZSgwLCB0YXJnZXQubGVuZ3RoKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gKC4uLmFyZ3MpID0+IHtcclxuICBsZXQgY2hpbGRyZW4gPSBhcmdzLnNsaWNlKDAsIC0xKSxcclxuICAgY3R4ID0gYXJnc1thcmdzLmxlbmd0aCAtIDFdO1xyXG5cclxuICBsZXQgcmVnaW9ucyA9IGN0eC5jYW52YXNbU3ltYm9sLmZvcigncmVnaW9ucycpXSxcclxuICAgIG1vdXNlUG9pbnRzID0gY3R4LmNhbnZhc1tTeW1ib2wuZm9yKCdtb3VzZVBvaW50cycpXSxcclxuICAgIGV4dGVuc2lvbnMgPSBjdHguY2FudmFzW1N5bWJvbC5mb3IoJ2V4dGVuc2lvbnMnKV07XHJcblxyXG4gIGxldCBjYWNoZTtcclxuXHJcbiAgY3ljbGVNb3VzZURhdGEoY3R4KTtcclxuXHJcbiAgZW1wdHkocmVnaW9ucyk7XHJcbiAgZW1wdHkobW91c2VQb2ludHMpO1xyXG5cclxuICBsZXQgbGVuID0gY2hpbGRyZW4ubGVuZ3RoO1xyXG5cclxuICAvL2ZsYXR0ZW4gY2hpbGRyZW4gZHVyaW5nIHRoZSBsb29wIHByb2Nlc3MgdG8gc2F2ZSBjcHVcclxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICBsZXQgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuXHJcbiAgICAvL2ZsYXR0ZW5pbmcgYWxnb3JpdGhtXHJcbiAgICBpZiAoY2hpbGQgJiYgY2hpbGQuY29uc3RydWN0b3IgPT09IEFycmF5KSB7XHJcbiAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgIGNoaWxkID0gY2hpbGRyZW5baV07XHJcblxyXG4gICAgICAvL3JlcGVhdCBhcyBuZWNlc3NhcnlcclxuICAgICAgd2hpbGUgKGNoaWxkICYmIGNoaWxkLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xyXG4gICAgICAgIGNoaWxkcmVuID0gY29uY2F0LmFwcGx5KFtdLCBjaGlsZHJlbik7XHJcbiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgbGVuID0gY2hpbGRyZW4ubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIC8vY2hpbGQgbXVzdCBiZSB0cnV0aHlcclxuICAgIGlmICghY2hpbGQpIHtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHsgcHJvcHMsIHR5cGUgfSA9IGNoaWxkO1xyXG5cclxuICAgIGlmICh0eXBlID09PSAndHJhbnNmb3JtJykge1xyXG5cclxuICAgICAgLy9jb3B5IHRyYW5zZm9ybVN0YWNrIHZhbHVlcyB0byBtYXRyaXhcclxuICAgICAgbWF0cml4WzBdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcbiAgICAgIC8vaW5jcmVhc2UgdGhlIGluZGV4XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvL3BlcmZvcm0gdGhlIHRyYW5zZm9ybSBtYXRoXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IC8vZFxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzBdICsgbWF0cml4WzJdICogcHJvcHNbMV07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IC8vYlxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzBdICsgbWF0cml4WzNdICogcHJvcHNbMV07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IC8vY1xyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzJdICsgbWF0cml4WzJdICogcHJvcHNbM107XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IC8vZFxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzJdICsgbWF0cml4WzNdICogcHJvcHNbM107XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IC8vZVxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzWzRdICsgbWF0cml4WzJdICogcHJvcHNbNV0gKyBtYXRyaXhbNF07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IC8vZlxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzWzRdICsgbWF0cml4WzNdICogcHJvcHNbNV0gKyBtYXRyaXhbNV07XHJcblxyXG4gICAgICAvL21vZGlmeSB0aGUgY3R4XHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMV1cclxuICAgICAgKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzZXRUcmFuc2Zvcm0nKSB7XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPSBwcm9wc1swXTsvL2FcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdID0gcHJvcHNbMV07Ly9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IHByb3BzWzJdOy8vY1xyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10gPSBwcm9wc1szXTsvL2RcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdID0gcHJvcHNbNF07Ly9lXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IHByb3BzWzVdOy8vZlxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKHByb3BzWzBdLCBwcm9wc1sxXSwgcHJvcHNbMl0sIHByb3BzWzNdLCBwcm9wc1s0XSwgcHJvcHNbNV0pO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzY2FsZScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPSBtYXRyaXhbMF0gKiBwcm9wcy54OyAvL2FcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdID0gbWF0cml4WzFdICogcHJvcHMueDsgLy9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IG1hdHJpeFsyXSAqIHByb3BzLnk7IC8vY1xyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10gPSBtYXRyaXhbM10gKiBwcm9wcy55OyAvL2RcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdID0gbWF0cml4WzRdOyAvL2VcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdOyAvL2ZcclxuXHJcbiAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNF0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMV1cclxuICAgICAgKTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAndHJhbnNsYXRlJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodHJhbnNmb3JtU3RhY2tJbmRleCA+IHRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IG1hdHJpeFswXTsgLy9hXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IG1hdHJpeFsxXTsgLy9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IG1hdHJpeFsyXTsgLy9jXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IG1hdHJpeFszXTsgLy9kXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XSArIG1hdHJpeFswXSAqIHByb3BzLnggKyBtYXRyaXhbMl0gKiBwcm9wcy55OyAvL2VcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdICsgbWF0cml4WzFdICogcHJvcHMueCArIG1hdHJpeFszXSAqIHByb3BzLnk7IC8vZlxyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3JvdGF0ZScpIHtcclxuICAgICAgbWF0cml4WzBdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDZdO1xyXG4gICAgICBtYXRyaXhbMV0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV07XHJcbiAgICAgIG1hdHJpeFsyXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XTtcclxuICAgICAgbWF0cml4WzNdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdO1xyXG4gICAgICBtYXRyaXhbNF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl07XHJcbiAgICAgIG1hdHJpeFs1XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXTtcclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrSW5kZXggKz0gNjtcclxuICAgICAgaWYgKHRyYW5zZm9ybVN0YWNrSW5kZXggPiB0cmFuc2Zvcm1TdGFjay5sZW5ndGgpIHtcclxuICAgICAgICBpbmNyZWFzZVRyYW5zZm9ybVN0YWNrU2l6ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0gPVxyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzLmNvcyArIG1hdHJpeFsyXSAqIHByb3BzLnNpbjsgLy9hXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9XHJcbiAgICAgICAgbWF0cml4WzFdICogcHJvcHMuY29zICsgbWF0cml4WzNdICogcHJvcHMuc2luOyAvL2JcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID1cclxuICAgICAgICBtYXRyaXhbMF0gKiAtcHJvcHMuc2luICsgbWF0cml4WzJdICogcHJvcHMuY29zOyAvL2NcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID1cclxuICAgICAgICBtYXRyaXhbMV0gKiAtcHJvcHMuc2luICsgbWF0cml4WzNdICogcHJvcHMuY29zOyAvL2RcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdID0gbWF0cml4WzRdOyAvL2VcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdID0gbWF0cml4WzVdOy8vZlxyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3NrZXdYJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodHJhbnNmb3JtU3RhY2tJbmRleCA+IHRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9IG1hdHJpeFswXTsgLy9hXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XSA9IG1hdHJpeFsxXTsgLy9iXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSA9IC8vY1xyXG4gICAgICAgIG1hdHJpeFswXSAqIHByb3BzLnggKyBtYXRyaXhbMl07XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSA9IC8vZFxyXG4gICAgICAgIG1hdHJpeFsxXSAqIHByb3BzLnggKyBtYXRyaXhbM107XHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XTsgLy9lXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IG1hdHJpeFs1XTsgLy9mXHJcblxyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICApO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3NrZXdZJykge1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCArPSA2O1xyXG4gICAgICBpZiAodHJhbnNmb3JtU3RhY2tJbmRleCA+IHRyYW5zZm9ybVN0YWNrLmxlbmd0aCkge1xyXG4gICAgICAgIGluY3JlYXNlVHJhbnNmb3JtU3RhY2tTaXplKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSA9XHJcbiAgICAgICAgbWF0cml4WzBdICogMSArIG1hdHJpeFsyXSAqIHByb3BzLnk7IC8vYVxyXG4gICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0gPVxyXG4gICAgICAgIG1hdHJpeFsxXSAqIDEgKyBtYXRyaXhbM10gKiBwcm9wcy55OyAvL2JcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdID0gbWF0cml4WzJdOyAvL2NcclxuICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDNdID0gbWF0cml4WzNdOyAvL2RcclxuXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXSA9IG1hdHJpeFs0XTsgLy9lXHJcbiAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXSA9IG1hdHJpeFs1XTsgLy9mXHJcblxyXG4gICAgICBjdHguc2V0VHJhbnNmb3JtKFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAncmVzdG9yZScpIHtcclxuICAgICAgdHJhbnNmb3JtU3RhY2tJbmRleCAtPSA2O1xyXG4gICAgICBtYXRyaXhbMF0gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl07XHJcbiAgICAgIG1hdHJpeFsxXSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA1XTtcclxuICAgICAgbWF0cml4WzJdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdO1xyXG4gICAgICBtYXRyaXhbM10gPSB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM107XHJcbiAgICAgIG1hdHJpeFs0XSA9IHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAyXTtcclxuICAgICAgbWF0cml4WzVdID0gdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdO1xyXG5cclxuICAgICAgY3R4LnNldFRyYW5zZm9ybShtYXRyaXhbMF0sIG1hdHJpeFsxXSwgbWF0cml4WzJdLCBtYXRyaXhbM10sIG1hdHJpeFs0XSwgbWF0cml4WzVdKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsUmVjdCcpIHtcclxuICAgICAgY3R4LmZpbGxSZWN0KHByb3BzLngsIHByb3BzLnksIHByb3BzLndpZHRoLCBwcm9wcy5oZWlnaHQpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZVJlY3QnKSB7XHJcbiAgICAgIGN0eC5zdHJva2VSZWN0KHByb3BzLngsIHByb3BzLnksIHByb3BzLndpZHRoLCBwcm9wcy5oZWlnaHQpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsZWFyUmVjdCcpIHtcclxuICAgICAgY3R4LmNsZWFyUmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdyZWN0Jykge1xyXG4gICAgICBjdHgucmVjdChwcm9wcy54LCBwcm9wcy55LCBwcm9wcy53aWR0aCwgcHJvcHMuaGVpZ2h0KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsU3R5bGUnKSB7XHJcbiAgICAgIGZpbGxTdHlsZVN0YWNrLnB1c2goY3R4LmZpbGxTdHlsZSk7XHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBwcm9wcy52YWx1ZTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzdHJva2VTdHlsZScpIHtcclxuICAgICAgc3Ryb2tlU3R5bGVTdGFjay5wdXNoKGN0eC5zdHJva2VTdHlsZSk7XHJcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IHByb3BzLnZhbHVlO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZEZpbGxTdHlsZScpIHtcclxuICAgICAgY3R4LmZpbGxTdHlsZSA9IGZpbGxTdHlsZVN0YWNrLnBvcCgpO1xyXG5cclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRTdHJva2VTdHlsZScpIHtcclxuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gc3Ryb2tlU3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZSA9PT0gJ2xpbmVTdHlsZScpIHtcclxuICAgICAgbGluZVN0eWxlU3RhY2sucHVzaCh7XHJcbiAgICAgICAgbGluZVdpZHRoOiBjdHgubGluZVdpZHRoLFxyXG4gICAgICAgIGxpbmVDYXA6IGN0eC5saW5lQ2FwLFxyXG4gICAgICAgIGxpbmVKb2luOiBjdHgubGluZUpvaW4sXHJcbiAgICAgICAgbWl0ZXJMaW1pdDogY3R4Lm1pdGVyTGltaXQsXHJcbiAgICAgICAgbGluZURhc2g6IGN0eC5nZXRMaW5lRGFzaCgpLFxyXG4gICAgICAgIGxpbmVEYXNoT2Zmc2V0OiBjdHgubGluZURhc2hPZmZzZXRcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBpZiAocHJvcHMubGluZVdpZHRoICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IHByb3BzLmxpbmVXaWR0aDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUNhcCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5saW5lQ2FwID0gcHJvcHMubGluZUNhcDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZUpvaW4gIT09IG51bGwpIHtcclxuICAgICAgICBjdHgubGluZUpvaW4gPSBwcm9wcy5saW5lSm9pbjtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubWl0ZXJMaW1pdCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5taXRlckxpbWl0ID0gcHJvcHMubWl0ZXJMaW1pdDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMubGluZURhc2ggIT09IG51bGwpIHtcclxuICAgICAgICBjdHguc2V0TGluZURhc2gocHJvcHMubGluZURhc2gpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocHJvcHMubGluZURhc2hPZmZzZXQgIT09IG51bGwpIHtcclxuICAgICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBwcm9wcy5saW5lRGFzaE9mZnNldDtcclxuICAgICAgfVxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZExpbmVTdHlsZScpIHtcclxuICAgICAgY2FjaGUgPSBsaW5lU3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LmxpbmVXaWR0aCA9IGNhY2hlLmxpbmVXaWR0aDtcclxuICAgICAgY3R4LmxpbmVDYXAgPSBjYWNoZS5saW5lQ2FwO1xyXG4gICAgICBjdHgubGluZUpvaW4gPSBjYWNoZS5saW5lSm9pbjtcclxuICAgICAgY3R4Lm1pdGVyTGltaXQgPSBjYWNoZS5taXRlckxpbWl0O1xyXG4gICAgICBjdHguc2V0TGluZURhc2goY2FjaGUubGluZURhc2gpO1xyXG4gICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBjYWNoZS5saW5lRGFzaE9mZnNldDtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICd0ZXh0U3R5bGUnKSB7XHJcbiAgICAgIHRleHRTdHlsZVN0YWNrLnB1c2goe1xyXG4gICAgICAgIGZvbnQ6IGN0eC5mb250LFxyXG4gICAgICAgIHRleHRBbGlnbjogY3R4LnRleHRBbGlnbixcclxuICAgICAgICB0ZXh0QmFzZWxpbmU6IGN0eC50ZXh0QmFzZWxpbmUsXHJcbiAgICAgICAgZGlyZWN0aW9uOiBjdHguZGlyZWN0aW9uXHJcbiAgICAgIH0pO1xyXG4gICAgICBpZiAocHJvcHMuZm9udCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5mb250ID0gcHJvcHMuZm9udDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMudGV4dEFsaWduICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnRleHRBbGlnbiA9IHByb3BzLnRleHRBbGlnbjtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMudGV4dEJhc2VsaW5lICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnRleHRCYXNlbGluZSA9IHByb3BzLnRleHRCYXNlbGluZTtcclxuICAgICAgfVxyXG4gICAgICBpZiAocHJvcHMuZGlyZWN0aW9uICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LmRpcmVjdGlvbiA9IHByb3BzLmRpcmVjdGlvbjtcclxuICAgICAgfVxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZFRleHRTdHlsZScpIHtcclxuICAgICAgY2FjaGUgPSB0ZXh0U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LmZvbnQgPSBjYWNoZS5mb250O1xyXG4gICAgICBjdHgudGV4dEFsaWduID0gY2FjaGUudGV4dEFsaWduO1xyXG4gICAgICBjdHgudGV4dEJhc2VsaW5lID0gY2FjaGUudGV4dEJhc2VsaW5lO1xyXG4gICAgICBjdHguZGlyZWN0aW9uID0gY2FjaGUuZGlyZWN0aW9uO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3NoYWRvd1N0eWxlJykge1xyXG4gICAgICBzaGFkb3dTdHlsZVN0YWNrLnB1c2goe1xyXG4gICAgICAgIHNoYWRvd0JsdXI6IGN0eC5zaGFkb3dCbHVyLFxyXG4gICAgICAgIHNoYWRvd0NvbG9yOiBjdHguc2hhZG93Q29sb3IsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WDogY3R4LnNoYWRvd09mZnNldFgsXHJcbiAgICAgICAgc2hhZG93T2Zmc2V0WTogY3R4LnNoYWRvd09mZnNldFlcclxuICAgICAgfSk7XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dCbHVyICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd0JsdXIgPSBwcm9wcy5zaGFkb3dCbHVyO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dDb2xvciAhPT0gbnVsbCkge1xyXG4gICAgICAgIGN0eC5zaGFkb3dDb2xvciA9IHByb3BzLnNoYWRvd0NvbG9yO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRYICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBwcm9wcy5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9wcy5zaGFkb3dPZmZzZXRZICE9PSBudWxsKSB7XHJcbiAgICAgICAgY3R4LnNoYWRvd09mZnNldFkgPSBwcm9wcy5zaGFkb3dPZmZzZXRZO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kU2hhZG93U3R5bGUnKSB7XHJcbiAgICAgIGNhY2hlID0gc2hhZG93U3R5bGVTdGFjay5wb3AoKTtcclxuICAgICAgY3R4LnNoYWRvd0JsdXIgPSBjYWNoZS5zaGFkb3dCbHVyO1xyXG4gICAgICBjdHguc2hhZG93Q29sb3IgPSBjYWNoZS5zaGFkb3dDb2xvcjtcclxuICAgICAgY3R4LnNoYWRvd09mZnNldFggPSBjYWNoZS5zaGFkb3dPZmZzZXRYO1xyXG4gICAgICBjdHguc2hhZG93T2Zmc2V0WSA9IGNhY2hlLnNoYWRvd09mZnNldFk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3Ryb2tlVGV4dCcpIHtcclxuICAgICAgaWYgKHByb3BzLm1heFdpZHRoKSB7XHJcbiAgICAgICAgY3R4LnN0cm9rZVRleHQocHJvcHMudGV4dCwgcHJvcHMueCwgcHJvcHMueSwgcHJvcHMubWF4V2lkdGgpO1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5zdHJva2VUZXh0KHByb3BzLnRleHQsIHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxUZXh0Jykge1xyXG4gICAgICBpZiAocHJvcHMubWF4V2lkdGgpIHtcclxuICAgICAgICBjdHguZmlsbFRleHQocHJvcHMudGV4dCwgcHJvcHMueCwgcHJvcHMueSwgcHJvcHMubWF4V2lkdGgpO1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcbiAgICAgIGN0eC5maWxsVGV4dChwcm9wcy50ZXh0LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdkcmF3SW1hZ2UnKSB7XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLCBwcm9wcy5keCwgcHJvcHMuZHkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2RyYXdJbWFnZVNpemUnKSB7XHJcbiAgICAgIGN0eC5kcmF3SW1hZ2UocHJvcHMuaW1nLCBwcm9wcy5keCwgcHJvcHMuZHksIHByb3BzLmRXaWR0aCwgcHJvcHMuZEhlaWdodCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZHJhd0ltYWdlU291cmNlJykge1xyXG4gICAgICBjdHguZHJhd0ltYWdlKHByb3BzLmltZywgcHJvcHMuc3gsIHByb3BzLnN5LCBwcm9wcy5zV2lkdGgsIHByb3BzLnNIZWlnaHQsIHByb3BzLmR4LCBwcm9wcy5keSwgcHJvcHMuZFdpZHRoLCBwcm9wcy5kSGVpZ2h0KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdzdHJva2VBcmMnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgcHJvcHMuY291bnRlcmNsb2Nrd2lzZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2ZpbGxBcmMnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY3R4LmFyYyhwcm9wcy54LCBwcm9wcy55LCBwcm9wcy5yLCBwcm9wcy5zdGFydEFuZ2xlLCBwcm9wcy5lbmRBbmdsZSwgcHJvcHMuY291bnRlcmNsb2Nrd2lzZSk7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY3R4LmZpbGwoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdtb3ZlVG8nKSB7XHJcbiAgICAgIGN0eC5tb3ZlVG8ocHJvcHMueCwgcHJvcHMueSk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnbGluZVRvJykge1xyXG4gICAgICBjdHgubGluZVRvKHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlemllckN1cnZlVG8nKSB7XHJcbiAgICAgIGN0eC5iZXppZXJDdXJ2ZVRvKHByb3BzLmNwMXgsIHByb3BzLmNwMXksIHByb3BzLmNwMngsIHByb3BzLmNwMnksIHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3F1YWRyYXRpY0N1cnZlVG8nKSB7XHJcbiAgICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHByb3BzLmNweCwgcHJvcHMuY3B5LCBwcm9wcy54LCBwcm9wcy55KTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdhcmMnKSB7XHJcbiAgICAgIGN0eC5hcmMocHJvcHMueCwgcHJvcHMueSwgcHJvcHMuciwgcHJvcHMuc3RhcnRBbmdsZSwgcHJvcHMuZW5kQW5nbGUsIHByb3BzLmNvdW50ZXJjbG9ja3dpc2UpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2FyY1RvJykge1xyXG4gICAgICBjdHguYXJjVG8ocHJvcHMueDEsIHByb3BzLnkxLCBwcm9wcy54MiwgcHJvcHMueTIsIHByb3BzLnIpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VsbGlwc2UnKSB7XHJcbiAgICAgIC8vaWYgdGhlIG1ldGhvZCBpcyBwcm92aWRlZCBieSB0aGUgYnJvd3NlclxyXG4gICAgICBpZiAoc3VwcG9ydHNFbGxpcHNlKSB7XHJcbiAgICAgICAgY3R4LmVsbGlwc2UoXHJcbiAgICAgICAgICBwcm9wcy54LFxyXG4gICAgICAgICAgcHJvcHMueSxcclxuICAgICAgICAgIHByb3BzLnJhZGl1c1gsXHJcbiAgICAgICAgICBwcm9wcy5yYWRpdXNZLFxyXG4gICAgICAgICAgcHJvcHMucm90YXRpb24sXHJcbiAgICAgICAgICBwcm9wcy5zdGFydEFuZ2xlLFxyXG4gICAgICAgICAgcHJvcHMuZW5kQW5nbGUsXHJcbiAgICAgICAgICBwcm9wcy5hbnRpY2xvY2t3aXNlXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHgudHJhbnNsYXRlKHByb3BzLngsIHByb3BzLnkpO1xyXG4gICAgICBjdHgucm90YXRlKHByb3BzLnJvdGF0aW9uKTtcclxuICAgICAgY3R4LnNjYWxlKHByb3BzLnJhZGl1c1gsIHByb3BzLnJhZGl1c1kpO1xyXG4gICAgICBjdHguYXJjKDAsIDAsIDEsIHByb3BzLnN0YXJ0QW5nbGUsIHByb3BzLmVuZEFuZ2xlLCBwcm9wcy5hbnRpY2xvY2t3aXNlKTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdnbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIGdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvblN0YWNrLnB1c2goY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbik7XHJcbiAgICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBwcm9wcy52YWx1ZTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRHbG9iYWxDb21wb3NpdGVPcGVyYXRpb24nKSB7XHJcbiAgICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSBnbG9iYWxDb21wb3NpdGVPcGVyYXRpb25TdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdmaWxsJykge1xyXG4gICAgICBjdHguZmlsbCgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ3N0cm9rZScpIHtcclxuICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2JlZ2luQ2xpcCcpIHtcclxuICAgICAgY3R4LnNhdmUoKTtcclxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2NsaXAnKSB7XHJcbiAgICAgIGN0eC5jbGlwKCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnZW5kQ2xpcCcpIHtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdiZWdpblBhdGgnKSB7XHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdjbG9zZVBhdGgnKSB7XHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdnbG9iYWxBbHBoYScpIHtcclxuICAgICAgZ2xvYmFsQWxwaGFTdGFjay5wdXNoKGN0eC5nbG9iYWxBbHBoYSk7XHJcbiAgICAgIGN0eC5nbG9iYWxBbHBoYSAqPSBwcm9wcy52YWx1ZTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdlbmRHbG9iYWxBbHBoYScpIHtcclxuICAgICAgY3R4Lmdsb2JhbEFscGhhID0gZ2xvYmFsQWxwaGFTdGFjay5wb3AoKTtcclxuICAgICAgY29udGludWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGUgPT09ICdoaXRSZWN0JyAmJiByZWdpb25zKSB7XHJcbiAgICAgIGNhY2hlID0gW1xyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA2XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNV0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDRdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAzXSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gMl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDFdXHJcbiAgICAgIF07XHJcblxyXG4gICAgICByZWdpb25zLnB1c2goe1xyXG4gICAgICAgIGlkOiBwcm9wcy5pZCxcclxuICAgICAgICBwb2ludHM6IHByb3BzLnBvaW50cyxcclxuICAgICAgICBtYXRyaXg6IGNhY2hlLFxyXG4gICAgICAgIC8vcmVjdGFuZ2xlIVxyXG4gICAgICAgIHBvbHlnb246IGZhbHNlLFxyXG4gICAgICAgIGhvdmVyOiBmYWxzZSxcclxuICAgICAgICB0b3VjaGVkOiBmYWxzZSxcclxuICAgICAgICBjbGlja2VkOiBmYWxzZVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2hpdFJlZ2lvbicgJiYgcmVnaW9ucykge1xyXG4gICAgICBjYWNoZSA9IFtcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gNl0sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDVdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSA0XSxcclxuICAgICAgICB0cmFuc2Zvcm1TdGFja1t0cmFuc2Zvcm1TdGFja0luZGV4IC0gM10sXHJcbiAgICAgICAgdHJhbnNmb3JtU3RhY2tbdHJhbnNmb3JtU3RhY2tJbmRleCAtIDJdLFxyXG4gICAgICAgIHRyYW5zZm9ybVN0YWNrW3RyYW5zZm9ybVN0YWNrSW5kZXggLSAxXVxyXG4gICAgICBdO1xyXG5cclxuICAgICAgcmVnaW9ucy5wdXNoKHtcclxuICAgICAgICBpZDogcHJvcHMuaWQsXHJcbiAgICAgICAgcG9pbnRzOiBwcm9wcy5wb2ludHMsXHJcbiAgICAgICAgbWF0cml4OiBjYWNoZSxcclxuICAgICAgICBwb2x5Z29uOiB0cnVlLFxyXG4gICAgICAgIGhvdmVyOiBmYWxzZSxcclxuICAgICAgICB0b3VjaGVkOiBmYWxzZSxcclxuICAgICAgICBjbGlja2VkOiBmYWxzZVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnaW1hZ2VTbW9vdGhpbmdFbmFibGVkJykge1xyXG4gICAgICBpbWFnZVNtb290aGluZ0VuYWJsZWRTdGFjay5wdXNoKGN0eC5pbWFnZVNtb290aGluZ0VuYWJsZWQpO1xyXG4gICAgICBjdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gcHJvcHMudmFsdWU7XHJcblxyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZSA9PT0gJ2VuZEltYWdlU21vb3RoaW5nRW5hYmxlZCcpIHtcclxuICAgICAgY3R4LmltYWdlU21vb3RoaW5nRW5hYmxlZCA9IGltYWdlU21vb3RoaW5nRW5hYmxlZFN0YWNrLnBvcCgpO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZXh0ZW5zaW9ucyAmJiBleHRlbnNpb25zW3R5cGVdKSB7XHJcbiAgICAgIGV4dGVuc2lvbnNbdHlwZV0ocHJvcHMsIGN0eCk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG4gIH1cclxufTtcblxuLyoqKi8gfSxcbi8qIDQyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IHNldFRyYW5zZm9ybSA9IF9fd2VicGFja19yZXF1aXJlX18oOSk7XHJcblxyXG5sZXQgcmVzZXRUcmFuc2Zvcm0gPSAoLi4uY2hpbGRyZW4pID0+IHNldFRyYW5zZm9ybShbMSwgMCwgMCwgMSwgMCwgMF0sIGNoaWxkcmVuKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcmVzZXRUcmFuc2Zvcm07XG5cbi8qKiovIH0sXG4vKiA0MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ3Jlc3RvcmUnKTtcclxuXHJcbmxldCByb3RhdGUgPSAociwgLi4uY2hpbGRyZW4pID0+IFtcclxuICBuZXcgSW5zdHJ1Y3Rpb24oJ3JvdGF0ZScsIHsgY29zOiBNYXRoLmNvcyhyKSwgc2luOiBNYXRoLnNpbihyKSB9KSxcclxuICBjaGlsZHJlbixcclxuICBlbmRcclxuXTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcm90YXRlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHNjYWxlID0gKHgsIHksIC4uLmNoaWxkcmVuKSA9PiB7XHJcbiAgaWYgKHR5cGVvZiB5ICE9PSAnbnVtYmVyJykge1xyXG4gICAgY2hpbGRyZW4gPSBbeV0uY29uY2F0KGNoaWxkcmVuKTtcclxuICAgIHkgPSB4O1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignc2NhbGUnLCB7IHgsIHkgfSksXHJcbiAgICBjaGlsZHJlbixcclxuICAgIGVuZFxyXG4gIF07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNjYWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbignZW5kU2hhZG93U3R5bGUnKTtcclxuXHJcbmxldCBzaGFkb3dTdHlsZSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IHtcclxuICB2YWx1ZSA9IHZhbHVlIHx8IHt9O1xyXG4gIHZhciByZXN1bHQgPSB7XHJcbiAgICBzaGFkb3dCbHVyOiBudWxsLFxyXG4gICAgc2hhZG93Q29sb3I6IG51bGwsXHJcbiAgICBzaGFkb3dPZmZzZXRYOiBudWxsLFxyXG4gICAgc2hhZG93T2Zmc2V0WTogbnVsbFxyXG4gIH07XHJcblxyXG4gIGlmICh0eXBlb2YgdmFsdWUuc2hhZG93Qmx1ciAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5zaGFkb3dCbHVyID0gdmFsdWUuc2hhZG93Qmx1cjtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5zaGFkb3dDb2xvciAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC5zaGFkb3dDb2xvciA9IHZhbHVlLnNoYWRvd0NvbG9yO1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnNoYWRvd09mZnNldFggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuc2hhZG93T2Zmc2V0WCA9IHZhbHVlLnNoYWRvd09mZnNldFg7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUuZGlyZWN0aW9uICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LnNoYWRvd09mZnNldFkgPSB2YWx1ZS5zaGFkb3dPZmZzZXRZO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbignc2hhZG93U3R5bGUnLCB2YWx1ZSksXHJcbiAgICBjaGlsZHJlbixcclxuICAgIGVuZFxyXG4gIF07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNoYWRvd1N0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ2ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHNrZXdYID0gKHgsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgbmV3IEluc3RydWN0aW9uKCdza2V3WCcsIHsgeDogTWF0aC50YW4oeCkgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNrZXdYO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ3ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHNrZXdZID0gKHgsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgbmV3IEluc3RydWN0aW9uKCdza2V3WScsIHsgeTogTWF0aC50YW4oeSkgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHNrZXdZO1xyXG5cblxuLyoqKi8gfSxcbi8qIDQ4ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGNhY2hlID0gbmV3IEluc3RydWN0aW9uKCdzdHJva2UnKTtcclxuXHJcbmxldCBzdHJva2UgPSAoKSA9PiBjYWNoZTtcclxubW9kdWxlLmV4cG9ydHMgPSBzdHJva2U7XHJcblxuXG4vKioqLyB9LFxuLyogNDkgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApLFxyXG4gICAgcGkyID0gTWF0aC5QSSAqIDI7XHJcblxyXG5sZXQgc3Ryb2tlQXJjID0gKC4uLmFyZ3MpID0+IHtcclxuICBsZXQgW3gsIHksIHIsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBjb3VudGVyY2xvY2t3aXNlXSA9IGFyZ3M7XHJcbiAgbGV0IHByb3BzID0geyB4OiAwLCB5OiAwLCByOiB4LCBzdGFydEFuZ2xlOiAwLCBlbmRBbmdsZTogcGkyLCBjb3VudGVyY2xvY2t3aXNlOiBmYWxzZSB9O1xyXG5cclxuXHJcbiAgaWYgKGFyZ3MubGVuZ3RoID4gMykge1xyXG4gICAgcHJvcHMuc3RhcnRBbmdsZSA9IHN0YXJ0QW5nbGU7XHJcbiAgICBwcm9wcy5lbmRBbmdsZSA9IGVuZEFuZ2xlO1xyXG4gICAgcHJvcHMuY291bnRlcmNsb2Nrd2lzZSA9ICEhY291bnRlcmNsb2Nrd2lzZTtcclxuICB9XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA+IDEpe1xyXG4gICAgcHJvcHMueCA9IHg7XHJcbiAgICBwcm9wcy55ID0geTtcclxuICAgIHByb3BzLnIgPSByO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbihcInN0cm9rZUFyY1wiLCAgcHJvcHMpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzdHJva2VBcmM7XHJcblxuXG4vKioqLyB9LFxuLyogNTAgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5sZXQgSW5zdHJ1Y3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDApO1xyXG5cclxubGV0IHN0cm9rZVJlY3QgPSAoLi4uYXJncykgPT4gbmV3IEluc3RydWN0aW9uKCdzdHJva2VSZWN0JyxcclxuICBhcmdzLmxlbmd0aCA+IDIgP1xyXG4gICAgeyB4OiBhcmdzWzBdLCB5OiBhcmdzWzFdLCB3aWR0aDogYXJnc1syXSwgaGVpZ2h0OiBhcmdzWzNdIH0gOlxyXG4gICAgeyB4OiAwLCB5OiAwLCB3aWR0aDogYXJnc1swXSwgaGVpZ2h0OiBhcmdzWzFdIH1cclxuKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc3Ryb2tlUmVjdDtcclxuXG5cbi8qKiovIH0sXG4vKiA1MSAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZFN0cm9rZVN0eWxlJyk7XHJcblxyXG5sZXQgc3Ryb2tlU3R5bGUgPSAodmFsdWUsIC4uLmNoaWxkcmVuKSA9PiBbXHJcbiAgbmV3IEluc3RydWN0aW9uKCdzdHJva2VTdHlsZScsIHsgdmFsdWUgfSksXHJcbiAgY2hpbGRyZW4sXHJcbiAgZW5kXHJcbl07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHN0cm9rZVN0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDUyICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxuXHJcbmxldCBzdHJva2VUZXh0ID0gKC4uLmFyZ3MpID0+IHtcclxuICBsZXQgW3RleHQsIHgsIHksIG1heFdpZHRoXSA9IGFyZ3M7XHJcblxyXG4gIGlmIChhcmdzLmxlbmd0aCA8IDQpIHtcclxuICAgIG1heFdpZHRoID0gbnVsbDtcclxuICB9XHJcbiAgaWYgKGFyZ3MubGVuZ3RoIDwgMykge1xyXG4gICAgeCA9IDA7XHJcbiAgICB5ID0gMDtcclxuICB9XHJcbiAgcmV0dXJuIG5ldyBJbnN0cnVjdGlvbignc3Ryb2tlVGV4dCcsIHtcclxuICAgIHRleHQsXHJcbiAgICB4LFxyXG4gICAgeSxcclxuICAgIG1heFdpZHRoXHJcbiAgfSk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHN0cm9rZVRleHQ7XG5cbi8qKiovIH0sXG4vKiA1MyAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbmxldCBJbnN0cnVjdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oMCk7XHJcbmxldCBlbmQgPSBuZXcgSW5zdHJ1Y3Rpb24oJ2VuZFRleHRTdHlsZScpO1xyXG5cclxubGV0IHRleHRTdHlsZSA9ICh2YWx1ZSwgLi4uY2hpbGRyZW4pID0+IHtcclxuICB2YWx1ZSA9IHZhbHVlIHx8IHt9O1xyXG4gIHZhciByZXN1bHQgPSB7XHJcbiAgICBmb250OiBudWxsLFxyXG4gICAgdGV4dEFsaWduOiBudWxsLFxyXG4gICAgdGV4dEJhc2VsaW5lOiBudWxsLFxyXG4gICAgZGlyZWN0aW9uOiBudWxsXHJcbiAgfTtcclxuXHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5mb250ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LmZvbnQgPSB2YWx1ZS5mb250O1xyXG4gIH1cclxuICBpZiAodHlwZW9mIHZhbHVlLnRleHRBbGlnbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJlc3VsdC50ZXh0QWxpZ24gPSB2YWx1ZS50ZXh0QWxpZ247XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgdmFsdWUudGV4dEJhc2VsaW5lICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmVzdWx0LnRleHRCYXNlbGluZSA9IHZhbHVlLnRleHRCYXNlbGluZTtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZS5kaXJlY3Rpb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXN1bHQuZGlyZWN0aW9uID0gdmFsdWUuZGlyZWN0aW9uO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbigndGV4dFN0eWxlJywgcmVzdWx0KSxcclxuICAgIGNoaWxkcmVuLFxyXG4gICAgZW5kXHJcbiAgXTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdGV4dFN0eWxlO1xyXG5cblxuLyoqKi8gfSxcbi8qIDU0ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHRyYW5zZm9ybSA9ICh2YWx1ZXMsIC4uLmNoaWxkcmVuKSA9PiB7XHJcbiAgcmV0dXJuIFtcclxuICAgIG5ldyBJbnN0cnVjdGlvbigndHJhbnNmb3JtJyxbXHJcbiAgICAgIHZhbHVlc1swXSxcclxuICAgICAgdmFsdWVzWzFdLFxyXG4gICAgICB2YWx1ZXNbMl0sXHJcbiAgICAgIHZhbHVlc1szXSxcclxuICAgICAgdmFsdWVzWzRdLFxyXG4gICAgICB2YWx1ZXNbNV1cclxuICAgIF0pLFxyXG4gICAgY2hpbGRyZW4sXHJcbiAgICBlbmRcclxuICBdO1xyXG59O1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdHJhbnNmb3JtO1xyXG5cblxuLyoqKi8gfSxcbi8qIDU1ICovXG4vKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHtcblxubGV0IEluc3RydWN0aW9uID0gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcclxubGV0IGVuZCA9IG5ldyBJbnN0cnVjdGlvbigncmVzdG9yZScpO1xyXG5cclxubGV0IHRyYW5zbGF0ZSA9ICh4LCB5LCAuLi5jaGlsZHJlbikgPT4gW1xyXG4gIG5ldyBJbnN0cnVjdGlvbigndHJhbnNsYXRlJywgeyB4OiB4LCB5OiB5IH0pLFxyXG4gIGNoaWxkcmVuLFxyXG4gIGVuZFxyXG5dO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0cmFuc2xhdGU7XHJcblxuXG4vKioqLyB9LFxuLyogNTYgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG4vLyBTb3VyY2U6IGh0dHA6Ly9qc2ZpZGRsZS5uZXQvdld4OFYvXG4vLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU2MDMxOTUvZnVsbC1saXN0LW9mLWphdmFzY3JpcHQta2V5Y29kZXNcblxuLyoqXG4gKiBDb25lbmllbmNlIG1ldGhvZCByZXR1cm5zIGNvcnJlc3BvbmRpbmcgdmFsdWUgZm9yIGdpdmVuIGtleU5hbWUgb3Iga2V5Q29kZS5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBrZXlDb2RlIHtOdW1iZXJ9IG9yIGtleU5hbWUge1N0cmluZ31cbiAqIEByZXR1cm4ge01peGVkfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzZWFyY2hJbnB1dCkge1xuICAvLyBLZXlib2FyZCBFdmVudHNcbiAgaWYgKHNlYXJjaElucHV0ICYmICdvYmplY3QnID09PSB0eXBlb2Ygc2VhcmNoSW5wdXQpIHtcbiAgICB2YXIgaGFzS2V5Q29kZSA9IHNlYXJjaElucHV0LndoaWNoIHx8IHNlYXJjaElucHV0LmtleUNvZGUgfHwgc2VhcmNoSW5wdXQuY2hhckNvZGVcbiAgICBpZiAoaGFzS2V5Q29kZSkgc2VhcmNoSW5wdXQgPSBoYXNLZXlDb2RlXG4gIH1cblxuICAvLyBOdW1iZXJzXG4gIGlmICgnbnVtYmVyJyA9PT0gdHlwZW9mIHNlYXJjaElucHV0KSByZXR1cm4gbmFtZXNbc2VhcmNoSW5wdXRdXG5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIChjYXN0IHRvIHN0cmluZylcbiAgdmFyIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hJbnB1dClcblxuICAvLyBjaGVjayBjb2Rlc1xuICB2YXIgZm91bmROYW1lZEtleSA9IGNvZGVzW3NlYXJjaC50b0xvd2VyQ2FzZSgpXVxuICBpZiAoZm91bmROYW1lZEtleSkgcmV0dXJuIGZvdW5kTmFtZWRLZXlcblxuICAvLyBjaGVjayBhbGlhc2VzXG4gIHZhciBmb3VuZE5hbWVkS2V5ID0gYWxpYXNlc1tzZWFyY2gudG9Mb3dlckNhc2UoKV1cbiAgaWYgKGZvdW5kTmFtZWRLZXkpIHJldHVybiBmb3VuZE5hbWVkS2V5XG5cbiAgLy8gd2VpcmQgY2hhcmFjdGVyP1xuICBpZiAoc2VhcmNoLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHNlYXJjaC5jaGFyQ29kZUF0KDApXG5cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEdldCBieSBuYW1lXG4gKlxuICogICBleHBvcnRzLmNvZGVbJ2VudGVyJ10gLy8gPT4gMTNcbiAqL1xuXG52YXIgY29kZXMgPSBleHBvcnRzLmNvZGUgPSBleHBvcnRzLmNvZGVzID0ge1xuICAnYmFja3NwYWNlJzogOCxcbiAgJ3RhYic6IDksXG4gICdlbnRlcic6IDEzLFxuICAnc2hpZnQnOiAxNixcbiAgJ2N0cmwnOiAxNyxcbiAgJ2FsdCc6IDE4LFxuICAncGF1c2UvYnJlYWsnOiAxOSxcbiAgJ2NhcHMgbG9jayc6IDIwLFxuICAnZXNjJzogMjcsXG4gICdzcGFjZSc6IDMyLFxuICAncGFnZSB1cCc6IDMzLFxuICAncGFnZSBkb3duJzogMzQsXG4gICdlbmQnOiAzNSxcbiAgJ2hvbWUnOiAzNixcbiAgJ2xlZnQnOiAzNyxcbiAgJ3VwJzogMzgsXG4gICdyaWdodCc6IDM5LFxuICAnZG93bic6IDQwLFxuICAnaW5zZXJ0JzogNDUsXG4gICdkZWxldGUnOiA0NixcbiAgJ2NvbW1hbmQnOiA5MSxcbiAgJ2xlZnQgY29tbWFuZCc6IDkxLFxuICAncmlnaHQgY29tbWFuZCc6IDkzLFxuICAnbnVtcGFkIConOiAxMDYsXG4gICdudW1wYWQgKyc6IDEwNyxcbiAgJ251bXBhZCAtJzogMTA5LFxuICAnbnVtcGFkIC4nOiAxMTAsXG4gICdudW1wYWQgLyc6IDExMSxcbiAgJ251bSBsb2NrJzogMTQ0LFxuICAnc2Nyb2xsIGxvY2snOiAxNDUsXG4gICdteSBjb21wdXRlcic6IDE4MixcbiAgJ215IGNhbGN1bGF0b3InOiAxODMsXG4gICc7JzogMTg2LFxuICAnPSc6IDE4NyxcbiAgJywnOiAxODgsXG4gICctJzogMTg5LFxuICAnLic6IDE5MCxcbiAgJy8nOiAxOTEsXG4gICdgJzogMTkyLFxuICAnWyc6IDIxOSxcbiAgJ1xcXFwnOiAyMjAsXG4gICddJzogMjIxLFxuICBcIidcIjogMjIyXG59XG5cbi8vIEhlbHBlciBhbGlhc2VzXG5cbnZhciBhbGlhc2VzID0gZXhwb3J0cy5hbGlhc2VzID0ge1xuICAnd2luZG93cyc6IDkxLFxuICAn4oenJzogMTYsXG4gICfijKUnOiAxOCxcbiAgJ+KMgyc6IDE3LFxuICAn4oyYJzogOTEsXG4gICdjdGwnOiAxNyxcbiAgJ2NvbnRyb2wnOiAxNyxcbiAgJ29wdGlvbic6IDE4LFxuICAncGF1c2UnOiAxOSxcbiAgJ2JyZWFrJzogMTksXG4gICdjYXBzJzogMjAsXG4gICdyZXR1cm4nOiAxMyxcbiAgJ2VzY2FwZSc6IDI3LFxuICAnc3BjJzogMzIsXG4gICdwZ3VwJzogMzMsXG4gICdwZ2RuJzogMzQsXG4gICdpbnMnOiA0NSxcbiAgJ2RlbCc6IDQ2LFxuICAnY21kJzogOTFcbn1cblxuXG4vKiFcbiAqIFByb2dyYW1hdGljYWxseSBhZGQgdGhlIGZvbGxvd2luZ1xuICovXG5cbi8vIGxvd2VyIGNhc2UgY2hhcnNcbmZvciAoaSA9IDk3OyBpIDwgMTIzOyBpKyspIGNvZGVzW1N0cmluZy5mcm9tQ2hhckNvZGUoaSldID0gaSAtIDMyXG5cbi8vIG51bWJlcnNcbmZvciAodmFyIGkgPSA0ODsgaSA8IDU4OyBpKyspIGNvZGVzW2kgLSA0OF0gPSBpXG5cbi8vIGZ1bmN0aW9uIGtleXNcbmZvciAoaSA9IDE7IGkgPCAxMzsgaSsrKSBjb2Rlc1snZicraV0gPSBpICsgMTExXG5cbi8vIG51bXBhZCBrZXlzXG5mb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykgY29kZXNbJ251bXBhZCAnK2ldID0gaSArIDk2XG5cbi8qKlxuICogR2V0IGJ5IGNvZGVcbiAqXG4gKiAgIGV4cG9ydHMubmFtZVsxM10gLy8gPT4gJ0VudGVyJ1xuICovXG5cbnZhciBuYW1lcyA9IGV4cG9ydHMubmFtZXMgPSBleHBvcnRzLnRpdGxlID0ge30gLy8gdGl0bGUgZm9yIGJhY2t3YXJkIGNvbXBhdFxuXG4vLyBDcmVhdGUgcmV2ZXJzZSBtYXBwaW5nXG5mb3IgKGkgaW4gY29kZXMpIG5hbWVzW2NvZGVzW2ldXSA9IGlcblxuLy8gQWRkIGFsaWFzZXNcbmZvciAodmFyIGFsaWFzIGluIGFsaWFzZXMpIHtcbiAgY29kZXNbYWxpYXNdID0gYWxpYXNlc1thbGlhc11cbn1cblxuXG4vKioqLyB9LFxuLyogNTcgKi9cbi8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykge1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChwb2ludCwgdnMpIHtcbiAgICAvLyByYXktY2FzdGluZyBhbGdvcml0aG0gYmFzZWQgb25cbiAgICAvLyBodHRwOi8vd3d3LmVjc2UucnBpLmVkdS9Ib21lcGFnZXMvd3JmL1Jlc2VhcmNoL1Nob3J0X05vdGVzL3BucG9seS5odG1sXG4gICAgXG4gICAgdmFyIHggPSBwb2ludFswXSwgeSA9IHBvaW50WzFdO1xuICAgIFxuICAgIHZhciBpbnNpZGUgPSBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMCwgaiA9IHZzLmxlbmd0aCAtIDE7IGkgPCB2cy5sZW5ndGg7IGogPSBpKyspIHtcbiAgICAgICAgdmFyIHhpID0gdnNbaV1bMF0sIHlpID0gdnNbaV1bMV07XG4gICAgICAgIHZhciB4aiA9IHZzW2pdWzBdLCB5aiA9IHZzW2pdWzFdO1xuICAgICAgICBcbiAgICAgICAgdmFyIGludGVyc2VjdCA9ICgoeWkgPiB5KSAhPSAoeWogPiB5KSlcbiAgICAgICAgICAgICYmICh4IDwgKHhqIC0geGkpICogKHkgLSB5aSkgLyAoeWogLSB5aSkgKyB4aSk7XG4gICAgICAgIGlmIChpbnRlcnNlY3QpIGluc2lkZSA9ICFpbnNpZGU7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBpbnNpZGU7XG59O1xuXG5cbi8qKiovIH0sXG4vKiA1OCAqL1xuLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAnYWN0aXZlUmVnaW9ucyc6IF9fd2VicGFja19yZXF1aXJlX18oMTApLFxuICAnYXJjJzogX193ZWJwYWNrX3JlcXVpcmVfXygxMSksXG4gICdhcmNUbyc6IF9fd2VicGFja19yZXF1aXJlX18oMTIpLFxuICAnYmVnaW5QYXRoJzogX193ZWJwYWNrX3JlcXVpcmVfXygyKSxcbiAgJ2JlemllckN1cnZlVG8nOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDEzKSxcbiAgJ2NsZWFyUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oMTQpLFxuICAnY2xpcCc6IF9fd2VicGFja19yZXF1aXJlX18oMTUpLFxuICAnY2xpcFBhdGgnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDE2KSxcbiAgJ2Nsb3NlUGF0aCc6IF9fd2VicGFja19yZXF1aXJlX18oMyksXG4gICdjcmVhdGVSZWd1bGFyUG9seWdvbic6IF9fd2VicGFja19yZXF1aXJlX18oMTcpLFxuICAnY3JlYXRlV3JhcHBlcic6IF9fd2VicGFja19yZXF1aXJlX18oMTgpLFxuICAnY3ljbGVNb3VzZURhdGEnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpLFxuICAnZHJhd0ltYWdlJzogX193ZWJwYWNrX3JlcXVpcmVfXygxOSksXG4gICdlbGxpcHNlJzogX193ZWJwYWNrX3JlcXVpcmVfXygyMCksXG4gICdmaWxsJzogX193ZWJwYWNrX3JlcXVpcmVfXygyMSksXG4gICdmaWxsQXJjJzogX193ZWJwYWNrX3JlcXVpcmVfXygyMiksXG4gICdmaWxsUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oMjMpLFxuICAnZmlsbFN0eWxlJzogX193ZWJwYWNrX3JlcXVpcmVfXygyNCksXG4gICdmaWxsVGV4dCc6IF9fd2VicGFja19yZXF1aXJlX18oMjUpLFxuICAnZ2xvYmFsQWxwaGEnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDI2KSxcbiAgJ2dsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbic6IF9fd2VicGFja19yZXF1aXJlX18oMjcpLFxuICAnaGl0UmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oMjgpLFxuICAnaGl0UmVnaW9uJzogX193ZWJwYWNrX3JlcXVpcmVfXygyOSksXG4gICdpbWFnZVNtb290aGluZ0VuYWJsZWQnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMwKSxcbiAgJ2luaXRpYWxpemUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMxKSxcbiAgJ0luc3RydWN0aW9uJzogX193ZWJwYWNrX3JlcXVpcmVfXygwKSxcbiAgJ2ludmVydE1hdHJpeCc6IF9fd2VicGFja19yZXF1aXJlX18oNSksXG4gICdrZXlEYXRhJzogX193ZWJwYWNrX3JlcXVpcmVfXygzMiksXG4gICdsaW5lU3R5bGUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDMzKSxcbiAgJ2xpbmVUbyc6IF9fd2VicGFja19yZXF1aXJlX18oNiksXG4gICdtb3VzZURhdGEnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM0KSxcbiAgJ21vdmVUbyc6IF9fd2VicGFja19yZXF1aXJlX18oNyksXG4gICdtb3ZlVG9MaW5lVG8nOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM1KSxcbiAgJ3BhdGgnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM2KSxcbiAgJ3BsYWNlSG9sZGVyJzogX193ZWJwYWNrX3JlcXVpcmVfXygzNyksXG4gICdwb2ludEluUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oOCksXG4gICdxdWFkcmF0aWNDdXJ2ZVRvJzogX193ZWJwYWNrX3JlcXVpcmVfXygzOCksXG4gICdyYWYnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDM5KSxcbiAgJ3JlY3QnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQwKSxcbiAgJ3JlbmRlcic6IF9fd2VicGFja19yZXF1aXJlX18oNDEpLFxuICAncmVzZXRUcmFuc2Zvcm0nOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQyKSxcbiAgJ3JvdGF0ZSc6IF9fd2VicGFja19yZXF1aXJlX18oNDMpLFxuICAnc2NhbGUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ0KSxcbiAgJ3NldFRyYW5zZm9ybSc6IF9fd2VicGFja19yZXF1aXJlX18oOSksXG4gICdzaGFkb3dTdHlsZSc6IF9fd2VicGFja19yZXF1aXJlX18oNDUpLFxuICAnc2tld1gnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ2KSxcbiAgJ3NrZXdZJzogX193ZWJwYWNrX3JlcXVpcmVfXyg0NyksXG4gICdzdHJva2UnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDQ4KSxcbiAgJ3N0cm9rZUFyYyc6IF9fd2VicGFja19yZXF1aXJlX18oNDkpLFxuICAnc3Ryb2tlUmVjdCc6IF9fd2VicGFja19yZXF1aXJlX18oNTApLFxuICAnc3Ryb2tlU3R5bGUnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDUxKSxcbiAgJ3N0cm9rZVRleHQnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDUyKSxcbiAgJ3RleHRTdHlsZSc6IF9fd2VicGFja19yZXF1aXJlX18oNTMpLFxuICAndHJhbnNmb3JtJzogX193ZWJwYWNrX3JlcXVpcmVfXyg1NCksXG4gICd0cmFuc2Zvcm1Qb2ludHMnOiBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpLFxuICAndHJhbnNsYXRlJzogX193ZWJwYWNrX3JlcXVpcmVfXyg1NSlcbn07XG5cbi8qKiovIH1cbi8qKioqKiovIF0pO1xufSk7Il19 | |
const repatch = require('repatch'); | |
const e2d = require('e2d'); | |
const components = []; | |
const app = { pointer: false, mouseData: null, activeRegions: null }; | |
const ctx = document.createElement('canvas').getContext('2d'); | |
ctx.canvas.width = 400; | |
ctx.canvas.height = 300; | |
document.body.appendChild(ctx.canvas); | |
e2d.raf(() => { | |
app.mouseData = e2d.mouseData(ctx); | |
app.activeRegions = e2d.activeRegions(ctx); | |
app.pointer = false; | |
components.forEach(x => { | |
const region = app.activeRegions[x.id]; | |
const prevActive = x.active; | |
x.hover = !!region; | |
if (region.clicked) { | |
x.active = true; | |
} | |
if (x.active && x.hover && !app.mouseData.state) { | |
x.onClick(app); | |
} | |
if (!app.mouseData.state) { | |
x.active = false; | |
} | |
x.dirty = x.update(app) || x.dirty || (prevActive !== x.active); | |
}); | |
components.sort((x, y) => x.zIndex < y.zIndex ? -1 : x.zIndex > y.zIndex ? 1 : 0); | |
const view = components.map(x => x.dirty ? x._cache = x.render() : x._cache); | |
components.forEach(x => (x.dirty = false, true)); | |
e2d.render( | |
e2d.clearRect(ctx.canvas.width, ctx.canvas.height), | |
view, | |
ctx | |
); | |
}) | |
let id = -1; | |
class Component { | |
constructor({ position = [0, 0], scale = [1, 1], rotation = 0, alpha = 0, center = [0, 0], onClick = x => {} }) { | |
this.id = (++id).toString(36); | |
this.position = position; | |
this.scale = scale; | |
this.center = center; | |
this.rotation = rotaion; | |
this.alpha = alpha; | |
this.dirty = true; | |
this.active = false; | |
this.hover = false; | |
this._cache = []; | |
this.onClick = onClick; | |
} | |
render(...children) { | |
return e2d.translate(this.position[0], this.position[1], | |
e2d.rotate(this.rotation, | |
e2d.scale(this.scale[0], this.scale[1], | |
e2d.translate(-this.center[0], -this.center[1], ...children) | |
) | |
) | |
); | |
} | |
} | |
;}, 0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "requirebin-sketch", | |
"version": "1.0.0", | |
"dependencies": { | |
"repatch": "1.3.2", | |
"e2d": "4.0.0-rc.1" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- contents of this file will be placed inside the <body> --> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- contents of this file will be placed inside the <head> --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment