advanced.reporting.asset.php
1 month ago
advanced.reporting.js
1 month ago
calculated.field.asset.php
1 month ago
calculated.field.js
1 month ago
conditional.block.asset.php
1 month ago
conditional.block.js
1 month ago
dynamic.value.asset.php
1 month ago
dynamic.value.js
1 month ago
main.asset.php
1 month ago
main.css
1 month ago
main.js
1 month ago
media.field.asset.php
1 month ago
media.field.js
1 month ago
media.field.restrictions.asset.php
1 month ago
media.field.restrictions.js
1 month ago
multi.step.asset.php
1 month ago
multi.step.js
1 month ago
calculated.field.js
370 lines
| 1 | /******/ (() => { // webpackBootstrap |
| 2 | /******/ "use strict"; |
| 3 | /******/ var __webpack_modules__ = ({ |
| 4 | |
| 5 | /***/ "./frontend/calculated.field/functions.js" |
| 6 | /*!************************************************!*\ |
| 7 | !*** ./frontend/calculated.field/functions.js ***! |
| 8 | \************************************************/ |
| 9 | (__unused_webpack_module, __webpack_exports__, __webpack_require__) { |
| 10 | |
| 11 | __webpack_require__.r(__webpack_exports__); |
| 12 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| 13 | /* harmony export */ convertMillisToDateString: () => (/* binding */ convertMillisToDateString), |
| 14 | /* harmony export */ getCalculatedWrapper: () => (/* binding */ getCalculatedWrapper), |
| 15 | /* harmony export */ isCalculated: () => (/* binding */ isCalculated) |
| 16 | /* harmony export */ }); |
| 17 | function getCalculatedWrapper(node) { |
| 18 | return node.closest('.jet-form-builder__calculated-field'); |
| 19 | } |
| 20 | |
| 21 | /** |
| 22 | * @param node {HTMLElement} |
| 23 | * @return {boolean} |
| 24 | */ |
| 25 | function isCalculated(node) { |
| 26 | var _getCalculatedWrapper; |
| 27 | return !!((_getCalculatedWrapper = getCalculatedWrapper(node)?.dataset?.formula?.length) !== null && _getCalculatedWrapper !== void 0 ? _getCalculatedWrapper : ''); |
| 28 | } |
| 29 | |
| 30 | /** |
| 31 | * Formats milliseconds into a string according to the specified format. |
| 32 | * |
| 33 | * Supported placeholders: |
| 34 | * YYYY — 4-digit year (2024) |
| 35 | * MM — month with leading zero (01–12) |
| 36 | * M — month without leading zero (1–12) |
| 37 | * MMM — abbreviated month name (Jan–Dec) |
| 38 | * MMMM — full month name (January–December) |
| 39 | * DD — day of month with leading zero (01–31) |
| 40 | * D — day of month without leading zero (1–31) |
| 41 | * HH — hours with leading zero (00–23) in 24-hour format |
| 42 | * H — hours without leading zero (0–23) in 24-hour format |
| 43 | * hh — hours with leading zero (01–12) in 12-hour format |
| 44 | * h — hours without leading zero (1–12) in 12-hour format |
| 45 | * mm — minutes with leading zero (00–59) |
| 46 | * m — minutes without leading zero (0–59) |
| 47 | * ss — seconds with leading zero (00–59) |
| 48 | * s — seconds without leading zero (0–59) |
| 49 | * dddd — full day of week name (Monday–Sunday) |
| 50 | * ddd — abbreviated day of week name (Mon–Sun) |
| 51 | * A — AM/PM designation |
| 52 | * |
| 53 | * @param {number|string} millisInput — milliseconds |
| 54 | * @param {string} format — format string |
| 55 | * @returns {string|number} |
| 56 | */ |
| 57 | function convertMillisToDateString(millisInput, format = 'YYYY-MM-DD') { |
| 58 | const millis = eval(millisInput); |
| 59 | if (!millis || isNaN(millis) || null === millis || 0 === millis) { |
| 60 | return 0; |
| 61 | } |
| 62 | const date = new Date(millis); |
| 63 | const monthsFull = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; |
| 64 | const monthsShort = monthsFull.map(m => m.slice(0, 3)); |
| 65 | const daysFull = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; |
| 66 | const daysShort = daysFull.map(d => d.slice(0, 3)); |
| 67 | const hours12 = date.getHours() % 12 || 12; // Convert 0 to 12 for 12-hour format |
| 68 | const ampm = date.getHours() >= 12 ? 'PM' : 'AM'; |
| 69 | const map = { |
| 70 | YYYY: date.getFullYear(), |
| 71 | MM: String(date.getMonth() + 1).padStart(2, '0'), |
| 72 | M: date.getMonth() + 1, |
| 73 | MMM: monthsShort[date.getMonth()], |
| 74 | MMMM: monthsFull[date.getMonth()], |
| 75 | DD: String(date.getDate()).padStart(2, '0'), |
| 76 | D: date.getDate(), |
| 77 | HH: String(date.getHours()).padStart(2, '0'), |
| 78 | H: date.getHours(), |
| 79 | hh: String(hours12).padStart(2, '0'), |
| 80 | // 12-hour format with leading zero |
| 81 | h: hours12, |
| 82 | // 12-hour format without leading zero |
| 83 | mm: String(date.getMinutes()).padStart(2, '0'), |
| 84 | m: date.getMinutes(), |
| 85 | ss: String(date.getSeconds()).padStart(2, '0'), |
| 86 | s: date.getSeconds(), |
| 87 | dddd: daysFull[date.getDay()], |
| 88 | ddd: daysShort[date.getDay()], |
| 89 | A: ampm // AM/PM |
| 90 | }; |
| 91 | const sortedKeys = Object.keys(map).sort((a, b) => b.length - a.length); |
| 92 | |
| 93 | // Use temporary placeholders to prevent conflicts |
| 94 | let formatted = format; |
| 95 | const placeholders = {}; |
| 96 | |
| 97 | // First pass: replace format tokens with unique placeholders |
| 98 | sortedKeys.forEach((key, index) => { |
| 99 | const placeholder = `\x00${index}\x00`; // Use index-based unique identifier |
| 100 | placeholders[placeholder] = String(map[key]); |
| 101 | |
| 102 | // Use word boundaries for single-letter tokens to avoid replacing letters in text |
| 103 | const pattern = key.length <= 2 && /^[a-zA-Z]+$/.test(key) ? new RegExp(`\\b${key}\\b`, 'g') : new RegExp(key, 'g'); |
| 104 | formatted = formatted.replace(pattern, placeholder); |
| 105 | }); |
| 106 | |
| 107 | // Second pass: replace placeholders with actual values |
| 108 | for (const [placeholder, value] of Object.entries(placeholders)) { |
| 109 | formatted = formatted.split(placeholder).join(value); |
| 110 | } |
| 111 | return formatted; |
| 112 | } |
| 113 | |
| 114 | |
| 115 | /***/ }, |
| 116 | |
| 117 | /***/ "./frontend/calculated.field/input.js" |
| 118 | /*!********************************************!*\ |
| 119 | !*** ./frontend/calculated.field/input.js ***! |
| 120 | \********************************************/ |
| 121 | (__unused_webpack_module, __webpack_exports__, __webpack_require__) { |
| 122 | |
| 123 | __webpack_require__.r(__webpack_exports__); |
| 124 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| 125 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) |
| 126 | /* harmony export */ }); |
| 127 | /* harmony import */ var _functions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./functions */ "./frontend/calculated.field/functions.js"); |
| 128 | var _window$JetFormBuilde; |
| 129 | |
| 130 | const { |
| 131 | InputData, |
| 132 | CalculatedFormula |
| 133 | } = window.JetFormBuilderAbstract; |
| 134 | const { |
| 135 | applyFilters |
| 136 | } = JetPlugins.hooks; |
| 137 | const { |
| 138 | applyFilters: deprecatedApplyFilters = false |
| 139 | } = (_window$JetFormBuilde = window?.JetFormBuilderMain?.filters) !== null && _window$JetFormBuilde !== void 0 ? _window$JetFormBuilde : {}; |
| 140 | |
| 141 | // eslint-disable-next-line max-lines-per-function |
| 142 | function CalculatedData() { |
| 143 | InputData.call(this); |
| 144 | this.formula = ''; |
| 145 | this.precision = 0; |
| 146 | this.sepDecimal = ''; |
| 147 | this.sepThousands = ''; |
| 148 | this.visibleValNode = null; |
| 149 | this.valueTypeProp = 'number'; |
| 150 | this.isSupported = function (node) { |
| 151 | return (0,_functions__WEBPACK_IMPORTED_MODULE_0__.isCalculated)(node); |
| 152 | }; |
| 153 | this.setValue = function () { |
| 154 | const formula = new CalculatedFormula(this, { |
| 155 | forceFunction: true |
| 156 | }); |
| 157 | formula.observe(this.formula); |
| 158 | formula.setResult = () => { |
| 159 | if ('date' === this.valueTypeProp) { |
| 160 | const date_formula = formula.calculate(); |
| 161 | this.value.current = (0,_functions__WEBPACK_IMPORTED_MODULE_0__.convertMillisToDateString)(date_formula, this.dateFormat); |
| 162 | } else { |
| 163 | this.value.current = formula.calculate(); |
| 164 | } |
| 165 | }; |
| 166 | formula.relatedCallback = input => { |
| 167 | const value = applyFilters('jet.fb.calculated.callback', false, input, this); |
| 168 | if (false !== value) { |
| 169 | return value; |
| 170 | } |
| 171 | const response = 'number' === this.valueTypeProp ? input.calcValue : input.value.current; |
| 172 | if (false === deprecatedApplyFilters) { |
| 173 | return response; |
| 174 | } |
| 175 | const filterResult = deprecatedApplyFilters('forms/calculated-field-value', input.value.current, jQuery(input.nodes[0])); |
| 176 | return filterResult === input.value.current ? response : filterResult; |
| 177 | }; |
| 178 | formula.emptyValue = () => 'number' === this.valueTypeProp ? 0 : ''; |
| 179 | formula.setResult(); |
| 180 | this.value.current = this.value.applySanitizers(this.value.current); |
| 181 | this.beforeSubmit(resolve => { |
| 182 | this.value.silence(); |
| 183 | this.value.current = null; |
| 184 | this.value.silence(); |
| 185 | formula.setResult(); |
| 186 | resolve(); |
| 187 | }, this); |
| 188 | }; |
| 189 | this.setNode = function (node) { |
| 190 | InputData.prototype.setNode.call(this, node); |
| 191 | InputData.prototype.reQueryValue = () => {}; |
| 192 | const { |
| 193 | formula, |
| 194 | precision, |
| 195 | sepDecimal, |
| 196 | valueType, |
| 197 | sepThousands, |
| 198 | dateFormat |
| 199 | } = (0,_functions__WEBPACK_IMPORTED_MODULE_0__.getCalculatedWrapper)(node).dataset; |
| 200 | this.formula = formula; |
| 201 | this.precision = +precision; |
| 202 | this.sepDecimal = sepDecimal !== null && sepDecimal !== void 0 ? sepDecimal : ''; |
| 203 | this.sepThousands = sepThousands !== null && sepThousands !== void 0 ? sepThousands : ''; |
| 204 | this.visibleValNode = node.nextElementSibling; |
| 205 | this.valueTypeProp = valueType; |
| 206 | this.dateFormat = dateFormat; |
| 207 | this.inputType = 'calculated'; |
| 208 | }; |
| 209 | this.addListeners = function () { |
| 210 | // silence is golden |
| 211 | }; |
| 212 | |
| 213 | // calculated field can't be validated |
| 214 | this.report = () => {}; |
| 215 | this.reQueryValue = () => {}; |
| 216 | this.revertValue = () => {}; |
| 217 | } |
| 218 | CalculatedData.prototype = Object.create(InputData.prototype); |
| 219 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (CalculatedData); |
| 220 | |
| 221 | /***/ }, |
| 222 | |
| 223 | /***/ "./frontend/calculated.field/signal.js" |
| 224 | /*!*********************************************!*\ |
| 225 | !*** ./frontend/calculated.field/signal.js ***! |
| 226 | \*********************************************/ |
| 227 | (__unused_webpack_module, __webpack_exports__, __webpack_require__) { |
| 228 | |
| 229 | __webpack_require__.r(__webpack_exports__); |
| 230 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { |
| 231 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) |
| 232 | /* harmony export */ }); |
| 233 | /* harmony import */ var _functions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./functions */ "./frontend/calculated.field/functions.js"); |
| 234 | |
| 235 | const { |
| 236 | BaseSignal |
| 237 | } = window.JetFormBuilderAbstract; |
| 238 | |
| 239 | /** |
| 240 | * @property {CalculatedData} input Related input instance |
| 241 | */ |
| 242 | function SignalCalculated() { |
| 243 | BaseSignal.call(this); |
| 244 | this.isSupported = function (node) { |
| 245 | return (0,_functions__WEBPACK_IMPORTED_MODULE_0__.isCalculated)(node); |
| 246 | }; |
| 247 | this.baseSignal = function () { |
| 248 | const [node] = this.input.nodes; |
| 249 | const isNumber = 'number' === this.input.valueTypeProp; |
| 250 | this.input.calcValue = isNumber ? this.withPrecision() : this.input.value.current; |
| 251 | this.input.value.silence(); |
| 252 | this.input.value.current = isNumber ? this.convertValue() : this.input.value.current; |
| 253 | this.input.value.silence(); |
| 254 | this.input.visibleValNode.textContent = this.input.value.current; |
| 255 | node.value = this.input.calcValue; |
| 256 | }; |
| 257 | this.runSignal = function () { |
| 258 | this.baseSignal(); |
| 259 | const [node] = this.input.nodes; |
| 260 | this.triggerJQuery(node); |
| 261 | }; |
| 262 | } |
| 263 | SignalCalculated.prototype = Object.create(BaseSignal.prototype); |
| 264 | SignalCalculated.prototype.convertValue = function () { |
| 265 | const value = this.input.value.current; |
| 266 | if (Number.isNaN(Number(value))) { |
| 267 | return 0; |
| 268 | } |
| 269 | const parts = this.withPrecision().toString().split('.'); |
| 270 | if (this.input.sepThousands) { |
| 271 | parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, this.input.sepThousands); |
| 272 | } |
| 273 | return parts.join(this.input.sepDecimal); |
| 274 | }; |
| 275 | SignalCalculated.prototype.withPrecision = function () { |
| 276 | return Number(this.input.value.current).toFixed(this.input.precision); |
| 277 | }; |
| 278 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SignalCalculated); |
| 279 | |
| 280 | /***/ } |
| 281 | |
| 282 | /******/ }); |
| 283 | /************************************************************************/ |
| 284 | /******/ // The module cache |
| 285 | /******/ var __webpack_module_cache__ = {}; |
| 286 | /******/ |
| 287 | /******/ // The require function |
| 288 | /******/ function __webpack_require__(moduleId) { |
| 289 | /******/ // Check if module is in cache |
| 290 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; |
| 291 | /******/ if (cachedModule !== undefined) { |
| 292 | /******/ return cachedModule.exports; |
| 293 | /******/ } |
| 294 | /******/ // Create a new module (and put it into the cache) |
| 295 | /******/ var module = __webpack_module_cache__[moduleId] = { |
| 296 | /******/ // no module.id needed |
| 297 | /******/ // no module.loaded needed |
| 298 | /******/ exports: {} |
| 299 | /******/ }; |
| 300 | /******/ |
| 301 | /******/ // Execute the module function |
| 302 | /******/ if (!(moduleId in __webpack_modules__)) { |
| 303 | /******/ delete __webpack_module_cache__[moduleId]; |
| 304 | /******/ var e = new Error("Cannot find module '" + moduleId + "'"); |
| 305 | /******/ e.code = 'MODULE_NOT_FOUND'; |
| 306 | /******/ throw e; |
| 307 | /******/ } |
| 308 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); |
| 309 | /******/ |
| 310 | /******/ // Return the exports of the module |
| 311 | /******/ return module.exports; |
| 312 | /******/ } |
| 313 | /******/ |
| 314 | /************************************************************************/ |
| 315 | /******/ /* webpack/runtime/define property getters */ |
| 316 | /******/ (() => { |
| 317 | /******/ // define getter functions for harmony exports |
| 318 | /******/ __webpack_require__.d = (exports, definition) => { |
| 319 | /******/ for(var key in definition) { |
| 320 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { |
| 321 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); |
| 322 | /******/ } |
| 323 | /******/ } |
| 324 | /******/ }; |
| 325 | /******/ })(); |
| 326 | /******/ |
| 327 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ |
| 328 | /******/ (() => { |
| 329 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) |
| 330 | /******/ })(); |
| 331 | /******/ |
| 332 | /******/ /* webpack/runtime/make namespace object */ |
| 333 | /******/ (() => { |
| 334 | /******/ // define __esModule on exports |
| 335 | /******/ __webpack_require__.r = (exports) => { |
| 336 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { |
| 337 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); |
| 338 | /******/ } |
| 339 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); |
| 340 | /******/ }; |
| 341 | /******/ })(); |
| 342 | /******/ |
| 343 | /************************************************************************/ |
| 344 | var __webpack_exports__ = {}; |
| 345 | // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk. |
| 346 | (() => { |
| 347 | /*!*******************************************!*\ |
| 348 | !*** ./frontend/calculated.field/main.js ***! |
| 349 | \*******************************************/ |
| 350 | __webpack_require__.r(__webpack_exports__); |
| 351 | /* harmony import */ var _input__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./input */ "./frontend/calculated.field/input.js"); |
| 352 | /* harmony import */ var _signal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./signal */ "./frontend/calculated.field/signal.js"); |
| 353 | |
| 354 | |
| 355 | const { |
| 356 | addFilter |
| 357 | } = JetPlugins.hooks; |
| 358 | addFilter('jet.fb.inputs', 'jet-form-builder/calculated-field', function (inputs) { |
| 359 | inputs = [_input__WEBPACK_IMPORTED_MODULE_0__["default"], ...inputs]; |
| 360 | return inputs; |
| 361 | }); |
| 362 | addFilter('jet.fb.signals', 'jet-form-builder/calculated-field', function (signals) { |
| 363 | signals = [_signal__WEBPACK_IMPORTED_MODULE_1__["default"], ...signals]; |
| 364 | return signals; |
| 365 | }); |
| 366 | })(); |
| 367 | |
| 368 | /******/ })() |
| 369 | ; |
| 370 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJvbnRlbmQvY2FsY3VsYXRlZC5maWVsZC5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFJQTtBQUVBO0FBSUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUlBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7OztBQy9HQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUVBO0FBSUE7QUFDQTtBQUNBO0FBRUE7QUFNQTtBQUdBO0FBRUE7QUFHQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBR0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBRUE7Ozs7Ozs7Ozs7Ozs7OztBQzNIQTtBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFJQTtBQUNBO0FBR0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFJQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FDdEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1BBOzs7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDTkE7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUVBO0FBSUE7QUFFQTtBQUNBO0FBR0E7QUFJQTtBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qZmIvLi9mcm9udGVuZC9jYWxjdWxhdGVkLmZpZWxkL2Z1bmN0aW9ucy5qcyIsIndlYnBhY2s6Ly9qZmIvLi9mcm9udGVuZC9jYWxjdWxhdGVkLmZpZWxkL2lucHV0LmpzIiwid2VicGFjazovL2pmYi8uL2Zyb250ZW5kL2NhbGN1bGF0ZWQuZmllbGQvc2lnbmFsLmpzIiwid2VicGFjazovL2pmYi93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9qZmIvd2VicGFjay9ydW50aW1lL2RlZmluZSBwcm9wZXJ0eSBnZXR0ZXJzIiwid2VicGFjazovL2pmYi93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL2pmYi93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL2pmYi8uL2Zyb250ZW5kL2NhbGN1bGF0ZWQuZmllbGQvbWFpbi5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBnZXRDYWxjdWxhdGVkV3JhcHBlciggbm9kZSApIHtcblx0cmV0dXJuIG5vZGUuY2xvc2VzdCggJy5qZXQtZm9ybS1idWlsZGVyX19jYWxjdWxhdGVkLWZpZWxkJyApO1xufVxuXG4vKipcbiAqIEBwYXJhbSAgbm9kZSB7SFRNTEVsZW1lbnR9XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc0NhbGN1bGF0ZWQoIG5vZGUgKSB7XG5cdHJldHVybiAhIShcblx0XHRnZXRDYWxjdWxhdGVkV3JhcHBlciggbm9kZSApPy5kYXRhc2V0Py5mb3JtdWxhPy5sZW5ndGggPz8gJydcblx0KTtcbn1cblxuLyoqXG4gKiBGb3JtYXRzIG1pbGxpc2Vjb25kcyBpbnRvIGEgc3RyaW5nIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGZvcm1hdC5cbiAqXG4gKiBTdXBwb3J0ZWQgcGxhY2Vob2xkZXJzOlxuICogWVlZWSDigJQgNC1kaWdpdCB5ZWFyICgyMDI0KVxuICogTU0gICDigJQgbW9udGggd2l0aCBsZWFkaW5nIHplcm8gKDAx4oCTMTIpXG4gKiBNICAgIOKAlCBtb250aCB3aXRob3V0IGxlYWRpbmcgemVybyAoMeKAkzEyKVxuICogTU1NICDigJQgYWJicmV2aWF0ZWQgbW9udGggbmFtZSAoSmFu4oCTRGVjKVxuICogTU1NTSDigJQgZnVsbCBtb250aCBuYW1lIChKYW51YXJ54oCTRGVjZW1iZXIpXG4gKiBERCAgIOKAlCBkYXkgb2YgbW9udGggd2l0aCBsZWFkaW5nIHplcm8gKDAx4oCTMzEpXG4gKiBEICAgIOKAlCBkYXkgb2YgbW9udGggd2l0aG91dCBsZWFkaW5nIHplcm8gKDHigJMzMSlcbiAqIEhIICAg4oCUIGhvdXJzIHdpdGggbGVhZGluZyB6ZXJvICgwMOKAkzIzKSBpbiAyNC1ob3VyIGZvcm1hdFxuICogSCAgICDigJQgaG91cnMgd2l0aG91dCBsZWFkaW5nIHplcm8gKDDigJMyMykgaW4gMjQtaG91ciBmb3JtYXRcbiAqIGhoICAg4oCUIGhvdXJzIHdpdGggbGVhZGluZyB6ZXJvICgwMeKAkzEyKSBpbiAxMi1ob3VyIGZvcm1hdFxuICogaCAgICDigJQgaG91cnMgd2l0aG91dCBsZWFkaW5nIHplcm8gKDHigJMxMikgaW4gMTItaG91ciBmb3JtYXRcbiAqIG1tICAg4oCUIG1pbnV0ZXMgd2l0aCBsZWFkaW5nIHplcm8gKDAw4oCTNTkpXG4gKiBtICAgIOKAlCBtaW51dGVzIHdpdGhvdXQgbGVhZGluZyB6ZXJvICgw4oCTNTkpXG4gKiBzcyAgIOKAlCBzZWNvbmRzIHdpdGggbGVhZGluZyB6ZXJvICgwMOKAkzU5KVxuICogcyAgICDigJQgc2Vjb25kcyB3aXRob3V0IGxlYWRpbmcgemVybyAoMOKAkzU5KVxuICogZGRkZCDigJQgZnVsbCBkYXkgb2Ygd2VlayBuYW1lIChNb25kYXnigJNTdW5kYXkpXG4gKiBkZGQgIOKAlCBhYmJyZXZpYXRlZCBkYXkgb2Ygd2VlayBuYW1lIChNb27igJNTdW4pXG4gKiBBICAgIOKAlCBBTS9QTSBkZXNpZ25hdGlvblxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gbWlsbGlzSW5wdXQg4oCUIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdCDigJQgZm9ybWF0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ3xudW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRNaWxsaXNUb0RhdGVTdHJpbmcoIG1pbGxpc0lucHV0LCBmb3JtYXQgPSAnWVlZWS1NTS1ERCcgKSB7XG5cdGNvbnN0IG1pbGxpcyA9IGV2YWwoIG1pbGxpc0lucHV0ICk7XG5cblx0aWYgKCAhbWlsbGlzIHx8IGlzTmFOKCBtaWxsaXMgKSB8fCBudWxsID09PSBtaWxsaXMgfHwgMCA9PT0gbWlsbGlzICkge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cblx0Y29uc3QgZGF0ZSA9IG5ldyBEYXRlKCBtaWxsaXMgKTtcblxuXHRjb25zdCBtb250aHNGdWxsID0gW1xuXHRcdCdKYW51YXJ5JywgJ0ZlYnJ1YXJ5JywgJ01hcmNoJywgJ0FwcmlsJywgJ01heScsICdKdW5lJyxcblx0XHQnSnVseScsICdBdWd1c3QnLCAnU2VwdGVtYmVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXG5cdF07XG5cdGNvbnN0IG1vbnRoc1Nob3J0ID0gbW9udGhzRnVsbC5tYXAoIG0gPT4gbS5zbGljZSggMCwgMyApICk7XG5cblx0Y29uc3QgZGF5c0Z1bGwgPSBbXG5cdFx0J1N1bmRheScsICdNb25kYXknLCAnVHVlc2RheScsICdXZWRuZXNkYXknLCAnVGh1cnNkYXknLCAnRnJpZGF5JywgJ1NhdHVyZGF5J1xuXHRdO1xuXG5cdGNvbnN0IGRheXNTaG9ydCA9IGRheXNGdWxsLm1hcCggZCA9PiBkLnNsaWNlKCAwLCAzICkgKTtcblxuXHRjb25zdCBob3VyczEyID0gZGF0ZS5nZXRIb3VycygpICUgMTIgfHwgMTI7IC8vIENvbnZlcnQgMCB0byAxMiBmb3IgMTItaG91ciBmb3JtYXRcblx0Y29uc3QgYW1wbSAgICA9IGRhdGUuZ2V0SG91cnMoKSA+PSAxMiA/ICdQTScgOiAnQU0nO1xuXG5cdGNvbnN0IG1hcCA9IHtcblx0XHRZWVlZOiBkYXRlLmdldEZ1bGxZZWFyKCksXG5cdFx0TU06IFN0cmluZyggZGF0ZS5nZXRNb250aCgpICsgMSApLnBhZFN0YXJ0KCAyLCAnMCcgKSxcblx0XHRNOiBkYXRlLmdldE1vbnRoKCkgKyAxLFxuXHRcdE1NTTogbW9udGhzU2hvcnRbIGRhdGUuZ2V0TW9udGgoKSBdLFxuXHRcdE1NTU06IG1vbnRoc0Z1bGxbIGRhdGUuZ2V0TW9udGgoKSBdLFxuXHRcdEREOiBTdHJpbmcoIGRhdGUuZ2V0RGF0ZSgpICkucGFkU3RhcnQoIDIsICcwJyApLFxuXHRcdEQ6IGRhdGUuZ2V0RGF0ZSgpLFxuXHRcdEhIOiBTdHJpbmcoIGRhdGUuZ2V0SG91cnMoKSApLnBhZFN0YXJ0KCAyLCAnMCcgKSxcblx0XHRIOiBkYXRlLmdldEhvdXJzKCksXG5cdFx0aGg6IFN0cmluZyggaG91cnMxMiApLnBhZFN0YXJ0KCAyLCAnMCcgKSwgLy8gMTItaG91ciBmb3JtYXQgd2l0aCBsZWFkaW5nIHplcm9cblx0XHRoOiBob3VyczEyLCAvLyAxMi1ob3VyIGZvcm1hdCB3aXRob3V0IGxlYWRpbmcgemVyb1xuXHRcdG1tOiBTdHJpbmcoIGRhdGUuZ2V0TWludXRlcygpICkucGFkU3RhcnQoIDIsICcwJyApLFxuXHRcdG06IGRhdGUuZ2V0TWludXRlcygpLFxuXHRcdHNzOiBTdHJpbmcoIGRhdGUuZ2V0U2Vjb25kcygpICkucGFkU3RhcnQoIDIsICcwJyApLFxuXHRcdHM6IGRhdGUuZ2V0U2Vjb25kcygpLFxuXHRcdGRkZGQ6IGRheXNGdWxsWyBkYXRlLmdldERheSgpIF0sXG5cdFx0ZGRkOiBkYXlzU2hvcnRbIGRhdGUuZ2V0RGF5KCkgXSxcblx0XHRBOiBhbXBtLCAvLyBBTS9QTVxuXHR9O1xuXG5cdGNvbnN0IHNvcnRlZEtleXMgPSBPYmplY3Qua2V5cyggbWFwICkuc29ydCggKCBhLCBiICkgPT4gYi5sZW5ndGggLSBhLmxlbmd0aCApO1xuXG5cdC8vIFVzZSB0ZW1wb3JhcnkgcGxhY2Vob2xkZXJzIHRvIHByZXZlbnQgY29uZmxpY3RzXG5cdGxldCBmb3JtYXR0ZWQgPSBmb3JtYXQ7XG5cdGNvbnN0IHBsYWNlaG9sZGVycyA9IHt9O1xuXG5cdC8vIEZpcnN0IHBhc3M6IHJlcGxhY2UgZm9ybWF0IHRva2VucyB3aXRoIHVuaXF1ZSBwbGFjZWhvbGRlcnNcblx0c29ydGVkS2V5cy5mb3JFYWNoKCAoIGtleSwgaW5kZXggKSA9PiB7XG5cdFx0Y29uc3QgcGxhY2Vob2xkZXIgPSBgXFx4MDAke2luZGV4fVxceDAwYDsgLy8gVXNlIGluZGV4LWJhc2VkIHVuaXF1ZSBpZGVudGlmaWVyXG5cdFx0cGxhY2Vob2xkZXJzW3BsYWNlaG9sZGVyXSA9IFN0cmluZyggbWFwW2tleV0gKTtcblxuXHRcdC8vIFVzZSB3b3JkIGJvdW5kYXJpZXMgZm9yIHNpbmdsZS1sZXR0ZXIgdG9rZW5zIHRvIGF2b2lkIHJlcGxhY2luZyBsZXR0ZXJzIGluIHRleHRcblx0XHRjb25zdCBwYXR0ZXJuID0ga2V5Lmxlbmd0aCA8PSAyICYmIC9eW2EtekEtWl0rJC8udGVzdCgga2V5IClcblx0XHRcdD8gbmV3IFJlZ0V4cCggYFxcXFxiJHtrZXl9XFxcXGJgLCAnZycgKVxuXHRcdFx0OiBuZXcgUmVnRXhwKCBrZXksICdnJyApO1xuXG5cdFx0Zm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UoIHBhdHRlcm4sIHBsYWNlaG9sZGVyICk7XG5cdH0gKTtcblxuXHQvLyBTZWNvbmQgcGFzczogcmVwbGFjZSBwbGFjZWhvbGRlcnMgd2l0aCBhY3R1YWwgdmFsdWVzXG5cdGZvciAoIGNvbnN0IFtwbGFjZWhvbGRlciwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKCBwbGFjZWhvbGRlcnMgKSApIHtcblx0XHRmb3JtYXR0ZWQgPSBmb3JtYXR0ZWQuc3BsaXQoIHBsYWNlaG9sZGVyICkuam9pbiggdmFsdWUgKTtcblx0fVxuXG5cdHJldHVybiBmb3JtYXR0ZWQ7XG59XG5cbmV4cG9ydCB7IGlzQ2FsY3VsYXRlZCwgZ2V0Q2FsY3VsYXRlZFdyYXBwZXIsIGNvbnZlcnRNaWxsaXNUb0RhdGVTdHJpbmcgfTsiLCJpbXBvcnQgeyBnZXRDYWxjdWxhdGVkV3JhcHBlciwgaXNDYWxjdWxhdGVkLCBjb252ZXJ0TWlsbGlzVG9EYXRlU3RyaW5nIH0gZnJvbSAnLi9mdW5jdGlvbnMnO1xuXG5jb25zdCB7XG5cdCAgICAgIElucHV0RGF0YSxcblx0ICAgICAgQ2FsY3VsYXRlZEZvcm11bGEsXG4gICAgICB9ID0gd2luZG93LkpldEZvcm1CdWlsZGVyQWJzdHJhY3Q7XG5jb25zdCB7XG5cdCAgICAgIGFwcGx5RmlsdGVycyxcbiAgICAgIH0gPSBKZXRQbHVnaW5zLmhvb2tzO1xuXG5jb25zdCB7XG5cdCAgICAgIGFwcGx5RmlsdGVyczogZGVwcmVjYXRlZEFwcGx5RmlsdGVycyA9IGZhbHNlLFxuICAgICAgfSA9IHdpbmRvdz8uSmV0Rm9ybUJ1aWxkZXJNYWluPy5maWx0ZXJzID8/IHt9O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxpbmVzLXBlci1mdW5jdGlvblxuZnVuY3Rpb24gQ2FsY3VsYXRlZERhdGEoKSB7XG5cdElucHV0RGF0YS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5mb3JtdWxhICAgICAgICA9ICcnO1xuXHR0aGlzLnByZWNpc2lvbiAgICAgID0gMDtcblx0dGhpcy5zZXBEZWNpbWFsICAgICA9ICcnO1xuXHR0aGlzLnNlcFRob3VzYW5kcyAgID0gJyc7XG5cdHRoaXMudmlzaWJsZVZhbE5vZGUgPSBudWxsO1xuXHR0aGlzLnZhbHVlVHlwZVByb3AgID0gJ251bWJlcic7XG5cblx0dGhpcy5pc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICggbm9kZSApIHtcblx0XHRyZXR1cm4gaXNDYWxjdWxhdGVkKCBub2RlICk7XG5cdH07XG5cdHRoaXMuc2V0VmFsdWUgICAgPSBmdW5jdGlvbiAoKSB7XG5cdFx0Y29uc3QgZm9ybXVsYSA9IG5ldyBDYWxjdWxhdGVkRm9ybXVsYSggdGhpcywgeyBmb3JjZUZ1bmN0aW9uOiB0cnVlIH0gKTtcblxuXHRcdGZvcm11bGEub2JzZXJ2ZSggdGhpcy5mb3JtdWxhICk7XG5cdFx0Zm9ybXVsYS5zZXRSZXN1bHQgICAgICAgPSAoKSA9PiB7XG5cdFx0XHRpZiAoICdkYXRlJyA9PT0gdGhpcy52YWx1ZVR5cGVQcm9wICkge1xuXHRcdFx0XHRjb25zdCBkYXRlX2Zvcm11bGEgPSBmb3JtdWxhLmNhbGN1bGF0ZSgpO1xuXHRcdFx0XHR0aGlzLnZhbHVlLmN1cnJlbnQgPSBjb252ZXJ0TWlsbGlzVG9EYXRlU3RyaW5nKCBkYXRlX2Zvcm11bGEsIHRoaXMuZGF0ZUZvcm1hdCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy52YWx1ZS5jdXJyZW50ID0gZm9ybXVsYS5jYWxjdWxhdGUoKTtcblx0XHRcdH1cblx0XHR9O1xuXHRcdGZvcm11bGEucmVsYXRlZENhbGxiYWNrID0gKCBpbnB1dCApID0+IHtcblx0XHRcdGNvbnN0IHZhbHVlID0gYXBwbHlGaWx0ZXJzKFxuXHRcdFx0XHQnamV0LmZiLmNhbGN1bGF0ZWQuY2FsbGJhY2snLFxuXHRcdFx0XHRmYWxzZSxcblx0XHRcdFx0aW5wdXQsXG5cdFx0XHRcdHRoaXMsXG5cdFx0XHQpO1xuXG5cdFx0XHRpZiAoIGZhbHNlICE9PSB2YWx1ZSApIHtcblx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCByZXNwb25zZSA9ICdudW1iZXInID09PSB0aGlzLnZhbHVlVHlwZVByb3Bcblx0XHRcdCAgICAgICAgICAgICAgICAgPyBpbnB1dC5jYWxjVmFsdWVcblx0XHRcdCAgICAgICAgICAgICAgICAgOiBpbnB1dC52YWx1ZS5jdXJyZW50O1xuXG5cdFx0XHRpZiAoIGZhbHNlID09PSBkZXByZWNhdGVkQXBwbHlGaWx0ZXJzICkge1xuXHRcdFx0XHRyZXR1cm4gcmVzcG9uc2U7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IGZpbHRlclJlc3VsdCA9IGRlcHJlY2F0ZWRBcHBseUZpbHRlcnMoXG5cdFx0XHRcdCdmb3Jtcy9jYWxjdWxhdGVkLWZpZWxkLXZhbHVlJyxcblx0XHRcdFx0aW5wdXQudmFsdWUuY3VycmVudCxcblx0XHRcdFx0alF1ZXJ5KCBpbnB1dC5ub2Rlc1sgMCBdICksXG5cdFx0XHQpO1xuXG5cdFx0XHRyZXR1cm4gZmlsdGVyUmVzdWx0ID09PSBpbnB1dC52YWx1ZS5jdXJyZW50XG5cdFx0XHQgICAgICAgPyByZXNwb25zZVxuXHRcdFx0ICAgICAgIDogZmlsdGVyUmVzdWx0O1xuXHRcdH07XG5cblx0XHRmb3JtdWxhLmVtcHR5VmFsdWUgPSAoKSA9PiAnbnVtYmVyJyA9PT0gdGhpcy52YWx1ZVR5cGVQcm9wXG5cdFx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAwXG5cdFx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJztcblx0XHRmb3JtdWxhLnNldFJlc3VsdCgpO1xuXHRcdHRoaXMudmFsdWUuY3VycmVudCA9IHRoaXMudmFsdWUuYXBwbHlTYW5pdGl6ZXJzKCB0aGlzLnZhbHVlLmN1cnJlbnQgKTtcblxuXHRcdHRoaXMuYmVmb3JlU3VibWl0KCAoIHJlc29sdmUgKSA9PiB7XG5cdFx0XHR0aGlzLnZhbHVlLnNpbGVuY2UoKTtcblx0XHRcdHRoaXMudmFsdWUuY3VycmVudCA9IG51bGw7XG5cdFx0XHR0aGlzLnZhbHVlLnNpbGVuY2UoKTtcblxuXHRcdFx0Zm9ybXVsYS5zZXRSZXN1bHQoKTtcblx0XHRcdHJlc29sdmUoKTtcblx0XHR9LCB0aGlzICk7XG5cdH07XG5cblx0dGhpcy5zZXROb2RlICAgICAgPSBmdW5jdGlvbiAoIG5vZGUgKSB7XG5cdFx0SW5wdXREYXRhLnByb3RvdHlwZS5zZXROb2RlLmNhbGwoIHRoaXMsIG5vZGUgKTtcblx0XHRJbnB1dERhdGEucHJvdG90eXBlLnJlUXVlcnlWYWx1ZSA9ICgpID0+IHt9O1xuXG5cdFx0Y29uc3Qge1xuXHRcdFx0ICAgICAgZm9ybXVsYSxcblx0XHRcdCAgICAgIHByZWNpc2lvbixcblx0XHRcdCAgICAgIHNlcERlY2ltYWwsXG5cdFx0XHQgICAgICB2YWx1ZVR5cGUsXG5cdFx0XHQgICAgICBzZXBUaG91c2FuZHMsXG5cdFx0XHQgICAgICBkYXRlRm9ybWF0LFxuXHRcdCAgICAgIH0gPSBnZXRDYWxjdWxhdGVkV3JhcHBlciggbm9kZSApLmRhdGFzZXQ7XG5cblx0XHR0aGlzLmZvcm11bGEgICAgICAgID0gZm9ybXVsYTtcblx0XHR0aGlzLnByZWNpc2lvbiAgICAgID0gK3ByZWNpc2lvbjtcblx0XHR0aGlzLnNlcERlY2ltYWwgICAgID0gc2VwRGVjaW1hbCA/PyAnJztcblx0XHR0aGlzLnNlcFRob3VzYW5kcyAgID0gc2VwVGhvdXNhbmRzID8/ICcnO1xuXHRcdHRoaXMudmlzaWJsZVZhbE5vZGUgPSBub2RlLm5leHRFbGVtZW50U2libGluZztcblx0XHR0aGlzLnZhbHVlVHlwZVByb3AgID0gdmFsdWVUeXBlO1xuXHRcdHRoaXMuZGF0ZUZvcm1hdCAgICAgPSBkYXRlRm9ybWF0O1xuXHRcdHRoaXMuaW5wdXRUeXBlICAgICAgPSAnY2FsY3VsYXRlZCc7XG5cdH07XG5cdHRoaXMuYWRkTGlzdGVuZXJzID0gZnVuY3Rpb24gKCkge1xuXHRcdC8vIHNpbGVuY2UgaXMgZ29sZGVuXG5cdH07XG5cblx0Ly8gY2FsY3VsYXRlZCBmaWVsZCBjYW4ndCBiZSB2YWxpZGF0ZWRcblx0dGhpcy5yZXBvcnQgPSAoKSA9PiB7fTtcblxuXHR0aGlzLnJlUXVlcnlWYWx1ZSA9ICgpID0+IHt9O1xuXG5cdHRoaXMucmV2ZXJ0VmFsdWUgPSAoKSA9PiB7fTtcbn1cblxuQ2FsY3VsYXRlZERhdGEucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggSW5wdXREYXRhLnByb3RvdHlwZSApO1xuXG5leHBvcnQgZGVmYXVsdCBDYWxjdWxhdGVkRGF0YTtcbiIsImltcG9ydCB7IGlzQ2FsY3VsYXRlZCB9IGZyb20gJy4vZnVuY3Rpb25zJztcblxuY29uc3Qge1xuXHQgICAgICBCYXNlU2lnbmFsLFxuICAgICAgfSA9IHdpbmRvdy5KZXRGb3JtQnVpbGRlckFic3RyYWN0O1xuXG4vKipcbiAqIEBwcm9wZXJ0eSB7Q2FsY3VsYXRlZERhdGF9IGlucHV0IFJlbGF0ZWQgaW5wdXQgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gU2lnbmFsQ2FsY3VsYXRlZCgpIHtcblx0QmFzZVNpZ25hbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5pc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICggbm9kZSApIHtcblx0XHRyZXR1cm4gaXNDYWxjdWxhdGVkKCBub2RlICk7XG5cdH07XG5cblx0dGhpcy5iYXNlU2lnbmFsID0gZnVuY3Rpb24gKCkge1xuXHRcdGNvbnN0IFsgbm9kZSBdID0gdGhpcy5pbnB1dC5ub2RlcztcblxuXHRcdGNvbnN0IGlzTnVtYmVyID0gJ251bWJlcicgPT09IHRoaXMuaW5wdXQudmFsdWVUeXBlUHJvcDtcblxuXHRcdHRoaXMuaW5wdXQuY2FsY1ZhbHVlID0gaXNOdW1iZXJcblx0XHQgICAgICAgICAgICAgICAgICAgICAgID8gdGhpcy53aXRoUHJlY2lzaW9uKClcblx0XHQgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5pbnB1dC52YWx1ZS5jdXJyZW50O1xuXG5cdFx0dGhpcy5pbnB1dC52YWx1ZS5zaWxlbmNlKCk7XG5cdFx0dGhpcy5pbnB1dC52YWx1ZS5jdXJyZW50ID0gaXNOdW1iZXJcblx0XHQgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMuY29udmVydFZhbHVlKClcblx0XHQgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuaW5wdXQudmFsdWUuY3VycmVudDtcblx0XHR0aGlzLmlucHV0LnZhbHVlLnNpbGVuY2UoKTtcblxuXHRcdHRoaXMuaW5wdXQudmlzaWJsZVZhbE5vZGUudGV4dENvbnRlbnQgPSB0aGlzLmlucHV0LnZhbHVlLmN1cnJlbnQ7XG5cblx0XHRub2RlLnZhbHVlID0gdGhpcy5pbnB1dC5jYWxjVmFsdWU7XG5cdH07XG5cblx0dGhpcy5ydW5TaWduYWwgPSBmdW5jdGlvbiAoKSB7XG5cdFx0dGhpcy5iYXNlU2lnbmFsKCk7XG5cblx0XHRjb25zdCBbIG5vZGUgXSA9IHRoaXMuaW5wdXQubm9kZXM7XG5cblx0XHR0aGlzLnRyaWdnZXJKUXVlcnkoIG5vZGUgKTtcblx0fTtcbn1cblxuU2lnbmFsQ2FsY3VsYXRlZC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBCYXNlU2lnbmFsLnByb3RvdHlwZSApO1xuXG5TaWduYWxDYWxjdWxhdGVkLnByb3RvdHlwZS5jb252ZXJ0VmFsdWUgPSBmdW5jdGlvbiAoKSB7XG5cdGNvbnN0IHZhbHVlID0gdGhpcy5pbnB1dC52YWx1ZS5jdXJyZW50O1xuXG5cdGlmICggTnVtYmVyLmlzTmFOKCBOdW1iZXIoIHZhbHVlICkgKSApIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXG5cdGNvbnN0IHBhcnRzID0gdGhpcy53aXRoUHJlY2lzaW9uKCkudG9TdHJpbmcoKS5zcGxpdCggJy4nICk7XG5cblx0aWYgKCB0aGlzLmlucHV0LnNlcFRob3VzYW5kcyApIHtcblx0XHRwYXJ0c1sgMCBdID0gcGFydHNbIDAgXS5yZXBsYWNlKFxuXHRcdFx0L1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csXG5cdFx0XHR0aGlzLmlucHV0LnNlcFRob3VzYW5kcyxcblx0XHQpO1xuXHR9XG5cblx0cmV0dXJuIHBhcnRzLmpvaW4oIHRoaXMuaW5wdXQuc2VwRGVjaW1hbCApO1xufTtcblxuU2lnbmFsQ2FsY3VsYXRlZC5wcm90b3R5cGUud2l0aFByZWNpc2lvbiA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuIE51bWJlciggdGhpcy5pbnB1dC52YWx1ZS5jdXJyZW50ICkudG9GaXhlZCggdGhpcy5pbnB1dC5wcmVjaXNpb24gKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNpZ25hbENhbGN1bGF0ZWQ7IiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRpZiAoIShtb2R1bGVJZCBpbiBfX3dlYnBhY2tfbW9kdWxlc19fKSkge1xuXHRcdGRlbGV0ZSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRcdHZhciBlID0gbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIiArIG1vZHVsZUlkICsgXCInXCIpO1xuXHRcdGUuY29kZSA9ICdNT0RVTEVfTk9UX0ZPVU5EJztcblx0XHR0aHJvdyBlO1xuXHR9XG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyIsImltcG9ydCBDYWxjdWxhdGVkRGF0YSBmcm9tICcuL2lucHV0JztcbmltcG9ydCBTaWduYWxDYWxjdWxhdGVkIGZyb20gJy4vc2lnbmFsJztcblxuY29uc3QgeyBhZGRGaWx0ZXIgfSA9IEpldFBsdWdpbnMuaG9va3M7XG5cbmFkZEZpbHRlcihcblx0J2pldC5mYi5pbnB1dHMnLFxuXHQnamV0LWZvcm0tYnVpbGRlci9jYWxjdWxhdGVkLWZpZWxkJyxcblx0ZnVuY3Rpb24gKCBpbnB1dHMgKSB7XG5cdFx0aW5wdXRzID0gWyBDYWxjdWxhdGVkRGF0YSwgLi4uaW5wdXRzIF07XG5cblx0XHRyZXR1cm4gaW5wdXRzO1xuXHR9LFxuKTtcblxuYWRkRmlsdGVyKFxuXHQnamV0LmZiLnNpZ25hbHMnLFxuXHQnamV0LWZvcm0tYnVpbGRlci9jYWxjdWxhdGVkLWZpZWxkJyxcblx0ZnVuY3Rpb24gKCBzaWduYWxzICkge1xuXHRcdHNpZ25hbHMgPSBbIFNpZ25hbENhbGN1bGF0ZWQsIC4uLnNpZ25hbHMgXTtcblxuXHRcdHJldHVybiBzaWduYWxzO1xuXHR9LFxuKTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0= |