1(self["webpackChunkWebComponents"] = self["webpackChunkWebComponents"] || []).push([["runestone"],{ 2 3/***/ 88288: 4/*!*************************************************!*\ 5 !*** ./runestone/common/css/presenter_mode.css ***! 6 \*************************************************/ 7/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 8 9"use strict"; 10__webpack_require__.r(__webpack_exports__); 11// extracted by mini-css-extract-plugin 12 13 14/***/ }), 15 16/***/ 64778: 17/*!********************************************************************!*\ 18 !*** ./runestone/common/css/runestone-custom-sphinx-bootstrap.css ***! 19 \********************************************************************/ 20/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 21 22"use strict"; 23__webpack_require__.r(__webpack_exports__); 24// extracted by mini-css-extract-plugin 25 26 27/***/ }), 28 29/***/ 88874: 30/*!**************************************************!*\ 31 !*** ./runestone/common/css/user-highlights.css ***! 32 \**************************************************/ 33/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 34 35"use strict"; 36__webpack_require__.r(__webpack_exports__); 37// extracted by mini-css-extract-plugin 38 39 40/***/ }), 41 42/***/ 23746: 43/*!*********************************************!*\ 44 !*** ./runestone/matrixeq/css/matrixeq.css ***! 45 \*********************************************/ 46/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 47 48"use strict"; 49__webpack_require__.r(__webpack_exports__); 50// extracted by mini-css-extract-plugin 51 52 53/***/ }), 54 55/***/ 86324: 56/*!******************************************************!*\ 57 !*** ./runestone/webgldemo/css/webglinteractive.css ***! 58 \******************************************************/ 59/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 60 61"use strict"; 62__webpack_require__.r(__webpack_exports__); 63// extracted by mini-css-extract-plugin 64 65 66/***/ }), 67 68/***/ 21294: 69/*!******************************************!*\ 70 !*** ./runestone/common/js/bookfuncs.js ***! 71 \******************************************/ 72/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 73 74"use strict"; 75__webpack_require__.r(__webpack_exports__); 76/* harmony export */ __webpack_require__.d(__webpack_exports__, { 77/* harmony export */ "pageProgressTracker": () => (/* binding */ pageProgressTracker) 78/* harmony export */ }); 79/** 80 * 81 * User: bmiller 82 * Original: 2011-04-20 83 * Date: 2019-06-14 84 * Time: 2:01 PM 85 * This change marks the beginning of version 4.0 of the runestone components 86 * Login/logout is no longer handled through javascript but rather server side. 87 * Many of the components depend on the runestone:login event so we will keep that 88 * for now to keep the churn fairly minimal. 89 */ 90 91/* 92 93 Copyright (C) 2011 Brad Miller [email protected] 94 95 This program is free software: you can redistribute it and/or modify 96 it under the terms of the GNU General Public License as published by 97 the Free Software Foundation, either version 3 of the License, or 98 (at your option) any later version. 99 100 This program is distributed in the hope that it will be useful, 101 but WITHOUT ANY WARRANTY; without even the implied warranty of 102 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 103 GNU General Public License for more details. 104 105 You should have received a copy of the GNU General Public License 106 along with this program. If not, see <http://www.gnu.org/licenses/>. 107 108 */ 109 110// 111// Page decoration functions 112// 113 114function addReadingList() { 115 if (eBookConfig.readings) { 116 var l, nxt, path_parts, nxt_link; 117 let cur_path_parts = window.location.pathname.split("/"); 118 let name = 119 cur_path_parts[cur_path_parts.length - 2] + 120 "/" + 121 cur_path_parts[cur_path_parts.length - 1]; 122 let position = eBookConfig.readings.indexOf(name); 123 let num_readings = eBookConfig.readings.length; 124 if (position == eBookConfig.readings.length - 1) { 125 // no more readings 126 l = $("<div />", { 127 text: `Finished reading assignment. Page ${num_readings} of ${num_readings}.`, 128 }); 129 } else if (position >= 0) { 130 // get next name 131 nxt = eBookConfig.readings[position + 1]; 132 path_parts = cur_path_parts.slice(0, cur_path_parts.length - 2); 133 path_parts.push(nxt); 134 nxt_link = path_parts.join("/"); 135 l = $("<a />", { 136 name: "link", 137 class: "btn btn-lg ' + 'buttonConfirmCompletion'", 138 href: nxt_link, 139 text: `Continue to page ${ 140 position + 2 141 } of ${num_readings} in the reading assignment.`, 142 }); 143 } else { 144 l = $("<div />", { 145 text: "This page is not part of the last reading assignment you visited.", 146 }); 147 } 148 $("#main-content").append(l); 149 } 150} 151 152function timedRefresh() { 153 var timeoutPeriod = 900000; // 75 minutes 154 $(document).on("idle.idleTimer", function () {
155 // After timeout period send the user back to the index. This will force a login 156 // if needed when they want to go to a particular page. This may not be perfect 157 // but its an easy way to make sure laptop users are properly logged in when they 158 // take quizzes and save stuff. 159 if (location.href.indexOf("index.html") < 0) { 160 console.log("Idle timer - " + location.pathname); 161 location.href = 162 eBookConfig.app + 163 "/default/user/login?_next=" + 164 location.pathname + 165 location.search; 166 } 167 }); 168 $.idleTimer(timeoutPeriod); 169} 170 171class PageProgressBar { 172 constructor(actDict) { 173 this.possible = 0; 174 this.total = 1; 175 if (actDict && Object.keys(actDict).length > 0) { 176 this.activities = actDict; 177 } else { 178 let activities = { page: 0 }; 179 $(".runestone").each(function (idx, e) { 180 activities[e.firstElementChild.id] = 0; 181 }); 182 this.activities = activities; 183 } 184 this.calculateProgress(); 185 if ( 186 window.location.pathname.match( 187 /.*(index.html|toctree.html|Exercises.html|search.html)$/i 188 ) 189 ) { 190 $("#scprogresscontainer").hide(); 191 } 192 this.renderProgress(); 193 } 194 195 calculateProgress() { 196 for (let k in this.activities) { 197 if (k !== undefined) { 198 this.possible++; 199 if (this.activities[k] > 0) { 200 this.total++; 201 } 202 } 203 } 204 } 205 206 renderProgress() { 207 let value = 0; 208 $("#scprogresstotal").text(this.total); 209 $("#scprogressposs").text(this.possible); 210 try { 211 value = (100 * this.total) / this.possible; 212 } catch (e) { 213 value = 0; 214 } 215 $("#subchapterprogress").progressbar({ 216 value: value, 217 }); 218 if (!eBookConfig.isLoggedIn) { 219 $("#subchapterprogress>div").addClass("loggedout"); 220 } 221 } 222 223 updateProgress(div_id) { 224 this.activities[div_id]++; 225 // Only update the progress bar on the first interaction with an object. 226 if (this.activities[div_id] === 1) { 227 this.total++; 228 let val = (100 * this.total) / this.possible; 229 $("#scprogresstotal").text(this.total); 230 $("#scprogressposs").text(this.possible); 231 $("#subchapterprogress").progressbar("option", "value", val); 232 if ( 233 val == 100.0 && 234 $("#completionButton").text().toLowerCase() === 235 "mark as completed" 236 ) { 237 $("#completionButton").click(); 238 } 239 } 240 } 241} 242 243var pageProgressTracker = {}; 244 245async function handlePageSetup() { 246 var mess; 247 if (eBookConfig.useRunestoneServices) { 248 let headers = new Headers({ 249 "Content-type": "application/json; charset=utf-8", 250 Accept: "application/json", 251 }); 252 let data = { timezoneoffset: new Date().getTimezoneOffset() / 60 }; 253 let request = new Request( 254 `${eBookConfig.new_server_prefix}/logger/set_tz_offset`, 255 { 256 method: "POST", 257 body: JSON.stringify(data), 258 headers: headers, 259 } 260 ); 261 try { 262 let response = await fetch(request); 263 if (!response.ok) { 264 console.error(`Failed to set timezone! ${response.statusText}`); 265 } 266 data = await response.json(); 267 } catch (e) { 268 console.error(`Error setting timezone ${e}`); 269 } 270 } 271 console.log(`This page served by ${eBookConfig.served_by}`); 272 if (eBookConfig.isLoggedIn) { 273 mess = `username: ${eBookConfig.username}`; 274 if (!eBookConfig.isInstructor) { 275 $("#ip_dropdown_link").remove(); 276 $("#inst_peer_link").remove(); 277 } 278 $(document).trigger("runestone:login");
279 addReadingList(); 280 // Avoid the timedRefresh on the grading page. 281 if ( 282 window.location.pathname.indexOf("/admin/grading") == -1 && 283 window.location.pathname.indexOf("/peer/") == -1 284 ) { 285 timedRefresh(); 286 } 287 } else { 288 mess = "Not logged in"; 289 $(document).trigger("runestone:logout"); 290 let bw = document.getElementById("browsing_warning"); 291 if (bw) { 292 bw.innerHTML = 293 "<p class='navbar_message'>Saving and Logging are Disabled</p>"; 294 } 295 let aw = document.getElementById("ad_warning"); 296 if (aw) { 297 aw.innerHTML = 298 "<p class='navbar_message'>ð« Log-in to Remove <a href='/runestone/default/ads'>Ads!</a> ð« </p>"; 299 } 300 } 301 $(".loggedinuser").html(mess); 302 303 pageProgressTracker = new PageProgressBar(eBookConfig.activities); 304 notifyRunestoneComponents(); 305} 306 307function setupNavbarLoggedIn() { 308 $("#profilelink").show(); 309 $("#passwordlink").show(); 310 $("#registerlink").hide(); 311 $("li.loginout").html( 312 '<a href="' + eBookConfig.app + '/default/user/logout">Log Out</a>' 313 ); 314} 315$(document).on("runestone:login", setupNavbarLoggedIn); 316 317function setupNavbarLoggedOut() { 318 if (eBookConfig.useRunestoneServices) { 319 console.log("setup navbar for logged out"); 320 $("#registerlink").show(); 321 $("#profilelink").hide(); 322 $("#passwordlink").hide(); 323 $("#ip_dropdown_link").hide(); 324 $("#inst_peer_link").hide(); 325 $("li.loginout").html( 326 '<a href="' + eBookConfig.app + '/default/user/login">Login</a>' 327 ); 328 $(".footer").html("user not logged in"); 329 } 330} 331$(document).on("runestone:logout", setupNavbarLoggedOut); 332 333function notifyRunestoneComponents() { 334 // Runestone components wait until login process is over to load components because of storage issues. This triggers the `dynamic import machinery`, which then sends the login complete signal when this and all dynamic imports are finished. 335 $(document).trigger("runestone:pre-login-complete"); 336} 337 338function placeAdCopy() { 339 if (typeof showAd !== "undefined" && showAd) { 340 let adNum = Math.floor(Math.random() * 2) + 1; 341 let adBlock = document.getElementById(`adcopy_${adNum}`); 342 let rsElements = document.querySelectorAll(".runestone"); 343 if (rsElements.length > 0) { 344 let randomIndex = Math.floor(Math.random() * rsElements.length); 345 rsElements[randomIndex].after(adBlock) 346 adBlock.style.display = "block"; 347 } 348 } 349} 350 351// initialize stuff 352$(function () { 353 if (eBookConfig) { 354 handlePageSetup(); 355 placeAdCopy(); 356 } else { 357 if (typeof eBookConfig === "undefined") { 358 console.log( 359 "eBookConfig is not defined. This page must not be set up for Runestone" 360 ); 361 } 362 } 363}); 364 365// misc stuff 366// todo: This could be further distributed but making a video.js file just for one function seems dumb. 367window.addEventListener("load", function () { 368 // add the video play button overlay image 369 $(".video-play-overlay").each(function () { 370 $(this).css( 371 "background-image", 372 "url('{{pathto('_static/play_overlay_icon.png', 1)}}')" 373 ); 374 }); 375 376 // This function is needed to allow the dropdown search bar to work; 377 // The default behaviour is that the dropdown menu closes when something in 378 // it (like the search bar) is clicked 379 $(function () { 380 // Fix input element click problem 381 $(".dropdown input, .dropdown label").click(function (e) { 382 e.stopPropagation(); 383 }); 384 }); 385 386 // re-write some urls 387 // This is tricker than it looks and you have to obey the rules for # anchors 388 // The #anchors must come after the query string as the server basically ignores any part 389 // of a url that comes after # - like a comment... 390 if (location.href.includes("mode=browsing")) { 391 let queryString = "?mode=browsing"; 392 document.querySelectorAll("a").forEach((link) => { 393 let anchorText = ""; 394 if (link.href.includes("books/published") && ! link.href.includes("?mode=browsing")) { 395 if (link.href.includes("#")) { 396 let aPoint = link.href.indexOf("#"); 397 anchorText = link.href.substring(aPoint); 398 link.href = link.href.substring(0,aPoint); 399 } 400 link.href = link.href.includes("?") 401 ? link.href + queryString.replace("?", "&") + anchorText 402 : link.href + queryString + anchorText; 403 } 404 }); 405 } 406}); 407 408 409/***/ }), 410 411/***/ 26886: 412/*!**************************************************!*\ 413 !*** ./runestone/common/js/jquery.idle-timer.js ***! 414 \**************************************************/ 415/***/ (() => { 416 417/*! 418 * jQuery idleTimer plugin 419 * version 0.9.100511 420 * by Paul Irish. 421 * http://github.com/paulirish/yui-misc/tree/ 422 * MIT license 423 424 * adapted from YUI idle timer by nzakas: 425 * http://github.com/nzakas/yui-misc/ 426*/ 427/* 428 * Copyright (c) 2009 Nicholas C. Zakas 429 * 430 * Permission is hereby granted, free of charge, to any person obtaining a copy 431 * of this software and associated documentation files (the "Software"), to deal 432 * in the Software without restriction, including without limitation the rights 433 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 434 * copies of the Software, and to permit persons to whom the Software is 435 * furnished to do so, subject to the following conditions: 436 * 437 * The above copyright notice and this permission notice shall be included in 438 * all copies or substantial portions of the Software. 439 * 440 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 441 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 442 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 443 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 444 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 445 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 446 * THE SOFTWARE. 447 */ 448 449/* updated to fix Chrome setTimeout issue by Zaid Zawaideh */ 450 451 // API available in <= v0.8 452 /******************************* 453 454 // idleTimer() takes an optional argument that defines the idle timeout 455 // timeout is in milliseconds; defaults to 30000 456 $.idleTimer(10000); 457 458 459 $(document).bind("idle.idleTimer", function(){ 460 // function you want to fire when the user goes idle 461 }); 462 463 464 $(document).bind("active.idleTimer", function(){ 465 // function you want to fire when the user becomes active again 466 }); 467 468 // pass the string 'destroy' to stop the timer 469 $.idleTimer('destroy'); 470 471 // you can query if the user is idle or not with data() 472 $.data(document,'idleTimer'); // 'idle' or 'active' 473 474 // you can get time elapsed since user when idle/active 475 $.idleTimer('getElapsedTime'); // time since state change in ms 476 477 ********/ 478 479 480 481 // API available in >= v0.9 482 /************************* 483 484 // bind to specific elements, allows for multiple timer instances 485 $(elem).idleTimer(timeout|'destroy'|'getElapsedTime'); 486 $.data(elem,'idleTimer'); // 'idle' or 'active' 487 488 // if you're using the old $.idleTimer api, you should not do $(document).idleTimer(...) 489 490 // element bound timers will only watch for events inside of them.
491 // you may just want page-level activity, in which case you may set up 492 // your timers on document, document.documentElement, and document.body 493 494 // You can optionally provide a second argument to override certain options. 495 // Here are the defaults, so you can omit any or all of them. 496 $(elem).idleTimer(timeout, { 497 startImmediately: true, //starts a timeout as soon as the timer is set up; otherwise it waits for the first event. 498 idle: false, //indicates if the user is idle 499 enabled: true, //indicates if the idle timer is enabled 500 events: 'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove' // activity is one of these events 501 }); 502 503 ********/ 504 505(function($){ 506 507$.idleTimer = function(newTimeout, elem, opts){ 508 509 // defaults that are to be stored as instance props on the elem 510 511 opts = $.extend({ 512 startImmediately: true, //starts a timeout as soon as the timer is set up 513 idle: false, //indicates if the user is idle 514 enabled: true, //indicates if the idle timer is enabled 515 timeout: 30000, //the amount of time (ms) before the user is considered idle 516 events: 'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove' // activity is one of these events 517 }, opts); 518 519 520 elem = elem || document; 521 522 /* (intentionally not documented) 523 * Toggles the idle state and fires an appropriate event. 524 * @return {void} 525 */ 526 var toggleIdleState = function(myelem){ 527 528 // curse you, mozilla setTimeout lateness bug! 529 if (typeof myelem === 'number'){ 530 myelem = undefined; 531 } 532 533 var obj = $.data(myelem || elem,'idleTimerObj'); 534 535 //toggle the state 536 obj.idle = !obj.idle; 537 538 // reset timeout 539 var elapsed = (+new Date()) - obj.olddate; 540 obj.olddate = +new Date(); 541 542 // handle Chrome always triggering idle after js alert or comfirm popup 543 if (obj.idle && (elapsed < opts.timeout)) { 544 obj.idle = false; 545 clearTimeout($.idleTimer.tId); 546 if (opts.enabled) 547 $.idleTimer.tId = setTimeout(toggleIdleState, opts.timeout); 548 return; 549 } 550 551 //fire appropriate event 552 553 // create a custom event, but first, store the new state on the element 554 // and then append that string to a namespace 555 var event = jQuery.Event( $.data(elem,'idleTimer', obj.idle ? "idle" : "active" ) + '.idleTimer' ); 556 557 // we do want this to bubble, at least as a temporary fix for jQuery 1.7 558 // event.stopPropagation(); 559 $(elem).trigger(event); 560 }, 561 562 /** 563 * Stops the idle timer. This removes appropriate event handlers 564 * and cancels any pending timeouts. 565 * @return {void} 566 * @method stop 567 * @static 568 */ 569 stop = function(elem){ 570 571 var obj = $.data(elem,'idleTimerObj') || {}; 572 573 //set to disabled 574 obj.enabled = false; 575 576 //clear any pending timeouts 577 clearTimeout(obj.tId); 578 579 //detach the event handlers 580 $(elem).off('.idleTimer'); 581 }, 582 583 584 /* (intentionally not documented) 585 * Handles a user event indicating that the user isn't idle. 586 * @param {Event} event A DOM2-normalized event object. 587 * @return {void} 588 */ 589 handleUserEvent = function(){ 590 591 var obj = $.data(this,'idleTimerObj'); 592 593 //clear any existing timeout 594 clearTimeout(obj.tId); 595 596 597 598 //if the idle timer is enabled 599 if (obj.enabled){ 600 601 602 //if it's idle, that means the user is no longer idle 603 if (obj.idle){ 604 toggleIdleState(this); 605 } 606 607 //set a new timeout 608 obj.tId = setTimeout(toggleIdleState, obj.timeout); 609 610 } 611 }; 612 613 614 /** 615 * Starts the idle timer. This adds appropriate event handlers 616 * and starts the first timeout. 617 * @param {int} newTimeout (Optional) A new value for the timeout period in ms. 618 * @return {void} 619 * @method $.idleTimer 620 * @static 621 */ 622 623 624 var obj = $.data(elem,'idleTimerObj') || {}; 625 626 obj.olddate = obj.olddate || +new Date(); 627 628 //assign a new timeout if necessary 629 if (typeof newTimeout === "number"){ 630 opts.timeout = newTimeout; 631 } else if (newTimeout === 'destroy') { 632 stop(elem); 633 return this; 634 } else if (newTimeout === 'getElapsedTime'){ 635 return (+new Date()) - obj.olddate; 636 } 637 638 //assign appropriate event handlers 639 $(elem).on($.trim((opts.events+' ').split(' ').join('.idleTimer ')),handleUserEvent); 640 641 642 obj.idle = opts.idle; 643 obj.enabled = opts.enabled; 644 obj.timeout = opts.timeout; 645 646
647 //set a timeout to toggle state. May wish to omit this in some situations 648 if (opts.startImmediately) { 649 obj.tId = setTimeout(toggleIdleState, obj.timeout); 650 } 651 652 // assume the user is active for the first x seconds. 653 $.data(elem,'idleTimer',"active"); 654 655 // store our instance on the object 656 $.data(elem,'idleTimerObj',obj); 657 658 659 660}; // end of $.idleTimer() 661 662 663// v0.9 API for defining multiple timers. 664$.fn.idleTimer = function(newTimeout,opts){ 665 // Allow omission of opts for backward compatibility 666 if (!opts) { 667 opts = {}; 668 } 669 670 if(this[0]){ 671 $.idleTimer(newTimeout,this[0],opts); 672 } 673 674 return this; 675}; 676 677 678})(jQuery); 679 680 681/***/ }), 682 683/***/ 43793: 684/*!*********************************************************************!*\ 685 !*** ./runestone/common/js/jquery_i18n/jquery.i18n.emitter.bidi.js ***! 686 \*********************************************************************/ 687/***/ (() => { 688 689/*! 690 * BIDI embedding support for jQuery.i18n 691 * 692 * Copyright (C) 2015, David Chan 693 * 694 * This code is dual licensed GPLv2 or later and MIT. You don't have to do 695 * anything special to choose one license or the other and you don't have to 696 * notify anyone which license you are using. You are free to use this code 697 * in commercial projects as long as the copyright header is left intact. 698 * See files GPL-LICENSE and MIT-LICENSE for details. 699 * 700 * @licence GNU General Public Licence 2.0 or later 701 * @licence MIT License 702 */ 703 704( function ( $ ) { 705 'use strict'; 706 var strongDirRegExp; 707 708 /** 709 * Matches the first strong directionality codepoint: 710 * - in group 1 if it is LTR 711 * - in group 2 if it is RTL 712 * Does not match if there is no strong directionality codepoint. 713 * 714 * Generated by UnicodeJS (see tools/strongDir) from the UCD; see 715 * https://phabricator.wikimedia.org/diffusion/GUJS/ . 716 */ 717 strongDirRegExp = new RegExp( 718 '(?:' + 719 '(' + 720 '[\u0041-\u005a\u0061-\u007a\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u02bb-\u02c1\u02d0\u02d1\u02e0-\u02e4\u02ee\u0370-\u0373\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0482\u048a-\u052f\u0531-\u0556\u0559-\u055f\u0561-\u0587\u0589\u0903-\u0939\u093b\u093d-\u0940\u0949-\u094c\u094e-\u0950\u0958-\u0961\u0964-\u0980\u0982\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd-\u09c0\u09c7\u09c8\u09cb\u09cc\u09ce\u09d7\u09dc\u09dd\u09df-\u09e1\u09e6-\u09f1\u09f4-\u09fa\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3e-\u0a40\u0a59-\u0a5c\u0a5e\u0a66-\u0a6f\u0a72-\u0a74\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd-\u0ac0\u0ac9\u0acb\u0acc\u0ad0\u0ae0\u0ae1\u0ae6-\u0af0\u0af9\u0b02\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b3e\u0b40\u0b47\u0b48\u0b4b\u0b4c\u0b57\u0b5c\u0b5d\u0b5f-\u0b61\u0b66-\u0b77\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe\u0bbf\u0bc1\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcc\u0bd0\u0bd7\u0be6-\u0bf2\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c41-\u0c44\u0c58-\u0c5a\u0c60\u0c61\u0c66-\u0c6f\u0c7f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd-\u0cc4\u0cc6-\u0cc8\u0cca\u0ccb\u0cd5\u0cd6\u0cde\u0ce0\u0ce1\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d40\u0d46-\u0d48\u0d4a-\u0d4c\u0d4e\u0d57\u0d5f-\u0d61\u0d66-\u0d75\u0d79-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dcf-\u0dd1\u0dd8-\u0ddf\u0de6-\u0def\u0df2-\u0df4\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e4f-\u0e5b\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0ed0-\u0ed9\u0edc-\u0edf\u0f00-\u0f17\u0f1a-\u0f34\u0f36\u0f38\u0f3e-\u0f47\u0f49-\u0f6c\u0f7f\u0f85\u0f88-\u0f8c\u0fbe-\u0fc5\u0fc7-\u0fcc\u0fce-\u0fda\u1000-\u102c\u1031\u1038\u103b\u103c\u103f-\u1057\u105a-\u105d\u1061-\u1070\u1075-\u1081\u1083\u1084\u1087-\u108c\u108e-\u109c\u109e-\u10c5\u10c7\u10cd\u10d0-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1360-\u137c\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u167f\u1681-\u169a\u16a0-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1735\u1736\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17b6\u17be-\u17c5\u17c7\u17c8\u17d4-\u17da\u17dc\u17e0-\u17e9\u1810-\u1819\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1923-\u1926\u1929-\u192b\u1930\u1931\u1933-\u1938\u
7201946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19da\u1a00-\u1a16\u1a19\u1a1a\u1a1e-\u1a55\u1a57\u1a61\u1a63\u1a64\u1a6d-\u1a72\u1a80-\u1a89\u1a90-\u1a99\u1aa0-\u1aad\u1b04-\u1b33\u1b35\u1b3b\u1b3d-\u1b41\u1b43-\u1b4b\u1b50-\u1b6a\u1b74-\u1b7c\u1b82-\u1ba1\u1ba6\u1ba7\u1baa\u1bae-\u1be5\u1be7\u1bea-\u1bec\u1bee\u1bf2\u1bf3\u1bfc-\u1c2b\u1c34\u1c35\u1c3b-\u1c49\u1c4d-\u1c7f\u1cc0-\u1cc7\u1cd3\u1ce1\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200e\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u214f\u2160-\u2188\u2336-\u237a\u2395\u249c-\u24e9\u26ac\u2800-\u28ff\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d70\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u302e\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u3190-\u31ba\u31f0-\u321c\u3220-\u324f\u3260-\u327b\u327f-\u32b0\u32c0-\u32cb\u32d0-\u32fe\u3300-\u3376\u337b-\u33dd\u33e0-\u33fe\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua60c\ua610-\ua62b\ua640-\ua66e\ua680-\ua69d\ua6a0-\ua6ef\ua6f2-\ua6f7\ua722-\ua787\ua789-\ua7ad\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua824\ua827\ua830-\ua837\ua840-\ua873\ua880-\ua8c3\ua8ce-\ua8d9\ua8f2-\ua8fd\ua900-\ua925\ua92e-\ua946\ua952\ua953\ua95f-\ua97c\ua983-\ua9b2\ua9b4\ua9b5\ua9ba\ua9bb\ua9bd-\ua9cd\ua9cf-\ua9d9\ua9de-\ua9e4\ua9e6-\ua9fe\uaa00-\uaa28\uaa2f\uaa30\uaa33\uaa34\uaa40-\uaa42\uaa44-\uaa4b\uaa4d\uaa50-\uaa59\uaa5c-\uaa7b\uaa7d-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaaeb\uaaee-\uaaf5\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab65\uab70-\uabe4\uabe6\uabe7\uabe9-\uabec\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\ue000-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]|\ud800[\udc00-\udc0b]|\ud800[\udc0d-\udc26]|\ud800[\udc28-\udc3a]|\ud800\udc3c|\ud800\udc3d|\ud800[\udc3f-\udc4d]|\ud800[\udc50-\udc5d]|\ud800[\udc80-\udcfa]|\ud800\udd00|\ud800\udd02|\ud800[\udd07-\udd33]|\ud800[\udd37-\udd3f]|\ud800[\uddd0-\uddfc]|\ud800[\ude80-\ude9c]|\ud800[\udea0-\uded0]|\ud800[\udf00-\udf23]|\ud800[\udf30-\udf4a]|\ud800[\udf50-\udf75]|\ud800[\udf80-\udf9d]|\ud800[\udf9f-\udfc3]|\ud800[\udfc8-\udfd5]|\ud801[\udc00-\udc9d]|\ud801[\udca0-\udca9]|\ud801[\udd00-\udd27]|\ud801[\udd30-\udd63]|\ud801\udd6f|\ud801[\ude00-\udf36]|\ud801[\udf40-\udf55]|\ud801[\udf60-\udf67]|\ud804\udc00|\ud804[\udc02-\udc37]|\ud804[\udc47-\udc4d]|\ud804[\udc66-\udc6f]|\ud804[\udc82-\udcb2]|\ud804\udcb7|\ud804\udcb8|\ud804[\udcbb-\udcc1]|\ud804[\udcd0-\udce8]|\ud804[\udcf0-\udcf9]|\ud804[\udd03-\udd26]|\ud804\udd2c|\ud804[\udd36-\udd43]|\ud804[\udd50-\udd72]|\ud804[\udd74-\udd76]|\ud804[\udd82-\uddb5]|\ud804[\uddbf-\uddc9]|\ud804\uddcd|\ud804[\uddd0-\udddf]|\ud804[\udde1-\uddf4]|\ud804[\ude00-\ude11]|\ud804[\ude13-\ude2e]|\ud804\ude32|\ud804\ude33|\ud804\ude35|\ud804[\ude38-\ude3d]|\ud804[\ude80-\ude86]|\ud804\ude88|\ud804[\ude8a-\ude8d]|\ud804[\ude8f-\ude9d]|\ud804[\ude9f-\udea9]|\ud804[\udeb0-\udede]|\ud804[\udee0-\udee2]|\ud804[\udef0-\udef9]|\ud804\udf02|\ud804\udf03|\ud804[\udf05-\udf0c]|\ud804\udf0f|\ud804\udf10|\ud804[\udf13-\udf28]|\ud804[\udf2a-\udf30]|\ud804\udf32|\ud804\udf33|\ud804[\udf35-\udf39]|\ud804[\udf3d-\udf3f]|\ud804[\udf41-\udf44]|\ud804\udf47|\ud804\udf48|\ud804[\udf4b-\udf4d]|\ud804\udf50|\ud804\udf57|\ud804[\udf5d-\udf63]|\ud805[\udc80-\udcb2]|\ud805\udcb9|\ud805[\udcbb-\udcbe]|\ud805\udcc1|\ud805[\udcc4-\udcc7]|\ud805[\udcd0-\udcd9]|\ud805[\udd80-\uddb1]|\ud805[\uddb8-\uddbb]|\ud805\uddbe|\ud805[\uddc1-\udddb]|\ud805[\ude00-\ude32]|\ud805\ude3b|\ud805\ude3c|\ud805\ude3e|\ud805[\ude41-\ude44]|\ud805[\ude50-\ude59]|\ud805[\ude80-\udeaa]|\ud805\udeac|\ud805\udeae|\ud805\udeaf|\ud805\udeb6|\ud805[\udec0-\udec9]|\ud805[\udf00-\udf19]|\ud805\udf20|\ud805\udf21|\ud805\udf26|\ud805[\udf30-\udf3f]|\ud806[\udca0-\udcf2]|\ud806\udcff|\ud806[\udec0-\udef8]|\ud808[\udc00-\udf99]|\ud809[\udc00-\udc6e]|\ud809[\udc70-\udc74]|\ud809[\udc80-\udd43]|\ud80c[\udc00-\udfff]|\ud80d[\udc00-\udc2e]|\ud811[\udc00-\ude46]|\ud81a[\udc00-\ude38]|\ud81a[\ude40-\ude5e]|\ud81a[\ude60-\ude69]|\ud81a\ude6e|\ud81a\ude6f|\ud81a[\uded0-\udeed]|\ud81a\udef5|\ud81a[\udf00-\udf2f]|\ud81a[\udf37-\udf45]|\ud81a[\udf50-\udf59]|\ud81a[\udf5b-\udf61]|\ud81a[\udf63-\udf77]|\ud81a[\udf7d-\udf8f]|\ud81b[\udf00-\udf44]|\ud81b[\udf50-\udf7e]|\ud81b[\udf93-\udf9f]|\ud82c\udc00|\ud82c\udc01|\ud82f[\udc00-\udc6a]|\ud82f[\udc70-\udc7c]|\ud82f[\udc80-\udc88]|\ud82f[\udc90-\udc99]|\ud82f\udc9c|\ud82f\udc9f|\ud834[\udc00-\udcf5]|\ud834[\udd00-\udd26]|\ud834[\udd29-\udd66]|\ud834[\udd6a-\udd72]|\ud834\udd83|\ud834\udd84|\ud834[\udd8c-\udda9]|\ud834[\uddae-\udde8]|\ud834[\udf60-\udf71]|\ud835[\udc00-\udc54]|\ud835[\udc56-\udc9c]|\ud835\udc9e|\ud835\udc9f|\ud835\udca2|\ud835\udca5|\ud835\udca6|\ud835[\udca9-\udcac]|\ud835[\udcae-\udcb9]|\ud835\udcbb|\ud835[\udcbd-\udcc3]|\ud835[\udcc5-\udd05]|\ud835[\udd07-\udd0a]|\ud835[\udd0d-\udd14]|\ud835[\udd16-\udd1c]|\ud835[\udd1e-\udd39]|\ud835[\udd3b-\udd3e]|\ud835[\udd40-\udd44]|\ud835\udd46|\ud835[\udd4a-\udd50
720]|\ud835[\udd52-\udea5]|\ud835[\udea8-\udeda]|\ud835[\udedc-\udf14]|\ud835[\udf16-\udf4e]|\ud835[\udf50-\udf88]|\ud835[\udf8a-\udfc2]|\ud835[\udfc4-\udfcb]|\ud836[\udc00-\uddff]|\ud836[\ude37-\ude3a]|\ud836[\ude6d-\ude74]|\ud836[\ude76-\ude83]|\ud836[\ude85-\ude8b]|\ud83c[\udd10-\udd2e]|\ud83c[\udd30-\udd69]|\ud83c[\udd70-\udd9a]|\ud83c[\udde6-\ude02]|\ud83c[\ude10-\ude3a]|\ud83c[\ude40-\ude48]|\ud83c\ude50|\ud83c\ude51|[\ud840-\ud868][\udc00-\udfff]|\ud869[\udc00-\uded6]|\ud869[\udf00-\udfff]|[\ud86a-\ud86c][\udc00-\udfff]|\ud86d[\udc00-\udf34]|\ud86d[\udf40-\udfff]|\ud86e[\udc00-\udc1d]|\ud86e[\udc20-\udfff]|[\ud86f-\ud872][\udc00-\udfff]|\ud873[\udc00-\udea1]|\ud87e[\udc00-\ude1d]|[\udb80-\udbbe][\udc00-\udfff]|\udbbf[\udc00-\udffd]|[\udbc0-\udbfe][\udc00-\udfff]|\udbff[\udc00-\udffd]' + 721 ')|(' + 722 '[\u0590\u05be\u05c0\u05c3\u05c6\u05c8-\u05ff\u07c0-\u07ea\u07f4\u07f5\u07fa-\u0815\u081a\u0824\u0828\u082e-\u0858\u085c-\u089f\u200f\ufb1d\ufb1f-\ufb28\ufb2a-\ufb4f\u0608\u060b\u060d\u061b-\u064a\u066d-\u066f\u0671-\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u0710\u0712-\u072f\u074b-\u07a5\u07b1-\u07bf\u08a0-\u08e2\ufb50-\ufd3d\ufd40-\ufdcf\ufdf0-\ufdfc\ufdfe\ufdff\ufe70-\ufefe]|\ud802[\udc00-\udd1e]|\ud802[\udd20-\ude00]|\ud802\ude04|\ud802[\ude07-\ude0b]|\ud802[\ude10-\ude37]|\ud802[\ude3b-\ude3e]|\ud802[\ude40-\udee4]|\ud802[\udee7-\udf38]|\ud802[\udf40-\udfff]|\ud803[\udc00-\ude5f]|\ud803[\ude7f-\udfff]|\ud83a[\udc00-\udccf]|\ud83a[\udcd7-\udfff]|\ud83b[\udc00-\uddff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\ude00-\udeef]|\ud83b[\udef2-\udeff]' + 723 ')' + 724 ')' 725 ); 726 727 /** 728 * Gets directionality of the first strongly directional codepoint 729 * 730 * This is the rule the BIDI algorithm uses to determine the directionality of 731 * paragraphs ( http://unicode.org/reports/tr9/#The_Paragraph_Level ) and 732 * FSI isolates ( http://unicode.org/reports/tr9/#Explicit_Directional_Isolates ). 733 * 734 * TODO: Does not handle BIDI control characters inside the text. 735 * TODO: Does not handle unallocated characters. 736 * 737 * @param {string} text The text from which to extract initial directionality. 738 * @return {string} Directionality (either 'ltr' or 'rtl') 739 */ 740 function strongDirFromContent( text ) { 741 var m = text.match( strongDirRegExp ); 742 if ( !m ) { 743 return null; 744 } 745 if ( m[ 2 ] === undefined ) { 746 return 'ltr'; 747 } 748 return 'rtl'; 749 } 750 751 $.extend( $.i18n.parser.emitter, { 752 /** 753 * Wraps argument with unicode control characters for directionality safety 754 * 755 * This solves the problem where directionality-neutral characters at the edge of 756 * the argument string get interpreted with the wrong directionality from the 757 * enclosing context, giving renderings that look corrupted like "(Ben_(WMF". 758 * 759 * The wrapping is LRE...PDF or RLE...PDF, depending on the detected 760 * directionality of the argument string, using the BIDI algorithm's own "First 761 * strong directional codepoint" rule. Essentially, this works round the fact that 762 * there is no embedding equivalent of U+2068 FSI (isolation with heuristic 763 * direction inference). The latter is cleaner but still not widely supported. 764 * 765 * @param {string[]} nodes The text nodes from which to take the first item. 766 * @return {string} Wrapped String of content as needed. 767 */ 768 bidi: function ( nodes ) { 769 var dir = strongDirFromContent( nodes[ 0 ] ); 770 if ( dir === 'ltr' ) { 771 // Wrap in LEFT-TO-RIGHT EMBEDDING ... POP DIRECTIONAL FORMATTING 772 return '\u202A' + nodes[ 0 ] + '\u202C'; 773 } 774 if ( dir === 'rtl' ) { 775 // Wrap in RIGHT-TO-LEFT EMBEDDING ... POP DIRECTIONAL FORMATTING 776 return '\u202B' + nodes[ 0 ] + '\u202C'; 777 } 778 // No strong directionality: do not wrap 779 return nodes[ 0 ]; 780 } 781 } ); 782}( jQuery ) ); 783 784 785/***/ }), 786 787/***/ 30423: 788/*!****************************************************************!*\ 789 !*** ./runestone/common/js/jquery_i18n/jquery.i18n.emitter.js ***! 790 \****************************************************************/ 791/***/ (() => { 792 793/*! 794 * jQuery Internationalization library 795 * 796 * Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar 797 * 798 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do 799 * anything special to choose one license or the other and you don't have to 800 * notify anyone which license you are using. You are free to use 801 * UniversalLanguageSelector in commercial projects as long as the copyright 802 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. 803 * 804 * @licence GNU General Public Licence 2.0 or later 805 * @licence MIT License 806 */ 807 808( function ( $ ) { 809 'use strict'; 810 811 var MessageParserEmitter = function () { 812 this.language = $.i18n.languages[ String.locale ] || $.i18n.languages[ 'default' ]; 813 }; 814 815 MessageParserEmitter.prototype = { 816 constructor: MessageParserEmitter, 817 818 /** 819 * (We put this method definition here, and not in prototype, to make 820 * sure it's not overwritten by any magic.) Walk entire node structure, 821 * applying replacements and template functions when appropriate 822 * 823 * @param {Mixed} node abstract syntax tree (top node or subnode) 824 * @param {Array} replacements for $1, $2, ... $n 825 * @return {Mixed} single-string node or array of nodes suitable for 826 * jQuery appending. 827 */ 828 emit: function ( node, replacements ) { 829 var ret, subnodes, operation, 830 messageParserEmitter = this; 831 832 switch ( typeof node ) { 833 case 'string': 834 case 'number': 835 ret = node; 836 break; 837 case 'object': 838 // node is an array of nodes 839 subnodes = $.map( node.slice( 1 ), function ( n ) { 840 return messageParserEmitter.emit( n, replacements ); 841 } ); 842 843 operation = node[ 0 ].toLowerCase(); 844 845 if ( typeof messageParserEmitter[ operation ] === 'function' ) { 846 ret = messageParserEmitter[ operation ]( subnodes, replacements ); 847 } else { 848 throw new Error( 'unknown operation "' + operation + '"' ); 849 } 850 851 break; 852 case 'undefined': 853 // Parsing the empty string (as an entire expression, or as a 854 // paramExpression in a template) results in undefined 855 // Perhaps a more clever parser can detect this, and return the 856 // empty string? Or is that useful information? 857 // The logical thing is probably to return the empty string here 858 // when we encounter undefined. 859 ret = ''; 860 break; 861 default: 862 throw new Error( 'unexpected type in AST: ' + typeof node ); 863 } 864 865 return ret; 866 }, 867 868 /** 869 * Parsing has been applied depth-first we can assume that all nodes 870 * here are single nodes Must return a single node to parents -- a 871 * jQuery with synthetic span However, unwrap any other synthetic spans 872 * in our children and pass them upwards 873 * 874 * @param {Array} nodes Mixed, some single nodes, some arrays of nodes. 875 * @return {string} 876 */ 877 concat: function ( nodes ) { 878 var result = ''; 879 880 $.each( nodes, function ( i, node ) { 881 // strings, integers, anything else 882 result += node;
883 } ); 884 885 return result; 886 }, 887 888 /** 889 * Return escaped replacement of correct index, or string if 890 * unavailable. Note that we expect the parsed parameter to be 891 * zero-based. i.e. $1 should have become [ 0 ]. if the specified 892 * parameter is not found return the same string (e.g. "$99" -> 893 * parameter 98 -> not found -> return "$99" ) TODO throw error if 894 * nodes.length > 1 ? 895 * 896 * @param {Array} nodes One element, integer, n >= 0 897 * @param {Array} replacements for $1, $2, ... $n 898 * @return {string} replacement 899 */ 900 replace: function ( nodes, replacements ) { 901 var index = parseInt( nodes[ 0 ], 10 ); 902 903 if ( index < replacements.length ) { 904 // replacement is not a string, don't touch! 905 return replacements[ index ]; 906 } else { 907 // index not found, fallback to displaying variable 908 return '$' + ( index + 1 ); 909 } 910 }, 911 912 /** 913 * Transform parsed structure into pluralization n.b. The first node may 914 * be a non-integer (for instance, a string representing an Arabic 915 * number). So convert it back with the current language's 916 * convertNumber. 917 * 918 * @param {Array} nodes List [ {String|Number}, {String}, {String} ... ] 919 * @return {string} selected pluralized form according to current 920 * language. 921 */ 922 plural: function ( nodes ) { 923 var count = parseFloat( this.language.convertNumber( nodes[ 0 ], 10 ) ), 924 forms = nodes.slice( 1 ); 925 926 return forms.length ? this.language.convertPlural( count, forms ) : ''; 927 }, 928 929 /** 930 * Transform parsed structure into gender Usage 931 * {{gender:gender|masculine|feminine|neutral}}. 932 * 933 * @param {Array} nodes List [ {String}, {String}, {String} , {String} ] 934 * @return {string} selected gender form according to current language 935 */ 936 gender: function ( nodes ) { 937 var gender = nodes[ 0 ], 938 forms = nodes.slice( 1 ); 939 940 return this.language.gender( gender, forms ); 941 }, 942 943 /** 944 * Transform parsed structure into grammar conversion. Invoked by 945 * putting {{grammar:form|word}} in a message 946 * 947 * @param {Array} nodes List [{Grammar case eg: genitive}, {String word}] 948 * @return {string} selected grammatical form according to current 949 * language. 950 */ 951 grammar: function ( nodes ) { 952 var form = nodes[ 0 ], 953 word = nodes[ 1 ]; 954 955 return word && form && this.language.convertGrammar( word, form ); 956 } 957 }; 958 959 $.extend( $.i18n.parser.emitter, new MessageParserEmitter() ); 960}( jQuery ) ); 961 962 963/***/ }), 964 965/***/ 9001: 966/*!******************************************************************!*\ 967 !*** ./runestone/common/js/jquery_i18n/jquery.i18n.fallbacks.js ***! 968 \******************************************************************/ 969/***/ (() => { 970 971/*! 972 * jQuery Internationalization library 973 * 974 * Copyright (C) 2012 Santhosh Thottingal 975 * 976 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do anything special to 977 * choose one license or the other and you don't have to notify anyone which license you are using. 978 * You are free to use UniversalLanguageSelector in commercial projects as long as the copyright 979 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. 980 * 981 * @licence GNU General Public Licence 2.0 or later 982 * @licence MIT License 983 */ 984( function ( $ ) { 985 'use strict'; 986 987 $.i18n = $.i18n || {}; 988 $.extend( $.i18n.fallbacks, { 989 ab: [ 'ru' ], 990 ace: [ 'id' ], 991 aln: [ 'sq' ], 992 // Not so standard - als is supposed to be Tosk Albanian, 993 // but in Wikipedia it's used for a Germanic language. 994 als: [ 'gsw', 'de' ], 995 an: [ 'es' ], 996 anp: [ 'hi' ], 997 arn: [ 'es' ], 998 arz: [ 'ar' ], 999 av: [ 'ru' ], 1000 ay: [ 'es' ], 1001 ba: [ 'ru' ], 1002 bar: [ 'de' ], 1003 'bat-smg': [ 'sgs', 'lt' ], 1004 bcc: [ 'fa' ], 1005 'be-x-old': [ 'be-tarask' ], 1006 bh: [ 'bho' ], 1007 bjn: [ 'id' ], 1008 bm: [ 'fr' ], 1009 bpy: [ 'bn' ], 1010 bqi: [ 'fa' ], 1011 bug: [ 'id' ], 1012 'cbk-zam': [ 'es' ], 1013 ce: [ 'ru' ], 1014 crh: [ 'crh-latn' ], 1015 'crh-cyrl': [ 'ru' ], 1016 csb: [ 'pl' ], 1017 cv: [ 'ru' ], 1018 'de-at': [ 'de' ], 1019 'de-ch': [ 'de' ], 1020 'de-formal': [ 'de' ], 1021 dsb: [ 'de' ], 1022 dtp: [ 'ms' ], 1023 egl: [ 'it' ], 1024 eml: [ 'it' ], 1025 ff: [ 'fr' ], 1026 fit: [ 'fi' ], 1027 'fiu-vro': [ 'vro', 'et' ], 1028 frc: [ 'fr' ], 1029 frp: [ 'fr' ], 1030 frr: [ 'de' ], 1031 fur: [ 'it' ], 1032 gag: [ 'tr' ], 1033 gan: [ 'gan-hant', 'zh-hant', 'zh-hans' ], 1034 'gan-hans': [ 'zh-hans' ], 1035 'gan-hant': [ 'zh-hant', 'zh-hans' ], 1036 gl: [ 'pt' ], 1037 glk: [ 'fa' ], 1038 gn: [ 'es' ], 1039 gsw: [ 'de' ], 1040 hif: [ 'hif-latn' ], 1041 hsb: [ 'de' ], 1042 ht: [ 'fr' ], 1043 ii: [ 'zh-cn', 'zh-hans' ], 1044 inh: [ 'ru' ], 1045 iu: [ 'ike-cans' ], 1046 jut: [ 'da' ], 1047 jv: [ 'id' ], 1048 kaa: [ 'kk-latn', 'kk-cyrl' ], 1049 kbd: [ 'kbd-cyrl' ], 1050 khw: [ 'ur' ], 1051 kiu: [ 'tr' ], 1052 kk: [ 'kk-cyrl' ], 1053 'kk-arab': [ 'kk-cyrl' ], 1054 'kk-latn': [ 'kk-cyrl' ], 1055 'kk-cn': [ 'kk-arab', 'kk-cyrl' ], 1056 'kk-kz': [ 'kk-cyrl' ], 1057 'kk-tr': [ 'kk-latn', 'kk-cyrl' ], 1058 kl: [ 'da' ], 1059 'ko-kp': [ 'ko' ], 1060 koi: [ 'ru' ], 1061 krc: [ 'ru' ], 1062 ks: [ 'ks-arab' ], 1063 ksh: [ 'de' ], 1064 ku: [ 'ku-latn' ], 1065 'ku-arab': [ 'ckb' ], 1066 kv: [ 'ru' ], 1067 lad: [ 'es' ], 1068 lb: [ 'de' ], 1069 lbe: [ 'ru' ], 1070 lez: [ 'ru' ], 1071 li: [ 'nl' ], 1072 lij: [ 'it' ], 1073 liv: [ 'et' ], 1074 lmo: [ 'it' ], 1075 ln: [ 'fr' ], 1076 ltg: [ 'lv' ], 1077 lzz: [ 'tr' ], 1078 mai: [ 'hi' ], 1079 'map-bms': [ 'jv', 'id' ], 1080 mg: [ 'fr' ], 1081 mhr: [ 'ru' ], 1082 min: [ 'id' ], 1083 mo: [ 'ro' ], 1084 mrj: [ 'ru' ], 1085 mwl: [ 'pt' ], 1086 myv: [ 'ru' ], 1087 mzn: [ 'fa' ], 1088 nah: [ 'es' ], 1089 nap: [ 'it' ], 1090 nds: [ 'de' ], 1091 'nds-nl': [ 'nl' ], 1092 'nl-informal': [ 'nl' ], 1093 no: [ 'nb' ], 1094 os: [ 'ru' ], 1095 pcd: [ 'fr' ], 1096 pdc: [ 'de' ], 1097 pdt: [ 'de' ], 1098 pfl: [ 'de' ], 1099 pms: [ 'it' ], 1100 pt: [ 'pt-br' ], 1101 'pt-br': [ 'pt' ], 1102 qu: [ 'es' ], 1103 qug: [ 'qu', 'es' ], 1104 rgn: [ 'it' ], 1105 rmy: [ 'ro' ], 1106 'roa-rup': [ 'rup' ], 1107 rue: [ 'uk', 'ru' ], 1108 ruq: [ 'ruq-latn', 'ro' ], 1109 'ruq-cyrl': [ 'mk' ], 1110 'ruq-latn': [ 'ro' ], 1111 sa: [ 'hi' ], 1112 sah: [ 'ru' ], 1113 scn: [ 'it' ], 1114 sg: [ 'fr' ], 1115 sgs: [ 'lt' ], 1116 sli: [ 'de' ], 1117 sr: [ 'sr-ec' ], 1118 srn: [ 'nl' ], 1119 stq: [ 'de' ], 1120 su: [ 'id' ], 1121 szl: [ 'pl' ], 1122 tcy: [ 'kn' ], 1123 tg: [ 'tg-cyrl' ], 1124 tt: [ 'tt-cyrl', 'ru' ], 1125 'tt-cyrl': [ 'ru' ], 1126 ty: [ 'fr' ], 1127 udm: [ 'ru' ], 1128 ug: [ 'ug-arab' ], 1129 uk: [ 'ru' ], 1130 vec: [ 'it' ], 1131 vep: [ 'et' ], 1132 vls: [ 'nl' ], 1133 vmf: [ 'de' ], 1134 vot: [ 'fi' ], 1135 vro: [ 'et' ], 1136 wa: [ 'fr' ], 1137 wo: [ 'fr' ], 1138 wuu: [ 'zh-hans' ], 1139 xal: [ 'ru' ], 1140 xmf: [ 'ka' ], 1141 yi: [ 'he' ], 1142 za: [ 'zh-hans' ], 1143 zea: [ 'nl' ], 1144 zh: [ 'zh-hans' ], 1145 'zh-classical': [ 'lzh' ], 1146 'zh-cn': [ 'zh-hans' ], 1147 'zh-hant': [ 'zh-hans' ], 1148 'zh-hk': [ 'zh-hant', 'zh-hans' ], 1149 'zh-min-nan': [ 'nan' ], 1150 'zh-mo': [ 'zh-hk', 'zh-hant', 'zh-hans' ], 1151 'zh-my': [ 'zh-sg', 'zh-hans' ], 1152 'zh-sg': [ 'zh-hans' ], 1153 'zh-tw': [ 'zh-hant', 'zh-hans' ], 1154 'zh-yue': [ 'yue' ] 1155 } ); 1156}( jQuery ) ); 1157 1158
1159/***/ }), 1160 1161/***/ 99283: 1162/*!********************************************************!*\ 1163 !*** ./runestone/common/js/jquery_i18n/jquery.i18n.js ***! 1164 \********************************************************/ 1165/***/ (() => { 1166 1167/*! 1168 * jQuery Internationalization library 1169 * 1170 * Copyright (C) 2012 Santhosh Thottingal 1171 * 1172 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do 1173 * anything special to choose one license or the other and you don't have to 1174 * notify anyone which license you are using. You are free to use 1175 * UniversalLanguageSelector in commercial projects as long as the copyright 1176 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. 1177 * 1178 * @licence GNU General Public Licence 2.0 or later 1179 * @licence MIT License 1180 */ 1181 1182( function ( $ ) { 1183 'use strict'; 1184 1185 var I18N, 1186 slice = Array.prototype.slice; 1187 /** 1188 * @constructor 1189 * @param {Object} options 1190 */ 1191 I18N = function ( options ) { 1192 // Load defaults 1193 this.options = $.extend( {}, I18N.defaults, options ); 1194 1195 this.parser = this.options.parser; 1196 this.locale = this.options.locale; 1197 this.messageStore = this.options.messageStore; 1198 this.languages = {}; 1199 }; 1200 1201 I18N.prototype = { 1202 /** 1203 * Localize a given messageKey to a locale. 1204 * @param {String} messageKey 1205 * @return {String} Localized message 1206 */ 1207 localize: function ( messageKey ) { 1208 var localeParts, localePartIndex, locale, fallbackIndex, 1209 tryingLocale, message; 1210 1211 locale = this.locale; 1212 fallbackIndex = 0; 1213 1214 while ( locale ) { 1215 // Iterate through locales starting at most-specific until 1216 // localization is found. As in fi-Latn-FI, fi-Latn and fi. 1217 localeParts = locale.split( '-' ); 1218 localePartIndex = localeParts.length; 1219 1220 do { 1221 tryingLocale = localeParts.slice( 0, localePartIndex ).join( '-' ); 1222 message = this.messageStore.get( tryingLocale, messageKey ); 1223 1224 if ( message ) { 1225 return message; 1226 } 1227 1228 localePartIndex--; 1229 } while ( localePartIndex ); 1230 1231 if ( locale === 'en' ) { 1232 break; 1233 } 1234 1235 locale = ( $.i18n.fallbacks[ this.locale ] && 1236 $.i18n.fallbacks[ this.locale ][ fallbackIndex ] ) || 1237 this.options.fallbackLocale; 1238 $.i18n.log( 'Trying fallback locale for ' + this.locale + ': ' + locale + ' (' + messageKey + ')' ); 1239 1240 fallbackIndex++; 1241 } 1242 1243 // key not found 1244 return ''; 1245 }, 1246 1247 /* 1248 * Destroy the i18n instance. 1249 */ 1250 destroy: function () { 1251 $.removeData( document, 'i18n' ); 1252 }, 1253 1254 /** 1255 * General message loading API This can take a URL string for 1256 * the json formatted messages. Example: 1257 * <code>load('path/to/all_localizations.json');</code> 1258 * 1259 * To load a localization file for a locale: 1260 * <code> 1261 * load('path/to/de-messages.json', 'de' ); 1262 * </code> 1263 * 1264 * To load a localization file from a directory: 1265 * <code> 1266 * load('path/to/i18n/directory', 'de' ); 1267 * </code> 1268 * The above method has the advantage of fallback resolution. 1269 * ie, it will automatically load the fallback locales for de. 1270 * For most usecases, this is the recommended method. 1271 * It is optional to have trailing slash at end. 1272 * 1273 * A data object containing message key- message translation mappings 1274 * can also be passed. Example: 1275 * <code> 1276 * load( { 'hello' : 'Hello' }, optionalLocale ); 1277 * </code> 1278 * 1279 * A source map containing key-value pair of languagename and locations 1280 * can also be passed. Example: 1281 * <code> 1282 * load( { 1283 * bn: 'i18n/bn.json', 1284 * he: 'i18n/he.json', 1285 * en: 'i18n/en.json' 1286 * } ) 1287 * </code> 1288 * 1289 * If the data argument is null/undefined/false, 1290 * all cached messages for the i18n instance will get reset. 1291 * 1292 * @param {string|Object} source 1293 * @param {string} locale Language tag 1294 * @return {jQuery.Promise} 1295 */ 1296 load: function ( source, locale ) { 1297 var fallbackLocales, locIndex, fallbackLocale, sourceMap = {}; 1298 if ( !source && !locale ) { 1299 source = 'i18n/' + $.i18n().locale + '.json'; 1300 locale = $.i18n().locale; 1301 } 1302 if ( typeof source === 'string' && 1303 // source extension should be json, but can have query params after that. 1304 source.split( '?' )[ 0 ].split( '.' ).pop() !== 'json' 1305 ) { 1306 // Load specified locale then check for fallbacks when directory is 1307 // specified in load() 1308 sourceMap[ locale ] = source + '/' + locale + '.json'; 1309 fallbackLocales = ( $.i18n.fallbacks[ locale ] || [] ) 1310 .concat( this.options.fallbackLocale ); 1311 for ( locIndex = 0; locIndex < fallbackLocales.length; locIndex++ ) { 1312 fallbackLocale = fallbackLocales[ locIndex ]; 1313 sourceMap[ fallbackLocale ] = source + '/' + fallbackLocale + '.json'; 1314 } 1315 return this.load( sourceMap ); 1316 } else { 1317 return this.messageStore.load( source, locale ); 1318 } 1319 1320 }, 1321 1322 /** 1323 * Does parameter and magic word substitution. 1324 * 1325 * @param {string} key Message key 1326 * @param {Array} parameters Message parameters 1327 * @return {string} 1328 */ 1329 parse: function ( key, parameters ) { 1330 var message = this.localize( key ); 1331 // FIXME: This changes the state of the I18N object, 1332 // should probably not change the 'this.parser' but just 1333 // pass it to the parser. 1334 this.parser.language = $.i18n.languages[ $.i18n().locale ] || $.i18n.languages[ 'default' ]; 1335 if ( message === '' ) { 1336 message = key; 1337 } 1338 return this.parser.parse( message, parameters ); 1339 } 1340 }; 1341 1342 /** 1343 * Process a message from the $.I18N instance 1344 * for the current document, stored in jQuery.data(document). 1345 * 1346 * @param {string} key Key of the message. 1347 * @param {string} param1 [param...] Variadic list of parameters for {key}. 1348 * @return {string|$.I18N} Parsed message, or if no key was given 1349 * the instance of $.I18N is returned. 1350 */ 1351 $.i18n = function ( key, param1 ) { 1352 var parameters, 1353 i18n = $.data( document, 'i18n' ), 1354 options = typeof key === 'object' && key; 1355 1356 // If the locale option for this call is different then the setup so far, 1357 // update it automatically. This doesn't just change the context for this 1358 // call but for all future call as well. 1359 // If there is no i18n setup yet, don't do this. It will be taken care of 1360 // by the `new I18N` construction below. 1361 // NOTE: It should only change language for this one call.
1362 // Then cache instances of I18N somewhere. 1363 if ( options && options.locale && i18n && i18n.locale !== options.locale ) { 1364 i18n.locale = options.locale; 1365 } 1366 1367 if ( !i18n ) { 1368 i18n = new I18N( options ); 1369 $.data( document, 'i18n', i18n ); 1370 } 1371 1372 if ( typeof key === 'string' ) { 1373 if ( param1 !== undefined ) { 1374 parameters = slice.call( arguments, 1 ); 1375 } else { 1376 parameters = []; 1377 } 1378 1379 return i18n.parse( key, parameters ); 1380 } else { 1381 // FIXME: remove this feature/bug. 1382 return i18n; 1383 } 1384 }; 1385 1386 $.fn.i18n = function () { 1387 var i18n = $.data( document, 'i18n' ); 1388 1389 if ( !i18n ) { 1390 i18n = new I18N(); 1391 $.data( document, 'i18n', i18n ); 1392 } 1393 1394 return this.each( function () { 1395 var $this = $( this ), 1396 messageKey = $this.data( 'i18n' ), 1397 lBracket, rBracket, type, key; 1398 1399 if ( messageKey ) { 1400 lBracket = messageKey.indexOf( '[' ); 1401 rBracket = messageKey.indexOf( ']' ); 1402 if ( lBracket !== -1 && rBracket !== -1 && lBracket < rBracket ) { 1403 type = messageKey.slice( lBracket + 1, rBracket ); 1404 key = messageKey.slice( rBracket + 1 ); 1405 if ( type === 'html' ) { 1406 $this.html( i18n.parse( key ) ); 1407 } else { 1408 $this.attr( type, i18n.parse( key ) ); 1409 } 1410 } else { 1411 $this.text( i18n.parse( messageKey ) ); 1412 } 1413 } else { 1414 $this.find( '[data-i18n]' ).i18n(); 1415 } 1416 } ); 1417 }; 1418 1419 function getDefaultLocale() { 1420 var nav, locale = $( 'html' ).attr( 'lang' ); 1421 1422 if ( !locale ) { 1423 if ( typeof window.navigator !== undefined ) { 1424 nav = window.navigator; 1425 locale = nav.language || nav.userLanguage || ''; 1426 } else { 1427 locale = ''; 1428 } 1429 } 1430 return locale; 1431 } 1432 1433 $.i18n.languages = {}; 1434 $.i18n.messageStore = $.i18n.messageStore || {}; 1435 $.i18n.parser = { 1436 // The default parser only handles variable substitution 1437 parse: function ( message, parameters ) { 1438 return message.replace( /\$(\d+)/g, function ( str, match ) { 1439 var index = parseInt( match, 10 ) - 1; 1440 return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match; 1441 } ); 1442 }, 1443 emitter: {} 1444 }; 1445 $.i18n.fallbacks = {}; 1446 $.i18n.debug = false; 1447 $.i18n.log = function ( /* arguments */ ) { 1448 if ( window.console && $.i18n.debug ) { 1449 window.console.log.apply( window.console, arguments ); 1450 } 1451 }; 1452 /* Static members */ 1453 I18N.defaults = { 1454 locale: getDefaultLocale(), 1455 fallbackLocale: 'en', 1456 parser: $.i18n.parser, 1457 messageStore: $.i18n.messageStore 1458 }; 1459 1460 // Expose constructor 1461 $.i18n.constructor = I18N; 1462}( jQuery ) ); 1463 1464/***/ }), 1465 1466/***/ 64793: 1467/*!*****************************************************************!*\ 1468 !*** ./runestone/common/js/jquery_i18n/jquery.i18n.language.js ***! 1469 \*****************************************************************/ 1470/***/ (() => { 1471 1472/* global pluralRuleParser */ 1473( function ( $ ) { 1474 'use strict'; 1475 1476 // jscs:disable 1477 var language = { 1478 // CLDR plural rules generated using 1479 // libs/CLDRPluralRuleParser/tools/PluralXML2JSON.html 1480 pluralRules: { 1481 ak: { 1482 one: 'n = 0..1' 1483 }, 1484 am: { 1485 one: 'i = 0 or n = 1' 1486 }, 1487 ar: { 1488 zero: 'n = 0', 1489 one: 'n = 1', 1490 two: 'n = 2', 1491 few: 'n % 100 = 3..10', 1492 many: 'n % 100 = 11..99' 1493 }, 1494 ars: { 1495 zero: 'n = 0', 1496 one: 'n = 1', 1497 two: 'n = 2', 1498 few: 'n % 100 = 3..10', 1499 many: 'n % 100 = 11..99' 1500 }, 1501 as: { 1502 one: 'i = 0 or n = 1' 1503 }, 1504 be: { 1505 one: 'n % 10 = 1 and n % 100 != 11', 1506 few: 'n % 10 = 2..4 and n % 100 != 12..14', 1507 many: 'n % 10 = 0 or n % 10 = 5..9 or n % 100 = 11..14' 1508 }, 1509 bh: { 1510 one: 'n = 0..1' 1511 }, 1512 bn: { 1513 one: 'i = 0 or n = 1' 1514 }, 1515 br: { 1516 one: 'n % 10 = 1 and n % 100 != 11,71,91', 1517 two: 'n % 10 = 2 and n % 100 != 12,72,92', 1518 few: 'n % 10 = 3..4,9 and n % 100 != 10..19,70..79,90..99', 1519 many: 'n != 0 and n % 1000000 = 0' 1520 }, 1521 bs: { 1522 one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11', 1523 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14' 1524 }, 1525 cs: { 1526 one: 'i = 1 and v = 0', 1527 few: 'i = 2..4 and v = 0', 1528 many: 'v != 0' 1529 }, 1530 cy: { 1531 zero: 'n = 0', 1532 one: 'n = 1', 1533 two: 'n = 2', 1534 few: 'n = 3', 1535 many: 'n = 6' 1536 }, 1537 da: { 1538 one: 'n = 1 or t != 0 and i = 0,1' 1539 }, 1540 dsb: { 1541 one: 'v = 0 and i % 100 = 1 or f % 100 = 1', 1542 two: 'v = 0 and i % 100 = 2 or f % 100 = 2', 1543 few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4' 1544 }, 1545 fa: { 1546 one: 'i = 0 or n = 1' 1547 }, 1548 ff: { 1549 one: 'i = 0,1' 1550 }, 1551 fil: { 1552 one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9' 1553 }, 1554 fr: { 1555 one: 'i = 0,1' 1556 }, 1557 ga: { 1558 one: 'n = 1', 1559 two: 'n = 2', 1560 few: 'n = 3..6', 1561 many: 'n = 7..10' 1562 }, 1563 gd: { 1564 one: 'n = 1,11', 1565 two: 'n = 2,12', 1566 few: 'n = 3..10,13..19' 1567 }, 1568 gu: { 1569 one: 'i = 0 or n = 1' 1570 }, 1571 guw: { 1572 one: 'n = 0..1' 1573 }, 1574 gv: { 1575 one: 'v = 0 and i % 10 = 1', 1576 two: 'v = 0 and i % 10 = 2', 1577 few: 'v = 0 and i % 100 = 0,20,40,60,80', 1578 many: 'v != 0' 1579 }, 1580 he: { 1581 one: 'i = 1 and v = 0', 1582 two: 'i = 2 and v = 0', 1583 many: 'v = 0 and n != 0..10 and n % 10 = 0' 1584 }, 1585 hi: { 1586 one: 'i = 0 or n = 1' 1587 }, 1588 hr: { 1589 one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11', 1590 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14' 1591 }, 1592 hsb: { 1593 one: 'v = 0 and i % 100 = 1 or f % 100 = 1', 1594 two: 'v = 0 and i % 100 = 2 or f % 100 = 2', 1595 few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4' 1596 }, 1597 hy: { 1598 one: 'i = 0,1' 1599 }, 1600 is: { 1601 one: 't = 0 and i % 10 = 1 and i % 100 != 11 or t != 0' 1602 }, 1603 iu: { 1604 one: 'n = 1', 1605 two: 'n = 2' 1606 }, 1607 iw: { 1608 one: 'i = 1 and v = 0', 1609 two: 'i = 2 and v = 0', 1610 many: 'v = 0 and n != 0..10 and n % 10 = 0' 1611 }, 1612 kab: { 1613 one: 'i = 0,1' 1614 }, 1615 kn: { 1616 one: 'i = 0 or n = 1' 1617 }, 1618 kw: { 1619 one: 'n = 1', 1620 two: 'n = 2' 1621 }, 1622 lag: { 1623 zero: 'n = 0', 1624 one: 'i = 0,1 and n != 0' 1625 }, 1626 ln: { 1627 one: 'n = 0..1' 1628 }, 1629 lt: { 1630 one: 'n % 10 = 1 and n % 100 != 11..19', 1631 few: 'n % 10 = 2..9 and n % 100 != 11..19', 1632 many: 'f != 0' 1633 }, 1634 lv: { 1635 zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19', 1636 one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1' 1637 }, 1638 mg: { 1639 one: 'n = 0..1' 1640 }, 1641 mk: { 1642 one: 'v = 0 and i % 10 = 1 or f % 10 = 1' 1643 }, 1644 mo: { 1645 one: 'i = 1 and v = 0', 1646 few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19' 1647 }, 1648 mr: { 1649 one: 'i = 0 or n = 1' 1650 }, 1651 mt: { 1652 one: 'n = 1', 1653 few: 'n = 0 or n % 100 = 2..10', 1654 many: 'n % 100 = 11..19' 1655 }, 1656 naq: { 1657 one: 'n = 1', 1658 two: 'n = 2' 1659 }, 1660 nso: { 1661 one: 'n = 0..1' 1662 }, 1663 pa: { 1664 one: 'n = 0..1' 1665 },
1666 pl: { 1667 one: 'i = 1 and v = 0', 1668 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14', 1669 many: 'v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14' 1670 }, 1671 prg: { 1672 zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19', 1673 one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1' 1674 }, 1675 pt: { 1676 one: 'i = 0..1' 1677 }, 1678 ro: { 1679 one: 'i = 1 and v = 0', 1680 few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19' 1681 }, 1682 ru: { 1683 one: 'v = 0 and i % 10 = 1 and i % 100 != 11', 1684 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14', 1685 many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14' 1686 }, 1687 se: { 1688 one: 'n = 1', 1689 two: 'n = 2' 1690 }, 1691 sh: { 1692 one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11', 1693 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14' 1694 }, 1695 shi: { 1696 one: 'i = 0 or n = 1', 1697 few: 'n = 2..10' 1698 }, 1699 si: { 1700 one: 'n = 0,1 or i = 0 and f = 1' 1701 }, 1702 sk: { 1703 one: 'i = 1 and v = 0', 1704 few: 'i = 2..4 and v = 0', 1705 many: 'v != 0' 1706 }, 1707 sl: { 1708 one: 'v = 0 and i % 100 = 1', 1709 two: 'v = 0 and i % 100 = 2', 1710 few: 'v = 0 and i % 100 = 3..4 or v != 0' 1711 }, 1712 sma: { 1713 one: 'n = 1', 1714 two: 'n = 2' 1715 }, 1716 smi: { 1717 one: 'n = 1', 1718 two: 'n = 2' 1719 }, 1720 smj: { 1721 one: 'n = 1', 1722 two: 'n = 2' 1723 }, 1724 smn: { 1725 one: 'n = 1', 1726 two: 'n = 2' 1727 }, 1728 sms: { 1729 one: 'n = 1', 1730 two: 'n = 2' 1731 }, 1732 sr: { 1733 one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11', 1734 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14' 1735 }, 1736 ti: { 1737 one: 'n = 0..1' 1738 }, 1739 tl: { 1740 one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9' 1741 }, 1742 tzm: { 1743 one: 'n = 0..1 or n = 11..99' 1744 }, 1745 uk: { 1746 one: 'v = 0 and i % 10 = 1 and i % 100 != 11', 1747 few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14', 1748 many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14' 1749 }, 1750 wa: { 1751 one: 'n = 0..1' 1752 }, 1753 zu: { 1754 one: 'i = 0 or n = 1' 1755 } 1756 }, 1757 // jscs:enable 1758 1759 /** 1760 * Plural form transformations, needed for some languages. 1761 * 1762 * @param {integer} count 1763 * Non-localized quantifier 1764 * @param {Array} forms 1765 * List of plural forms 1766 * @return {string} Correct form for quantifier in this language 1767 */ 1768 convertPlural: function ( count, forms ) { 1769 var pluralRules, 1770 pluralFormIndex, 1771 index, 1772 explicitPluralPattern = new RegExp( '\\d+=', 'i' ), 1773 formCount, 1774 form; 1775 1776 if ( !forms || forms.length === 0 ) { 1777 return ''; 1778 } 1779 1780 // Handle for Explicit 0= & 1= values 1781 for ( index = 0; index < forms.length; index++ ) { 1782 form = forms[ index ]; 1783 if ( explicitPluralPattern.test( form ) ) { 1784 formCount = parseInt( form.slice( 0, form.indexOf( '=' ) ), 10 ); 1785 if ( formCount === count ) { 1786 return ( form.slice( form.indexOf( '=' ) + 1 ) ); 1787 } 1788 forms[ index ] = undefined; 1789 } 1790 } 1791 1792 forms = $.map( forms, function ( form ) { 1793 if ( form !== undefined ) { 1794 return form; 1795 } 1796 } ); 1797 1798 pluralRules = this.pluralRules[ $.i18n().locale ]; 1799 1800 if ( !pluralRules ) { 1801 // default fallback. 1802 return ( count === 1 ) ? forms[ 0 ] : forms[ 1 ]; 1803 } 1804 1805 pluralFormIndex = this.getPluralForm( count, pluralRules ); 1806 pluralFormIndex = Math.min( pluralFormIndex, forms.length - 1 ); 1807 1808 return forms[ pluralFormIndex ]; 1809 }, 1810 1811 /** 1812 * For the number, get the plural for index 1813 * 1814 * @param {integer} number 1815 * @param {Object} pluralRules 1816 * @return {integer} plural form index 1817 */ 1818 getPluralForm: function ( number, pluralRules ) { 1819 var i, 1820 pluralForms = [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 1821 pluralFormIndex = 0; 1822 1823 for ( i = 0; i < pluralForms.length; i++ ) { 1824 if ( pluralRules[ pluralForms[ i ] ] ) { 1825 if ( pluralRuleParser( pluralRules[ pluralForms[ i ] ], number ) ) { 1826 return pluralFormIndex; 1827 } 1828 1829 pluralFormIndex++; 1830 } 1831 } 1832 1833 return pluralFormIndex; 1834 }, 1835 1836 /** 1837 * Converts a number using digitTransformTable. 1838 * 1839 * @param {number} num Value to be converted 1840 * @param {boolean} integer Convert the return value to an integer 1841 * @return {string} The number converted into a String. 1842 */ 1843 convertNumber: function ( num, integer ) { 1844 var tmp, item, i, 1845 transformTable, numberString, convertedNumber; 1846 1847 // Set the target Transform table: 1848 transformTable = this.digitTransformTable( $.i18n().locale ); 1849 numberString = String( num ); 1850 convertedNumber = ''; 1851 1852 if ( !transformTable ) { 1853 return num; 1854 } 1855 1856 // Check if the restore to Latin number flag is set: 1857 if ( integer ) {
1858 if ( parseFloat( num, 10 ) === num ) { 1859 return num; 1860 } 1861 1862 tmp = []; 1863 1864 for ( item in transformTable ) { 1865 tmp[ transformTable[ item ] ] = item; 1866 } 1867 1868 transformTable = tmp; 1869 } 1870 1871 for ( i = 0; i < numberString.length; i++ ) { 1872 if ( transformTable[ numberString[ i ] ] ) { 1873 convertedNumber += transformTable[ numberString[ i ] ]; 1874 } else { 1875 convertedNumber += numberString[ i ]; 1876 } 1877 } 1878 1879 return integer ? parseFloat( convertedNumber, 10 ) : convertedNumber; 1880 }, 1881 1882 /** 1883 * Grammatical transformations, needed for inflected languages. 1884 * Invoked by putting {{grammar:form|word}} in a message. 1885 * Override this method for languages that need special grammar rules 1886 * applied dynamically. 1887 * 1888 * @param {string} word 1889 * @param {string} form 1890 * @return {string} 1891 */ 1892 // eslint-disable-next-line no-unused-vars 1893 convertGrammar: function ( word, form ) { 1894 return word; 1895 }, 1896 1897 /** 1898 * Provides an alternative text depending on specified gender. Usage 1899 * {{gender:[gender|user object]|masculine|feminine|neutral}}. If second 1900 * or third parameter are not specified, masculine is used. 1901 * 1902 * These details may be overriden per language. 1903 * 1904 * @param {string} gender 1905 * male, female, or anything else for neutral. 1906 * @param {Array} forms 1907 * List of gender forms 1908 * 1909 * @return {string} 1910 */ 1911 gender: function ( gender, forms ) { 1912 if ( !forms || forms.length === 0 ) { 1913 return ''; 1914 } 1915 1916 while ( forms.length < 2 ) { 1917 forms.push( forms[ forms.length - 1 ] ); 1918 } 1919 1920 if ( gender === 'male' ) { 1921 return forms[ 0 ]; 1922 } 1923 1924 if ( gender === 'female' ) { 1925 return forms[ 1 ]; 1926 } 1927 1928 return ( forms.length === 3 ) ? forms[ 2 ] : forms[ 0 ]; 1929 }, 1930 1931 /** 1932 * Get the digit transform table for the given language 1933 * See http://cldr.unicode.org/translation/numbering-systems 1934 * 1935 * @param {string} language 1936 * @return {Array|boolean} List of digits in the passed language or false 1937 * representation, or boolean false if there is no information. 1938 */ 1939 digitTransformTable: function ( language ) { 1940 var tables = { 1941 ar: '٠١٢٣٤٥٦٧٨٩', 1942 fa: 'Û°Û±Û²Û³Û´ÛµÛ¶Û·Û¸Û¹', 1943 ml: '൦൧൨൩൪൫൬àµàµ®àµ¯', 1944 kn: '೦೧೨೩೪೫೬à³à³®à³¯', 1945 lo: 'à»à»à»à»à»à»à»à»à»à»', 1946 or: 'à¦à§à¨à©àªà«à¬àà®à¯', 1947 kh: 'á á¡á¢á£á¤á¥á¦á§á¨á©', 1948 pa: '੦੧੨੩੪੫੬à©à©®à©¯', 1949 gu: '૦૧૨૩૪૫૬à«à«®à«¯', 1950 hi: '०१२३४५६à¥à¥®à¥¯', 1951 my: 'áááááá áááá', 1952 ta: '௦௧௨௩௪௫௬à¯à¯®à¯¯', 1953 te: '౦౧౨౩౪౫౬à±à±®à±¯', 1954 th: 'à¹à¹à¹à¹à¹à¹à¹à¹à¹à¹', // FIXME use iso 639 codes 1955 bo: '༠༡༢༣༤༥༦༧༨༩' // FIXME use iso 639 codes 1956 }; 1957 1958 if ( !tables[ language ] ) { 1959 return false; 1960 } 1961 1962 return tables[ language ].split( '' ); 1963 } 1964 }; 1965 1966 $.extend( $.i18n.languages, { 1967 'default': language 1968 } ); 1969}( jQuery ) ); 1970 1971 1972/***/ }), 1973 1974/***/ 34517: 1975/*!*********************************************************************!*\ 1976 !*** ./runestone/common/js/jquery_i18n/jquery.i18n.messagestore.js ***! 1977 \*********************************************************************/ 1978/***/ (() => { 1979 1980/*! 1981 * jQuery Internationalization library - Message Store 1982 * 1983 * Copyright (C) 2012 Santhosh Thottingal 1984 * 1985 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do anything special to 1986 * choose one license or the other and you don't have to notify anyone which license you are using. 1987 * You are free to use UniversalLanguageSelector in commercial projects as long as the copyright 1988 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. 1989 * 1990 * @licence GNU General Public Licence 2.0 or later 1991 * @licence MIT License 1992 */ 1993 1994( function ( $ ) { 1995 'use strict'; 1996 1997 var MessageStore = function () { 1998 this.messages = {}; 1999 this.sources = {}; 2000 }; 2001 2002 function jsonMessageLoader( url ) { 2003 var deferred = $.Deferred(); 2004 2005 $.getJSON( url ) 2006 .done( deferred.resolve ) 2007 .fail( function ( jqxhr, settings, exception ) { 2008 $.i18n.log( 'Error in loading messages from ' + url + ' Exception: ' + exception ); 2009 // Ignore 404 exception, because we are handling fallabacks explicitly 2010 deferred.resolve(); 2011 } ); 2012 2013 return deferred.promise(); 2014 } 2015 2016 /** 2017 * See https://github.com/wikimedia/jquery.i18n/wiki/Specification#wiki-Message_File_Loading 2018 */ 2019 MessageStore.prototype = { 2020 2021 /** 2022 * General message loading API This can take a URL string for 2023 * the json formatted messages. 2024 * <code>load('path/to/all_localizations.json');</code> 2025 * 2026 * This can also load a localization file for a locale <code> 2027 * load( 'path/to/de-messages.json', 'de' ); 2028 * </code>
2029 * A data object containing message key- message translation mappings 2030 * can also be passed Eg: 2031 * <code> 2032 * load( { 'hello' : 'Hello' }, optionalLocale ); 2033 * </code> If the data argument is 2034 * null/undefined/false, 2035 * all cached messages for the i18n instance will get reset. 2036 * 2037 * @param {string|Object} source 2038 * @param {string} locale Language tag 2039 * @return {jQuery.Promise} 2040 */ 2041 load: function ( source, locale ) { 2042 var key = null, 2043 deferred = null, 2044 deferreds = [], 2045 messageStore = this; 2046 2047 if ( typeof source === 'string' ) { 2048 // This is a URL to the messages file. 2049 $.i18n.log( 'Loading messages from: ' + source ); 2050 deferred = jsonMessageLoader( source ) 2051 .done( function ( localization ) { 2052 messageStore.set( locale, localization ); 2053 } ); 2054 2055 return deferred.promise(); 2056 } 2057 2058 if ( locale ) { 2059 // source is an key-value pair of messages for given locale 2060 messageStore.set( locale, source ); 2061 2062 return $.Deferred().resolve(); 2063 } else { 2064 // source is a key-value pair of locales and their source 2065 for ( key in source ) { 2066 if ( Object.prototype.hasOwnProperty.call( source, key ) ) { 2067 locale = key; 2068 // No {locale} given, assume data is a group of languages, 2069 // call this function again for each language. 2070 deferreds.push( messageStore.load( source[ key ], locale ) ); 2071 } 2072 } 2073 return $.when.apply( $, deferreds ); 2074 } 2075 2076 }, 2077 2078 /** 2079 * Set messages to the given locale. 2080 * If locale exists, add messages to the locale. 2081 * 2082 * @param {string} locale 2083 * @param {Object} messages 2084 */ 2085 set: function ( locale, messages ) { 2086 if ( !this.messages[ locale ] ) { 2087 this.messages[ locale ] = messages; 2088 } else { 2089 this.messages[ locale ] = $.extend( this.messages[ locale ], messages ); 2090 } 2091 }, 2092 2093 /** 2094 * 2095 * @param {string} locale 2096 * @param {string} messageKey 2097 * @return {boolean} 2098 */ 2099 get: function ( locale, messageKey ) { 2100 return this.messages[ locale ] && this.messages[ locale ][ messageKey ]; 2101 } 2102 }; 2103 2104 $.extend( $.i18n.messageStore, new MessageStore() ); 2105}( jQuery ) ); 2106 2107 2108/***/ }), 2109 2110/***/ 25252: 2111/*!***************************************************************!*\ 2112 !*** ./runestone/common/js/jquery_i18n/jquery.i18n.parser.js ***! 2113 \***************************************************************/ 2114/***/ (() => { 2115 2116/*! 2117 * jQuery Internationalization library 2118 * 2119 * Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar 2120 * 2121 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do 2122 * anything special to choose one license or the other and you don't have to 2123 * notify anyone which license you are using. You are free to use 2124 * UniversalLanguageSelector in commercial projects as long as the copyright 2125 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. 2126 * 2127 * @licence GNU General Public Licence 2.0 or later 2128 * @licence MIT License 2129 */ 2130 2131( function ( $ ) { 2132 'use strict'; 2133 2134 var MessageParser = function ( options ) { 2135 this.options = $.extend( {}, $.i18n.parser.defaults, options ); 2136 this.language = $.i18n.languages[ String.locale ] || $.i18n.languages[ 'default' ]; 2137 this.emitter = $.i18n.parser.emitter; 2138 }; 2139 2140 MessageParser.prototype = { 2141 2142 constructor: MessageParser, 2143 2144 simpleParse: function ( message, parameters ) { 2145 return message.replace( /\$(\d+)/g, function ( str, match ) { 2146 var index = parseInt( match, 10 ) - 1; 2147 2148 return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match; 2149 } ); 2150 }, 2151 2152 parse: function ( message, replacements ) { 2153 if ( message.indexOf( '{{' ) < 0 ) { 2154 return this.simpleParse( message, replacements ); 2155 } 2156 2157 this.emitter.language = $.i18n.languages[ $.i18n().locale ] || 2158 $.i18n.languages[ 'default' ]; 2159 2160 return this.emitter.emit( this.ast( message ), replacements ); 2161 }, 2162 2163 ast: function ( message ) { 2164 var pipe, colon, backslash, anyCharacter, dollar, digits, regularLiteral, 2165 regularLiteralWithoutBar, regularLiteralWithoutSpace, escapedOrLiteralWithoutBar, 2166 escapedOrRegularLiteral, templateContents, templateName, openTemplate, 2167 closeTemplate, expression, paramExpression, result, 2168 pos = 0; 2169 2170 // Try parsers until one works, if none work return null 2171 function choice( parserSyntax ) { 2172 return function () { 2173 var i, result; 2174 2175 for ( i = 0; i < parserSyntax.length; i++ ) { 2176 result = parserSyntax[ i ](); 2177 2178 if ( result !== null ) { 2179 return result; 2180 } 2181 } 2182 2183 return null; 2184 }; 2185 } 2186 2187 // Try several parserSyntax-es in a row. 2188 // All must succeed; otherwise, return null. 2189 // This is the only eager one. 2190 function sequence( parserSyntax ) { 2191 var i, res, 2192 originalPos = pos, 2193 result = []; 2194 2195 for ( i = 0; i < parserSyntax.length; i++ ) { 2196 res = parserSyntax[ i ](); 2197 2198 if ( res === null ) { 2199 pos = originalPos; 2200 2201 return null; 2202 } 2203 2204 result.push( res ); 2205 } 2206 2207 return result; 2208 } 2209 2210 // Run the same parser over and over until it fails. 2211 // Must succeed a minimum of n times; otherwise, return null. 2212 function nOrMore( n, p ) { 2213 return function () { 2214 var originalPos = pos, 2215 result = [], 2216 parsed = p(); 2217 2218 while ( parsed !== null ) { 2219 result.push( parsed ); 2220 parsed = p(); 2221 } 2222 2223 if ( result.length < n ) { 2224 pos = originalPos; 2225 2226 return null; 2227 } 2228 2229 return result; 2230 }; 2231 } 2232 2233 // Helpers -- just make parserSyntax out of simpler JS builtin types 2234 2235 function makeStringParser( s ) { 2236 var len = s.length; 2237 2238 return function () { 2239 var result = null; 2240 2241 if ( message.slice( pos, pos + len ) === s ) { 2242 result = s; 2243 pos += len; 2244 } 2245 2246 return result; 2247 }; 2248 } 2249 2250 function makeRegexParser( regex ) { 2251 return function () { 2252 var matches = message.slice( pos ).match( regex ); 2253 2254 if ( matches === null ) { 2255 return null; 2256 } 2257 2258 pos += matches[ 0 ].length; 2259 2260 return matches[ 0 ]; 2261 }; 2262 } 2263 2264 pipe = makeStringParser( '|' ); 2265 colon = makeStringParser( ':' ); 2266 backslash = makeStringParser( '\\' ); 2267 anyCharacter = makeRegexParser( /^./ ); 2268 dollar = makeStringParser( '$' ); 2269 digits = makeRegexParser( /^\d+/ ); 2270 regularLiteral = makeRegexParser( /^[^{}[\]$\\]/ ); 2271 regularLiteralWithoutBar = makeRegexParser( /^[^{}[\]$\\|]/ ); 2272 regularLiteralWithoutSpace = makeRegexParser( /^[^{}[\]$\s]/ ); 2273 2274 // There is a general pattern: 2275 // parse a thing; 2276 // if it worked, apply transform, 2277 // otherwise return null. 2278 // But using this as a combinator seems to cause problems
2279 // when combined with nOrMore(). 2280 // May be some scoping issue. 2281 function transform( p, fn ) { 2282 return function () { 2283 var result = p(); 2284 2285 return result === null ? null : fn( result ); 2286 }; 2287 } 2288 2289 // Used to define "literals" within template parameters. The pipe 2290 // character is the parameter delimeter, so by default 2291 // it is not a literal in the parameter 2292 function literalWithoutBar() { 2293 var result = nOrMore( 1, escapedOrLiteralWithoutBar )(); 2294 2295 return result === null ? null : result.join( '' ); 2296 } 2297 2298 function literal() { 2299 var result = nOrMore( 1, escapedOrRegularLiteral )(); 2300 2301 return result === null ? null : result.join( '' ); 2302 } 2303 2304 function escapedLiteral() { 2305 var result = sequence( [ backslash, anyCharacter ] ); 2306 2307 return result === null ? null : result[ 1 ]; 2308 } 2309 2310 choice( [ escapedLiteral, regularLiteralWithoutSpace ] ); 2311 escapedOrLiteralWithoutBar = choice( [ escapedLiteral, regularLiteralWithoutBar ] ); 2312 escapedOrRegularLiteral = choice( [ escapedLiteral, regularLiteral ] ); 2313 2314 function replacement() { 2315 var result = sequence( [ dollar, digits ] ); 2316 2317 if ( result === null ) { 2318 return null; 2319 } 2320 2321 return [ 'REPLACE', parseInt( result[ 1 ], 10 ) - 1 ]; 2322 } 2323 2324 templateName = transform( 2325 // see $wgLegalTitleChars 2326 // not allowing : due to the need to catch "PLURAL:$1" 2327 makeRegexParser( /^[ !"$&'()*,./0-9;=?@A-Z^_`a-z~\x80-\xFF+-]+/ ), 2328 2329 function ( result ) { 2330 return result.toString(); 2331 } 2332 ); 2333 2334 function templateParam() { 2335 var expr, 2336 result = sequence( [ pipe, nOrMore( 0, paramExpression ) ] ); 2337 2338 if ( result === null ) { 2339 return null; 2340 } 2341 2342 expr = result[ 1 ]; 2343 2344 // use a "CONCAT" operator if there are multiple nodes, 2345 // otherwise return the first node, raw. 2346 return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[ 0 ]; 2347 } 2348 2349 function templateWithReplacement() { 2350 var result = sequence( [ templateName, colon, replacement ] ); 2351 2352 return result === null ? null : [ result[ 0 ], result[ 2 ] ]; 2353 } 2354 2355 function templateWithOutReplacement() { 2356 var result = sequence( [ templateName, colon, paramExpression ] ); 2357 2358 return result === null ? null : [ result[ 0 ], result[ 2 ] ]; 2359 } 2360 2361 templateContents = choice( [ 2362 function () { 2363 var res = sequence( [ 2364 // templates can have placeholders for dynamic 2365 // replacement eg: {{PLURAL:$1|one car|$1 cars}} 2366 // or no placeholders eg: 2367 // {{GRAMMAR:genitive|{{SITENAME}}} 2368 choice( [ templateWithReplacement, templateWithOutReplacement ] ), 2369 nOrMore( 0, templateParam ) 2370 ] ); 2371 2372 return res === null ? null : res[ 0 ].concat( res[ 1 ] ); 2373 }, 2374 function () { 2375 var res = sequence( [ templateName, nOrMore( 0, templateParam ) ] ); 2376 2377 if ( res === null ) { 2378 return null; 2379 } 2380 2381 return [ res[ 0 ] ].concat( res[ 1 ] ); 2382 } 2383 ] ); 2384 2385 openTemplate = makeStringParser( '{{' ); 2386 closeTemplate = makeStringParser( '}}' ); 2387 2388 function template() { 2389 var result = sequence( [ openTemplate, templateContents, closeTemplate ] ); 2390 2391 return result === null ? null : result[ 1 ]; 2392 } 2393 2394 expression = choice( [ template, replacement, literal ] ); 2395 paramExpression = choice( [ template, replacement, literalWithoutBar ] ); 2396 2397 function start() { 2398 var result = nOrMore( 0, expression )(); 2399 2400 if ( result === null ) { 2401 return null; 2402 } 2403 2404 return [ 'CONCAT' ].concat( result ); 2405 } 2406 2407 result = start(); 2408 2409 /* 2410 * For success, the pos must have gotten to the end of the input 2411 * and returned a non-null. 2412 * n.b. This is part of language infrastructure, so we do not throw an 2413 * internationalizable message. 2414 */ 2415 if ( result === null || pos !== message.length ) { 2416 throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + message ); 2417 } 2418 2419 return result; 2420 } 2421 2422 }; 2423 2424 $.extend( $.i18n.parser, new MessageParser() ); 2425}( jQuery ) ); 2426 2427/***/ }), 2428 2429/***/ 66563: 2430/*!***********************************************!*\ 2431 !*** ./runestone/common/js/presenter_mode.js ***! 2432 \***********************************************/ 2433/***/ (() => { 2434 2435var codeExercises; 2436var presenterCssLink; 2437var presentModeInitialized = false;
2438 2439function presentToggle() { 2440 if (!presentModeInitialized) { 2441 presentModeSetup(); 2442 presentModeInitialized = true; 2443 } 2444 let bod = $("body"); 2445 let presentClass = "present"; 2446 let fullHeightClass = "full-height"; 2447 let bottomClass = "bottom"; 2448 if (bod.hasClass(presentClass)) { 2449 $("section *") 2450 .not( 2451 "h1, .presentation-title, .btn-presenter, .runestone, .runestone *, section, .pre, code" 2452 ) 2453 .removeClass("hidden"); //show everything 2454 $("#completionButton").removeClass("hidden"); 2455 bod.removeClass(presentClass); 2456 $("." + fullHeightClass).removeClass(fullHeightClass); 2457 $("." + bottomClass).removeClass(bottomClass); 2458 localStorage.setItem("presentMode", "text"); 2459 codeExercises.removeClass("hidden"); 2460 presenterCssLink.disabled = true; // disable present_mode.css 2461 } else { 2462 $("section *") 2463 .not( 2464 "h1, .presentation-title, .btn-presenter, .runestone, .runestone *, section, .pre, code" 2465 ) 2466 .addClass("hidden"); // hide extraneous stuff 2467 $("#completionButton").addClass("hidden"); 2468 bod.addClass(presentClass); 2469 bod.addClass(fullHeightClass); 2470 $("html").addClass(fullHeightClass); 2471 $("section .runestone").addClass(fullHeightClass); 2472 $(".ac-caption").addClass(bottomClass); 2473 localStorage.setItem("presentMode", presentClass); 2474 // presenter_mode.css is loaded by webpack 2475 //loadPresenterCss(); // present_mode.css should only apply when in presenter mode. 2476 activateExercise(); 2477 } 2478} 2479 2480function loadPresenterCss() { 2481 presenterCssLink = document.createElement("link"); 2482 presenterCssLink.type = "text/css"; 2483 presenterCssLink.href = "../_static/presenter_mode.css"; 2484 presenterCssLink.rel = "stylesheet"; 2485 document.getElementsByTagName("head")[0].appendChild(presenterCssLink); 2486} 2487 2488function presentModeSetup() { 2489 // moved this out of configure 2490 let dataComponent = $("[data-childcomponent]"); 2491 2492 // this still leaves some things semi-messed up when you exit presenter mode. 2493 // but instructors will probably just learn to refresh the page. 2494 dataComponent.addClass("runestone"); 2495 dataComponent.parent().closest("div").not("section").addClass("runestone"); 2496 dataComponent.parent().closest("div").css("max-width", "none"); 2497 2498 dataComponent.each(function (index) { 2499 let me = $(this); 2500 $(this) 2501 .find(".ac_code_div, .ac_output") 2502 .wrapAll("<div class='ac-block' style='width: 100%;'></div>"); 2503 }); 2504 2505 codelensListener(500); 2506 $("section img").wrap('<div class="runestone">'); 2507 codeExercises = $(".runestone").not(".runestone .runestone"); 2508 // codeExercises.each(function(){ 2509 $("h1").before( 2510 "<div class='presentation-title'> \ 2511 <button class='prev-exercise btn-presenter btn-grey-outline' onclick='prevExercise()'>Back</button> \ 2512 <button class='next-exercise btn-presenter btn-grey-solid' onclick='nextExercise()'>Next</button> \ 2513 </div>" 2514 ); 2515} 2516function getActiveExercise() { 2517 return (active = codeExercises.filter(".active")); 2518} 2519 2520function activateExercise(index) { 2521 if (typeof index == "undefined") { 2522 index = 0; 2523 } 2524 2525 let active = getActiveExercise(); 2526 2527 if (codeExercises.length) { 2528 active.removeClass("active"); 2529 active = $(codeExercises[index]).addClass("active"); 2530 active.removeClass("hidden"); 2531 codeExercises.not(codeExercises.filter(".active")).addClass("hidden"); 2532 } 2533} 2534 2535window.nextExercise = function() { 2536 let active = getActiveExercise(); 2537 let nextIndex = codeExercises.index(active) + 1; 2538 if (nextIndex < codeExercises.length) { 2539 activateExercise(nextIndex); 2540 } 2541} 2542 2543window.prevExercise = function() { 2544 let active = getActiveExercise(); 2545 let prevIndex = codeExercises.index(active) - 1; 2546 if (prevIndex >= 0) { 2547 activateExercise(prevIndex); 2548 } 2549} 2550 2551function configure() { 2552 let rightNav = $(".navbar-right"); 2553 rightNav.prepend( 2554 "<li class='dropdown view-toggle'> \ 2555 <label>View: \ 2556 <select class='mode-select'> \ 2557 <option value='text'>Textbook</option> \ 2558 <option value='present'>Code Presenter</option> \ 2559 </select> \ 2560 </label> \ 2561 </li>" 2562 ); 2563 2564 let modeSelect = $(".mode-select").change(presentToggle); 2565} 2566 2567function codelensListener(duration) { 2568 // $(".ExecutionVisualizer").length ? configureCodelens() : setTimeout(codelensListener, duration); 2569 // configureCodelens(); 2570} 2571 2572function configureCodelens() { 2573 let acCodeTitle = document.createElement("h4"); 2574 acCodeTitle.textContent = "Active Code Window"; 2575 let acCode = $(".ac_code_div"); 2576 $(".ac_code_div").addClass("col-md-6"); 2577 acCode.prepend(acCodeTitle); 2578 2579 acOutTitle = document.createElement("h4"); 2580 acOutTitle.textContent = "Output Window"; 2581 let acOut = $(".ac_output").addClass("col-md-6"); 2582 $(".ac_output").prepend(acOutTitle); 2583 2584 let sketchpadTitle = document.createElement("h4"); 2585 sketchpadTitle.textContent = "Sketchpad"; 2586 let sketchpad = document.createElement("span"); 2587 $(sketchpad).addClass("sketchpad"); 2588 let sketchpadContainer = document.createElement("div"); 2589 $(sketchpadContainer).addClass("sketchpad-container"); 2590 sketchpadContainer.appendChild(sketchpadTitle); 2591 sketchpadContainer.appendChild(sketchpad); 2592 //$('.ac_output').append(sketchpadContainer); 2593 2594 let visualizers = $(".ExecutionVisualizer"); 2595 2596 console.log("Econtainer: ", this.eContainer); 2597 2598 $("[data-childcomponent]").on("click", "button.row-mode", function () { 2599 $(this).closest("[data-childcomponent]").removeClass("card-mode"); 2600 $(this).closest("[data-childcomponent]").addClass("row-mode"); 2601 $(this).next(".card-mode").removeClass("active-layout"); 2602 $(this).addClass("active-layout"); 2603 }); 2604 2605 $("[data-childcomponent]").on("click", "button.card-mode", function () { 2606 $(this).closest("[data-childcomponent]").removeClass("row-mode"); 2607 $(this).closest("[data-childcomponent]").addClass("card-mode"); 2608 $(this).prev(".row-mode").removeClass("active-layout"); 2609 $(this).addClass("active-layout"); 2610 }); 2611 2612 $("[data-childcomponent] .ac_section").each(function () { 2613 $(this).prepend( 2614 '<div class="presentation-options"><button class="row-mode layout-btn"><img src="../_images/row-btn-content.png" alt="Rows"></button><button class="card-mode layout-btn"><img src="../_images/card-btn-content.png" alt="Card"></button></div>' 2615 ); 2616 }); 2617 2618 visualizers.each(function (index) { 2619 let me = $(this); 2620 let col1 = me.find("#vizLayoutTdFirst"); 2621 let col2 = me.find("#vizLayoutTdSecond"); 2622 let dataVis = me.find("#dataViz"); 2623 let stackHeapTable = me.find("#stackHeapTable"); 2624 let output = me.find("#progOutputs"); 2625 output.css("display", "block"); 2626 me.parent().prepend( 2627 "<div class='presentation-title'><div class='title-text'> Example " + 2628 (Number(index) + 1) + 2629 "</div></div>" 2630 ); 2631 }); 2632 2633 acCode.each(function () { 2634 let section = $(this).closest(".ac-block").parent(); 2635 console.log(section, section.length); 2636 section.append(sketchpadContainer); 2637 }); 2638 2639 $("button.card-mode").click(); 2640 2641 let modeSelect = $(".mode-select"); 2642 let mode = localStorage.getItem("presentMode"); 2643 if (mode == "present") { 2644 modeSelect.val("present"); 2645 modeSelect.change(); 2646 } 2647} 2648 2649$(document).on("runestone:login-complete", function () { 2650 // if user is instructor, enable presenter mode 2651 if (eBookConfig.isInstructor) { 2652 configure(); 2653 } 2654}); 2655 2656 2657/***/ }), 2658 2659/***/ 22538: 2660/*!****************************************!*\ 2661 !*** ./runestone/common/js/pretext.js ***! 2662 \****************************************/ 2663/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2664 2665"use strict"; 2666__webpack_require__.r(__webpack_exports__); 2667/* harmony import */ var _runestonebase_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./runestonebase.js */ 2568); 2668/* 2669 Support functions for PreTeXt books running on Runestone 2670 2671*/ 2672 2673 2674 2675function setupPTXEvents() { 2676 let rb = new _runestonebase_js__WEBPACK_IMPORTED_MODULE_0__["default"](); 2677 // log an event when a knowl is opened. 2678 $("[data-knowl").on("click", function () { 2679 let div_id = $(this).data("refid"); 2680 rb.logBookEvent({ event: "knowl", act: "click", div_id: div_id }); 2681 }); 2682 // log an event when a sage cell is evaluated 2683 $(".sagecell_evalButton").on("click", function () { 2684 // find parents 2685 let container = $(this).closest(".sagecell-sage"); 2686 let code = $(container[0]).find(".sagecell_input")[0].textContent; 2687 rb.logBookEvent({ event: "sage", act: "run", div_id: container[0].id }); 2688 }); 2689 if (!eBookConfig.isInstructor) { 2690 $(".commentary").hide(); 2691 } 2692} 2693 2694window.addEventListener("load", function () { 2695 console.log("setting up pretext"); 2696 setupPTXEvents(); 2697 let wrap = document.getElementById("primary-navbar-sticky-wrapper"); 2698 if (wrap) { 2699 wrap.style.overflow="visible"; 2700 } 2701}); 2702 2703 2704/***/ }), 2705 2706/***/ 2568: 2707/*!**********************************************!*\ 2708 !*** ./runestone/common/js/runestonebase.js ***! 2709 \**********************************************/ 2710/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2711 2712"use strict"; 2713__webpack_require__.r(__webpack_exports__); 2714/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2715/* harmony export */ "default": () => (/* binding */ RunestoneBase) 2716/* harmony export */ }); 2717/* harmony import */ var _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bookfuncs.js */ 21294); 2718/* ******************************** 2719 * |docname| - Runestone Base Class 2720 * ******************************** 2721 * All runestone components should inherit from RunestoneBase. In addition all runestone components should do the following things: 2722 * 2723 * 1. Ensure that they are wrapped in a div with the class runestone 2724 * 2. Write their source AND their generated html to the database if the database is configured 2725 * 3. Properly save and restore their answers using the checkServer mechanism in this base class. Each component must provide an implementation of: 2726 * 2727 * - checkLocalStorage
2728 * - setLocalStorage 2729 * - restoreAnswers 2730 * - disableInteraction 2731 * 2732 * 4. provide a Selenium based unit test 2733 */ 2734 2735 2736//import "./../styles/runestone-custom-sphinx-bootstrap.css"; 2737 2738class RunestoneBase { 2739 constructor(opts) { 2740 this.component_ready_promise = new Promise( 2741 (resolve) => (this._component_ready_resolve_fn = resolve) 2742 ); 2743 this.optional = false; 2744 if (typeof window.allComponents === "undefined") { 2745 window.allComponents = []; 2746 } 2747 window.allComponents.push(this); 2748 if (opts) { 2749 this.sid = opts.sid; 2750 this.graderactive = opts.graderactive; 2751 this.showfeedback = true; 2752 if (opts.timed) { 2753 this.isTimed = true; 2754 } 2755 if (opts.enforceDeadline) { 2756 this.deadline = opts.deadline; 2757 } 2758 if ($(opts.orig).data("optional")) { 2759 this.optional = true; 2760 } else { 2761 this.optional = false; 2762 } 2763 if (opts.selector_id) { 2764 this.selector_id = opts.selector_id; 2765 } 2766 if (typeof opts.assessmentTaken !== "undefined") { 2767 this.assessmentTaken = opts.assessmentTaken; 2768 } else { 2769 // default to true as this opt is only provided from a timedAssessment 2770 this.assessmentTaken = true; 2771 } 2772 // This is for the selectquestion points 2773 // If a selectquestion is part of a timed exam it will get 2774 // the timedWrapper options. 2775 if (typeof opts.timedWrapper !== "undefined") { 2776 this.timedWrapper = opts.timedWrapper; 2777 } else { 2778 // However sometimes selectquestions 2779 // are used in regular assignments. The hacky way to detect this 2780 // is to look for doAssignment in the URL and then grab 2781 // the assignment name from the heading. 2782 if (location.href.indexOf("doAssignment") >= 0) { 2783 this.timedWrapper = $("h1#assignment_name").text(); 2784 } else { 2785 this.timedWrapper = null; 2786 } 2787 } 2788 if ($(opts.orig).data("question_label")) { 2789 this.question_label = $(opts.orig).data("question_label"); 2790 } 2791 this.is_toggle = true ? opts.is_toggle : 0; 2792 this.is_select = true ? opts.is_select : 0; 2793 2794 } 2795 this.mjelements = []; 2796 let self = this; 2797 this.mjReady = new Promise(function(resolve, reject) { 2798 self.mjresolver = resolve; 2799 }); 2800 this.aQueue = new AutoQueue(); 2801 this.jsonHeaders = new Headers({ 2802 "Content-type": "application/json; charset=utf-8", 2803 Accept: "application/json", 2804 }); 2805 } 2806 2807 // _`logBookEvent` 2808 //---------------- 2809 // This function sends the provided ``eventInfo`` to the `hsblog endpoint` of the server. Awaiting this function returns either ``undefined`` (if Runestone services are not available) or the data returned by the server as a JavaScript object (already JSON-decoded). 2810 async logBookEvent(eventInfo) { 2811 if (this.graderactive) { 2812 return; 2813 } 2814 let post_return; 2815 eventInfo.course_name = eBookConfig.course; 2816 eventInfo.clientLoginStatus = eBookConfig.isLoggedIn; 2817 eventInfo.timezoneoffset = new Date().getTimezoneOffset() / 60; 2818 if (typeof(this.percent) === "number") { 2819 eventInfo.percent = this.percent; 2820 } 2821 if ( 2822 eBookConfig.isLoggedIn && 2823 eBookConfig.useRunestoneServices && 2824 eBookConfig.logLevel > 0 2825 ) { 2826 post_return = this.postLogMessage(eventInfo); 2827 } 2828 if (!this.isTimed || eBookConfig.debug) { 2829 let prefix = eBookConfig.isLoggedIn ? "Save" : "Not"; 2830 console.log(`${prefix} logging event ` + JSON.stringify(eventInfo)); 2831 } 2832 // When selectquestions are part of an assignment especially toggle questions 2833 // we need to count using the selector_id of the select question. 2834 // We also need to log an event for that selector so that we will know 2835 // that interaction has taken place. This is **independent** of how the 2836 // autograder will ultimately grade the question! 2837 if (this.selector_id) { 2838 eventInfo.div_id = this.selector_id.replace( 2839 "-toggleSelectedQuestion", 2840 "" 2841 ); 2842 eventInfo.event = "selectquestion"; 2843 eventInfo.act = "interaction"; 2844 this.postLogMessage(eventInfo); 2845 } 2846 if ( 2847 typeof _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__.pageProgressTracker.updateProgress === "function" && 2848 eventInfo.act != "edit" && 2849 this.optional == false 2850 ) { 2851 _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__.pageProgressTracker.updateProgress(eventInfo.div_id); 2852 } 2853 return post_return; 2854 } 2855 2856 async postLogMessage(eventInfo) { 2857 var post_return;
2858 let request = new Request( 2859 `${eBookConfig.new_server_prefix}/logger/bookevent`, { 2860 method: "POST", 2861 headers: this.jsonHeaders, 2862 body: JSON.stringify(eventInfo), 2863 } 2864 ); 2865 try { 2866 var response = await fetch(request); 2867 if (!response.ok) { 2868 if (response.status === 422) { 2869 // Get details about why this is unprocesable. 2870 post_return = await response.json(); 2871 console.log(post_return.detail); 2872 throw new Error("Unprocessable Request"); 2873 } else if (response.status == 401) { 2874 post_return = await response.json(); 2875 console.log( 2876 `Missing authentication token ${post_return.detail}` 2877 ); 2878 throw new Error("Missing authentication token"); 2879 } 2880 throw new Error(`Failed to save the log entry 2881 Status: ${response.status}`); 2882 } 2883 post_return = await response.json(); 2884 } catch (e) { 2885 let detail = "none"; 2886 if (post_return && post_return.detail) { 2887 detail = post_return.detail; 2888 } 2889 if (eBookConfig.loginRequired) { 2890 alert(`Error: Your action was not saved! 2891 The error was ${e} 2892 Status Code: ${response.status} 2893 Detail: ${detail}. 2894 Please report this error!`); 2895 } 2896 // send a request to save this error 2897 console.log(`Error: ${e} Detail: ${detail} Status Code: ${response.status}`); 2898 } 2899 return post_return; 2900 } 2901 // .. _logRunEvent: 2902 // 2903 // logRunEvent 2904 // ----------- 2905 // This function sends the provided ``eventInfo`` to the `runlog endpoint`. When awaited, this function returns the data (decoded from JSON) the server sent back. 2906 async logRunEvent(eventInfo) { 2907 let post_promise = "done"; 2908 if (this.graderactive) { 2909 return; 2910 } 2911 eventInfo.course = eBookConfig.course; 2912 eventInfo.clientLoginStatus = eBookConfig.isLoggedIn; 2913 eventInfo.timezoneoffset = new Date().getTimezoneOffset() / 60; 2914 if (this.forceSave || "to_save" in eventInfo === false) { 2915 eventInfo.save_code = "True"; 2916 } 2917 if ( 2918 eBookConfig.isLoggedIn && 2919 eBookConfig.useRunestoneServices && 2920 eBookConfig.logLevel > 0 2921 ) { 2922 let request = new Request( 2923 `${eBookConfig.new_server_prefix}/logger/runlog`, { 2924 method: "POST", 2925 headers: this.jsonHeaders, 2926 body: JSON.stringify(eventInfo), 2927 } 2928 ); 2929 let response = await fetch(request); 2930 if (!response.ok) { 2931 post_promise = await response.json(); 2932 if (eBookConfig.loginRequired) { 2933 alert(`Failed to save your code 2934 Status is ${response.status} 2935 Detail: ${post_promise.detail}`); 2936 } else { 2937 console.log( 2938 `Did not save the code. Status: ${response.status}` 2939 ); 2940 } 2941 } else { 2942 post_promise = await response.json(); 2943 } 2944 } 2945 if (!this.isTimed || eBookConfig.debug) { 2946 console.log("running " + JSON.stringify(eventInfo)); 2947 } 2948 if ( 2949 typeof _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__.pageProgressTracker.updateProgress === "function" && 2950 this.optional == false 2951 ) { 2952 _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__.pageProgressTracker.updateProgress(eventInfo.div_id); 2953 } 2954 return post_promise; 2955 } 2956 /* Checking/loading from storage 2957 **WARNING:** DO NOT `await` this function! 2958 This function, although async, does not explicitly resolve its promise by returning a value. The reason for this is because it is called by the constructor for nearly every component. In Javascript constructors cannot be async! 2959 2960 One of the recommended ways to handle the async requirements from within a constructor is to use an attribute as a promise and resolve that attribute at the appropriate time. 2961 */ 2962 async checkServer( 2963 // A string specifying the event name to use for querying the :ref:`getAssessResults` endpoint. 2964 eventInfo, 2965 // If true, this function will invoke ``indicate_component_ready()`` just before it returns. This is provided since most components are ready after this function completes its work. 2966 // 2967 // TODO: This defaults to false, to avoid causing problems with any components that haven't been updated and tested. After all Runestone components have been updated, default this to true and remove the extra parameter from most calls to this function. 2968 will_be_ready = false 2969 ) { 2970 // Check if the server has stored answer 2971 let self = this; 2972 this.checkServerComplete = new Promise(function(resolve, reject) { 2973 self.csresolver = resolve; 2974 }); 2975 if ( 2976 eBookConfig.isLoggedIn && 2977 (this.useRunestoneServices || this.graderactive) 2978 ) { 2979 let data = {}; 2980 data.div_id = this.divid; 2981 data.course = eBookConfig.course; 2982 data.event = eventInfo; 2983 if (this.graderactive && this.deadline) { 2984 data.deadline = this.deadline; 2985 data.rawdeadline = this.rawdeadline; 2986 data.tzoff = this.tzoff; 2987 } 2988 if (this.sid) { 2989 data.sid = this.sid; 2990 } 2991 if (!(data.div_id && data.course && data.event)) { 2992 console.log( 2993 `A required field is missing data ${data.div_id}:${data.course}:${data.event}` 2994 ); 2995 } 2996 // If we are NOT in practice mode and we are not in a peer exercise 2997 // and assessmentTaken is true 2998 if ( 2999 !eBookConfig.practice_mode && 3000 !eBookConfig.peer && 3001 this.assessmentTaken 3002 ) {
3003 let request = new Request( 3004 `${eBookConfig.new_server_prefix}/assessment/results`, { 3005 method: "POST", 3006 body: JSON.stringify(data), 3007 headers: this.jsonHeaders, 3008 } 3009 ); 3010 try { 3011 let response = await fetch(request); 3012 if (response.ok) { 3013 data = await response.json(); 3014 data = data.detail; 3015 this.repopulateFromStorage(data); 3016 this.attempted = true; 3017 if (typeof(data.correct) !== "undefined") { 3018 this.correct = data.correct; 3019 } else { 3020 this.correct = null; 3021 } 3022 this.csresolver("server"); 3023 } else { 3024 console.log( 3025 `HTTP Error getting results: ${response.statusText}` 3026 ); 3027 this.checkLocalStorage(); // just go right to local storage 3028 this.csresolver("local"); 3029 } 3030 } catch (err) { 3031 try { 3032 this.checkLocalStorage(); 3033 } catch (err) { 3034 console.log(err); 3035 } 3036 } 3037 } else { 3038 this.loadData({}); 3039 this.csresolver("not taken"); 3040 } 3041 } else { 3042 this.checkLocalStorage(); // just go right to local storage 3043 this.csresolver("local"); 3044 } 3045 3046 if (will_be_ready) { 3047 this.indicate_component_ready(); 3048 } 3049 } 3050 3051 // This method assumes that ``this.componentDiv`` refers to the ``div`` containing the component, and that this component's ID is set. 3052 indicate_component_ready() { 3053 // Add a class to indicate the component is now ready. 3054 this.containerDiv.classList.add("runestone-component-ready"); 3055 // Resolve the ``this.component_ready_promise``. 3056 this._component_ready_resolve_fn(); 3057 } 3058 3059 loadData(data) { 3060 // for most classes, loadData doesn't do anything. But for Parsons, and perhaps others in the future, 3061 // initialization can happen even when there's no history to be loaded 3062 return null; 3063 } 3064 3065 /** 3066 * repopulateFromStorage is called after a successful API call is made to ``getAssessResults`` in 3067 * the checkServer method in this class 3068 * 3069 * ``restoreAnswers,`` ``setLocalStorage`` and ``checkLocalStorage`` are defined in the child classes. 3070 * 3071 * @param {*} data - a JSON object representing the data needed to restore a previous answer for a component 3072 * @param {*} status - the http status 3073 * @param {*} whatever - ignored 3074 */ 3075 repopulateFromStorage(data) { 3076 // decide whether to use the server's answer (if there is one) or to load from storage 3077 if (data !== null && data !== "no data" && this.shouldUseServer(data)) { 3078 this.restoreAnswers(data); 3079 this.setLocalStorage(data); 3080 } else { 3081 this.checkLocalStorage(); 3082 } 3083 } 3084 shouldUseServer(data) { 3085 // returns true if server data is more recent than local storage or if server storage is correct 3086 if ( 3087 data.correct === "T" || 3088 localStorage.length === 0 || 3089 this.graderactive === true || 3090 this.isTimed 3091 ) { 3092 return true; 3093 } 3094 let ex = localStorage.getItem(this.localStorageKey()); 3095 if (ex === null) { 3096 return true; 3097 } 3098 let storedData; 3099 try { 3100 storedData = JSON.parse(ex); 3101 } catch (err) { 3102 // error while parsing; likely due to bad value stored in storage 3103 console.log(err.message); 3104 localStorage.removeItem(this.localStorageKey()); 3105 // definitely don't want to use local storage here 3106 return true; 3107 } 3108 if (data.answer == storedData.answer) return true; 3109 let storageDate = new Date(storedData.timestamp); 3110 let serverDate = new Date(data.timestamp); 3111 return serverDate >= storageDate; 3112 } 3113 // Return the key which to be used when accessing local storage. 3114 localStorageKey() { 3115 return ( 3116 eBookConfig.email + 3117 ":" + 3118 eBookConfig.course + 3119 ":" + 3120 this.divid + 3121 "-given" 3122 ); 3123 } 3124 addCaption(elType) { 3125 //someElement.parentNode.insertBefore(newElement, someElement.nextSibling); 3126 if (!this.isTimed) { 3127 var capDiv = document.createElement("p"); 3128 if (this.question_label) { 3129 this.caption = `Activity: ${this.question_label} ${this.caption}
3129 <span class="runestone_caption_divid">(${this.divid})</span>`; 3130 $(capDiv).html(this.caption); 3131 $(capDiv).addClass(`${elType}_caption`); 3132 } else { 3133 $(capDiv).html(this.caption + " (" + this.divid + ")"); 3134 $(capDiv).addClass(`${elType}_caption`); 3135 $(capDiv).addClass(`${elType}_caption_text`); 3136 } 3137 this.capDiv = capDiv; 3138 //this.outerDiv.parentNode.insertBefore(capDiv, this.outerDiv.nextSibling); 3139 this.containerDiv.appendChild(capDiv); 3140 } 3141 } 3142 3143 hasUserActivity() { 3144 return this.isAnswered; 3145 } 3146 3147 checkCurrentAnswer() { 3148 console.log( 3149 "Each component should provide an implementation of checkCurrentAnswer" 3150 ); 3151 } 3152 3153 async logCurrentAnswer() { 3154 console.log( 3155 "Each component should provide an implementation of logCurrentAnswer" 3156 ); 3157 } 3158 renderFeedback() { 3159 console.log( 3160 "Each component should provide an implementation of renderFeedback" 3161 ); 3162 } 3163 disableInteraction() { 3164 console.log( 3165 "Each component should provide an implementation of disableInteraction" 3166 ); 3167 } 3168 3169 toString() { 3170 return `${this.constructor.name}: ${this.divid}`; 3171 } 3172 3173 queueMathJax(component) { 3174 if (typeof(MathJax) === "undefined") { 3175 console.log("Error -- MathJax is not loaded") 3176 return Promise.resolve(null); 3177 } else { 3178 // See - https://docs.mathjax.org/en/latest/advanced/typeset.html 3179 // Per the above we should keep track of the promises and only call this 3180 // a second time if all previous promises have resolved. 3181 // Create a queue of components 3182 // should wait until defaultPageReady is defined 3183 // If defaultPageReady is not defined then just enqueue the components. 3184 // Once defaultPageReady is defined 3185 // the window.runestoneMathReady promise will be fulfilled when the 3186 // initial typesetting is complete. 3187 if (MathJax.typesetPromise) { 3188 if (typeof(window.runestoneMathReady) !== "undefined") { 3189 return window.runestoneMathReady.then( 3190 () => this.mjresolver(this.aQueue.enqueue(component)) 3191 ) 3192 } else { 3193 return this.mjresolver(this.aQueue.enqueue(component)) 3194 } 3195 } else { 3196 console.log(`Waiting on MathJax!! ${MathJax.typesetPromise}`); 3197 setTimeout(() => this.queueMathJax(component), 200); 3198 console.log(`Returning mjready promise: ${this.mjReady}
3198`) 3199 return this.mjReady; 3200 } 3201 } 3202 } 3203 3204 decorateStatus() { 3205 let rsDiv = $(this.containerDiv).closest("div.runestone")[0]; 3206 if (this.correct) { 3207 rsDiv.classList.add("isCorrect"); 3208 } else { 3209 if (this.correct === null) { 3210 rsDiv.classList.add("notAnswered"); 3211 } else { 3212 rsDiv.classList.add("isInCorrect"); 3213 } 3214 } 3215 } 3216 3217} 3218 3219 3220// Inspiration and lots of code for this solution come from 3221// https://stackoverflow.com/questions/53540348/js-async-await-tasks-queue 3222// The idea here is that until MathJax is ready we can just enqueue things 3223// once mathjax becomes ready then we can drain the queue and continue as usual. 3224 3225class Queue { 3226 constructor() { this._items = []; } 3227 enqueue(item) { this._items.push(item); } 3228 dequeue() { return this._items.shift(); } 3229 get size() { return this._items.length; } 3230} 3231 3232class AutoQueue extends Queue { 3233 constructor() { 3234 super(); 3235 this._pendingPromise = false; 3236 } 3237 3238 enqueue(component) { 3239 return new Promise((resolve, reject) => { 3240 super.enqueue({ component, resolve, reject }); 3241 this.dequeue(); 3242 }); 3243 } 3244 3245 async dequeue() { 3246 if (this._pendingPromise) return false; 3247 3248 let item = super.dequeue(); 3249 3250 if (!item) return false; 3251 3252 try { 3253 this._pendingPromise = true; 3254 3255 let payload = await MathJax.startup.defaultPageReady().then( 3256 async function() { 3257 console.log(`MathJax Ready -- dequeing a typesetting run for ${item.component.id}`) 3258 return await MathJax.typesetPromise([item.component]) 3259 } 3260 ); 3261 3262 this._pendingPromise = false; item.resolve(payload); 3263 } 3264 catch (e) { 3265 this._pendingPromise = false; 3266 item.reject(e); 3267 } finally { 3268 this.dequeue(); 3269 } 3270 3271 return true; 3272 } 3273 } 3274 3275 3276 window.RunestoneBase = RunestoneBase; 3277 3278 3279/***/ }), 3280 3281/***/ 75106: 3282/*!**************************************!*\ 3283 !*** ./runestone/common/js/theme.js ***! 3284 \**************************************/ 3285/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 3286 3287"use strict"; 3288__webpack_require__.r(__webpack_exports__); 3289/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3290/* harmony export */ "getSwitch": () => (/* binding */ getSwitch), 3291/* harmony export */ "switchTheme": () => (/* binding */ switchTheme) 3292/* harmony export */ }); 3293function getSwitch() { 3294 const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); 3295 const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; 3296 3297 if (currentTheme) { 3298 document.documentElement.setAttribute('data-theme', currentTheme); 3299 3300 if (currentTheme === 'dark') { 3301 toggleSwitch.checked = true; 3302 } 3303 } 3304} 3305 3306function switchTheme() { 3307 3308 var checkBox = document.getElementById("checkbox"); 3309 if (checkBox.checked == true) { 3310 document.documentElement.setAttribute('data-theme', 'dark'); 3311 localStorage.setItem('theme', 'dark'); //add this 3312 } 3313 else { 3314 document.documentElement.setAttribute('data-theme', 'light'); 3315 localStorage.setItem('theme', 'light'); //add this 3316 } 3317} 3318 3319 3320/***/ }), 3321 3322/***/ 70114: 3323/*!************************************************!*\ 3324 !*** ./runestone/common/js/user-highlights.js ***! 3325 \************************************************/ 3326/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 3327 3328"use strict"; 3329__webpack_require__.r(__webpack_exports__); 3330/* harmony import */ var _css_user_highlights_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../css/user-highlights.css */ 88874); 3331/*global variable declarations*/ 3332 3333 3334 3335 3336 3337function getCompletions() { 3338 // Get the completion status 3339 if ( 3340 window.location.href.match( 3341 /(index.html|toctree.html|genindex.html|navhelp.html|toc.html|assignments.html|Exercises.html)/ 3342 ) 3343 ) { 3344 return; 3345 } 3346 3347 var currentPathname = window.location.pathname; 3348 if (currentPathname.indexOf("?") !== -1) { 3349 currentPathname = currentPathname.substring( 3350 0, 3351 currentPathname.lastIndexOf("?") 3352 ); 3353 } 3354 var data = { 3355 lastPageUrl: currentPathname, 3356 isPtxBook: isPreTeXt() 3357 }; 3358 jQuery 3359 .ajax({ 3360 url: `${eBookConfig.new_server_prefix}/logger/getCompletionStatus`, 3361 data: data, 3362 async: false, 3363 }) 3364 .done(function (data) {
3365 if (data != "None") { 3366 var completionData = data.detail; 3367 var completionClass, completionMsg; 3368 if (completionData[0].completionStatus == 1) { 3369 completionClass = "buttonConfirmCompletion"; 3370 completionMsg = 3371 "<i class='glyphicon glyphicon-ok'></i> Completed. Well Done!"; 3372 } else { 3373 completionClass = "buttonAskCompletion"; 3374 completionMsg = "Mark as Completed"; 3375 } 3376 $("#scprogresscontainer").append( 3377 '<div style="text-align:center"><button class="btn btn-lg ' + 3378 completionClass + 3379 '" id="completionButton">' + 3380 completionMsg + 3381 "</button></div>" 3382 ); 3383 } 3384 }); 3385} 3386 3387function showLastPositionBanner() { 3388 var lastPositionVal = $.getUrlVar("lastPosition"); 3389 if (typeof lastPositionVal !== "undefined") { 3390 $("body").append( 3391 '<img src="../_static/last-point.png" style="position:absolute; padding-top:55px; left: 10px; top: ' + 3392 parseInt(lastPositionVal) + 3393 'px;"/>' 3394 ); 3395 $("html, body").animate({ scrollTop: parseInt(lastPositionVal) }, 1000); 3396 } 3397} 3398 3399function addNavigationAndCompletionButtons() { 3400 if ( 3401 window.location.href.match( 3402 /(index.html|genindex.html|navhelp.html|toc.html|assignments.html|Exercises.html|toctree.html)/ 3403 ) 3404 ) { 3405 return; 3406 } 3407 var navLinkBgRightHiddenPosition = -$("#navLinkBgRight").outerWidth() - 5; 3408 var navLinkBgRightHalfOpen; 3409 var navLinkBgRightFullOpen = 0; 3410 3411 if ($("#completionButton").hasClass("buttonAskCompletion")) { 3412 navLinkBgRightHalfOpen = navLinkBgRightHiddenPosition + 70; 3413 } else if ($("#completionButton").hasClass("buttonConfirmCompletion")) { 3414 navLinkBgRightHalfOpen = 0; 3415 } 3416 var relationsNextIconInitialPosition = $("#relations-next").css("right"); 3417 var relationsNextIconNewPosition = -(navLinkBgRightHiddenPosition + 35); 3418 3419 $("#navLinkBgRight").css("right", navLinkBgRightHiddenPosition).show(); 3420 var navBgShown = false; 3421 $(window).scroll(function () { 3422 if ( 3423 $(window).scrollTop() + $(window).height() == 3424 $(document).height() 3425 ) { 3426 $("#navLinkBgRight").animate( 3427 { right: navLinkBgRightHalfOpen }, 3428 200 3429 ); 3430 $("#navLinkBgLeft").animate({ left: "0px" }, 200); 3431 if ($("#completionButton").hasClass("buttonConfirmCompletion")) { 3432 $("#relations-next").animate( 3433 { right: relationsNextIconNewPosition }, 3434 200 3435 ); 3436 } 3437 navBgShown = true; 3438 } else if (navBgShown) { 3439 $("#navLinkBgRight").animate( 3440 { right: navLinkBgRightHiddenPosition }, 3441 200 3442 ); 3443 $("#navLinkBgLeft").animate({ left: "-65px" }, 200); 3444 $("#relations-next").animate({ 3445 right: relationsNextIconInitialPosition, 3446 }); 3447 navBgShown = false; 3448 } 3449 }); 3450 3451 var completionFlag = 0; 3452 if ($("#completionButton").hasClass("buttonAskCompletion")) { 3453 completionFlag = 0; 3454 } else { 3455 completionFlag = 1; 3456 } 3457 // Make sure we mark this page as visited regardless of how flakey 3458 // the onunload handlers become. 3459 processPageState(completionFlag); 3460 $("#completionButton").on("click", function () { 3461 if ($(this).hasClass("buttonAskCompletion")) { 3462 $(this) 3463 .removeClass("buttonAskCompletion") 3464 .addClass("buttonConfirmCompletion") 3465 .html( 3466 "<i class='glyphicon glyphicon-ok'></i> Completed. Well Done!" 3467 ); 3468 $("#navLinkBgRight").animate({ right: navLinkBgRightFullOpen }); 3469 $("#relations-next").animate({ 3470 right: relationsNextIconNewPosition, 3471 }); 3472 navLinkBgRightHalfOpen = 0; 3473 completionFlag = 1; 3474 } else if ($(this).hasClass("buttonConfirmCompletion")) { 3475 $(this) 3476 .removeClass("buttonConfirmCompletion") 3477 .addClass("buttonAskCompletion") 3478 .html("Mark as Completed"); 3479 navLinkBgRightHalfOpen = navLinkBgRightHiddenPosition + 70; 3480 $("#navLinkBgRight").animate({ right: navLinkBgRightHalfOpen }); 3481 $("#relations-next").animate({ 3482 right: relationsNextIconInitialPosition, 3483 }); 3484 completionFlag = 0; 3485 } 3486 processPageState(completionFlag); 3487 }); 3488 3489 $(window).on("beforeunload", function (e) { 3490 if (completionFlag == 0) { 3491 processPageState(completionFlag); 3492 } 3493 }); 3494} 3495 3496// _ decorateTableOfContents 3497// ------------------------- 3498function decorateTableOfContents() { 3499 if ( 3500 window.location.href.toLowerCase().indexOf("toc.html") != -1 || 3501 window.location.href.toLowerCase().indexOf("index.html") != -1 3502 ) { 3503 jQuery.get( 3504 `${eBookConfig.new_server_prefix}/logger/getAllCompletionStatus`, 3505 function (data) { 3506 var subChapterList;
3507 if (data != "None") { 3508 subChapterList = data.detail; 3509 3510 var allSubChapterURLs = $("#main-content div li a"); 3511 $.each(subChapterList, function (index, item) { 3512 for (var s = 0; s < allSubChapterURLs.length; s++) { 3513 if ( 3514 allSubChapterURLs[s].href.indexOf( 3515 item.chapterName + "/" + item.subChapterName 3516 ) != -1 3517 ) { 3518 if (item.completionStatus == 1) { 3519 $(allSubChapterURLs[s].parentElement) 3520 .addClass("completed") 3521 .append( 3522 '<span class="infoTextCompleted">- Completed this topic on ' + 3523 item.endDate + 3524 "</span>" 3525 ) 3526 .children() 3527 .first() 3528 .hover( 3529 function () { 3530 $(this) 3531 .next(".infoTextCompleted") 3532 .show(); 3533 }, 3534 function () { 3535 $(this) 3536 .next(".infoTextCompleted") 3537 .hide(); 3538 } 3539 ); 3540 } else if (item.completionStatus == 0) { 3541 $(allSubChapterURLs[s].parentElement) 3542 .addClass("active") 3543 .append( 3544 '<span class="infoTextActive">Last read this topic on ' + 3545 item.endDate + 3546 "</span>" 3547 ) 3548 .children() 3549 .first() 3550 .hover( 3551 function () { 3552 $(this) 3553 .next(".infoTextActive") 3554 .show(); 3555 }, 3556 function () { 3557 $(this) 3558 .next(".infoTextActive") 3559 .hide(); 3560 } 3561 ); 3562 } 3563 } 3564 } 3565 }); 3566 } 3567 } 3568 ); 3569 var data = { course: eBookConfig.course }; 3570 jQuery.get( 3571 `${eBookConfig.new_server_prefix}/logger/getlastpage`, 3572 data, 3573 function (data) { 3574 var lastPageData; 3575 if (data != "None") { 3576 lastPageData = data.detail; 3577 if (lastPageData.lastPageChapter != null) { 3578 $("#continue-reading") 3579 .show() 3580 .html( 3581 '<div id="jump-to-chapter" class="alert alert-info" ><strong>You were Last Reading:</strong> ' + 3582 lastPageData.lastPageChapter + 3583 (lastPageData.lastPageSubchapter 3584 ? " > " + 3585 lastPageData.lastPageSubchapter 3586 : "") + 3587 ' <a href="' + 3588 lastPageData.lastPageUrl + 3589 "?lastPosition=" + 3590 lastPageData.lastPageScrollLocation + 3591 '">Continue Reading</a></div>' 3592 ); 3593 } 3594 } 3595 } 3596 ); 3597 } 3598} 3599 3600function enableCompletions() { 3601 getCompletions(); 3602 showLastPositionBanner(); 3603 addNavigationAndCompletionButtons(); 3604 decorateTableOfContents(); 3605} 3606 3607// call enable user highlights after login 3608$(document).on("runestone:login", enableCompletions); 3609 3610function isPreTeXt() { 3611 let ptxMarker = document.querySelector("body.pretext"); 3612 if (ptxMarker) { 3613 return true; 3614 } else { 3615 return false;
3616 } 3617} 3618// _ processPageState 3619// ------------------------- 3620function processPageState(completionFlag) { 3621 /*Log last page visited*/ 3622 var currentPathname = window.location.pathname; 3623 if (currentPathname.indexOf("?") !== -1) { 3624 currentPathname = currentPathname.substring( 3625 0, 3626 currentPathname.lastIndexOf("?") 3627 ); 3628 } 3629 // Is this a ptx book? 3630 let isPtxBook = isPreTeXt() 3631 var data = { 3632 lastPageUrl: currentPathname, 3633 lastPageScrollLocation: $(window).scrollTop(), 3634 completionFlag: completionFlag, 3635 course: eBookConfig.course, 3636 isPtxBook: isPtxBook, 3637 }; 3638 $(document).ajaxError(function (e, jqhxr, settings, exception) { 3639 console.log("Request Failed for " + settings.url); 3640 console.log(e); 3641 }); 3642 jQuery.ajax({ 3643 url: `${eBookConfig.new_server_prefix}/logger/updatelastpage`, 3644 contentType: "application/json; charset=utf-8", 3645 dataType: "json", 3646 data: JSON.stringify(data), 3647 method: "POST", 3648 async: true, 3649 }); 3650} 3651 3652$.extend({ 3653 getUrlVars: function () { 3654 var vars = [], 3655 hash; 3656 var hashes = window.location.search 3657 .slice(window.location.search.indexOf("?") + 1) 3658 .split("&"); 3659 for (var i = 0; i < hashes.length; i++) { 3660 hash = hashes[i].split("="); 3661 vars.push(hash[0]); 3662 vars[hash[0]] = hash[1]; 3663 } 3664 return vars; 3665 }, 3666 getUrlVar: function (name) { 3667 return $.getUrlVars()[name]; 3668 }, 3669}); 3670 3671 3672/***/ }), 3673 3674/***/ 11968: 3675/*!*****************************************************************************************************************!*\ 3676 !*** ./runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/static/bootstrap-sphinx.js ***! 3677 \*****************************************************************************************************************/ 3678/***/ (() => { 3679 3680(function ($) { 3681 /** 3682 * Patch TOC list. 3683 * 3684 * Will mutate the underlying span to have a correct ul for nav. 3685 * 3686 * @param $span: Span containing nested UL's to mutate. 3687 * @param minLevel: Starting level for nested lists. (1: global, 2: local). 3688 */ 3689 var patchToc = function ($ul, minLevel) { 3690 var findA, 3691 patchTables, 3692 $localLi; 3693 3694 // Find all a "internal" tags, traversing recursively. 3695 findA = function ($elem, level) { 3696 level = level || 0; 3697 var $items = $elem.find("> li > a.internal, > ul, > li > ul"); 3698 3699 // Iterate everything in order. 3700 $items.each(function (index, item) { 3701 var $item = $(item), 3702 tag = item.tagName.toLowerCase(), 3703 $childrenLi = $item.children('li'), 3704 $parentLi = $($item.parent('li'), $item.parent().parent('li')); 3705 3706 // Add dropdowns if more children and above minimum level. 3707 if (tag === 'ul' && level >= minLevel && $childrenLi.length > 0) { 3708 $parentLi 3709 .addClass('dropdown-submenu') 3710 .children('a').first().attr('tabindex', -1); 3711 3712 $item.addClass('dropdown-menu'); 3713 } 3714 3715 findA($item, level + 1); 3716 }); 3717 }; 3718 3719 findA($ul); 3720 }; 3721 3722 /** 3723 * Patch all tables to remove ``docutils`` class and add Bootstrap base 3724 * ``table`` class. 3725 */ 3726 patchTables = function () { 3727 $("table.docutils") 3728 .removeClass("docutils") 3729 .addClass("table") 3730 .attr("border", 0); 3731 }; 3732 3733$(function () { 3734 3735 /* 3736 * Scroll the window to avoid the topnav bar 3737 * https://github.com/twitter/bootstrap/issues/1768 3738 */ 3739 if ($("#navbar.navbar-fixed-top").length > 0) { 3740 var navHeight = $("#navbar").height(), 3741 shiftWindow = function() { scrollBy(0, -navHeight - 10); }; 3742 3743 if (location.hash) { 3744 shiftWindow(); 3745 } 3746 3747 window.addEventListener("hashchange", shiftWindow); 3748 } 3749 3750 // Add styling, structure to TOC's. 3751 $(".dropdown-menu").each(function () { 3752 $(this).find("ul").each(function (index, item){ 3753 var $item = $(item); 3754 $item.addClass('unstyled'); 3755 }); 3756 }); 3757 3758 // Global TOC. 3759 if ($("ul.globaltoc li").length) { 3760 patchToc($("ul.globaltoc"), 1); 3761 } else { 3762 // Remove Global TOC. 3763 $(".globaltoc-container").remove(); 3764 } 3765 3766 // Local TOC. 3767 patchToc($("ul.localtoc"), 2); 3768 3769 // Mutate sub-lists (for bs-2.3.0). 3770 $(".dropdown-menu ul").not(".dropdown-menu").each(function () { 3771 var $ul = $(this), 3772 $parent = $ul.parent(), 3773 tag = $parent[0].tagName.toLowerCase(), 3774 $kids = $ul.children().detach(); 3775 3776 // Replace list with items if submenu header. 3777 if (tag === "ul") { 3778 $ul.replaceWith($kids); 3779 } else if (tag === "li") { 3780 // Insert into previous list. 3781 $parent.after($kids); 3782 $ul.remove(); 3783 } 3784 }); 3785 3786 // Add divider in page TOC. 3787 $localLi = $("ul.localtoc li"); 3788 if ($localLi.length > 2) { 3789 $localLi.first().after('<li class="divider"></li>'); 3790 } 3791 3792 // Enable dropdown. 3793 $('.dropdown-toggle').dropdown(); 3794 3795 // Patch tables. 3796 patchTables(); 3797 3798 // Add Note, Warning styles. 3799 $('div.note').addClass('alert').addClass('alert-info'); 3800 $('div.warning').addClass('alert').addClass('alert-warning'); 3801 3802 // Inline code styles to Bootstrap style. 3803 $('tt.docutils.literal').not(".xref").each(function (i, e) { 3804 // ignore references 3805 if (!$(e).parent().hasClass("reference")) { 3806 $(e).replaceWith(function () { 3807 return $("<code />").text($(this).text()); 3808 }); 3809 }}); 3810 }); 3811}(window.jQuery)); 3812 3813 3814/***/ }), 3815 3816/***/ 36350: 3817/*!**************************!*\ 3818 !*** ./webpack.index.js ***! 3819 \**************************/ 3820/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 3821 3822"use strict"; 3823__webpack_require__.r(__webpack_exports__); 3824/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3825/* harmony export */ "runestone_auto_import": () => (/* binding */ runestone_auto_import), 3826/* harmony export */ "runestone_import": () => (/* binding */ runestone_import) 3827/* harmony export */ }); 3828/* harmony import */ var jquery_ui_jquery_ui_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery-ui/jquery-ui.js */ 86301); 3829/* harmony import */ var jquery_ui_jquery_ui_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery_ui_jquery_ui_js__WEBPACK_IMPORTED_MODULE_0__); 3830/* harmony import */ var jquery_ui_themes_base_jquery_ui_all_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery-ui/themes/base/jquery.ui.all.css */ 47581); 3831/* harmony import */ var _runestone_common_js_jquery_idle_timer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./runestone/common/js/jquery.idle-timer.js */ 26886); 3832/* harmony import */ var _runestone_common_js_jquery_idle_timer_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_idle_timer_js__WEBPACK_IMPORTED_MODULE_2__); 3833/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.js */ 99283); 3834/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_js__WEBPACK_IMPORTED_MODULE_3__); 3835/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_emitter_bidi_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.emitter.bidi.js */ 43793); 3836/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_emitter_bidi_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_emitter_bidi_js__WEBPACK_IMPORTED_MODULE_4__); 3837/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_emitter_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.emitter.js */ 30423); 3838/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_emitter_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_emitter_js__WEBPACK_IMPORTED_MODULE_5__); 3839/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_fallbacks_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.fallbacks.js */ 9001); 3840/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_fallbacks_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_fallbacks_js__WEBPACK_IMPORTED_MODULE_6__); 3841/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_messagestore_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.messagestore.js */ 34517); 3842/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_messagestore_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_messagestore_js__WEBPACK_IMPORTED_MODULE_7__); 3843/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_parser_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.parser.js */ 25252); 3844/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_parser_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_parser_js__WEBPACK_IMPORTED_MODULE_8__); 3845/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_language_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.language.js */ 64793); 3846/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_language_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_language_js__WEBPACK_IMPORTED_MODULE_9__); 3847/* harmony import */ var bootstrap_dist_js_bootstrap_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! bootstrap/dist/js/bootstrap.js */ 43734); 3848/* harmony import */ var bootstrap_dist_js_bootstrap_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(bootstrap_dist_js_bootstrap_js__WEBPACK_IMPORTED_MODULE_10__); 3849/* harmony import */ var bootstrap_dist_css_bootstrap_css__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! bootstrap/dist/css/bootstrap.css */ 97318); 3850/* harmony import */ var _runestone_common_project_template_templates_plugin_layouts_sphinx_bootstrap_static_bootstrap_sphinx_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/static/bootstrap-sphinx.js */ 11968); 3851/* harmony import */ var _runestone_common_project_template_templates_plugin_layouts_sphinx_bootstrap_static_bootstrap_sphinx_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_project_template_templates_plugin_layouts_sphinx_bootstrap_static_bootstrap_sphinx_js__WEBPACK_IMPORTED_MODULE_12__); 3852/* harmony import */ var _runestone_common_css_runestone_custom_sphinx_bootstrap_css__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./runestone/common/css/runestone-custom-sphinx-bootstrap.css */ 64778); 3853/* harmony import */ var _runestone_common_js_bookfuncs_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./runestone/common/js/bookfuncs.js */ 21294); 3854/* harmony import */ var _runestone_common_js_user_highlights_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./runestone/common/js/user-highlights.js */ 70114); 3855/* harmony import */ var _runestone_common_js_pretext_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./runestone/common/js/pretext.js */ 22538); 3856/* harmony import */ var _runestone_matrixeq_css_matrixeq_css__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./runestone/matrixeq/css/matrixeq.css */ 23746); 3857/* harmony import */ var _runestone_webgldemo_css_webglinteractive_css__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./runestone/webgldemo/css/webglinteractive.css */ 86324); 3858/* harmony import */ var _runestone_common_js_theme_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./runestone/common/js/theme.js */ 75106); 3859/* harmony import */ var _runestone_common_js_presenter_mode_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./runestone/common/js/presenter_mode.js */ 66563); 3860/* harmony import */ var _runestone_common_js_presenter_mode_js__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_presenter_mode_js__WEBPACK_IMPORTED_MODULE_20__); 3861/* harmony import */ var _runestone_common_css_presenter_mode_css__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./runestone/common/css/presenter_mode.css */ 88288); 3862// *********************************************************************************** 3863// |docname| - A framework allowing a Runestone component to load only the JS it needs 3864// *********************************************************************************** 3865// The JavaScript required by all Runestone components is quite large and results in slow page loads. This approach enables a Runestone component to load only the JavaScript it needs, rather than loading JavaScript for all the components regardless of which are actually used.
3866// 3867// To accomplish this, webpack's split-chunks ability analyzes all JS, starting from this file. The dynamic imports below are transformed by webpack into the dynamic fetches of just the JS required by each file and all its dependencies. (If using static imports, webpack will assume that all files are already statically loaded via script tags, defeating the purpose of this framework.) 3868// 3869// However, this approach leads to complexity: 3870// 3871// - The ``data-component`` attribute of each component must be kept in sync with the keys of the ``module_map`` below. 3872// - The values in the ``module_map`` must be kept in sync with the JavaScript files which implement each of the components. 3873 3874 3875 3876// Static imports 3877// ============== 3878// These imports are (we assume) needed by all pages. However, it would be much better to load these in the modules that actually use them. 3879// 3880// These are static imports; code in `dynamically loaded components`_ deals with dynamic imports. 3881// 3882// jQuery-related imports. 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894// Bootstrap 3895 3896 3897 3898 3899 3900// Misc 3901 3902 3903 3904 3905// These belong in dynamic imports for the obvious component; however, these components don't include a ``data-component`` attribute. 3906 3907 3908 3909// These are only needed for the Runestone book, but not in a library mode (such as pretext). I would prefer to dynamically load them. However, these scripts are so small I haven't bothered to do so. 3910 3911 3912 3913 3914// Dynamically loaded components 3915// ============================= 3916// This provides a list of modules that components can dynamically import. Webpack will create a list of imports for each based on its analysis. 3917const module_map = { 3918 // Wrap each import in a function, so that it won't occur until the function is called. While something cleaner would be nice, webpack can't analyze things like ``import(expression)``. 3919 // 3920 // The keys must match the value of each component's ``data-component`` attribute -- the ``runestone_import`` and ``runestone_auto_import`` functions assume this. 3921 activecode: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_handsontable_es_index_js-node_modules_handsontable_dist_handsontable_ful-dcc440"), __webpack_require__.e("vendors-node_modules_codemirror_mode_clike_clike_js-node_modules_codemirror_mode_javascript_j-f062af"), __webpack_require__.e("vendors-node_modules_codemirror_addon_edit_matchbrackets_js-node_modules_codemirror_addon_hin-ab90ac"), __webpack_require__.e("runestone_codelens_js_pytutor-embed_bundle_js"), __webpack_require__.e("node_modules_moment_locale_sync_recursive_-runestone_activecode_js_acfactory_js-node_modules_-ef73b3")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/activecode/js/acfactory.js */ 86902)), 3922 ble: () => __webpack_require__.e(/*! import() */ "runestone_cellbotics_js_ble_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/cellbotics/js/ble.js */ 14818)), 3923 // Always import the timed version of a component if available, since the timed components also define the component's factory and include the component as well. Note that ``acfactory`` imports the timed components of ActiveCode, so it follows this pattern. 3924 clickablearea: () => 3925 Promise.all(/*! import() */[__webpack_require__.e("runestone_clickableArea_js_timedclickable_js"), __webpack_require__.e("runestone_clickableArea_css_clickable_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/clickableArea/js/timedclickable.js */ 61581)), 3926 codelens: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_codelens_js_pytutor-embed_bundle_js"), __webpack_require__.e("runestone_codelens_js_codelens_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/codelens/js/codelens.js */ 12882)), 3927 datafile: () => __webpack_require__.e(/*! import() */ "runestone_datafile_js_datafile_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/datafile/js/datafile.js */ 55789)), 3928 dragndrop: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_dragndrop_js_timeddnd_js"), __webpack_require__.e("runestone_dragndrop_css_dragndrop_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/dragndrop/js/timeddnd.js */ 47496)), 3929 fillintheblank: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_fitb_js_timedfitb_js"), __webpack_require__.e("runestone_fitb_css_fitb_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/fitb/js/timedfitb.js */ 74309)), 3930 groupsub: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_select2_dist_css_select2_css-node_modules_select2_dist_js_select2_min_js"), __webpack_require__.e("runestone_groupsub_js_groupsub_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/groupsub/js/groupsub.js */ 45280)), 3931 khanex: () => __webpack_require__.e(/*! import() */ "runestone_khanex_js_khanex_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/khanex/js/khanex.js */ 13435)), 3932 lp_build: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_codemirror_mode_clike_clike_js-node_modules_codemirror_mode_javascript_j-f062af"), __webpack_require__.e("runestone_lp_js_lp_js-node_modules_codemirror_lib_codemirror_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/lp/js/lp.js */ 2013)), 3933 multiplechoice: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_mchoice_js_timedmc_js"), __webpack_require__.e("runestone_mchoice_css_mchoice_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/mchoice/js/timedmc.js */ 95983)), 3934 hparsons: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_handsontable_es_index_js-node_modules_handsontable_dist_handsontable_ful-dcc440"), __webpack_require__.e("vendors-node_modules_micro-parsons_micro-parsons_micro-parsons_js-node_modules_micro-parsons_-974bff"), __webpack_require__.e("node_modules_moment_locale_sync_recursive_-runestone_hparsons_js_hp
3934arsons_js-node_modules_mic-5ea6d2")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/hparsons/js/hparsons.js */ 58722)), 3935 parsons: () => __webpack_require__.e(/*! import() */ "runestone_parsons_js_timedparsons_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/parsons/js/timedparsons.js */ 79661)), 3936 poll: () => __webpack_require__.e(/*! import() */ "runestone_poll_js_poll_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/poll/js/poll.js */ 37350)), 3937 quizly: () => __webpack_require__.e(/*! import() */ "runestone_quizly_js_quizly_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/quizly/js/quizly.js */ 16207)), 3938 reveal: () => __webpack_require__.e(/*! import() */ "runestone_reveal_js_reveal_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/reveal/js/reveal.js */ 12632)), 3939 selectquestion: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_selectquestion_js_selectone_js"), __webpack_require__.e("runestone_selectquestion_css_selectquestion_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/selectquestion/js/selectone.js */ 63931)), 3940 shortanswer: () => 3941 Promise.all(/*! import() */[__webpack_require__.e("runestone_shortanswer_js_timed_shortanswer_js"), __webpack_require__.e("runestone_shortanswer_css_shortanswer_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/shortanswer/js/timed_shortanswer.js */ 87483)), 3942 showeval: () => __webpack_require__.e(/*! import() */ "runestone_showeval_js_showEval_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/showeval/js/showEval.js */ 6224)), 3943 simple_sensor: () => __webpack_require__.e(/*! import() */ "runestone_cellbotics_js_simple_sensor_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/cellbotics/js/simple_sensor.js */ 72389)), 3944 spreadsheet: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_jexcel_dist_jexcel_js-node_modules_jexcel_dist_jexcel_css"), __webpack_require__.e("runestone_spreadsheet_js_spreadsheet_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/spreadsheet/js/spreadsheet.js */ 60611)), 3945 tabbedStuff: () => __webpack_require__.e(/*! import() */ "runestone_tabbedStuff_js_tabbedstuff_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/tabbedStuff/js/tabbedstuff.js */ 97887)), 3946 timedAssessment: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_handsontable_es_index_js-node_modules_handsontable_dist_handsontable_ful-dcc440"), __webpack_require__.e("vendors-node_modules_codemirror_mode_clike_clike_js-node_modules_codemirror_mode_javascript_j-f062af"), __webpack_require__.e("vendors-node_modules_codemirror_addon_edit_matchbrackets_js-node_modules_codemirror_addon_hin-ab90ac"), __webpack_require__.e("runestone_codelens_js_pytutor-embed_bundle_js"), __webpack_require__.e("node_modules_moment_locale_sync_recursive_-runestone_activecode_js_acfactory_js-node_modules_-ef73b3"), __webpack_require__.e("runestone_parsons_js_timedparsons_js"), __webpack_require__.e("runestone_dragndrop_js_timeddnd_js"), __webpack_require__.e("runestone_mchoice_js_timedmc_js"), __webpack_require__.e("runestone_selectquestion_js_selectone_js"), __webpack_require__.e("runestone_clickableArea_js_timedclickable_js"), __webpack_require__.e("runestone_fitb_js_timedfitb_js"), __webpack_require__.e("runestone_shortanswer_js_timed_shortanswer_js"), __webpack_require__.e("runestone_timed_js_timed_js-runestone_clickableArea_css_clickable_css-runestone_dragndrop_css-8bfd54")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/timed/js/timed.js */ 58707)), 3947 wavedrom: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_wavedrom_skins_default_js-node_modules_wavedrom_wavedrom_min_js"), __webpack_require__.e("runestone_wavedrom_js_wavedrom_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/wavedrom/js/wavedrom.js */ 32405)), 3948 // TODO: since this isn't in a ``data-component``, need to trigger an import of this code manually. 3949 webwork: () => __webpack_require__.e(/*! import() */ "runestone_webwork_js_webwork_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/webwork/js/webwork.js */ 66142)), 3950 youtube: () => __webpack_require__.e(/*! import() */ "runestone_video_js_runestonevideo_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/video/js/runestonevideo.js */ 48657)), 3951}; 3952 3953// .. _dynamic import machinery: 3954// 3955// Dynamic import machinery 3956// ======================== 3957// Fulfill a promise when the Runestone pre-login complete event occurs. 3958let pre_login_complete_promise = new Promise((resolve) => 3959 $(document).on("runestone:pre-login-complete", resolve) 3960); 3961let loadedComponents;
3962// Provide a simple function to import the JS for all components on the page. 3963function runestone_auto_import() { 3964 // Create a set of ``data-component`` values, to avoid duplication. 3965 const s = new Set( 3966 // All Runestone components have a ``data-component`` attribute. 3967 $("[data-component]") 3968 .map( 3969 // Extract the value of the data-component attribute. 3970 (index, element) => $(element).attr("data-component") 3971 // Switch from a jQuery object back to an array, passing that to the Set constructor. 3972 ) 3973 .get() 3974 ); 3975 // webwork questions are not wrapped in div with a data-component so we have to check a different way 3976 if (document.querySelector(".webwork-button")) { 3977 s.add("webwork"); 3978 } 3979 3980 // Load JS for each of the components found. 3981 const a = [...s].map((value) => 3982 // If there's no JS for this component, return an empty Promise. 3983 (module_map[value] || (() => Promise.resolve()))() 3984 ); 3985 3986 // Send the Runestone login complete event when all JS is loaded and the pre-login is also complete. 3987 Promise.all([pre_login_complete_promise, ...a]).then(() => 3988 $(document).trigger("runestone:login-complete") 3989 ); 3990} 3991 3992// Load component JS when the document is ready. 3993$(document).ready(runestone_auto_import); 3994 3995// Provide a function to import one specific Runestone component. 3996// the import function inside module_map is async -- runestone_import 3997// should be awaited when necessary to ensure the import completes 3998async function runestone_import(component_name) { 3999 return module_map[component_name](); 4000} 4001 4002async function popupScratchAC() { 4003 // load the activecode bundle 4004 await runestone_import("activecode"); 4005 // scratchDiv will be defined if we have already created a scratch 4006 // activecode. If its not defined then we need to get it ready to toggle 4007 if (!eBookConfig.scratchDiv) { 4008 window.ACFactory.createScratchActivecode(); 4009 let divid = eBookConfig.scratchDiv; 4010 window.edList[divid] = ACFactory.createActiveCode( 4011 $(`#${divid}`)[0], 4012 eBookConfig.acDefaultLanguage 4013 ); 4014 if (eBookConfig.isLoggedIn) { 4015 window.edList[divid].enableSaveLoad(); 4016 } 4017 } 4018 window.ACFactory.toggleScratchActivecode(); 4019} 4020 4021// Set the directory containing this script as the `path <https://webpack.js.org/guides/public-path/#on-the-fly>`_ for all webpacked scripts. 4022const script_src = document.currentScript.src; 4023__webpack_require__.p = script_src.substring( 4024 0, 4025 script_src.lastIndexOf("/") + 1 4026); 4027 4028// Manual exports 4029// ============== 4030// Webpack's ``output.library`` setting doesn't seem to work with the split chunks plugin; do all exports manually through the ``window`` object instead. 4031const rc = {}; 4032rc.runestone_import = runestone_import; 4033rc.runestone_auto_import = runestone_auto_import; 4034rc.getSwitch = _runestone_common_js_theme_js__WEBPACK_IMPORTED_MODULE_19__.getSwitch; 4035rc.switchTheme = _runestone_common_js_theme_js__WEBPACK_IMPORTED_MODULE_19__.switchTheme; 4036rc.popupScratchAC = popupScratchAC; 4037window.runestoneComponents = rc; 4038 4039 4040/***/ }), 4041 4042/***/ 65311: 4043/*!*************************!*\ 4044 !*** external "jQuery" ***! 4045 \*************************/ 4046/***/ ((module) => { 4047 4048"use strict"; 4049module.exports = jQuery; 4050 4051/***/ }) 4052 4053}, 4054/******/ __webpack_require__ => { // webpackRuntimeModules 4055/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) 4056/******/ __webpack_require__.O(0, ["vendors-node_modules_bootstrap_dist_js_bootstrap_js-node_modules_jquery-ui_jquery-ui_js-node_-72cd89"], () => (__webpack_exec__(36350))); 4057/******/ var __webpack_exports__ = __webpack_require__.O(); 4058/******/ } 4059]); 4060//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuZXN0b25lLjBkY2I5YjcyNjlkNDkyYWUuYnVuZGxlLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7Ozs7O0FDQUE7Ozs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7Ozs7Ozs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBOztBQUVBO0FBQ0E7O0F
4060BRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELGNBQWMsS0FBSyxhQUFhO0FBQzNGLGFBQWE7QUFDYixVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixLQUFLLGNBQWM7QUFDckMsYUFBYTtBQUNiLFVBQVU7QUFDVjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQSxTQUFTO0FBQ1QscUJBQXFCO0FBQ3JCO0FBQ0EsZUFBZSw4QkFBOEI7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELG9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hLE9BQU8sYUFBYSwwQkFBMEIsR0FBRyxZQUFZO0FBQzFFLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7Ozs7Ozs7Ozs7O0FDdktEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQzs7Ozs7Ozs7Ozs7QUN6TEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qjs7QUFFN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckIsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxrREFBa0Q7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxtQkFBbUI7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLGVBQWU7QUFDNUIsYUFBYSxRQUFRO0FBQ3JCLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixtQ0FBbUM7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQixhQUFhLE9BQU87QUFDcEIsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLFlBQVksUUFBUSxtREFBbUQsSUFBSTtBQUMzRSxhQUFhLGVBQWU7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtB
4060QUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7Ozs7Ozs7Ozs7QUN2U0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNB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OztBQUV4QztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsQ0FBQzs7Ozs7Ozs7OztBQ3JURDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUMsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStEO0FBQy9ELEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7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PQUEwQztBQUNwRSxvQkFBb0Isc1RBQTZDO0FBQ2pFLGtCQUFrQix3S0FBeUM7QUFDM0Qsb0JBQW9CLCtVQUFpQztBQUNyRCwwQkFBMEIsc1BBQTJDO0FBQ3JFLG9CQUFvQiwrZkFBNkM7QUFDakUsbUJBQW1CLHNMQUFnRDtBQUNuRSxnQkFBZ0IsZ0tBQXFDO0FBQ3JELGtCQUFrQix3S0FBeUM7QUFDM0Qsa0JBQWtCLHdLQUF5QztBQUMzRCwwQkFBMEIsc1JBQW9EO0FBQzlFO0FBQ0EsUUFBUSwwUkFBeUQ7QUFDakUsb0JBQW9CLCtLQUE2QztBQUNqRSx5QkFBeUIsOExBQW9EO0FBQzdFLHVCQUF1QixtVEFBbUQ7QUFDMUUsdUJBQXVCLDRMQUFtRDtBQUMxRSwyQkFBMkIsZ3dDQUF1QztBQUNsRSxvQkFBb0IsNlNBQTZDO0FBQ2pFO0FBQ0EsbUJBQW1CLDRLQUEyQztBQUM5RCxtQkFBbUIsc0x
4060BQWdEO0FBQ25FOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixNQUFNO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJGQUEyRjtBQUMzRjtBQUNBO0FBQ0E7QUFDQSxlQUFlLHFFQUFTO0FBQ3hCLGlCQUFpQix1RUFBVztBQUM1QjtBQUNBOzs7Ozs7Ozs7Ozs7QUMvS0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9jc3MvcHJlc2VudGVyX21vZGUuY3NzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2Nzcy9ydW5lc3RvbmUtY3VzdG9tLXNwaGlueC1ib290c3RyYXAuY3NzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2Nzcy91c2VyLWhpZ2hsaWdodHMuY3NzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvbWF0cml4ZXEvY3NzL21hdHJpeGVxLmNzcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL3dlYmdsZGVtby9jc3Mvd2ViZ2xpbnRlcmFjdGl2ZS5jc3MiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3J1bmVzdG9uZS9jb21tb24vanMvYm9va2Z1bmNzLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL2pxdWVyeS5pZGxlLXRpbWVyLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL2pxdWVyeV9pMThuL2pxdWVyeS5pMThuLmVtaXR0ZXIuYmlkaS5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5lbWl0dGVyLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL2pxdWVyeV9pMThuL2pxdWVyeS5pMThuLmZhbGxiYWNrcy5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5sYW5ndWFnZS5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5tZXNzYWdlc3RvcmUuanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4ucGFyc2VyLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL3ByZXNlbnRlcl9tb2RlLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL3ByZXRleHQuanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3J1bmVzdG9uZS9jb21tb24vanMvcnVuZXN0b25lYmFzZS5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy90aGVtZS5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy91c2VyLWhpZ2hsaWdodHMuanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3J1bmVzdG9uZS9jb21tb24vcHJvamVjdF90ZW1wbGF0ZS9fdGVtcGxhdGVzL3BsdWdpbl9sYXlvdXRzL3NwaGlueF9ib290c3RyYXAvc3RhdGljL2Jvb3RzdHJhcC1zcGhpbnguanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3dlYnBhY2suaW5kZXguanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy9leHRlcm5hbCB2YXIgXCJqUXVlcnlcIiJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvKipcbiAqXG4gKiBVc2VyOiBibWlsbGVyXG4gKiBPcmlnaW5hbDogMjAxMS0wNC0yMFxuICogRGF0ZTogMjAxOS0wNi0xNFxuICogVGltZTogMjowMSBQTVxuICogVGhpcyBjaGFuZ2UgbWFya3MgdGhlIGJlZ2lubmluZyBvZiB2ZXJzaW9uIDQuMCBvZiB0aGUgcnVuZXN0b25lIGNvbXBvbmVudHNcbiAqIExvZ2luL2xvZ291dCBpcyBubyBsb25nZXIgaGFuZGxlZCB0aHJvdWdoIGphdmFzY3JpcHQgYnV0IHJhdGhlciBzZXJ2ZXIgc2lkZS5cbiAqIE1hbnkgb2YgdGhlIGNvbXBvbmVudHMgZGVwZW5kIG9uIHRoZSBydW5lc3RvbmU6bG9naW4gZXZlbnQgc28gd2Ugd2lsbCBrZWVwIHRoYXRcbiAqIGZvciBub3cgdG8ga2VlcCB0aGUgY2h1cm4gZmFpcmx5IG1pbmltYWwuXG4gKi9cblxuLypcblxuIENvcHlyaWdodCAoQykgMjAxMSAgQnJhZCBNaWxsZXIgIGJvbmVsYWtlQGdtYWlsLmNvbVxuXG4gVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cblxuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG5cbiBZb3Ugc2hvdWxkIGhh
4060dmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuXG4gKi9cblxuLy9cbi8vIFBhZ2UgZGVjb3JhdGlvbiBmdW5jdGlvbnNcbi8vXG5cbmZ1bmN0aW9uIGFkZFJlYWRpbmdMaXN0KCkge1xuICAgIGlmIChlQm9va0NvbmZpZy5yZWFkaW5ncykge1xuICAgICAgICB2YXIgbCwgbnh0LCBwYXRoX3BhcnRzLCBueHRfbGluaztcbiAgICAgICAgbGV0IGN1cl9wYXRoX3BhcnRzID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLnNwbGl0KFwiL1wiKTtcbiAgICAgICAgbGV0IG5hbWUgPVxuICAgICAgICAgICAgY3VyX3BhdGhfcGFydHNbY3VyX3BhdGhfcGFydHMubGVuZ3RoIC0gMl0gK1xuICAgICAgICAgICAgXCIvXCIgK1xuICAgICAgICAgICAgY3VyX3BhdGhfcGFydHNbY3VyX3BhdGhfcGFydHMubGVuZ3RoIC0gMV07XG4gICAgICAgIGxldCBwb3NpdGlvbiA9IGVCb29rQ29uZmlnLnJlYWRpbmdzLmluZGV4T2YobmFtZSk7XG4gICAgICAgIGxldCBudW1fcmVhZGluZ3MgPSBlQm9va0NvbmZpZy5yZWFkaW5ncy5sZW5ndGg7XG4gICAgICAgIGlmIChwb3NpdGlvbiA9PSBlQm9va0NvbmZpZy5yZWFkaW5ncy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAvLyBubyBtb3JlIHJlYWRpbmdzXG4gICAgICAgICAgICBsID0gJChcIjxkaXYgLz5cIiwge1xuICAgICAgICAgICAgICAgIHRleHQ6IGBGaW5pc2hlZCByZWFkaW5nIGFzc2lnbm1lbnQuIFBhZ2UgJHtudW1fcmVhZGluZ3N9IG9mICR7bnVtX3JlYWRpbmdzfS5gLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPj0gMCkge1xuICAgICAgICAgICAgLy8gZ2V0IG5leHQgbmFtZVxuICAgICAgICAgICAgbnh0ID0gZUJvb2tDb25maWcucmVhZGluZ3NbcG9zaXRpb24gKyAxXTtcbiAgICAgICAgICAgIHBhdGhfcGFydHMgPSBjdXJfcGF0aF9wYXJ0cy5zbGljZSgwLCBjdXJfcGF0aF9wYXJ0cy5sZW5ndGggLSAyKTtcbiAgICAgICAgICAgIHBhdGhfcGFydHMucHVzaChueHQpO1xuICAgICAgICAgICAgbnh0X2xpbmsgPSBwYXRoX3BhcnRzLmpvaW4oXCIvXCIpO1xuICAgICAgICAgICAgbCA9ICQoXCI8YSAvPlwiLCB7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJsaW5rXCIsXG4gICAgICAgICAgICAgICAgY2xhc3M6IFwiYnRuIGJ0bi1sZyAnICsgJ2J1dHRvbkNvbmZpcm1Db21wbGV0aW9uJ1wiLFxuICAgICAgICAgICAgICAgIGhyZWY6IG54dF9saW5rLFxuICAgICAgICAgICAgICAgIHRleHQ6IGBDb250aW51ZSB0byBwYWdlICR7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uICsgMlxuICAgICAgICAgICAgICAgIH0gb2YgJHtudW1fcmVhZGluZ3N9IGluIHRoZSByZWFkaW5nIGFzc2lnbm1lbnQuYCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbCA9ICQoXCI8ZGl2IC8+XCIsIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBcIlRoaXMgcGFnZSBpcyBub3QgcGFydCBvZiB0aGUgbGFzdCByZWFkaW5nIGFzc2lnbm1lbnQgeW91IHZpc2l0ZWQuXCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAkKFwiI21haW4tY29udGVudFwiKS5hcHBlbmQobCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiB0aW1lZFJlZnJlc2goKSB7XG4gICAgdmFyIHRpbWVvdXRQZXJpb2QgPSA5MDAwMDA7IC8vIDc1IG1pbnV0ZXNcbiAgICAkKGRvY3VtZW50KS5vbihcImlkbGUuaWRsZVRpbWVyXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gQWZ0ZXIgdGltZW91dCBwZXJpb2Qgc2VuZCB0aGUgdXNlciBiYWNrIHRvIHRoZSBpbmRleC4gIFRoaXMgd2lsbCBmb3JjZSBhIGxvZ2luXG4gICAgICAgIC8vIGlmIG5lZWRlZCB3aGVuIHRoZXkgd2FudCB0byBnbyB0byBhIHBhcnRpY3VsYXIgcGFnZS4gIFRoaXMgbWF5IG5vdCBiZSBwZXJmZWN0XG4gICAgICAgIC8vIGJ1dCBpdHMgYW4gZWFzeSB3YXkgdG8gbWFrZSBzdXJlIGxhcHRvcCB1c2VycyBhcmUgcHJvcGVybHkgbG9nZ2VkIGluIHdoZW4gdGhleVxuICAgICAgICAvLyB0YWtlIHF1aXp6ZXMgYW5kIHNhdmUgc3R1ZmYuXG4gICAgICAgIGlmIChsb2NhdGlvbi5ocmVmLmluZGV4T2YoXCJpbmRleC5odG1sXCIpIDwgMCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJJZGxlIHRpbWVyIC0gXCIgKyBsb2NhdGlvbi5wYXRobmFtZSk7XG4gICAgICAgICAgICBsb2NhdGlvbi5ocmVmID1cbiAgICAgICAgICAgICAgICBlQm9va0NvbmZpZy5hcHAgK1xuICAgICAgICAgICAgICAgIFwiL2RlZmF1bHQvdXNlci9sb2dpbj9fbmV4dD1cIiArXG4gICAgICAgICAgICAgICAgbG9jYXRpb24ucGF0aG5hbWUgK1xuICAgICAgICAgICAgICAgIGxvY2F0aW9uLnNlYXJjaDtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgICQuaWRsZVRpbWVyKHRpbWVvdXRQZXJpb2QpO1xufVxuXG5jbGFzcyBQYWdlUHJvZ3Jlc3NCYXIge1xuICAgIGNvbnN0cnVjdG9yKGFjdERpY3QpIHtcbiAgICAgICAgdGhpcy5wb3NzaWJsZSA9IDA7XG4gICAgICAgIHRoaXMudG90YWwgPSAxO1xuICAgICAgICBpZiAoYWN0RGljdCAmJiBPYmplY3Qua2V5cyhhY3REaWN0KS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2aXRpZXMgPSBhY3REaWN0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGFjdGl2aXRpZXMgPSB7IHBhZ2U6IDAgfTtcbiAgICAgICAgICAgICQoXCIucnVuZXN0b25lXCIpLmVhY2goZnVuY3Rpb24gKGlkeCwgZSkge1xuICAgICAgICAgICAgICAgIGFjdGl2aXRpZXNbZS5maXJzdEVsZW1lbnRDaGlsZC5pZF0gPSAwO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2aXRpZXMgPSBhY3Rpdml0aWVzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2FsY3VsYXRlUHJvZ3Jlc3MoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLm1hdGNoKFxuICAgICAgICAgICAgICAgIC8uKihpbmRleC5odG1sfHRvY3RyZWUuaHRtbHxFeGVyY2lzZXMuaHRtbHxzZWFyY2guaHRtbCkkL2lcbiAgICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgICAkKFwiI3NjcHJvZ3Jlc3Njb250YWluZXJcIikuaGlkZSgpO1xuICAgICAgICB9XG4gICAgICAgI
4060HRoaXMucmVuZGVyUHJvZ3Jlc3MoKTtcbiAgICB9XG5cbiAgICBjYWxjdWxhdGVQcm9ncmVzcygpIHtcbiAgICAgICAgZm9yIChsZXQgayBpbiB0aGlzLmFjdGl2aXRpZXMpIHtcbiAgICAgICAgICAgIGlmIChrICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBvc3NpYmxlKys7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZpdGllc1trXSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b3RhbCsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbmRlclByb2dyZXNzKCkge1xuICAgICAgICBsZXQgdmFsdWUgPSAwO1xuICAgICAgICAkKFwiI3NjcHJvZ3Jlc3N0b3RhbFwiKS50ZXh0KHRoaXMudG90YWwpO1xuICAgICAgICAkKFwiI3NjcHJvZ3Jlc3Nwb3NzXCIpLnRleHQodGhpcy5wb3NzaWJsZSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YWx1ZSA9ICgxMDAgKiB0aGlzLnRvdGFsKSAvIHRoaXMucG9zc2libGU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHZhbHVlID0gMDtcbiAgICAgICAgfVxuICAgICAgICAkKFwiI3N1YmNoYXB0ZXJwcm9ncmVzc1wiKS5wcm9ncmVzc2Jhcih7XG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIWVCb29rQ29uZmlnLmlzTG9nZ2VkSW4pIHtcbiAgICAgICAgICAgICQoXCIjc3ViY2hhcHRlcnByb2dyZXNzPmRpdlwiKS5hZGRDbGFzcyhcImxvZ2dlZG91dFwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZVByb2dyZXNzKGRpdl9pZCkge1xuICAgICAgICB0aGlzLmFjdGl2aXRpZXNbZGl2X2lkXSsrO1xuICAgICAgICAvLyBPbmx5IHVwZGF0ZSB0aGUgcHJvZ3Jlc3MgYmFyIG9uIHRoZSBmaXJzdCBpbnRlcmFjdGlvbiB3aXRoIGFuIG9iamVjdC5cbiAgICAgICAgaWYgKHRoaXMuYWN0aXZpdGllc1tkaXZfaWRdID09PSAxKSB7XG4gICAgICAgICAgICB0aGlzLnRvdGFsKys7XG4gICAgICAgICAgICBsZXQgdmFsID0gKDEwMCAqIHRoaXMudG90YWwpIC8gdGhpcy5wb3NzaWJsZTtcbiAgICAgICAgICAgICQoXCIjc2Nwcm9ncmVzc3RvdGFsXCIpLnRleHQodGhpcy50b3RhbCk7XG4gICAgICAgICAgICAkKFwiI3NjcHJvZ3Jlc3Nwb3NzXCIpLnRleHQodGhpcy5wb3NzaWJsZSk7XG4gICAgICAgICAgICAkKFwiI3N1YmNoYXB0ZXJwcm9ncmVzc1wiKS5wcm9ncmVzc2JhcihcIm9wdGlvblwiLCBcInZhbHVlXCIsIHZhbCk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgdmFsID09IDEwMC4wICYmXG4gICAgICAgICAgICAgICAgJChcIiNjb21wbGV0aW9uQnV0dG9uXCIpLnRleHQoKS50b0xvd2VyQ2FzZSgpID09PVxuICAgICAgICAgICAgICAgICAgICBcIm1hcmsgYXMgY29tcGxldGVkXCJcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5jbGljaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgdmFyIHBhZ2VQcm9ncmVzc1RyYWNrZXIgPSB7fTtcblxuYXN5bmMgZnVuY3Rpb24gaGFuZGxlUGFnZVNldHVwKCkge1xuICAgIHZhciBtZXNzO1xuICAgIGlmIChlQm9va0NvbmZpZy51c2VSdW5lc3RvbmVTZXJ2aWNlcykge1xuICAgICAgICBsZXQgaGVhZGVycyA9IG5ldyBIZWFkZXJzKHtcbiAgICAgICAgICAgIFwiQ29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOFwiLFxuICAgICAgICAgICAgQWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgfSk7XG4gICAgICAgIGxldCBkYXRhID0geyB0aW1lem9uZW9mZnNldDogbmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpIC8gNjAgfTtcbiAgICAgICAgbGV0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdChcbiAgICAgICAgICAgIGAke2VCb29rQ29uZmlnLm5ld19zZXJ2ZXJfcHJlZml4fS9sb2dnZXIvc2V0X3R6X29mZnNldGAsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShkYXRhKSxcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocmVxdWVzdCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHNldCB0aW1lem9uZSEgJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3Igc2V0dGluZyB0aW1lem9uZSAke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc29sZS5sb2coYFRoaXMgcGFnZSBzZXJ2ZWQgYnkgJHtlQm9va0NvbmZpZy5zZXJ2ZWRfYnl9YCk7XG4gICAgaWYgKGVCb29rQ29uZmlnLmlzTG9nZ2VkSW4pIHtcbiAgICAgICAgbWVzcyA9IGB1c2VybmFtZTogJHtlQm9va0NvbmZpZy51c2VybmFtZX1gO1xuICAgICAgICBpZiAoIWVCb29rQ29uZmlnLmlzSW5zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgJChcIiNpcF9kcm9wZG93bl9saW5rXCIpLnJlbW92ZSgpO1xuICAgICAgICAgICAgJChcIiNpbnN0X3BlZXJfbGlua1wiKS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgICAkKGRvY3VtZW50KS50cmlnZ2VyKFwicnVuZXN0b25lOmxvZ2luXCIpO1xuICAgICAgICBhZGRSZWFkaW5nTGlzdCgpO1xuICAgICAgICAvLyBBdm9pZCB0aGUgdGltZWRSZWZyZXNoIG9uIHRoZSBncmFkaW5nIHBhZ2UuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5pbmRleE9mKFwiL2FkbWluL2dyYWRpbmdcIikgPT0gLTEgJiZcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5pbmRleE9mKFwiL3BlZXIvXCIpID09IC0xXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGltZWRSZWZyZXNoKCk7XG4gICAgICAgI
4060H1cbiAgICB9IGVsc2Uge1xuICAgICAgICBtZXNzID0gXCJOb3QgbG9nZ2VkIGluXCI7XG4gICAgICAgICQoZG9jdW1lbnQpLnRyaWdnZXIoXCJydW5lc3RvbmU6bG9nb3V0XCIpO1xuICAgICAgICBsZXQgYncgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImJyb3dzaW5nX3dhcm5pbmdcIik7XG4gICAgICAgIGlmIChidykge1xuICAgICAgICAgICAgYncuaW5uZXJIVE1MID1cbiAgICAgICAgICAgICAgICBcIjxwIGNsYXNzPSduYXZiYXJfbWVzc2FnZSc+U2F2aW5nIGFuZCBMb2dnaW5nIGFyZSBEaXNhYmxlZDwvcD5cIjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYXcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImFkX3dhcm5pbmdcIik7XG4gICAgICAgIGlmIChhdykge1xuICAgICAgICAgICAgYXcuaW5uZXJIVE1MID1cbiAgICAgICAgICAgICAgICBcIjxwIGNsYXNzPSduYXZiYXJfbWVzc2FnZSc+8J+aqyBMb2ctaW4gdG8gUmVtb3ZlIDxhIGhyZWY9Jy9ydW5lc3RvbmUvZGVmYXVsdC9hZHMnPkFkcyE8L2E+IPCfmqsgJm5ic3A7PC9wPlwiO1xuICAgICAgICB9XG4gICAgfVxuICAgICQoXCIubG9nZ2VkaW51c2VyXCIpLmh0bWwobWVzcyk7XG5cbiAgICBwYWdlUHJvZ3Jlc3NUcmFja2VyID0gbmV3IFBhZ2VQcm9ncmVzc0JhcihlQm9va0NvbmZpZy5hY3Rpdml0aWVzKTtcbiAgICBub3RpZnlSdW5lc3RvbmVDb21wb25lbnRzKCk7XG59XG5cbmZ1bmN0aW9uIHNldHVwTmF2YmFyTG9nZ2VkSW4oKSB7XG4gICAgJChcIiNwcm9maWxlbGlua1wiKS5zaG93KCk7XG4gICAgJChcIiNwYXNzd29yZGxpbmtcIikuc2hvdygpO1xuICAgICQoXCIjcmVnaXN0ZXJsaW5rXCIpLmhpZGUoKTtcbiAgICAkKFwibGkubG9naW5vdXRcIikuaHRtbChcbiAgICAgICAgJzxhIGhyZWY9XCInICsgZUJvb2tDb25maWcuYXBwICsgJy9kZWZhdWx0L3VzZXIvbG9nb3V0XCI+TG9nIE91dDwvYT4nXG4gICAgKTtcbn1cbiQoZG9jdW1lbnQpLm9uKFwicnVuZXN0b25lOmxvZ2luXCIsIHNldHVwTmF2YmFyTG9nZ2VkSW4pO1xuXG5mdW5jdGlvbiBzZXR1cE5hdmJhckxvZ2dlZE91dCgpIHtcbiAgICBpZiAoZUJvb2tDb25maWcudXNlUnVuZXN0b25lU2VydmljZXMpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJzZXR1cCBuYXZiYXIgZm9yIGxvZ2dlZCBvdXRcIik7XG4gICAgICAgICQoXCIjcmVnaXN0ZXJsaW5rXCIpLnNob3coKTtcbiAgICAgICAgJChcIiNwcm9maWxlbGlua1wiKS5oaWRlKCk7XG4gICAgICAgICQoXCIjcGFzc3dvcmRsaW5rXCIpLmhpZGUoKTtcbiAgICAgICAgJChcIiNpcF9kcm9wZG93bl9saW5rXCIpLmhpZGUoKTtcbiAgICAgICAgJChcIiNpbnN0X3BlZXJfbGlua1wiKS5oaWRlKCk7XG4gICAgICAgICQoXCJsaS5sb2dpbm91dFwiKS5odG1sKFxuICAgICAgICAgICAgJzxhIGhyZWY9XCInICsgZUJvb2tDb25maWcuYXBwICsgJy9kZWZhdWx0L3VzZXIvbG9naW5cIj5Mb2dpbjwvYT4nXG4gICAgICAgICk7XG4gICAgICAgICQoXCIuZm9vdGVyXCIpLmh0bWwoXCJ1c2VyIG5vdCBsb2dnZWQgaW5cIik7XG4gICAgfVxufVxuJChkb2N1bWVudCkub24oXCJydW5lc3RvbmU6bG9nb3V0XCIsIHNldHVwTmF2YmFyTG9nZ2VkT3V0KTtcblxuZnVuY3Rpb24gbm90aWZ5UnVuZXN0b25lQ29tcG9uZW50cygpIHtcbiAgICAvLyBSdW5lc3RvbmUgY29tcG9uZW50cyB3YWl0IHVudGlsIGxvZ2luIHByb2Nlc3MgaXMgb3ZlciB0byBsb2FkIGNvbXBvbmVudHMgYmVjYXVzZSBvZiBzdG9yYWdlIGlzc3Vlcy4gVGhpcyB0cmlnZ2VycyB0aGUgYGR5bmFtaWMgaW1wb3J0IG1hY2hpbmVyeWAsIHdoaWNoIHRoZW4gc2VuZHMgdGhlIGxvZ2luIGNvbXBsZXRlIHNpZ25hbCB3aGVuIHRoaXMgYW5kIGFsbCBkeW5hbWljIGltcG9ydHMgYXJlIGZpbmlzaGVkLlxuICAgICQoZG9jdW1lbnQpLnRyaWdnZXIoXCJydW5lc3RvbmU6cHJlLWxvZ2luLWNvbXBsZXRlXCIpO1xufVxuXG5mdW5jdGlvbiBwbGFjZUFkQ29weSgpIHtcbiAgICBpZiAodHlwZW9mIHNob3dBZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzaG93QWQpIHtcbiAgICAgICAgbGV0IGFkTnVtID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMikgKyAxO1xuICAgICAgICBsZXQgYWRCbG9jayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBhZGNvcHlfJHthZE51bX1gKTtcbiAgICAgICAgbGV0IHJzRWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLnJ1bmVzdG9uZVwiKTtcbiAgICAgICAgaWYgKHJzRWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbGV0IHJhbmRvbUluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcnNFbGVtZW50cy5sZW5ndGgpO1xuICAgICAgICAgICAgcnNFbGVtZW50c1tyYW5kb21JbmRleF0uYWZ0ZXIoYWRCbG9jaylcbiAgICAgICAgICAgIGFkQmxvY2suc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gaW5pdGlhbGl6ZSBzdHVmZlxuJChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGVCb29rQ29uZmlnKSB7XG4gICAgICAgIGhhbmRsZVBhZ2VTZXR1cCgpO1xuICAgICAgICBwbGFjZUFkQ29weSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2YgZUJvb2tDb25maWcgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIFwiZUJvb2tDb25maWcgaXMgbm90IGRlZmluZWQuICBUaGlzIHBhZ2UgbXVzdCBub3QgYmUgc2V0IHVwIGZvciBSdW5lc3RvbmVcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cbn0pO1xuXG4vLyBtaXNjIHN0dWZmXG4vLyB0b2RvOiAgVGhpcyBjb3VsZCBiZSBmdXJ0aGVyIGRpc3RyaWJ1dGVkIGJ1dCBtYWtpbmcgYSB2aWRlby5qcyBmaWxlIGp1c3QgZm9yIG9uZSBmdW5jdGlvbiBzZWVtcyBkdW1iLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBhZGQgdGhlIHZpZGVvIHBsYXkgYnV0dG9uIG92ZXJsYXkgaW1hZ2VcbiAgICAkKFwiLnZpZGVvLXBsYXktb3ZlcmxheVwiKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCh0aGlzKS5jc3MoXG4gICAgICAgICAgICBcImJhY2tncm91bmQtaW1hZ2VcIixcbiAgICAgICAgICAgIFwidXJsKCd7e3BhdGh0bygnX3N0YXRpYy9wbGF5X292ZXJsYXlfaWNvb
4060i5wbmcnLCAxKX19JylcIlxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBuZWVkZWQgdG8gYWxsb3cgdGhlIGRyb3Bkb3duIHNlYXJjaCBiYXIgdG8gd29yaztcbiAgICAvLyBUaGUgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdGhhdCB0aGUgZHJvcGRvd24gbWVudSBjbG9zZXMgd2hlbiBzb21ldGhpbmcgaW5cbiAgICAvLyBpdCAobGlrZSB0aGUgc2VhcmNoIGJhcikgaXMgY2xpY2tlZFxuICAgICQoZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBGaXggaW5wdXQgZWxlbWVudCBjbGljayBwcm9ibGVtXG4gICAgICAgICQoXCIuZHJvcGRvd24gaW5wdXQsIC5kcm9wZG93biBsYWJlbFwiKS5jbGljayhmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyByZS13cml0ZSBzb21lIHVybHNcbiAgICAvLyBUaGlzIGlzIHRyaWNrZXIgdGhhbiBpdCBsb29rcyBhbmQgeW91IGhhdmUgdG8gb2JleSB0aGUgcnVsZXMgZm9yICMgYW5jaG9yc1xuICAgIC8vIFRoZSAjYW5jaG9ycyBtdXN0IGNvbWUgYWZ0ZXIgdGhlIHF1ZXJ5IHN0cmluZyBhcyB0aGUgc2VydmVyIGJhc2ljYWxseSBpZ25vcmVzIGFueSBwYXJ0XG4gICAgLy8gb2YgYSB1cmwgdGhhdCBjb21lcyBhZnRlciAjIC0gbGlrZSBhIGNvbW1lbnQuLi5cbiAgICBpZiAobG9jYXRpb24uaHJlZi5pbmNsdWRlcyhcIm1vZGU9YnJvd3NpbmdcIikpIHtcbiAgICAgICAgbGV0IHF1ZXJ5U3RyaW5nID0gXCI/bW9kZT1icm93c2luZ1wiO1xuICAgICAgICBkb2
4060N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiYVwiKS5mb3JFYWNoKChsaW5rKSA9PiB7XG4gICAgICAgICAgICBsZXQgYW5jaG9yVGV4dCA9IFwiXCI7XG4gICAgICAgICAgICBpZiAobGluay5ocmVmLmluY2x1ZGVzKFwiYm9va3MvcHVibGlzaGVkXCIpICYmICEgbGluay5ocmVmLmluY2x1ZGVzKFwiP21vZGU9YnJvd3NpbmdcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAobGluay5ocmVmLmluY2x1ZGVzKFwiI1wiKSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgYVBvaW50ID0gbGluay5ocmVmLmluZGV4T2YoXCIjXCIpO1xuICAgICAgICAgICAgICAgICAgICBhbmNob3JUZXh0ID0gbGluay5ocmVmLnN1YnN0cmluZyhhUG9pbnQpO1xuICAgICAgICAgICAgICAgICAgICBsaW5rLmhyZWYgPSBsaW5rLmhyZWYuc3Vic3RyaW5nKDAsYVBvaW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGluay5ocmVmID0gbGluay5ocmVmLmluY2x1ZGVzKFwiP1wiKVxuICAgICAgICAgICAgICAgICAgICA/IGxpbmsuaHJlZiArIHF1ZXJ5U3RyaW5nLnJlcGxhY2UoXCI/XCIsIFwiJlwiKSArIGFuY2hvclRleHRcbiAgICAgICAgICAgICAgICAgICAgOiBsaW5rLmhyZWYgKyBxdWVyeVN0cmluZyArIGFuY2hvclRleHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn0pO1xuIiwiLyohXG4gKiBqUXVlcnkgaWRsZVRpbWVyIHBsdWdpblxuICogdmVyc2lvbiAwLjkuMTAwNTExXG4gKiBieSBQYXVsIElyaXNoLlxuICogICBodHRwOi8vZ2l0aHViLmNvbS9wYXVsaXJpc2gveXVpLW1pc2MvdHJlZS9cbiAqIE1JVCBsaWNlbnNlXG5cbiAqIGFkYXB0ZWQgZnJvbSBZVUkgaWRsZSB0aW1lciBieSBuemFrYXM6XG4gKiAgIGh0dHA6Ly9naXRodWIuY29tL256YWthcy95dWktbWlzYy9cbiovXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDA5IE5pY2hvbGFzIEMuIFpha2FzXG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbiAqIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG4vKiB1cGRhdGVkIHRvIGZpeCBDaHJvbWUgc2V0VGltZW91dCBpc3N1ZSBieSBaYWlkIFphd2FpZGVoICovXG5cbiAvLyBBUEkgYXZhaWxhYmxlIGluIDw9IHYwLjhcbiAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4gLy8gaWRsZVRpbWVyKCkgdGFrZXMgYW4gb3B0aW9uYWwgYXJndW1lbnQgdGhhdCBkZWZpbmVzIHRoZSBpZGxlIHRpbWVvdXRcbiAvLyB0aW1lb3V0IGlzIGluIG1pbGxpc2Vjb25kczsgZGVmYXVsdHMgdG8gMzAwMDBcbiAkLmlkbGVUaW1lcigxMDAwMCk7XG5cblxuICQoZG9jdW1lbnQpLmJpbmQoXCJpZGxlLmlkbGVUaW1lclwiLCBmdW5jdGlvbigpe1xuICAgIC8vIGZ1bmN0aW9uIHlvdSB3YW50IHRvIGZpcmUgd2hlbiB0aGUgdXNlciBnb2VzIGlkbGVcbiB9KTtcblxuXG4gJChkb2N1bWVudCkuYmluZChcImFjdGl2ZS5pZGxlVGltZXJcIiwgZnVuY3Rpb24oKXtcbiAgLy8gZnVuY3Rpb24geW91IHdhbnQgdG8gZmlyZSB3aGVuIHRoZSB1c2VyIGJlY29tZXMgYWN0aXZlIGFnYWluXG4gfSk7XG5cbiAvLyBwYXNzIHRoZSBzdHJpbmcgJ2Rlc3Ryb3knIHRvIHN0b3AgdGhlIHRpbWVyXG4gJC5pZGxlVGltZXIoJ2Rlc3Ryb3knKTtcblxuIC8vIHlvdSBjYW4gcXVlcnkgaWYgdGhlIHVzZXIgaXMgaWRsZSBvciBub3Qgd2l0aCBkYXRhKClcbiAkLmRhdGEoZG9jdW1lbnQsJ2lkbGVUaW1lcicpOyAgLy8gJ2lkbGUnICBvciAnYWN0aXZlJ1xuXG4gLy8geW91IGNhbiBnZXQgdGltZSBlbGFwc2VkIHNpbmNlIHVzZXIgd2hlbiBpZGxlL2FjdGl2ZVxuICQuaWRsZVRpbWVyKCdnZXRFbGFwc2VkVGltZScpOyAvLyB0aW1lIHNpbmNlIHN0YXRlIGNoYW5nZSBpbiBtc1xuXG4gKioqKioqKiovXG5cblxuXG4gLy8gQVBJIGF2YWlsYWJsZSBpbiA+PSB2MC45XG4gLyoqKioqKioqKioqKioqKioqKioqKioqKipcblxuIC8vIGJpbmQgdG8gc3BlY2lmaWMgZWxlbWVudHMsIGFsbG93cyBmb3IgbXVsdGlwbGUgdGltZXIgaW5zdGFuY2VzXG4gJChlbGVtKS5pZGxlVGltZXIodGltZW91dHwnZGVzdHJveSd8J2dldEVsYXBzZWRUaW1lJyk7XG4gJC5kYXRhKGVsZW0sJ2lkbGVUaW
40601lcicpOyAgLy8gJ2lkbGUnICBvciAnYWN0aXZlJ1xuXG4gLy8gaWYgeW91J3JlIHVzaW5nIHRoZSBvbGQgJC5pZGxlVGltZXIgYXBpLCB5b3Ugc2hvdWxkIG5vdCBkbyAkKGRvY3VtZW50KS5pZGxlVGltZXIoLi4uKVxuXG4gLy8gZWxlbWVudCBib3VuZCB0aW1lcnMgd2lsbCBvbmx5IHdhdGNoIGZvciBldmVudHMgaW5zaWRlIG9mIHRoZW0uXG4gLy8geW91IG1heSBqdXN0IHdhbnQgcGFnZS1sZXZlbCBhY3Rpdml0eSwgaW4gd2hpY2ggY2FzZSB5b3UgbWF5IHNldCB1cFxuIC8vICAgeW91ciB0aW1lcnMgb24gZG9jdW1lbnQsIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgYW5kIGRvY3VtZW50LmJvZHlcblxuIC8vIFlvdSBjYW4gb3B0aW9uYWxseSBwcm92aWRlIGEgc2Vjb25kIGFyZ3VtZW50IHRvIG92ZXJyaWRlIGNlcnRhaW4gb3B0aW9ucy5cbiAvLyBIZXJlIGFyZSB0aGUgZGVmYXVsdHMsIHNvIHlvdSBjYW4gb21pdCBhbnkgb3IgYWxsIG9mIHRoZW0uXG4gJChlbGVtKS5pZGxlVGltZXIodGltZW91dCwge1xuICAgc3RhcnRJbW1lZGlhdGVseTogdHJ1ZSwgLy9zdGFydHMgYSB0aW1lb3V0IGFzIHNvb24gYXMgdGhlIHRpbWVyIGlzIHNldCB1cDsgb3RoZXJ3aXNlIGl0IHdhaXRzIGZvciB0aGUgZmlyc3QgZXZlbnQuXG4gICBpZGxlOiAgICBmYWxzZSwgICAgICAgICAvL2luZGljYXRlcyBpZiB0aGUgdXNlciBpcyBpZGxlXG4gICBlbmFibGVkOiB0cnVlLCAgICAgICAgICAvL2luZGljYXRlcyBpZiB0aGUgaWRsZSB0aW1lciBpcyBlbmFibGVkXG4gICBldmVudHM6ICAnbW91c2Vtb3ZlIGtleWRvd24gRE9NTW91c2VTY3JvbGwgbW91c2V3aGVlbCBtb3VzZWRvd24gdG91Y2hzdGFydCB0b3VjaG1vdmUnIC8vIGFjdGl2aXR5IGlzIG9uZSBvZiB0aGVzZSBldmVudHNcbiB9KTtcblxuICoqKioqKioqL1xuXG4oZnVuY3Rpb24oJCl7XG5cbiQuaWRsZVRpbWVyID0gZnVuY3Rpb24obmV3VGltZW91dCwgZWxlbSwgb3B0cyl7XG5cbiAgICAvLyBkZWZhdWx0cyB0aGF0IGFyZSB0byBiZSBzdG9yZWQgYXMgaW5zdGFuY2UgcHJvcHMgb24gdGhlIGVsZW1cblxuXHRvcHRzID0gJC5leHRlbmQoe1xuXHRcdHN0YXJ0SW1tZWRpYXRlbHk6IHRydWUsIC8vc3RhcnRzIGEgdGltZW91dCBhcyBzb29uIGFzIHRoZSB0aW1lciBpcyBzZXQgdXBcblx0XHRpZGxlOiAgICBmYWxzZSwgICAgICAgICAvL2luZGljYXRlcyBpZiB0aGUgdXNlciBpcyBpZGxlXG5cdFx0ZW5hYmxlZDogdHJ1ZSwgICAgICAgICAgLy9pbmRpY2F0ZXMgaWYgdGhlIGlkbGUgdGltZXIgaXMgZW5hYmxlZFxuXHRcdHRpbWVvdXQ6IDMwMDAwLCAgICAgICAgIC8vdGhlIGFtb3VudCBvZiB0aW1lIChtcykgYmVmb3JlIHRoZSB1c2VyIGlzIGNvbnNpZGVyZWQgaWRsZVxuXHRcdGV2ZW50czogICdtb3VzZW1vdmUga2V5ZG93biBET01Nb3VzZVNjcm9sbCBtb3VzZXdoZWVsIG1vdXNlZG93biB0b3VjaHN0YXJ0IHRvdWNobW92ZScgLy8gYWN0aXZpdHkgaXMgb25lIG9mIHRoZXNlIGV2ZW50c1xuXHR9LCBvcHRzKTtcblxuXG4gICAgZWxlbSA9IGVsZW0gfHwgZG9jdW1lbnQ7XG5cbiAgICAvKiAoaW50ZW50aW9uYWxseSBub3QgZG9jdW1lbnRlZClcbiAgICAgKiBUb2dnbGVzIHRoZSBpZGxlIHN0YXRlIGFuZCBmaXJlcyBhbiBhcHByb3ByaWF0ZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgICAqL1xuICAgIHZhciB0b2dnbGVJZGxlU3RhdGUgPSBmdW5jdGlvbihteWVsZW0pe1xuXG4gICAgICAgIC8vIGN1cnNlIHlvdSwgbW96aWxsYSBzZXRUaW1lb3V0IGxhdGVuZXNzIGJ1ZyFcbiAgICAgICAgaWYgKHR5cGVvZiBteWVsZW0gPT09ICdudW1iZXInKXtcbiAgICAgICAgICAgIG15ZWxlbSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvYmogPSAkLmRhdGEobXllbGVtIHx8IGVsZW0sJ2lkbGVUaW1lck9iaicpO1xuXG4gICAgICAgIC8vdG9nZ2xlIHRoZSBzdGF0ZVxuICAgICAgICBvYmouaWRsZSA9ICFvYmouaWRsZTtcblxuICAgICAgICAvLyByZXNldCB0aW1lb3V0IFxuICAgICAgICB2Y
4060XIgZWxhcHNlZCA9ICgrbmV3IERhdGUoKSkgLSBvYmoub2xkZGF0ZTtcbiAgICAgICAgb2JqLm9sZGRhdGUgPSArbmV3IERhdGUoKTtcblxuICAgICAgICAvLyBoYW5kbGUgQ2hyb21lIGFsd2F5cyB0cmlnZ2VyaW5nIGlkbGUgYWZ0ZXIganMgYWxlcnQgb3IgY29tZmlybSBwb3B1cFxuICAgICAgICBpZiAob2JqLmlkbGUgJiYgKGVsYXBzZWQgPCBvcHRzLnRpbWVvdXQpKSB7XG4gICAgICAgICAgICAgICAgb2JqLmlkbGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoJC5pZGxlVGltZXIudElkKTtcbiAgICAgICAgICAgICAgICBpZiAob3B0cy5lbmFibGVkKVxuICAgICAgICAgICAgICAgICAgJC5pZGxlVGltZXIudElkID0gc2V0VGltZW91dCh0b2dnbGVJZGxlU3RhdGUsIG9wdHMudGltZW91dCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvL2ZpcmUgYXBwcm9wcmlhdGUgZXZlbnRcblxuICAgICAgICAvLyBjcmVhdGUgYSBjdXN0b20gZXZlbnQsIGJ1dCBmaXJzdCwgc3RvcmUgdGhlIG5ldyBzdGF0ZSBvbiB0aGUgZWxlbWVudFxuICAgICAgICAvLyBhbmQgdGhlbiBhcHBlbmQgdGhhdCBzdHJpbmcgdG8gYSBuYW1lc3BhY2VcbiAgICAgICAgdmFyIGV2ZW50ID0galF1ZXJ5LkV2ZW50KCAkLmRhdGEoZWxlbSwnaWRsZVRpbWVyJywgb2JqLmlkbGUgPyBcImlkbGVcIiA6IFwiYWN0aXZlXCIgKSAgKyAnLmlkbGVUaW1lcicgICApO1xuXG4gICAgICAgIC8vIHdlIGRvIHdhbnQgdGhpcyB0byBidWJibGUsIGF0IGxlYXN0IGFzIGEgdGVtcG9yYXJ5IGZpeCBmb3IgalF1ZXJ5IDEuN1xuICAgICAgICAvLyBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgJChlbGVtKS50cmlnZ2VyKGV2ZW50KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogU3RvcHMgdGhlIGlkbGUgdGltZXIuIFRoaXMgcmVtb3ZlcyBhcHByb3ByaWF0ZSBldmVudCBoYW5kbGVyc1xuICAgICAqIGFuZCBjYW5jZWxzIGFueSBwZW5kaW5nIHRpbWVvdXRzLlxuICAgICAqIEByZXR1cm4ge3ZvaWR9XG4gICAgICogQG1ldGhvZCBzdG9wXG4gICAgICogQHN0YXRpY1xuICAgICAqL1xuICAgIHN0b3AgPSBmdW5jdGlvbihlbGVtKXtcblxuICAgICAgICB2Y
4060XIgb2JqID0gJC5kYXRhKGVsZW0sJ2lkbGVUaW1lck9iaicpIHx8IHt9O1xuXG4gICAgICAgIC8vc2V0IHRvIGRpc2FibGVkXG4gICAgICAgIG9iai5lbmFibGVkID0gZmFsc2U7XG5cbiAgICAgICAgLy9jbGVhciBhbnkgcGVuZGluZyB0aW1lb3V0c1xuICAgICAgICBjbGVhclRpbWVvdXQob2JqLnRJZCk7XG5cbiAgICAgICAgLy9kZXRhY2ggdGhlIGV2ZW50IGhhbmRsZXJzXG4gICAgICAgICQoZWxlbSkub2ZmKCcuaWRsZVRpbWVyJyk7XG4gICAgfSxcblxuXG4gICAgLyogKGludGVudGlvbmFsbHkgbm90IGRvY3VtZW50ZWQpXG4gICAgICogSGFuZGxlcyBhIHVzZXIgZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSB1c2VyIGlzbid0IGlkbGUuXG4gICAgICogQHBhcmFtIHtFdmVudH0gZXZlbnQgQSBET00yLW5vcm1hbGl6ZWQgZXZlbnQgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge3ZvaWR9XG4gICAgICovXG4gICAgaGFuZGxlVXNlckV2ZW50ID0gZnVuY3Rpb24oKXtcblxuICAgICAgICB2YXIgb2JqID0gJC5kYXRhKHRoaXMsJ2lkbGVUaW1lck9iaicpO1xuXG4gICAgICAgIC8vY2xlYXIgYW55IGV4aXN0aW5nIHRpbWVvdXRcbiAgICAgICAgY2xlYXJUaW1lb3V0KG9iai50SWQpO1xuXG5cblxuICAgICAgICAvL2lmIHRoZSBpZGxlIHRpbWVyIGlzIGVuYWJsZWRcbiAgICAgICAgaWYgKG9iai5lbmFibGVkKXtcblxuXG4gICAgICAgICAgICAvL2lmIGl0J3MgaWRsZSwgdGhhdCBtZWFucyB0aGUgdXNlciBpcyBubyBsb25nZXIgaWRsZVxuICAgICAgICAgICAgaWYgKG9iai5pZGxlKXtcbiAgICAgICAgICAgICAgICB0b2dnbGVJZGxlU3RhdGUodGhpcyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vc2V0IGEgbmV3IHRpbWVvdXRcbiAgICAgICAgICAgIG9iai50SWQgPSBzZXRUaW1lb3V0KHRvZ2dsZUlkbGVTdGF0ZSwgb2JqLnRpbWVvdXQpO1xuXG4gICAgICAgIH1cbiAgICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogU3RhcnRzIHRoZSBpZGxlIHRpbWVyLiBUaGlzIGFkZHMgYXBwcm9wcmlhdGUgZXZlbnQgaGFuZGxlcnNcbiAgICAgKiBhbmQgc3RhcnRzIHRoZSBmaXJzdCB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7aW50fSBuZXdUaW1lb3V0IChPcHRpb25hbCkgQSBuZXcgdmFsdWUgZm9yIHRoZSB0aW1lb3V0IHBlcmlvZCBpbiBtcy5cbiAgICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgICAqIEBtZXRob2QgJC5pZGxlVGltZXJcbiAgICAgKiBAc3RhdGljXG4gICAgICovXG5cblxuICAgIHZhciBvYmogPSAkLmRhdGEoZWxlbSwnaWRsZVRpbWVyT2JqJykgfHwge307XG5cbiAgICBvYmoub2xkZGF0ZSA9IG9iai5vbGRkYXRlIHx8ICtuZXcgRGF0ZSgpO1xuXG4gICAgLy9hc3NpZ24gYSBuZXcgdGltZW91dCBpZiBuZWNlc3NhcnlcbiAgICBpZiAodHlwZW9mIG5ld1RpbWVvdXQgPT09IFwibnVtYmVyXCIpe1xuICAgICAgICBvcHRzLnRpbWVvdXQgPSBuZXdUaW1lb3V0O1xuICAgIH0gZWxzZSBpZiAobmV3VGltZW91dCA9PT0gJ2Rlc3Ryb3knKSB7XG4gICAgICAgIHN0b3AoZWxlbSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0gZWxzZSBpZiAobmV3VGltZW91dCA9PT0gJ2dldEVsYXBzZWRUaW1lJyl7XG4gICAgICAgIHJldHVybiAoK25ldyBEYXRlKCkpIC0gb2JqLm9sZGRhdGU7XG4gICAgfVxuXG4gICAgLy9hc3NpZ24gYXBwcm9wcmlhdGUgZXZlbnQgaGFuZGxlcnNcbiAgICAkKGVsZW0pLm9uKCQudHJpbSgob3B0cy5ldmVudHMrJyAnKS5zcGxpdCgnICcpLmpvaW4oJy5pZGxlVGltZXIgJykpLGhhbmRsZVVzZXJFdmVudCk7XG5cblxuICAgIG9iai5pZGxlICAgID0gb3B0cy5pZGxlO1xuICAgIG9iai5lbmFibGVkID0gb3B0cy5lbmFibGVkO1xuICAgIG9iai50aW1lb3V0ID0gb3B0cy50aW1lb3V0O1xuXG5cbiAgICAvL3NldCBhIHRpbWVvdXQgdG8gdG9nZ2xlIHN0YXRlLiBNYXkgd2lzaCB0byBvbWl0IHRoaXMgaW4gc29tZSBzaXR1YXRpb25zXG5cdGlmIChvcHRzLnN0YXJ0SW1tZWRpYXRlbHkpIHtcblx0ICAgIG9iai50SWQgPSBzZXRUaW1lb3V0KHRvZ2dsZUlkbGVTdGF0ZSwgb2JqLnRpbWVvdXQpO1xuXHR9XG5cbiAgICAvLyBhc3N1bWUgdGhlIHVzZXIgaXMgYWN0aXZlIGZvciB0aGUgZmlyc3QgeCBzZWNvbmRzLlxuICAgICQuZGF0YShlbGVtLCdpZGxlVGltZXInLFwiYWN0aXZlXCIpO1xuXG4gICAgLy8gc3RvcmUgb3VyIGluc3RhbmNlIG9uIHRoZSBvYmplY3RcbiAgICAkLmRhdGEoZWxlbSwnaWRsZVRpbWVyT2JqJyxvYmopO1xuXG5cblxufTsgLy8gZW5kIG9mICQuaWRsZVRpbWVyKClcblxuXG4vLyB2MC45IEFQSSBmb3IgZGVmaW5pbmcgbXVsdGlwbGUgdGltZXJzLlxuJC5mbi5pZGxlVGltZXIgPSBmdW5jdGlvbihuZXdUaW1lb3V0LG9wdHMpe1xuXHQvLyBBbGxvdyBvbWlzc2lvbiBvZiBvcHRzIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG5cdGlmICghb3B0cykge1xuXHRcdG9wdHMgPSB7fTtcblx0fVxuXG4gICAgaWYodGhpc1swXSl7XG4gICAgICAgICQuaWRsZVRpbWVyKG5ld1RpbWVvdXQsdGhpc1swXSxvcHRzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbn07XG5cblxufSkoalF1ZXJ5KTtcbiIsIi8qIVxuICogQklESSBlbWJlZGRpbmcgc3VwcG9ydCBmb3IgalF1ZXJ5LmkxOG5cbiAqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTUsIERhdmlkIENoYW5cbiAqXG4gKiBUaGlzIGNvZGUgaXMgZHVhbCBsaWNlbnNlZCBHUEx2MiBvciBsYXRlciBhbmQgTUlULiBZb3UgZG9uJ3QgaGF2ZSB0byBkb1xuICogYW55dGhpbmcgc3BlY2lhbCB0byBjaG9vc2Ugb25lIGxpY2Vuc2Ugb3IgdGhlIG90aGVyIGFuZCB5b3UgZG9uJ3QgaGF2ZSB0b1xuICogbm90aWZ5IGFueW9uZSB3aGljaCBsaWNlbnNlIHlvdSBhcmUgdXNpbmcuIFlvdSBhcmUgZnJlZSB0byB1c2UgdGhpcyBjb2RlXG4gKiBpbiBjb21tZXJjaWFsIHByb2plY3RzIGFzIGxvbmcgYXMgdGhlIGNvcHlyaWdodCBoZWFkZXIgaXMgbGVmdCBpbnRhY3QuXG4gKiBTZWUgZmlsZXMgR1BMLUxJQ0VOU0UgYW5kIE1JVC1MSUNFTlNFIGZvciBkZXRhaWxzLlxuICpcbiAqIEBsaWNlbmNlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbmNlIDIuMCBvciBsYXRlclxuICogQGxpY2VuY2UgTUlUIExpY2Vuc2VcbiAqL1xuXG4oIGZ1bmN0aW9uICggJCApIHtcblx0J3VzZSBzdHJpY3QnO1xuXHR2YXIgc3Ryb25nRGlyUmVnRXhwO1xuXG5cdC8qKlxuXHQgKiBNYXRjaGVzIHRoZSBmaXJzdCBzdHJvbmcgZGlyZWN0aW9uYWxpdHkgY29kZXBvaW50OlxuXHQgKiAtIGluIGdyb3VwIDEgaWYgaXQgaXMgTFRSXG5cdCAqIC0gaW4gZ3JvdXAgMiBpZiBpdCBpcyBSVExcblx0ICogRG9lcyBub3QgbWF0Y2ggaWYgdGhlcmUgaXMgbm8gc3Ryb25nIGRpcmVjdGlvbmFsaXR5IGNvZGVwb2ludC5cblx0ICpcblx0ICogR2VuZXJhdGVkIGJ5IFVuaWNvZGVKUyAoc2VlIHRvb2xzL3N0cm9uZ0RpcikgZnJvbSB0aGUgVUNEOyBzZWVcblx0ICogaHR0cHM6Ly9waGFicmljYXRvci53aWtpbWVkaWEub3JnL2RpZmZ1c2lvbi9HVUpTLyAuXG5cdCAqL1xuXHRzdHJvbmdEaXJSZWdFeHAgPSBuZXcgUmVnRXhwKFxuXHRcdCcoPzonICtcblx0XHRcdCcoJyArXG5cdFx0XHRcdCdb
4060XFx1MDA0MS1cXHUwMDVhXFx1MDA2MS1cXHUwMDdhXFx1MDBhYVxcdTAwYjVcXHUwMGJhXFx1MDBjMC1cXHUwMGQ2XFx1MDBkOC1cXHUwMGY2XFx1MDBmOC1cXHUwMmI4XFx1MDJiYi1cXHUwMmMxXFx1MDJkMFxcdTAyZDFcXHUwMmUwLVxcdTAyZTRcXHUwMmVlXFx1MDM3MC1cXHUwMzczXFx1MDM3NlxcdTAzNzdcXHUwMzdhLVxcdTAzN2RcXHUwMzdmXFx1MDM4NlxcdTAzODgtXFx1MDM4YVxcdTAzOGNcXHUwMzhlLVxcdTAzYTFcXHUwM2EzLVxcdTAzZjVcXHUwM2Y3LVxcdTA0ODJcXHUwNDhhLVxcdTA1MmZcXHUwNTMxLVxcdTA1NTZcXHUwNTU5LVxcdTA1NWZcXHUwNTYxLVxcdTA1ODdcXHUwNTg5XFx1MDkwMy1cXHUwOTM5XFx1MDkzYlxcdTA5M2QtXFx1MDk0MFxcdTA5NDktXFx1MDk0Y1xcdTA5NGUtXFx1MDk1MFxcdTA5NTgtXFx1MDk2MVxcdTA5NjQtXFx1MDk4MFxcdTA5ODJcXHUwOTgzXFx1MDk4NS1cXHUwOThjXFx1MDk4ZlxcdTA5OTBcXHUwOTkzLVxcdTA5YThcXHUwOWFhLVxcdTA5YjBcXHUwOWIyXFx1MDliNi1cXHUwOWI5XFx1MDliZC1cXHUwOWMwXFx1MDljN1xcdTA5YzhcXHUwOWNiXFx1MDljY1xcdTA5Y2VcXHUwOWQ3XFx1MDlkY1xcdTA5ZGRcXHUwOWRmLVxcdTA5ZTFcXHUwOWU2LVxcdTA5ZjFcXHUwOWY0LVxcdTA5ZmFcXHUwYTAzXFx1MGEwNS1cXHUwYTBhXFx1MGEwZlxcdTBhMTBcXHUwYTEzLVxcdTBhMjhcXHUwYTJhLVxcdTBhMzBcXHUwYTMyXFx1MGEzM1xcdTBhMzVcXHUwYTM2XFx1MGEzOFxcdTBhMzlcXHUwYTNlLVxcdTBhNDBcXHUwYTU5LVxcdTBhNWNcXHUwYTVlXFx1MGE2Ni1cXHUwYTZmXFx1MGE3Mi1cXHUwYTc0XFx1MGE4M1xcdTBhODUtXFx1MGE4ZFxcdTBhOGYtXFx1MGE5MVxcdTBhOTMtXFx1MGFhOFxcdTBhYWEtXFx1MGFiMFxcdTBhYjJcXHUwYWIzXFx1MGFiNS1cXHUwYWI5XFx1MGFiZC1cXHUwYWMwXFx1MGFjOVxcdTBhY2JcXHUwYWNjXFx1MGFkMFxcdTBhZTBcXHUwYWUxXFx1MGFlNi1cXHUwYWYwXFx1MGFmOVxcdTBiMDJcXHUwYjAzXFx1MGIwNS1cXHUwYjBjXFx1MGIwZlxcdTBiMTBcXHUwYjEzLVxcdTBiMjhcXHUwYjJhLVxcdTBiMzBcXHUwYjMyXFx1MGIzM1xcdTBiMzUtXFx1MGIzOVxcdTBiM2RcXHUwYjNlXFx1MGI0MFxcdTBiNDdcXHUwYjQ4XFx1MGI0YlxcdTBiNGNcXHUwYjU3XFx1MGI1Y1xcdTBiNWRcXHUwYjVmLVxcdTBiNjFcXHUwYjY2LVxcdTBiNzdcXHUwYjgzXFx1MGI4NS1cXHUwYjhhXFx1MGI4ZS1cXHUwYjkwXFx1MGI5Mi1cXHUwYjk1XFx1MGI5OVxcdTBiOWFcXHUwYjljXFx1MGI5ZVxcdTBiOWZcXHUwYmEzXFx1MGJhNFxcdTBiYTgtXFx1MGJhYVxcdTBiYWUtXFx1MGJiOVxcdTBiYmVcXHUwYmJmXFx1MGJjMVxcdTBiYzJcXHUwYmM2LVxcdTBiYzhcXHUwYmNhLVxcdTBiY2NcXHUwYmQwXFx1MGJkN1xcdTBiZTYtXFx1MGJmMlxcdTBjMDEtXFx1MGMwM1xcdTBjMDUtXFx1MGMwY1xcdTBjMGUtXFx1MGMxMFxcdTBjMTItXFx1MGMyOFxcdTBjMmEtXFx1MGMzOVxcdTBjM2RcXHUwYzQxLVxcdTBjNDRcXHUwYzU4LVxcdTBjNWFcXHUwYzYwXFx1MGM2MVxcdTBjNjYtXFx1MGM2ZlxcdTBjN2ZcXHUwYzgyXFx1MGM4M1xcdTBjODUtXFx1MGM4Y1xcdTBjOGUtXFx1MGM5MFxcdTBjOTItXFx1MGNhOFxcdTBjYWEtXFx1MGNiM1xcdTBjYjUtXFx1MGNiOVxcdTBjYmQtXFx1MGNjNFxcdTBjYzYtXFx1MGNjOFxcdTBjY2FcXHUwY2NiXFx1MGNkNVxcdTBjZDZcXHUwY2RlXFx1MGNlMFxcdTBjZTFcXHUwY2U2LVxcdTBjZWZcXHUwY2YxXFx1MGNmMlxcdTBkMDJcXHUwZDAzXFx1MGQwNS1cXHUwZDBjXFx1MGQwZS1cXHUwZDEwXFx1MGQxMi1cXHUwZDNhXFx1MGQzZC1cXHUwZDQwXFx1MGQ0Ni1cXHUwZDQ4XFx1MGQ0YS1cXHUwZDRjXFx1MGQ0ZVxcdTBkNTdcXHUwZDVmLVxcdTBkNjFcXHUwZDY2LVxcdTBkNzVcXHUwZDc5LVxcdTBkN2ZcXHUwZDgyXFx1MGQ4M1xcdTBkODUtXFx1MGQ5NlxcdTBkOWEtXFx1MGRiMVxcdTBkYjMtXFx1MGRiYlxcdTBkYmRcXHUwZGMwLVxcdTBkYzZcXHUwZGNmLVxcdTBkZDFcXHUwZGQ4LVxcdTBkZGZcXHUwZGU2LVxcdTBkZWZcXHUwZGYyLVxcdTBkZjRcXHUwZTAxLVxcdTBlMzBcXHUwZTMyXFx1MGUzM1xcdTBlNDAtXFx1MGU0NlxcdTBlNGYtXFx1MGU1YlxcdTBlODFcXHUwZTgyXFx1MGU4NFxcdTBlODdcXHUwZTg4XFx1MGU4YVxcdTBlOGRcXHUwZTk0LVxcdTBlOTdcXHUwZTk5LVxcdTBlOWZcXHUwZWExLVxcdTBlYTNcXHUwZWE1XFx1MGVhN1xcdTBlYWFcXHUwZWFiXFx1MGVhZC1cXHUwZWIwXFx1MGViMlxcdTBlYjNcXHUwZWJkXFx1MGVjMC1cXHUwZWM0XFx1MGVjNlxcdTBlZDAtXFx1MGVkOVxcdTBlZGMtXFx1MGVkZlxcdTBmMDAtXFx1MGYxN1xcdTBmMWEtXFx1MGYzNFxcdTBmMzZcXHUwZjM4XFx1MGYzZS1cXHUwZjQ3XFx1MGY0OS1cXHUwZjZjXFx1MGY3ZlxcdTBmODVcXHUwZjg4LVxcdTBmOGNcXHUwZmJlLVxcdTBmYzVcXHUwZmM3LVxcdTBmY2NcXHUwZmNlLVxcdTBmZGFcXHUxMDAwLVxcdTEwMmNcXHUxMDMxXFx1MTAzOFxcdTEwM2JcXHUxMDNjXFx1MTAzZi1cXHUxMDU3XFx1MTA1YS1cXHUxMDVkXFx1MTA2MS1cXHUxMDcwXFx1MTA3NS1cXHUxMDgxXFx1MTA4M1xcdTEwODRcXHUxMDg3LVxcdTEwOGNcXHUxMDhlLVxcdTEwOWNcXHUxMDllLVxcdTEwYzVcXHUxMGM3XFx1MTBjZFxcdTEwZDAtXFx1MTI0OFxcdTEyNGEtXFx1MTI0ZFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVhLVxcdTEyNWRcXHUxMjYwLVxcdTEyODhcXHUxMjhhLVxcdTEyOGRcXHUxMjkwLVxcdTEyYjBcXHUxMmIyLVxcdTEyYjVcXHUxMmI4LVxcdTEyYmVcXHUxMmMwXFx1MTJjMi1cXHUxMmM1XFx1MTJjOC1cXHUxMmQ2XFx1MTJkOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVhXFx1MTM2MC1cXHUxMzdjXFx1MTM4MC1cXHUxMzhmXFx1MTNhMC1cXHUxM2Y1XFx1MTNmOC1cXHUxM2ZkXFx1MTQwMS1cXHUxNjdmXFx1MTY4MS1cXHUxNjlhXFx1MTZhMC1cXHUxNmY4XFx1MTcwMC1cXHUxNzBjXFx1MTcwZS1cXHUxNzExXFx1MTcyMC1cXHUxNzMxXFx1MTczNVxcdTE3MzZcXHUxNzQwLVxcdTE3NTFcXHUxNzYwLVxcdTE3NmNcXHUxNzZlLVxcdTE3NzBcXHUxNzgwLVxcdTE3YjNcXHUxN2I2XFx1MTdiZS1cXHUxN2M1XFx1MTdjN1xcdTE3YzhcXHUxN2Q0LVxcdTE3ZGFcXHUxN2RjXFx1MTdlMC1cXHUxN2U5XFx1MTgxMC1cXHUxODE5XFx1MTgyMC1cXHUxODc3XFx1MTg4MC1cXHUxOGE4XFx1MThhYVxcdTE4YjAtXFx1MThmNVxcdTE5MDAtXFx1MTkxZVxcdTE5MjMtXFx1MTkyNlxcdTE5MjktXFx1MTkyYlxcdTE5MzBcXHUxOTMxXFx1MTkzMy1cXHUxOTM4XFx1MTk0Ni1cXHUxOTZkXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOWFiXFx1MTliMC1cXHUxOWM5XFx1MTlkMC1cXHUxOWRhXFx1MWEwMC1cXHUxYTE2XFx1MWExOVxcdTFhMWFcXHUxYTFlLVxcdTFhNTVcXHUxYTU3XFx1MWE2MVxcdTFhNjNcXHUxYTY0XFx1MWE2ZC1cXHUxYTcyXFx1MWE4MC1cXHUxYTg5XFx1MWE5MC1cXHUxYTk5XFx1MWFhMC1cXHUxYWFkXFx1MWIwNC1cXHUxYjMzXFx1MWIzNVxcdTFiM2JcXHUxYjNkLVxcdTFiNDFcXHUxYjQzLVxcdTFiNGJcXHUxYjUwLVxcdTFiNmFcXHUxYjc0LVxcdTFiN2NcXHUxYjgyLVxcdTFiYTFcXHUxYmE2XFx1MWJhN1xcdTFiYWFcXHUxYmFlLVxcdTFiZTVcXHUxYmU3XFx1MWJlYS1cXHUxYmVjXFx1MWJlZVxcdTFiZjJcXHUxYmYzXFx1MWJmYy1cXHUxYzJiXFx1MWMzNFxcdTFjMzVcXHUxYzNiLVxcdTFjNDlcXHUxYzRkLVxcdTFjN2ZcXHUxY2MwLVxcdTFjYzdcXHUxY2QzXFx1MWNlMVxcdTFjZTktXFx1MWNlY1xcdTFjZWUtXFx1MWNmM1xcdTFjZjVcXHUxY2Y2XFx1MWQwMC1cXHUxZGJmXFx1MWUwMC1cXHUxZjE1XFx1MWYxOC1cXHUxZjFkXFx1MWYyMC1cXHUxZjQ1XFx1MWY0OC1cXHUxZjRkXFx1MWY
40601MC1cXHUxZjU3XFx1MWY1OVxcdTFmNWJcXHUxZjVkXFx1MWY1Zi1cXHUxZjdkXFx1MWY4MC1cXHUxZmI0XFx1MWZiNi1cXHUxZmJjXFx1MWZiZVxcdTFmYzItXFx1MWZjNFxcdTFmYzYtXFx1MWZjY1xcdTFmZDAtXFx1MWZkM1xcdTFmZDYtXFx1MWZkYlxcdTFmZTAtXFx1MWZlY1xcdTFmZjItXFx1MWZmNFxcdTFmZjYtXFx1MWZmY1xcdTIwMGVcXHUyMDcxXFx1MjA3ZlxcdTIwOTAtXFx1MjA5Y1xcdTIxMDJcXHUyMTA3XFx1MjEwYS1cXHUyMTEzXFx1MjExNVxcdTIxMTktXFx1MjExZFxcdTIxMjRcXHUyMTI2XFx1MjEyOFxcdTIxMmEtXFx1MjEyZFxcdTIxMmYtXFx1MjEzOVxcdTIxM2MtXFx1MjEzZlxcdTIxNDUtXFx1MjE0OVxcdTIxNGVcXHUyMTRmXFx1MjE2MC1cXHUyMTg4XFx1MjMzNi1cXHUyMzdhXFx1MjM5NVxcdTI0OWMtXFx1MjRlOVxcdTI2YWNcXHUyODAwLVxcdTI4ZmZcXHUyYzAwLVxcdTJjMmVcXHUyYzMwLVxcdTJjNWVcXHUyYzYwLVxcdTJjZTRcXHUyY2ViLVxcdTJjZWVcXHUyY2YyXFx1MmNmM1xcdTJkMDAtXFx1MmQyNVxcdTJkMjdcXHUyZDJkXFx1MmQzMC1cXHUyZDY3XFx1MmQ2ZlxcdTJkNzBcXHUyZDgwLVxcdTJkOTZcXHUyZGEwLVxcdTJkYTZcXHUyZGE4LVxcdTJkYWVcXHUyZGIwLVxcdTJkYjZcXHUyZGI4LVxcdTJkYmVcXHUyZGMwLVxcdTJkYzZcXHUyZGM4LVxcdTJkY2VcXHUyZGQwLVxcdTJkZDZcXHUyZGQ4LVxcdTJkZGVcXHUzMDA1LVxcdTMwMDdcXHUzMDIxLVxcdTMwMjlcXHUzMDJlXFx1MzAyZlxcdTMwMzEtXFx1MzAzNVxcdTMwMzgtXFx1MzAzY1xcdTMwNDEtXFx1MzA5NlxcdTMwOWQtXFx1MzA5ZlxcdTMwYTEtXFx1MzBmYVxcdTMwZmMtXFx1MzBmZlxcdTMxMDUtXFx1MzEyZFxcdTMxMzEtXFx1MzE4ZVxcdTMxOTAtXFx1MzFiYVxcdTMxZjAtXFx1MzIxY1xcdTMyMjAtXFx1MzI0ZlxcdTMyNjAtXFx1MzI3YlxcdTMyN2YtXFx1MzJiMFxcdTMyYzAtXFx1MzJjYlxcdTMyZDAtXFx1MzJmZVxcdTMzMDAtXFx1MzM3NlxcdTMzN2ItXFx1MzNkZFxcdTMzZTAtXFx1MzNmZVxcdTM0MDAtXFx1NGRiNVxcdTRlMDAtXFx1OWZkNVxcdWEwMDAtXFx1YTQ4Y1xcdWE0ZDAtXFx1YTYwY1xcdWE2MTAtXFx1YTYyYlxcdWE2NDAtXFx1YTY2ZVxcdWE2ODAtXFx1YTY5ZFxcdWE2YTAtXFx1YTZlZlxcdWE2ZjItXFx1YTZmN1xcdWE3MjItXFx1YTc4N1xcdWE3ODktXFx1YTdhZFxcdWE3YjAtXFx1YTdiN1xcdWE3ZjctXFx1YTgwMVxcdWE4MDMtXFx1YTgwNVxcdWE4MDctXFx1YTgwYVxcdWE4MGMtXFx1YTgyNFxcdWE4MjdcXHVhODMwLVxcdWE4MzdcXHVhODQwLVxcdWE4NzNcXHVhODgwLVxcdWE4YzNcXHVhOGNlLVxcdWE4ZDlcXHVhOGYyLVxcdWE4ZmRcXHVhOTAwLVxcdWE5MjVcXHVhOTJlLVxcdWE5NDZcXHVhOTUyXFx1YTk1M1xcdWE5NWYtXFx1YTk3Y1xcdWE5ODMtXFx1YTliMlxcdWE5YjRcXHVhOWI1XFx1YTliYVxcdWE5YmJcXHVhOWJkLVxcdWE5Y2RcXHVhOWNmLVxcdWE5ZDlcXHVhOWRlLVxcdWE5ZTRcXHVhOWU2LVxcdWE5ZmVcXHVhYTAwLVxcdWFhMjhcXHVhYTJmXFx1YWEzMFxcdWFhMzNcXHVhYTM0XFx1YWE0MC1cXHVhYTQyXFx1YWE0NC1cXHVhYTRiXFx1YWE0ZFxcdWFhNTAtXFx1YWE1OVxcdWFhNWMtXFx1YWE3YlxcdWFhN2QtXFx1YWFhZlxcdWFhYjFcXHVhYWI1XFx1YWFiNlxcdWFhYjktXFx1YWFiZFxcdWFhYzBcXHVhYWMyXFx1YWFkYi1cXHVhYWViXFx1YWFlZS1cXHVhYWY1XFx1YWIwMS1cXHVhYjA2XFx1YWIwOS1cXHVhYjBlXFx1YWIxMS1cXHVhYjE2XFx1YWIyMC1cXHVhYjI2XFx1YWIyOC1cXHVhYjJlXFx1YWIzMC1cXHVhYjY1XFx1YWI3MC1cXHVhYmU0XFx1YWJlNlxcdWFiZTdcXHVhYmU5LVxcdWFiZWNcXHVhYmYwLVxcdWFiZjlcXHVhYzAwLVxcdWQ3YTNcXHVkN2IwLVxcdWQ3YzZcXHVkN2NiLVxcdWQ3ZmJcXHVlMDAwLVxcdWZhNmRcXHVmYTcwLVxcdWZhZDlcXHVmYjAwLVxcdWZiMDZcXHVmYjEzLVxcdWZiMTdcXHVmZjIxLVxcdWZmM2FcXHVmZjQxLVxcdWZmNWFcXHVmZjY2LVxcdWZmYmVcXHVmZmMyLVxcdWZmYzdcXHVmZmNhLVxcdWZmY2ZcXHVmZmQyLVxcdWZmZDdcXHVmZmR
4060hLVxcdWZmZGNdfFxcdWQ4MDBbXFx1ZGMwMC1cXHVkYzBiXXxcXHVkODAwW1xcdWRjMGQtXFx1ZGMyNl18XFx1ZDgwMFtcXHVkYzI4LVxcdWRjM2FdfFxcdWQ4MDBcXHVkYzNjfFxcdWQ4MDBcXHVkYzNkfFxcdWQ4MDBbXFx1ZGMzZi1cXHVkYzRkXXxcXHVkODAwW1xcdWRjNTAtXFx1ZGM1ZF18XFx1ZDgwMFtcXHVkYzgwLVxcdWRjZmFdfFxcdWQ4MDBcXHVkZDAwfFxcdWQ4MDBcXHVkZDAyfFxcdWQ4MDBbXFx1ZGQwNy1cXHVkZDMzXXxcXHVkODAwW1xcdWRkMzctXFx1ZGQzZl18XFx1ZDgwMFtcXHVkZGQwLVxcdWRkZmNdfFxcdWQ4MDBbXFx1ZGU4MC1cXHVkZTljXXxcXHVkODAwW1xcdWRlYTAtXFx1ZGVkMF18XFx1ZDgwMFtcXHVkZjAwLVxcdWRmMjNdfFxcdWQ4MDBbXFx1ZGYzMC1cXHVkZjRhXXxcXHVkODAwW1xcdWRmNTAtXFx1ZGY3NV18XFx1ZDgwMFtcXHVkZjgwLVxcdWRmOWRdfFxcdWQ4MDBbXFx1ZGY5Zi1cXHVkZmMzXXxcXHVkODAwW1xcdWRmYzgtXFx1ZGZkNV18XFx1ZDgwMVtcXHVkYzAwLVxcdWRjOWRdfFxcdWQ4MDFbXFx1ZGNhMC1cXHVkY2E5XXxcXHVkODAxW1xcdWRkMDAtXFx1ZGQyN118XFx1ZDgwMVtcXHVkZDMwLVxcdWRkNjNdfFxcdWQ4MDFcXHVkZDZmfFxcdWQ4MDFbXFx1ZGUwMC1cXHVkZjM2XXxcXHVkODAxW1xcdWRmNDAtXFx1ZGY1NV18XFx1ZDgwMVtcXHVkZjYwLVxcdWRmNjddfFxcdWQ4MDRcXHVkYzAwfFxcdWQ4MDRbXFx1ZGMwMi1cXHVkYzM3XXxcXHVkODA0W1xcdWRjNDctXFx1ZGM0ZF18XFx1ZDgwNFtcXHVkYzY2LVxcdWRjNmZdfFxcdWQ4MDRbXFx1ZGM4Mi1cXHVkY2IyXXxcXHVkODA0XFx1ZGNiN3xcXHVkODA0XFx1ZGNiOHxcXHVkODA0W1xcdWRjYmItXFx1ZGNjMV18XFx1ZDgwNFtcXHVkY2QwLVxcdWRjZThdfFxcdWQ4MDRbXFx1ZGNmMC1cXHVkY2Y5XXxcXHVkODA0W1xcdWRkMDMtXFx1ZGQyNl18XFx1ZDgwNFxcdWRkMmN8XFx1ZDgwNFtcXHVkZDM2LVxcdWRkNDNdfFxcdWQ4MDRbXFx1ZGQ1MC1cXHVkZDcyXXxcXHVkODA0W1xcdWRkNzQtXFx1ZGQ3Nl18XFx1ZDgwNFtcXHVkZDgyLVxcdWRkYjVdfFxcdWQ4MDRbXFx1ZGRiZi1cXHVkZGM5XXxcXHVkODA0XFx1ZGRjZHxcXHVkODA0W1xcdWRkZDAtXFx1ZGRkZl18XFx1ZDgwNFtcXHVkZGUxLVxcdWRkZjRdfFxcdWQ4MDRbXFx1ZGUwMC1cXHVkZTExXXxcXHVkODA0W1xcdWRlMTMtXFx1ZGUyZV18XFx1ZDgwNFxcdWRlMzJ8XFx1ZDgwNFxcdWRlMzN8XFx1ZDgwNFxcdWRlMzV8XFx1ZDgwNFtcXHVkZTM4LVxcdWRlM2RdfFxcdWQ4MDRbXFx1ZGU4MC1cXHVkZTg2XXxcXHVkODA0XFx1ZGU4OHxcXHVkODA0W1xcdWRlOGEtXFx1ZGU4ZF18XFx1ZDgwNFtcXHVkZThmLVxcdWRlOWRdfFxcdWQ4MDRbXFx1ZGU5Zi1cXHVkZWE5XXxcXHVkODA0W1xcdWRlYjAtXFx1ZGVkZV18XFx1ZDgwNFtcXHVkZWUwLVxcdWRlZTJdfFxcdWQ4MDRbXFx1ZGVmMC1cXHVkZWY5XXxcXHVkODA0XFx1ZGYwMnxcXHVkODA0XFx1ZGYwM3xcXHVkODA0W1xcdWRmMDUtXFx1ZGYwY118XFx1ZDgwNFxcdWRmMGZ8XFx1ZDgwNFxcdWRmMTB8XFx1ZDgwNFtcXHVkZjEzLVxcdWRmMjhdfFxcdWQ4MDRbXFx1ZGYyYS1cXHVkZjMwXXxcXHVkODA0XFx1ZGYzMnxcXHVkODA0XFx1ZGYzM3xcXHVkODA0W1xcdWRmMzUtXFx1ZGYzOV18XFx1ZDgwNFtcXHVkZjNkLVxcdWRmM2ZdfFxcdWQ4MDRbXFx1ZGY0MS1cXHVkZjQ0XXxcXHVkODA0XFx1ZGY0N3xcXHVkODA0XFx1ZGY0OHxcXHVkODA0W1xcdWRmNGItXFx1ZGY0ZF18XFx1ZDgwNFxcdWRmNTB8XFx1ZDgwNFxcdWRmNTd8XFx1ZDgwNFtcXHVkZjVkLVxcdWRmNjNdfFxcdWQ4MDVbXFx1ZGM4MC1cXHVkY2IyXXxcXHVkODA1XFx1ZGNiOXxcXHVkODA1W1xcdWRjYmItXFx1ZGNiZV18XFx1ZDgwNVxcdWRjYzF8XFx1ZDgwNVtcXHVkY2M0LVxcdWRjYzddfFxcdWQ4MDVbXFx1ZGNkMC1cXHVkY2Q5XXxcXHVkODA1W1xcdWRkODAtXFx1ZGRiMV18XFx1ZDgwNVtcXHVkZGI4LVxcdWRkYmJdfFxcdWQ4MDVcXHVkZGJlfFxcdWQ4MDVbXFx1ZGRjMS1cXHVkZGRiXXxcXHVkODA1W1xcdWRlMDAtXFx1ZGUzMl18XFx1ZDgwNVxcdWRlM2J8XFx1ZDgwNVxcdWRlM2N8XFx1ZDgwNVxcdWRlM2V8XFx1ZDgwNVtcXHVkZTQxLVxcdWRlNDRdfFxcdWQ4MDVbXFx1ZGU1MC1cXHVkZTU5XXxcXHVkODA1W1xcdWRlODAtXFx1ZGVhYV18XFx1ZDgwNVxcdWRlYWN8XFx1ZDgwNVxcdWRlYWV8XFx1ZDgwNVxcdWRlYWZ8XFx1ZDgwNVxcdWRlYjZ8XFx1ZDgwNVtcXHVkZWMwLVxcdWRlYzldfFxcdWQ4MDVbXFx1ZGYwMC1cXHVkZjE5XXxcXHVkODA1XFx1ZGYyMHxcXHVkODA1XFx1ZGYyMXxcXHVkODA1XFx1ZGYyNnxcXHVkODA1W1xcdWRmMzAtXFx1ZGYzZl18XFx1ZDgwNltcXHVkY2EwLVxcdWRjZjJdfFxcdWQ4MDZcXHVkY2ZmfFxcdWQ4MDZbXFx1ZGVjMC1cXHVkZWY4XXxcXHVkODA4W1xcdWRjMDAtXFx1ZGY5OV18XFx1ZDgwOVtcXHVkYzAwLVxcdWRjNmVdfFxcdWQ4MDlbXFx1ZGM3MC1cXHVkYzc0XXxcXHVkODA5W1xcdWRjODAtXFx1ZGQ0M118XFx1ZDgwY1tcXHVkYzAwLVxcdWRmZmZdfFxcdWQ4MGRbXFx1ZGMwMC1cXHVkYzJlXXxcXHVkODExW1xcdWRjMDAtXFx1ZGU0Nl18XFx1ZDgxYVtcXHVkYzAwLVxcdWRlMzhdfFxcdWQ4MWFbXFx1ZGU0MC1cXHVkZTVlXXxcXHVkODFhW1xcdWRlNjAtXFx1ZGU2OV18XFx1ZDgxYVxcdWRlNmV8XFx1ZDgxYVxcdWRlNmZ8XFx1ZDgxYVtcXHVkZWQwLVxcdWRlZWRdfFxcdWQ4MWFcXHVkZWY1fFxcdWQ4MWFbXFx1ZGYwMC1cXHVkZjJmXXxcXHVkODFhW1xcdWRmMzctXFx1ZGY0NV18XFx1ZDgxYVtcXHVkZjUwLVxcdWRmNTldfFxcdWQ4MWFbXFx1ZGY1Yi1cXHVkZjYxXXxcXHVkODFhW1xcdWRmNjMtXFx1ZGY3N118XFx1ZDgxYVtcXHVkZjdkLVxcdWRmOGZdfFxcdWQ4MWJbXFx1ZGYwMC1cXHVkZjQ0XXxcXHVkODFiW1xcdWRmNTAtXFx1ZGY3ZV18XFx1ZDgxYltcXHVkZjkzLVxcdWRmOWZdfFxcdWQ4MmNcXHVkYzAwfFxcdWQ4MmNcXHVkYzAxfFxcdWQ4MmZbXFx1ZGMwMC1cXHVkYzZhXXxcXHVkODJmW1xcdWRjNzAtXFx1ZGM3Y118XFx1ZDgyZltcXHVkYzgwLVxcdWRjODhdfFxcdWQ4MmZbXFx1ZGM5MC1cXHVkYzk5XXxcXHVkODJmXFx1ZGM5Y3xcXHVkODJmXFx1ZGM5ZnxcXHVkODM0W1xcdWRjMDAtXFx1ZGNmNV18XFx1ZDgzNFtcXHVkZDAwLVxcdWRkMjZdfFxcdWQ4MzRbXFx1ZGQyOS1cXHVkZDY2XXxcXHVkODM0W1xcdWRkNmEtXFx1ZGQ3Ml18XFx1ZDgzNFxcdWRkODN8XFx1ZDgzNFxcdWRkODR8XFx1ZDgzNFtcXHVkZDhjLVxcdWRkYTldfFxcdWQ4MzRbXFx1ZGRhZS1cXHVkZGU4XXxcXHVkODM0W1xcdWRmNjAtXFx1ZGY3MV18XFx1ZDgzNVtcXHVkYzAwLVxcdWRjNTRdfFxcdWQ4MzVbXFx1ZGM1Ni1cXHVkYzljXXxcXHVkODM1XFx1ZGM5ZXxcXHVkODM1XFx1ZGM5ZnxcXHVkODM1XFx1ZGNhMnxcXHVkODM1XFx1ZGNhNXxcXHVkODM1XFx1ZGNhNnxcXHVkODM1W1xcdWRjYTktXFx1ZGNhY118XFx1ZDgzNVtcXHVkY2FlLVxcdWRjYjldfFxcdWQ4MzVcXHVkY2JifFxcdWQ4MzVbXFx1ZGNiZC1cXHVkY2MzXXxcXHVkODM1W1xcdWRjYzUt
4060XFx1ZGQwNV18XFx1ZDgzNVtcXHVkZDA3LVxcdWRkMGFdfFxcdWQ4MzVbXFx1ZGQwZC1cXHVkZDE0XXxcXHVkODM1W1xcdWRkMTYtXFx1ZGQxY118XFx1ZDgzNVtcXHVkZDFlLVxcdWRkMzldfFxcdWQ4MzVbXFx1ZGQzYi1cXHVkZDNlXXxcXHVkODM1W1xcdWRkNDAtXFx1ZGQ0NF18XFx1ZDgzNVxcdWRkNDZ8XFx1ZDgzNVtcXHVkZDRhLVxcdWRkNTBdfFxcdWQ4MzVbXFx1ZGQ1Mi1cXHVkZWE1XXxcXHVkODM1W1xcdWRlYTgtXFx1ZGVkYV18XFx1ZDgzNVtcXHVkZWRjLVxcdWRmMTRdfFxcdWQ4MzVbXFx1ZGYxNi1cXHVkZjRlXXxcXHVkODM1W1xcdWRmNTAtXFx1ZGY4OF18XFx1ZDgzNVtcXHVkZjhhLVxcdWRmYzJdfFxcdWQ4MzVbXFx1ZGZjNC1cXHVkZmNiXXxcXHVkODM2W1xcdWRjMDAtXFx1ZGRmZl18XFx1ZDgzNltcXHVkZTM3LVxcdWRlM2FdfFxcdWQ4MzZbXFx1ZGU2ZC1cXHVkZTc0XXxcXHVkODM2W1xcdWRlNzYtXFx1ZGU4M118XFx1ZDgzNltcXHVkZTg1LVxcdWRlOGJdfFxcdWQ4M2NbXFx1ZGQxMC1cXHVkZDJlXXxcXHVkODNjW1xcdWRkMzAtXFx1ZGQ2OV18XFx1ZDgzY1tcXHVkZDcwLVxcdWRkOWFdfFxcdWQ4M2NbXFx1ZGRlNi1cXHVkZTAyXXxcXHVkODNjW1xcdWRlMTAtXFx1ZGUzYV18XFx1ZDgzY1tcXHVkZTQwLVxcdWRlNDhdfFxcdWQ4M2NcXHVkZTUwfFxcdWQ4M2NcXHVkZTUxfFtcXHVkODQwLVxcdWQ4NjhdW1xcdWRjMDAtXFx1ZGZmZl18XFx1ZDg2OVtcXHVkYzAwLVxcdWRlZDZdfFxcdWQ4NjlbXFx1ZGYwMC1cXHVkZmZmXXxbXFx1ZDg2YS1cXHVkODZjXVtcXHVkYzAwLVxcdWRmZmZdfFxcdWQ4NmRbXFx1ZGMwMC1cXHVkZjM0XXxcXHVkODZkW1xcdWRmNDAtXFx1ZGZmZl18XFx1ZDg2ZVtcXHVkYzAwLVxcdWRjMWRdfFxcdWQ4NmVbXFx1ZGMyMC1cXHVkZmZmXXxbXFx1ZDg2Zi1cXHVkODcyXVtcXHVkYzAwLVxcdWRmZmZdfFxcdWQ4NzNbXFx1ZGMwMC1cXHVkZWExXXxcXHVkODdlW1xcdWRjMDAtXFx1ZGUxZF18W1xcdWRiODAtXFx1ZGJiZV1bXFx1ZGMwMC1cXHVkZmZmXXxcXHVkYmJmW1xcdWRjMDAtXFx1ZGZmZF18W1xcdWRiYzAtXFx1ZGJmZV1bXFx1ZGMwMC1cXHVkZmZmXXxcXHVkYmZmW1xcdWRjMDAtXFx1ZGZmZF0nICtcblx0XHRcdCcpfCgnICtcblx0XHRcdFx0J1tcXHUwNTkwXFx1MDViZVxcdTA1YzBcXHUwNWMzXFx1MDVjNlxcdTA1YzgtXFx1MDVmZlxcdTA3YzAtXFx1MDdlYVxcdTA3ZjRcXHUwN2Y1XFx1MDdmYS1cXHUwODE1XFx1MDgxYVxcdTA4MjRcXHUwODI4XFx1MDgyZS1cXHUwODU4XFx1MDg1Yy1cXHUwODlmXFx1MjAwZlxcdWZiMWRcXHVmYjFmLVxcdWZiMjhcXHVmYjJhLVxcdWZiNGZcXHUwNjA4XFx1MDYwYlxcdTA2MGRcXHUwNjFiLVxcdTA2NGFcXHUwNjZkLVxcdTA2NmZcXHUwNjcxLVxcdTA2ZDVcXHUwNmU1XFx1MDZlNlxcdTA2ZWVcXHUwNmVmXFx1MDZmYS1cXHUwNzEwXFx1MDcxMi1cXHUwNzJmXFx1MDc0Yi1cXHUwN2E1XFx1MDdiMS1cXHUwN2JmXFx1MDhhMC1cXHUwOGUyXFx1ZmI1MC1cXHVmZDNkXFx1ZmQ0MC1cXHVmZGNmXFx1ZmRmMC1cXHVmZGZjXFx1ZmRmZVxcdWZkZmZcXHVmZTcwLVxcdWZlZmVdfFxcdWQ4MDJbXFx1ZGMwMC1cXHVkZDFlXXxcXHVkODAyW1xcdWRkMjAtXFx1ZGUwMF18XFx1ZDgwMlxcdWRlMDR8XFx1ZDgwMltcXHVkZTA3LVxcdWRlMGJdfFxcdWQ4MDJbXFx1ZGUxMC1cXHVkZTM3XXxcXHVkODAyW1xcdWRlM2ItXFx1ZGUzZV18XFx1ZDgwMltcXHVkZTQwLVxcdWRlZTRdfFxcdWQ4MDJbXFx1ZGVlNy1cXHVkZjM4XXxcXHVkODAyW1xcdWRmNDAtXFx1ZGZmZl18XFx1ZDgwM1tcXHVkYzAwLVxcdWRlNWZdfFxcdWQ4MDNbXFx1ZGU3Zi1cXHVkZmZmXXxcXHVkODNhW1xcdWRjMDAtXFx1ZGNjZl18XFx1ZDgzYVtcXHVkY2Q3LVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGMwMC1cXHVkZGZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZjAwLVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGYwMC1cXHVkZmZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZjAwLVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGYwMC1cXHVkZmZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZjAwLVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGYwMC1cXHVkZmZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZjAwLVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGYwMC1cXHVkZmZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZTAwLVxcdWRlZWZdfFxcdWQ4M2JbXFx1ZGVmMi1cXHVkZWZmXScgK1xuXHRcdFx0JyknICtcblx0XHQnKSdcblx0KTtcblxuXHQvKipcblx0ICogR2V0cyBkaXJlY3Rpb25hbGl0eSBvZiB0aGUgZmlyc3Qgc3Ryb25nbHkgZGlyZWN0aW9uYWwgY29kZXBvaW50XG5cdCAqXG5cdCAqIFRoaXMgaXMgdGhlIHJ1bGUgdGhlIEJJREkgYWxnb3JpdGhtIHVzZXMgdG8gZGV0ZXJtaW5lIHRoZSBkaXJlY3Rpb25hbGl0eSBvZlxuXHQgKiBwYXJhZ3JhcGhzICggaHR0cDovL3VuaWNvZGUub3JnL3JlcG9ydHMvdHI5LyNUaGVfUGFyYWdyYXBoX0xldmVsICkgYW5kXG5cdCAqIEZTSSBpc29sYXRlcyAoIGh0dHA6Ly91bmljb2RlLm9yZy9yZXBvcnRzL3RyOS8jRXhwbGljaXRfRGlyZWN0aW9uYWxfSXNvbGF0ZXMgKS5cblx0ICpcblx0ICogVE9ETzogRG9lcyBub3QgaGFuZGxlIEJJREkgY29udHJvbCBjaGFyYWN0ZXJzIGluc2lkZSB0aGUgdGV4dC5cblx0ICogVE9ETzogRG9lcyBub3QgaGFuZGxlIHVuYWxsb2NhdGVkIGNoYXJhY3RlcnMuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRoZSB0ZXh0IGZyb20gd2hpY2ggdG8gZXh0cmFjdCBpbml0aWFsIGRpcmVjdGlvbmFsaXR5LlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IERpcmVjdGlvbmFsaXR5IChlaXRoZXIgJ2x0cicgb3IgJ3J0bCcpXG5cdCAqL1xuXHRmdW5jdGlvbiBzdHJvbmdEaXJGcm9tQ29udGVudCggdGV4dCApIHtcblx0XHR2YXIgbSA9IHRleHQubWF0Y2goIHN0cm9uZ0RpclJlZ0V4cCApO1xuXHRcdGlmICggIW0gKSB7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cdFx0aWYgKCBtWyAyIF0gPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybiAnbHRyJztcblx0XHR9XG5cdFx0cmV0dXJuICdydGwnO1xuXHR9XG5cblx0JC5leHRlbmQoICQuaTE4bi5wYXJzZXIuZW1pdHRlciwge1xuXHRcdC8qKlxuXHRcdCAqIFdyYXBzIGFyZ3VtZW50IHdpdGggdW5pY29kZSBjb250cm9sIGNoYXJhY3RlcnMgZm9yIGRpcmVjdGlvbmFsaXR5IHNhZmV0eVxuXHRcdCAqXG5cdFx0ICogVGhpcyBzb2x2ZXMgdGhlIHByb2JsZW0gd2hlcmUgZGlyZWN0aW9uYWxpdHktbmV1dHJhbCBjaGFyYWN0ZXJzIGF0IHRoZSBlZGdlIG9mXG5cdFx0ICogdGhlIGFyZ3VtZW50IHN0cmluZyBnZXQgaW50ZXJwcmV0ZWQgd2l0aCB0aGUgd3JvbmcgZGlyZWN0aW9uYWxpdHkgZnJvbSB0aGVcblx0XHQgKiBlbmNsb3NpbmcgY29udGV4dCwgZ2l2aW5nIHJlbmRlcmluZ3MgdGhhdCBsb29rIGNvcnJ1cHRlZCBsaWtlIFwiKEJlbl8oV01GXCIuXG5cdFx0ICpcblx0XHQgKiBUaGUgd3JhcHBpbmcgaXMgTFJFLi4uUERGIG9yIFJMRS4uLlBERiwgZGVwZW5kaW5nIG9uIHRoZSBkZXRlY3RlZFxuXHRcdCAqIGRpcmVjdGlvbmFsaXR5IG9mIHRoZSBhcmd1bWVudCBzdHJpbmcsIHVzaW5nIHRoZSBCSURJIGFsZ29yaXRobSdzIG93biBcIkZpcnN0XG5cdFx0ICogc3Ryb25nIGRpcmVjdGlvbmFsIGNvZGVwb2ludFwiIHJ1bGUuIEVzc2VudGlhbGx5LCB0aGlzIHdvcmtzIHJvdW5kIHRoZSBmYWN0IHRoYXRcblx0XHQgKiB0aGVyZSBpcyBubyBlbWJlZGRpbmcgZXF1aXZhbGVudCBvZiBVKzIwNjggRlNJIChpc29sYXRpb24gd2l0aCBoZXVyaXN0aWNcblx0XHQgKiBkaXJlY3Rpb24gaW5mZXJlbmNlKS4gVGhlIGxhdHRlciBpcyBjbGVhbmVyIGJ1dCBzdGlsbCBub3Qgd2lkZWx5IHN1cHBvcnRlZC5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nW119IG5vZGVzIFRoZSB0ZXh0IG5vZGVzIGZyb20gd2h
4060pY2ggdG8gdGFrZSB0aGUgZmlyc3QgaXRlbS5cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9IFdyYXBwZWQgU3RyaW5nIG9mIGNvbnRlbnQgYXMgbmVlZGVkLlxuXHRcdCAqL1xuXHRcdGJpZGk6IGZ1bmN0aW9uICggbm9kZXMgKSB7XG5cdFx0XHR2YXIgZGlyID0gc3Ryb25nRGlyRnJvbUNvbnRlbnQoIG5vZGVzWyAwIF0gKTtcblx0XHRcdGlmICggZGlyID09PSAnbHRyJyApIHtcblx0XHRcdFx0Ly8gV3JhcCBpbiBMRUZULVRPLVJJR0hUIEVNQkVERElORyAuLi4gUE9QIERJUkVDVElPTkFMIEZPUk1BVFRJTkdcblx0XHRcdFx0cmV0dXJuICdcXHUyMDJBJyArIG5vZGVzWyAwIF0gKyAnXFx1MjAyQyc7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGRpciA9PT0gJ3J0bCcgKSB7XG5cdFx0XHRcdC8vIFdyYXAgaW4gUklHSFQtVE8tTEVGVCBFTUJFRERJTkcgLi4uIFBPUCBESVJFQ1RJT05BTCBGT1JNQVRUSU5HXG5cdFx0XHRcdHJldHVybiAnXFx1MjAyQicgKyBub2Rlc1sgMCBdICsgJ1xcdTIwMkMnO1xuXHRcdFx0fVxuXHRcdFx0Ly8gTm8gc3Ryb25nIGRpcmVjdGlvbmFsaXR5OiBkbyBub3Qgd3JhcFxuXHRcdFx0cmV0dXJuIG5vZGVzWyAwIF07XG5cdFx0fVxuXHR9ICk7XG59KCBqUXVlcnkgKSApO1xuIiwiLyohXG4gKiBqUXVlcnkgSW50ZXJuYXRpb25hbGl6YXRpb24gbGlicmFyeVxuICpcbiAqIENvcHlyaWdodCAoQykgMjAxMS0yMDEzIFNhbnRob3NoIFRob3R0aW5nYWwsIE5laWwgS2FuZGFsZ2FvbmthclxuICpcbiAqIGpxdWVyeS5pMThuIGlzIGR1YWwgbGljZW5zZWQgR1BMdjIgb3IgbGF0ZXIgYW5kIE1JVC4gWW91IGRvbid0IGhhdmUgdG8gZG9cbiAqIGFueXRoaW5nIHNwZWNpYWwgdG8gY2hvb3NlIG9uZSBsaWNlbnNlIG9yIHRoZSBvdGhlciBhbmQgeW91IGRvbid0IGhhdmUgdG9cbiAqIG5vdGlmeSBhbnlvbmUgd2hpY2ggbGljZW5zZSB5b3UgYXJlIHVzaW5nLiBZb3UgYXJlIGZyZWUgdG8gdXNlXG4gKiBVbml2ZXJzYWxMYW5ndWFnZVNlbGVjdG9yIGluIGNvbW1lcmNpYWwgcHJvamVjdHMgYXMgbG9uZyBhcyB0aGUgY29weXJpZ2h0XG4gKiBoZWFkZXIgaXMgbGVmdCBpbnRhY3QuIFNlZSBmaWxlcyBHUEwtTElDRU5TRSBhbmQgTUlULUxJQ0VOU0UgZm9yIGRldGFpbHMuXG4gKlxuICogQGxpY2VuY2UgR05VIEdlbmVyYWwgUHVibGljIExpY2VuY2UgMi4wIG9yIGxhdGVyXG4gKiBAbGljZW5jZSBNSVQgTGljZW5zZVxuICovXG5cbiggZnVuY3Rpb24gKCAkICkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIE1lc3NhZ2VQYXJzZXJFbWl0dGVyID0gZnVuY3Rpb24gKCkge1xuXHRcdHRoaXMubGFuZ3VhZ2UgPSAkLmkxOG4ubGFuZ3VhZ2VzWyBTdHJpbmcubG9jYWxlIF0gfHwgJC5pMThuLmxhbmd1YWdlc1sgJ2RlZmF1bHQnIF07XG5cdH07XG5cblx0TWVzc2FnZVBhcnNlckVtaXR0ZXIucHJvdG90eXBlID0ge1xuXHRcdGNvbnN0cnVjdG9yOiBNZXNzYWdlUGFyc2VyRW1pdHRlcixcblxuXHRcdC8qKlxuXHRcdCAqIChXZSBwdXQgdGhpcyBtZXRob2QgZGVmaW5pdGlvbiBoZXJlLCBhbmQgbm90IGluIHByb3RvdHlwZSwgdG8gbWFrZVxuXHRcdCAqIHN1cmUgaXQncyBub3Qgb3ZlcndyaXR0ZW4gYnkgYW55IG1hZ2ljLikgV2FsayBlbnRpcmUgbm9kZSBzdHJ1Y3R1cmUsXG5cdFx0ICogYXBwbHlpbmcgcmVwbGFjZW1lbnRzIGFuZCB0ZW1wbGF0ZSBmdW5jdGlvbnMgd2hlbiBhcHByb3ByaWF0ZVxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtNaXhlZH0gbm9kZSBhYnN0cmFjdCBzeW50YXggdHJlZSAodG9wIG5vZGUgb3Igc3Vibm9kZSlcblx0XHQgKiBAcGFyYW0ge0FycmF5fSByZXBsYWNlbWVudHMgZm9yICQxLCAkMiwgLi4uICRuXG5cdFx0ICogQHJldHVybiB7TWl4ZWR9IHNpbmdsZS1zdHJpbmcgbm9kZSBvciBhcnJheSBvZiBub2RlcyBzdWl0YWJsZSBmb3Jcblx0XHQgKiAgalF1ZXJ5IGFwcGVuZGluZy5cblx0XHQgKi9cblx0XHRlbWl0OiBmdW5jdGlvbiAoIG5vZGUsIHJlcGxhY2VtZW50cyApIHtcblx0XHRcdHZhciByZXQsIHN1Ym5vZGVzLCBvcGVyYXRpb24sXG5cdFx0XHRcdG1lc3NhZ2VQYXJzZXJFbWl0dGVyID0gdGhpcztcblxuXHRcdFx0c3dpdGNoICggdHlwZW9mIG5vZGUgKSB7XG5cdFx0XHRcdGNhc2UgJ3N0cmluZyc6XG5cdFx0XHRcdGNhc2UgJ251bWJlcic6XG5cdFx0XHRcdFx0cmV0ID0gbm9kZTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnb2JqZWN0Jzpcblx0XHRcdFx0Ly8gbm9kZSBpcyBhbiBhcnJheSBvZiBub2Rlc1xuXHRcdFx0XHRcdHN1Ym5vZGVzID0gJC5tYXAoIG5vZGUuc2xpY2UoIDEgKSwgZnVuY3Rpb24gKCBuICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIG1lc3NhZ2VQYXJzZXJFbWl0dGVyLmVtaXQoIG4sIHJlcGxhY2VtZW50cyApO1xuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHRcdG9wZXJhdGlvbiA9IG5vZGVbIDAgXS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0XHRcdFx0aWYgKCB0eXBlb2YgbWVzc2FnZVBhcnNlckVtaXR0ZXJbIG9wZXJhdGlvbiBdID09PSAnZnVuY3Rpb24nICkge1xuXHRcdFx0XHRcdFx0cmV0ID0gbWVzc2FnZVBhcnNlckVtaXR0ZXJbIG9wZXJhdGlvbiBdKCBzdWJub2RlcywgcmVwbGFjZW1lbnRzICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvciggJ3Vua25vd24gb3BlcmF0aW9uIFwiJyArIG9wZXJhdGlvbiArICdcIicgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAndW5kZWZpbmVkJzpcblx0XHRcdFx0Ly8gUGFyc2luZyB0aGUgZW1wdHkgc3RyaW5nIChhcyBhbiBlbnRpcmUgZXhwcmVzc2lvbiwgb3IgYXMgYVxuXHRcdFx0XHQvLyBwYXJhbUV4cHJlc3Npb24gaW4gYSB0ZW1wbGF0ZSkgcmVzdWx0cyBpbiB1bmRlZmluZWRcblx0XHRcdFx0Ly8gUGVyaGFwcyBhIG1vcmUgY2xldmVyIHBhcnNlciBjYW4gZGV0ZWN0IHRoaXMsIGFuZCByZXR1cm4gdGhlXG5cdFx0XHRcdC8vIGVtcHR5IHN0cmluZz8gT3IgaXMgdGhhdCB1c2VmdWwgaW5mb3JtYXRpb24/XG5cdFx0XHRcdC8vIFRoZSBsb2dpY2FsIHRoaW5nIGlzIHByb2JhYmx5IHRvIHJldHVybi
4060B0aGUgZW1wdHkgc3RyaW5nIGhlcmVcblx0XHRcdFx0Ly8gd2hlbiB3ZSBlbmNvdW50ZXIgdW5kZWZpbmVkLlxuXHRcdFx0XHRcdHJldCA9ICcnO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdHRocm93IG5ldyBFcnJvciggJ3VuZXhwZWN0ZWQgdHlwZSBpbiBBU1Q6ICcgKyB0eXBlb2Ygbm9kZSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBQYXJzaW5nIGhhcyBiZWVuIGFwcGxpZWQgZGVwdGgtZmlyc3Qgd2UgY2FuIGFzc3VtZSB0aGF0IGFsbCBub2Rlc1xuXHRcdCAqIGhlcmUgYXJlIHNpbmdsZSBub2RlcyBNdXN0IHJldHVybiBhIHNpbmdsZSBub2RlIHRvIHBhcmVudHMgLS0gYVxuXHRcdCAqIGpRdWVyeSB3aXRoIHN5bnRoZXRpYyBzcGFuIEhvd2V2ZXIsIHVud3JhcCBhbnkgb3RoZXIgc3ludGhldGljIHNwYW5zXG5cdFx0ICogaW4gb3VyIGNoaWxkcmVuIGFuZCBwYXNzIHRoZW0gdXB3YXJkc1xuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtBcnJheX0gbm9kZXMgTWl4ZWQsIHNvbWUgc2luZ2xlIG5vZGVzLCBzb21lIGFycmF5cyBvZiBub2Rlcy5cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdFx0ICovXG5cdFx0Y29uY2F0OiBmdW5jdGlvbiAoIG5vZGVzICkge1xuXHRcdFx0dmFyIHJlc3VsdCA9ICcnO1xuXG5cdFx0XHQkLmVhY2goIG5vZGVzLCBmdW5jdGlvbiAoIGksIG5vZGUgKSB7XG5cdFx0XHRcdC8vIHN0cmluZ3MsIGludGVnZXJzLCBhbnl0aGluZyBlbHNlXG5cdFx0XHRcdHJlc3VsdCArPSBub2RlO1xuXHRcdFx0fSApO1xuXG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBSZXR1cm4gZXNjYXBlZCByZXBsYWNlbWVudCBvZiBjb3JyZWN0IGluZGV4LCBvciBzdHJpbmcgaWZcblx0XHQgKiB1bmF2YWlsYWJsZS4gTm90ZSB0aGF0IHdlIGV4cGVjdCB0aGUgcGFyc2VkIHBhcmFtZXRlciB0byBiZVxuXHRcdCAqIHplcm8tYmFzZWQuIGkuZS4gJDEgc2hvdWxkIGhhdmUgYmVjb21lIFsgMCBdLiBpZiB0aGUgc3BlY2lmaWVkXG5cdFx0ICogcGFyYW1ldGVyIGlzIG5vdCBmb3VuZCByZXR1cm4gdGhlIHNhbWUgc3RyaW5nIChlLmcuIFwiJDk5XCIgLT5cblx0XHQgKiBwYXJhbWV0ZXIgOTggLT4gbm90IGZvdW5kIC0+IHJldHVybiBcIiQ5OVwiICkgVE9ETyB0aHJvdyBlcnJvciBpZlxuXHRcdCAqIG5vZGVzLmxlbmd0aCA+IDEgP1xuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtBcnJheX0gbm9kZXMgT25lIGVsZW1lbnQsIGludGVnZXIsIG4gPj0gMFxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IHJlcGxhY2VtZW50cyBmb3IgJDEsICQyLCAuLi4gJG5cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9IHJlcGxhY2VtZW50XG5cdFx0ICovXG5cdFx0cmVwbGFjZTogZnVuY3Rpb24gKCBub2RlcywgcmVwbGFjZW1lbnRzICkge1xuXHRcdFx0dmFyIGluZGV4ID0gcGFyc2VJbnQoIG5vZGVzWyAwIF0sIDEwICk7XG5cblx0XHRcdGlmICggaW5kZXggPCByZXBsYWNlbWVudHMubGVuZ3RoICkge1xuXHRcdFx0XHQvLyByZXBsYWNlbWVudCBpcyBub3QgYSBzdHJpbmcsIGRvbid0IHRvdWNoIVxuXHRcdFx0XHRyZXR1cm4gcmVwbGFjZW1lbnRzWyBpbmRleCBdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gaW5kZXggbm90IGZvdW5kLCBmYWxsYmFjayB0byBkaXNwbGF5aW5nIHZhcmlhYmxlXG5cdFx0XHRcdHJldHVybiAnJCcgKyAoIGluZGV4ICsgMSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBUcmFuc2Zvcm0gcGFyc2VkIHN0cnVjdHVyZSBpbnRvIHBsdXJhbGl6YXRpb24gbi5iLiBUaGUgZmlyc3Qgbm9kZSBtYXlcblx0XHQgKiBiZSBhIG5vbi1pbnRlZ2VyIChmb3IgaW5zdGFuY2UsIGEgc3RyaW5nIHJlcHJlc2VudGluZyBhbiBBcmFiaWNcblx0XHQgKiBudW1iZXIpLiBTbyBjb252ZXJ0IGl0IGJhY2sgd2l0aCB0aGUgY3VycmVudCBsYW5ndWFnZSdzXG5cdFx0ICogY29udmVydE51bWJlci5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IG5vZGVzIExpc3QgWyB7U3RyaW5nfE51bWJlcn0sIHtTdHJpbmd9LCB7U3RyaW5nfSAuLi4gXVxuXHRcdCAqIEByZXR1cm4ge3N0cmluZ30gc2VsZWN0ZWQgcGx1cmFsaXplZCBmb3JtIGFjY29yZGluZyB0byBjdXJyZW50XG5cdFx0ICogIGxhbmd1YWdlLlxuXHRcdCAqL1xuXHRcdHBsdXJhbDogZnVuY3Rpb24gKCBub2RlcyApIHtcblx0XHRcdHZhciBjb3VudCA9IHBhcnNlRmxvYXQoIHRoaXMubGFuZ3VhZ2UuY29udmVydE51bWJlciggbm9kZXNbIDAgXSwgMTAgKSApLFxuXHRcdFx0XHRmb3JtcyA9IG5vZGVzLnNsaWNlKCAxICk7XG5cblx0XHRcdHJldHVybiBmb3Jtcy5sZW5ndGggPyB0aGlzLmxhbmd1YWdlLmNvbnZlcnRQbHVyYWwoIGNvdW50LCBmb3JtcyApIDogJyc7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFRyYW5zZm9ybSBwYXJzZWQgc3RydWN0dXJlIGludG8gZ2VuZGVyIFVzYWdlXG5cdFx0ICoge3tnZW5kZXI6Z2VuZGVyfG1hc2N1bGluZXxmZW1pbmluZXxuZXV0cmFsfX0uXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge0FycmF5fSBub2RlcyBMaXN0IFsge1N0cmluZ30sIHtTdHJpbmd9LCB7U3RyaW5nfSAsIHtTdHJpbmd9IF1cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9IHNlbGVjdGVkIGdlbmRlciBmb3JtIGFjY29yZGluZyB0byBjdXJyZW50IGxhbmd1YWdlXG5cdFx0ICovXG5cdFx0Z2VuZGVyOiBmdW5jdGlvbiAoIG5vZGVzICkge1xuXHRcdFx0dmFyIGdlbmRlciA9IG5vZGVzWyAwIF0sXG5cdFx0XHRcdGZvcm1zID0gbm9kZXMuc2xpY2UoIDEgKTtcblxuXHRcdFx0cmV0dXJuIHRoaXMubGFuZ3VhZ2UuZ2VuZGVyKCBnZW5kZXIsIGZvcm1zICk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFRyYW5zZm9ybSBwYXJzZWQgc3RydWN0dXJlIGludG8gZ3JhbW1hciBjb252ZXJzaW9uLiBJbnZva2VkIGJ5XG5cdFx0ICogcHV0dGluZyB7e2dyYW1tYXI6Zm9ybXx3b3JkfX0gaW4gYSBtZXNzYWdlXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge0FycmF5fSBub2RlcyBMaXN0IFt7R3JhbW1hciBjYXNlIGVnOiBnZW5pdGl2ZX0sIHtTdHJpbmcgd29yZH1dXG5cdFx0ICogQHJldHVybi
4060B7c3RyaW5nfSBzZWxlY3RlZCBncmFtbWF0aWNhbCBmb3JtIGFjY29yZGluZyB0byBjdXJyZW50XG5cdFx0ICogIGxhbmd1YWdlLlxuXHRcdCAqL1xuXHRcdGdyYW1tYXI6IGZ1bmN0aW9uICggbm9kZXMgKSB7XG5cdFx0XHR2YXIgZm9ybSA9IG5vZGVzWyAwIF0sXG5cdFx0XHRcdHdvcmQgPSBub2Rlc1sgMSBdO1xuXG5cdFx0XHRyZXR1cm4gd29yZCAmJiBmb3JtICYmIHRoaXMubGFuZ3VhZ2UuY29udmVydEdyYW1tYXIoIHdvcmQsIGZvcm0gKTtcblx0XHR9XG5cdH07XG5cblx0JC5leHRlbmQoICQuaTE4bi5wYXJzZXIuZW1pdHRlciwgbmV3IE1lc3NhZ2VQYXJzZXJFbWl0dGVyKCkgKTtcbn0oIGpRdWVyeSApICk7XG4iLCIvKiFcbiAqIGpRdWVyeSBJbnRlcm5hdGlvbmFsaXphdGlvbiBsaWJyYXJ5XG4gKlxuICogQ29weXJpZ2h0IChDKSAyMDEyIFNhbnRob3NoIFRob3R0aW5nYWxcbiAqXG4gKiBqcXVlcnkuaTE4biBpcyBkdWFsIGxpY2Vuc2VkIEdQTHYyIG9yIGxhdGVyIGFuZCBNSVQuIFlvdSBkb24ndCBoYXZlIHRvIGRvIGFueXRoaW5nIHNwZWNpYWwgdG9cbiAqIGNob29zZSBvbmUgbGljZW5zZSBvciB0aGUgb3RoZXIgYW5kIHlvdSBkb24ndCBoYXZlIHRvIG5vdGlmeSBhbnlvbmUgd2hpY2ggbGljZW5zZSB5b3UgYXJlIHVzaW5nLlxuICogWW91IGFyZSBmcmVlIHRvIHVzZSBVbml2ZXJzYWxMYW5ndWFnZVNlbGVjdG9yIGluIGNvbW1lcmNpYWwgcHJvamVjdHMgYXMgbG9uZyBhcyB0aGUgY29weXJpZ2h0XG4gKiBoZWFkZXIgaXMgbGVmdCBpbnRhY3QuIFNlZSBmaWxlcyBHUEwtTElDRU5TRSBhbmQgTUlULUxJQ0VOU0UgZm9yIGRldGFpbHMuXG4gKlxuICogQGxpY2VuY2UgR05VIEdlbmVyYWwgUHVibGljIExpY2VuY2UgMi4wIG9yIGxhdGVyXG4gKiBAbGljZW5jZSBNSVQgTGljZW5zZVxuICovXG4oIGZ1bmN0aW9uICggJCApIHtcblx0J3VzZSBzdHJpY3QnO1xuXG5cdCQuaTE4biA9ICQuaTE4biB8fCB7fTtcblx0JC5leHRlbmQoICQuaTE4bi5mYWxsYmFja3MsIHtcblx0XHRhYjogWyAncnUnIF0sXG5cdFx0YWNlOiBbICdpZCcgXSxcblx0XHRhbG46IFsgJ3NxJyBdLFxuXHRcdC8vIE5vdCBzbyBzdGFuZGFyZCAtIGFscyBpcyBzdXBwb3NlZCB0byBiZSBUb3NrIEFsYmFuaWFuLFxuXHRcdC8vIGJ1dCBpbiBXaWtpcGVkaWEgaXQncyB1c2VkIGZvciBhIEdlcm1hbmljIGxhbmd1YWdlLlxuXHRcdGFsczogWyAnZ3N3JywgJ2RlJyBdLFxuXHRcdGFuOiBbICdlcycgXSxcblx0XHRhbnA6IFsgJ2hpJyBdLFxuXHRcdGFybjogWyAnZXMnIF0sXG5cdFx0YXJ6OiBbICdhcicgXSxcblx0XHRhdjogWyAncnUnIF0sXG5cdFx0YXk6IFsgJ2VzJyBdLFxuXHRcdGJhOiBbICdydScgXSxcblx0XHRiYXI6IFsgJ2RlJyBdLFxuXHRcdCdiYXQtc21nJzogWyAnc2dzJywgJ2x0JyBdLFxuXHRcdGJjYzogWyAnZmEnIF0sXG5cdFx0J2JlLXgtb2xkJzogWyAnYmUtdGFyYXNrJyBdLFxuXHRcdGJoOiBbICdiaG8nIF0sXG5cdFx0YmpuOiBbICdpZCcgXSxcblx0XHRibTogWyAnZnInIF0sXG5cdFx0YnB5OiBbICdibicgXSxcblx0XHRicWk6IFsgJ2ZhJyBdLFxuXHRcdGJ1ZzogWyAnaWQnIF0sXG5cdFx0J2Niay16YW0nOiBbICdlcycgXSxcblx0XHRjZTogWyAncnUnIF0sXG5cdFx0Y3JoOiBbICdjcmgtbGF0bicgXSxcblx0XHQnY3JoLWN5cmwnOiBbICdydScgXSxcblx0XHRjc2I6IFsgJ3BsJyBdLFxuXHRcdGN2OiBbICdydScgXSxcblx0XHQnZGUtYXQnOiBbICdkZScgXSxcblx0XHQnZGUtY2gnOiBbICdkZScgXSxcblx0XHQnZGUtZm9ybWFsJzogWyAnZGUnIF0sXG5cdFx0ZHNiOiBbICdkZScgXSxcblx0XHRkdHA6IFsgJ21zJyBdLFxuXHRcdGVnbDogWyAnaXQnIF0sXG5cdFx0ZW1sOiBbICdpdCcgXSxcblx0XHRmZjogWyAnZnInIF0sXG5cdFx0Zml0OiBbICdmaScgXSxcblx0XHQnZml1LXZybyc6IFsgJ3ZybycsICdldCcgXSxcblx0XHRmcmM6IFsgJ2ZyJyBdLFxuXHRcdGZycDogWyAnZnInIF0sXG5cdFx0ZnJyOiBbICdkZScgXSxcblx0XHRmdXI6IFsgJ2l0JyBdLFxuXHRcdGdhZzogWyAndHInIF0sXG5cdFx0Z2FuOiBbICdnYW4taGFudCcsICd6aC1oYW50JywgJ3poLWhhbnMnIF0sXG5cdFx0J2dhbi1oYW5zJzogWyAnemgtaGFucycgXSxcblx0XHQnZ2FuLWhhbnQnOiBbICd6aC1oYW50JywgJ3poLWhhbnMnIF0sXG5cdFx0Z2w6IFsgJ3B0JyBdLFxuXHRcdGdsazogWyAnZmEnIF0sXG5cdFx0Z246IFsgJ2VzJyBdLFxuXHRcdGdzdzogWyAnZGUnIF0sXG5cdFx0aGlmOiBbICdoaWYtbGF0bicgXSxcblx0XHRoc2I6IFsgJ2RlJyBdLFxuXHRcdGh0OiBbICdmcicgXSxcblx0XHRpaTogWyAnemgtY24nLCAnemgtaGFucycgXSxcblx0XHRpbmg6IFsgJ3J1JyBdLFxuXHRcdGl1OiBbICdpa2UtY2FucycgXSxcblx0XHRqdXQ6IFsgJ2RhJyBdLFxuXHRcdGp2OiBbICdpZCcgXSxcblx0XHRrYWE6IFsgJ2trLWxhdG4nLCAna2stY3lybCcgXSxcblx0XHRrYmQ6IFsgJ2tiZC1jeXJsJyBdLFxuXHRcdGtodzogWyAndXInIF0sXG5cdFx0a2l1OiBbICd0cicgXSxcblx0XHRrazogWyAna2stY3lybCcgXSxcblx0XHQna2stYXJhYic6IFsgJ2trLWN5cmwnIF0sXG5cdFx0J2trLWxhdG4nOiBbICdray1jeXJsJyBdLFxuXHRcdCdray1jbic6IFsgJ2trLWFyYWInLCAna2stY3lybCcgXSxcblx0XHQna2sta3onOiBbICdray1jeXJsJyBdLFxuXHRcdCdray10cic6IFsgJ2trLWxhdG4nLCAna2stY3lybCcgXSxcblx0XHRrbDogWyAnZGEnIF0sXG5cdFx0J2tvLWtwJzogWyAna28nIF0sXG5cdFx0a29pOiBbICdydScgXSxcblx0XHRrcmM6IFsgJ3J1JyBdLFxuXHRcdGtzOiBbICdrcy1hcmFiJyBdLFxuXHRcdGtzaDogWyAnZGUnIF0sXG5cdFx0a3U6IFsgJ2t1LWxhdG4nIF0sXG5cdFx0J2t1LWFyYWInOiBbICdja2InIF0sXG5cdFx0a3Y6IFsgJ3J1JyBdLFxuXHRcdGxhZDogWyAnZXMnIF0sXG5cdFx0bGI6IFsgJ2RlJyBdLFxuXHRcdGxiZTogWyAncnUnIF0sXG5cdFx0bGV6OiBbICdydScgXSxcblx0XHRsaTogWyAnbmwnIF0sXG5cdFx0bGlqOiBbICdpdCcgXSxcblx0XHRsaXY6IFsgJ2V0JyBdLFxuXHRcdGxtbzogWyAnaXQnIF0sXG5cdFx0bG46IFsgJ2ZyJyBdLFxuXHRcdGx0ZzogWyAnbHYnIF0sXG5cdFx0bHp6OiBbICd0cicgXSxcblx0XHRtYWk6IFsgJ2hpJyBdLFxuXHRcdCdtYXAtYm1zJzogW
4060yAnanYnLCAnaWQnIF0sXG5cdFx0bWc6IFsgJ2ZyJyBdLFxuXHRcdG1ocjogWyAncnUnIF0sXG5cdFx0bWluOiBbICdpZCcgXSxcblx0XHRtbzogWyAncm8nIF0sXG5cdFx0bXJqOiBbICdydScgXSxcblx0XHRtd2w6IFsgJ3B0JyBdLFxuXHRcdG15djogWyAncnUnIF0sXG5cdFx0bXpuOiBbICdmYScgXSxcblx0XHRuYWg6IFsgJ2VzJyBdLFxuXHRcdG5hcDogWyAnaXQnIF0sXG5cdFx0bmRzOiBbICdkZScgXSxcblx0XHQnbmRzLW5sJzogWyAnbmwnIF0sXG5cdFx0J25sLWluZm9ybWFsJzogWyAnbmwnIF0sXG5cdFx0bm86IFsgJ25iJyBdLFxuXHRcdG9zOiBbICdydScgXSxcblx0XHRwY2Q6IFsgJ2ZyJyBdLFxuXHRcdHBkYzogWyAnZGUnIF0sXG5cdFx0cGR0OiBbICdkZScgXSxcblx0XHRwZmw6IFsgJ2RlJyBdLFxuXHRcdHBtczogWyAnaXQnIF0sXG5cdFx0cHQ6IFsgJ3B0LWJyJyBdLFxuXHRcdCdwdC1icic6IFsgJ3B0JyBdLFxuXHRcdHF1OiBbICdlcycgXSxcblx0XHRxdWc6IFsgJ3F1JywgJ2VzJyBdLFxuXHRcdHJnbjogWyAnaXQnIF0sXG5cdFx0cm15OiBbICdybycgXSxcblx0XHQncm9hLXJ1cCc6IFsgJ3J1cCcgXSxcblx0XHRydWU6IFsgJ3VrJywgJ3J1JyBdLFxuXHRcdHJ1cTogWyAncnVxLWxhdG4nLCAncm8nIF0sXG5cdFx0J3J1cS1jeXJsJzogWyAnbWsnIF0sXG5cdFx0J3J1cS1sYXRuJzogWyAncm8nIF0sXG5cdFx0c2E6IFsgJ2hpJyBdLFxuXHRcdHNhaDogWyAncnUnIF0sXG5cdFx0c2NuOiBbICdpdCcgXSxcblx0XHRzZzogWyAnZnInIF0sXG5cdFx0c2dzOiBbICdsdCcgXSxcblx0XHRzbGk6IFsgJ2RlJyBdLFxuXHRcdHNyOiBbICdzci1lYycgXSxcblx0XHRzcm46IFsgJ25sJyBdLFxuXHRcdHN0cTogWyAnZGUnIF0sXG5cdFx0c3U6IFsgJ2lkJyBdLFxuXHRcdHN6bDogWyAncGwnIF0sXG5cdFx0dGN5OiBbICdrbicgXSxcblx0XHR0ZzogWyAndGctY3lybCcgXSxcblx0XHR0dDogWyAndHQtY3lybCcsICdydScgXSxcblx0XHQndHQtY3lybCc6IFsgJ3J1JyBdLFxuXHRcdHR5OiBbICdmcicgXSxcblx0XHR1ZG06IFsgJ3J1JyBdLFxuXHRcdHVnOiBbICd1Zy1hcmFiJyBdLFxuXHRcdHVrOiBbICdydScgXSxcblx0XHR2ZWM6IFsgJ2l0JyBdLFxuXHRcdHZlcDogWyAnZXQnIF0sXG5cdFx0dmxzOiBbICdubCcgXSxcblx0XHR2bWY6IFsgJ2RlJyBdLFxuXHRcdHZvdDogWyAnZmknIF0sXG5cdFx0dnJvOiBbICdldCcgXSxcblx0XHR3YTogWyAnZnInIF0sXG5cdFx0d286IFsgJ2ZyJyBdLFxuXHRcdHd1dTogWyAnemgtaGFucycgXSxcblx0XHR4YWw6IFsgJ3J1JyBdLFxuXHRcdHhtZjogWyAna2EnIF0sXG5cdFx0eWk6IFsgJ2hlJyBdLFxuXHRcdHphOiBbICd6aC1oYW5zJyBdLFxuXHRcdHplYTogWyAnbmwnIF0sXG5cdFx0emg6IFsgJ3poLWhhbnMnIF0sXG5cdFx0J3poLWNsYXNzaWNhbCc6IFsgJ2x6aCcgXSxcblx0XHQnemgtY24nOiBbICd6aC1oYW5zJyBdLFxuXHRcdCd6aC1oYW50JzogWyAnemgtaGFucycgXSxcblx0XHQnemgtaGsnOiBbICd6aC1oYW50JywgJ3poLWhhbnMnIF0sXG5cdFx0J3poLW1pbi1uYW4nOiBbICduYW4nIF0sXG5cdFx0J3poLW1vJzogWyAnemgtaGsnLCAnemgtaGFudCcsICd6aC1oYW5zJyBdLFxuXHRcdCd6aC1teSc6IFsgJ3poLXNnJywgJ3poLWhhbnMnIF0sXG5cdFx0J3poLXNnJzogWyAnemgtaGFucycgXSxcblx0XHQnemgtdHcnOiBbICd6aC1oYW50JywgJ3poLWhhbnMnIF0sXG5cdFx0J3poLXl1ZSc6IFsgJ3l1ZScgXVxuXHR9ICk7XG59KCBqUXVlcnkgKSApO1xuIiwiLyohXG4gKiBqUXVlcnkgSW50ZXJuYXRpb25hbGl6YXRpb24gbGlicmFyeVxuICpcbiAqIENvcHlyaWdodCAoQykgMjAxMiBTYW50aG9zaCBUaG90dGluZ2FsXG4gKlxuICoganF1ZXJ5LmkxOG4gaXMgZHVhbCBsaWNlbnNlZCBHUEx2MiBvciBsYXRlciBhbmQgTUlULiBZb3UgZG9uJ3QgaGF2ZSB0byBkb1xuICogYW55dGhpbmcgc3BlY2lhbCB0byBjaG9vc2Ugb25lIGxpY2Vuc2Ugb3IgdGhlIG90aGVyIGFuZCB5b3UgZG9uJ3QgaGF2ZSB0b1xuICogbm90aWZ5IGFueW9uZSB3aGljaCBsaWNlbnNlIHlvdSBhcmUgdXNpbmcuIFlvdSBhcmUgZnJlZSB0byB1c2VcbiAqIFVuaXZlcnNhbExhbmd1YWdlU2VsZWN0b3IgaW4gY29tbWVyY2lhbCBwcm9qZWN0cyBhcyBsb25nIGFzIHRoZSBjb3B5cmlnaHRcbiAqIGhlYWRlciBpcyBsZWZ0IGludGFjdC4gU2VlIGZpbGVzIEdQTC1MSUNFTlNFIGFuZCBNSVQtTElDRU5TRSBmb3IgZGV0YWlscy5cbiAqXG4gKiBAbGljZW5jZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5jZSAyLjAgb3IgbGF0ZXJcbiAqIEBsaWNlbmNlIE1JVCBMaWNlbnNlXG4gKi9cblxuKCBmdW5jdGlvbiAoICQgKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuXHR2YXIgSTE4Tixcblx0XHRzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcblx0LyoqXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuXHQgKi9cblx0STE4TiA9IGZ1bmN0aW9uICggb3B0aW9ucyApIHtcblx0XHQvLyBMb2FkIGRlZmF1bHRzXG5cdFx0dGhpcy5vcHRpb25zID0gJC5leHRlbmQoIHt9LCBJMThOLmRlZmF1bHRzLCBvcHRpb25zICk7XG5cblx0XHR0aGlzLnBhcnNlciA9IHRoaXMub3B0aW9ucy5wYXJzZXI7XG5cdFx0dGhpcy5sb2NhbGUgPSB0aGlzLm9wdGlvbnMubG9jYWxlO1xuXHRcdHRoaXMubWVzc2FnZVN0b3JlID0gdGhpcy5vcHRpb25zLm1lc3NhZ2VTdG9yZTtcblx0XHR0aGlzLmxhbmd1YWdlcyA9IHt9O1xuXHR9O1xuXG5cdEkxOE4ucHJvdG90eXBlID0ge1xuXHRcdC8qKlxuXHRcdCAqIExvY2FsaXplIGEgZ2l2ZW4gbWVzc2FnZUtleSB0byBhIGxvY2FsZS5cblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZUtleVxuXHRcdCAqIEByZXR1cm4ge1N0cmluZ30gTG9jYWxpemVkIG1lc3NhZ2Vcblx0XHQgKi9cblx0XHRsb2NhbGl6ZTogZnVuY3Rpb24gKCBtZXNzYWdlS2V5ICkge1xuXHRcdFx0dmFyIGxvY2FsZVBhcnRzLCBsb2NhbGVQYXJ0SW5kZXgsIGxvY2FsZSwgZmFsbGJhY2tJbmRleCxcblx0XHRcdFx0dHJ5aW5nTG9jYWxlLCBtZXNzYWdlO1xuXG5cdFx0XHRsb2NhbGUgPSB0aGlzLmxvY2FsZTtcblx0XHRcdGZhbGxiYWNrSW5kZXggPSAwO1xuXG5cdFx0XHR3aGlsZSAoIGxvY2FsZSApIHtcblx0XHRcdFx0Ly8gSXRlcmF0ZSB0aHJvdWdoIGxvY2FsZXMgc3RhcnRpbmcgYXQgbW9zdC1zcGVjaWZpYyB1bnRpbFxuXHRcdFx0XHQvLyBsb2NhbGl6YXRpb24gaXMgZm91bmQuIEFzIGluIGZpLUxhdG4tRkksIGZpLUxhdG4gYW5kIGZpLlxuXHRcdFx0XHRsb2NhbGVQYXJ0cyA9IGxvY2FsZS5zcGxpdCggJy0nICk7XG5cdFx0XHRcdGxvY2FsZVBhcnRJbmRleCA9IGxvY2FsZVBhcnRzLmxlbmd0aDtcblxuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0dHJ5aW5nTG9jYWxlID0gbG9jYWxlUGFydHMuc2xpY2UoIDAsIGxvY2FsZVBhcnRJbmRleCApLmpvaW4oICctJyApO1xuXHRcdFx0XHRcdG1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VTdG9yZS5nZXQoIHRyeWluZ0xvY2FsZSwgbWVzc2FnZUtleSApO1xuXG5cdFx0XHRcdFx0aWYgKCBtZXNzYWdlICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIG1lc3NhZ2U7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0bG9jYWxlUGFydEluZGV4LS07XG5cdFx0XHRcdH0gd2hpbGUgKCBsb2NhbGVQYXJ0SW5kZXggKTtcblxuXHRcdFx0XHRpZiAoIGxvY2FsZSA9PT0gJ2VuJyApIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGxvY2FsZSA9ICggJC5pMThuLmZhbGxiYWNrc1sgdGh
4060pcy5sb2NhbGUgXSAmJlxuXHRcdFx0XHRcdFx0JC5pMThuLmZhbGxiYWNrc1sgdGhpcy5sb2NhbGUgXVsgZmFsbGJhY2tJbmRleCBdICkgfHxcblx0XHRcdFx0XHRcdHRoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZTtcblx0XHRcdFx0JC5pMThuLmxvZyggJ1RyeWluZyBmYWxsYmFjayBsb2NhbGUgZm9yICcgKyB0aGlzLmxvY2FsZSArICc6ICcgKyBsb2NhbGUgKyAnICgnICsgbWVzc2FnZUtleSArICcpJyApO1xuXG5cdFx0XHRcdGZhbGxiYWNrSW5kZXgrKztcblx0XHRcdH1cblxuXHRcdFx0Ly8ga2V5IG5vdCBmb3VuZFxuXHRcdFx0cmV0dXJuICcnO1xuXHRcdH0sXG5cblx0XHQvKlxuXHRcdCAqIERlc3Ryb3kgdGhlIGkxOG4gaW5zdGFuY2UuXG5cdFx0ICovXG5cdFx0ZGVzdHJveTogZnVuY3Rpb24gKCkge1xuXHRcdFx0JC5yZW1vdmVEYXRhKCBkb2N1bWVudCwgJ2kxOG4nICk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEdlbmVyYWwgbWVzc2FnZSBsb2FkaW5nIEFQSSBUaGlzIGNhbiB0YWtlIGEgVVJMIHN0cmluZyBmb3Jcblx0XHQgKiB0aGUganNvbiBmb3JtYXR0ZWQgbWVzc2FnZXMuIEV4YW1wbGU6XG5cdFx0ICogPGNvZGU+bG9hZCgncGF0aC90by9hbGxfbG9jYWxpemF0aW9ucy5qc29uJyk7PC9jb2RlPlxuXHRcdCAqXG5cdFx0ICogVG8gbG9hZCBhIGxvY2FsaXphdGlvbiBmaWxlIGZvciBhIGxvY2FsZTpcblx0XHQgKiA8Y29kZT5cblx0XHQgKiBsb2FkKCdwYXRoL3RvL2RlLW1lc3NhZ2VzLmpzb24nLCAnZGUnICk7XG5cdFx0ICogPC9jb2RlPlxuXHRcdCAqXG5cdFx0ICogVG8gbG9hZCBhIGxvY2FsaXphdGlvbiBmaWxlIGZyb20gYSBkaXJlY3Rvcnk6XG5cdFx0ICogPGNvZGU+XG5cdFx0ICogbG9hZCgncGF0aC90by9pMThuL2RpcmVjdG9yeScsICdkZScgKTtcblx0XHQgKiA8L2NvZGU+XG5cdFx0ICogVGhlIGFib3ZlIG1ldGhvZCBoYXMgdGhlIGFkdmFudGFnZSBvZiBmYWxsYmFjayByZXNvbHV0aW9uLlxuXHRcdCAqIGllLCBpdCB3aWxsIGF1dG9tYXRpY2FsbHkgbG9hZCB0aGUgZmFsbGJhY2sgbG9jYWxlcyBmb3IgZGUuXG5cdFx0ICogRm9yIG1vc3QgdXNlY2FzZXMsIHRoaXMgaXMgdGhlIHJlY29tbWVuZGVkIG1ldGhvZC5cblx0XHQgKiBJdCBpcyBvcHRpb25hbCB0byBoYXZlIHRyYWlsaW5nIHNsYXNoIGF0IGVuZC5cblx0XHQgKlxuXHRcdCAqIEEgZGF0YSBvYmplY3QgY29udGFpbmluZyBtZXNzYWdlIGtleS0gbWVzc2FnZSB0cmFuc2xhdGlvbiBtYXBwaW5nc1xuXHRcdCAqIGNhbiBhbHNvIGJlIHBhc3NlZC4gRXhhbXBsZTpcblx0XHQgKiA8Y29kZT5cblx0XHQgKiBsb2FkKCB7ICdoZWxsbycgOiAnSGVsbG8nIH0sIG9wdGlvbmFsTG9jYWxlICk7XG5cdFx0ICogPC9jb2RlPlxuXHRcdCAqXG5cdFx0ICogQSBzb3VyY2UgbWFwIGNvbnRhaW5pbmcga2V5LXZhbHVlIHBhaXIgb2YgbGFuZ3VhZ2VuYW1lIGFuZCBsb2NhdGlvbnNcblx0XHQgKiBjYW4gYWxzbyBiZSBwYXNzZWQuIEV4YW1wbGU6XG5cdFx0ICogPGNvZGU+XG5cdFx0ICogbG9hZCgge1xuXHRcdCAqIGJuOiAnaTE4bi9ibi5qc29uJyxcblx0XHQgKiBoZTogJ2kxOG4vaGUuanNvbicsXG5cdFx0ICogZW46ICdpMThuL2VuLmpzb24nXG5cdFx0ICogfSApXG5cdFx0ICogPC9jb2RlPlxuXHRcdCAqXG5cdFx0ICogSWYgdGhlIGRhdGEgYXJndW1lbnQgaXMgbnVsbC91bmRlZmluZWQvZmFsc2UsXG5cdFx0ICogYWxsIGNhY2hlZCBtZXNzYWdlcyBmb3IgdGhlIGkxOG4gaW5zdGFuY2Ugd2lsbCBnZXQgcmVzZXQuXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge3N0cmluZ3xPYmplY3R9IHNvdXJjZVxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbGUgTGFuZ3VhZ2UgdGFnXG5cdFx0ICogQHJldHVybiB7alF1ZXJ5LlByb21pc2V9XG5cdFx0ICovXG5cdFx0bG9hZDogZnVuY3Rpb24gKCBzb3VyY2UsIGxvY2FsZSApIHtcblx0XHRcdHZhciBmYWxsYmFja0xvY2FsZXMsIGxvY0luZGV4LCBmYWxsYmFja0xvY2FsZSwgc291cmNlTWFwID0ge307XG5cdFx0XHRpZiAoICFzb3VyY2UgJiYgIWxvY2FsZSApIHtcblx0XHRcdFx0c291cmNlID0gJ2kxOG4vJyArICQuaTE4bigpLmxvY2FsZSArICcuanNvbic7XG5cdFx0XHRcdGxvY2FsZSA9ICQuaTE4bigpLmxvY2FsZTtcblx0XHRcdH1cblx0XHRcdGlmICggdHlwZW9mIHNvdXJjZSA9PT0gJ3N0cmluZycgJiZcblx0XHRcdFx0Ly8gc291cmNlIGV4dGVuc2lvbiBzaG91bGQgYmUganNvbiwgYnV0IGNhbiBoYXZlIHF1ZXJ5IHBhcmFtcyBhZnRlciB0aGF0LlxuXHRcdFx0XHRzb3VyY2Uuc3BsaXQoICc/JyApWyAwIF0uc3BsaXQoICcuJyApLnBvcCgpICE9PSAnanNvbidcblx0XHRcdCkge1xuXHRcdFx0XHQvLyBMb2FkIHNwZWNpZmllZCBsb2NhbGUgdGhlbiBjaGVjayBmb3IgZmFsbGJhY2tzIHdoZW4gZGlyZWN0b3J5IGlzXG5cdFx0XHRcdC8vIHNwZWNpZmllZCBpbiBsb2FkKClcblx0XHRcdFx0c291cmNlTWFwWyBsb2NhbGUgXSA9IHNvdXJjZSArICcvJyArIGxvY2FsZSArICcuanNvbic7XG5cdFx0XHRcdGZhbGxiYWNrTG9jYWxlcyA9ICggJC5pMThuLmZhbGxiYWNrc1sgbG9jYWxlIF0gfHwgW10gKVxuXHRcdFx0XHRcdC5jb25jYXQoIHRoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZSApO1xuXHRcdFx0XHRmb3IgKCBsb2NJbmRleCA9IDA7IGxvY0luZGV4IDwgZmFsbGJhY2tMb2NhbGVzLmxlbmd0aDsgbG9jSW5kZXgrKyApIHtcblx0XHRcdFx0XHRmYWxsYmFja0xvY2FsZSA9IGZhbGxiYWNrTG9jYWxlc1sgbG9jSW5kZXggXTtcblx0XHRcdFx0XHRzb3VyY2VNYXBbIGZhbGxiYWNrTG9jYWxlIF0gPSBzb3VyY2UgKyAnLycgKyBmYWxsYmFja0xvY2FsZSArICcuanNvbic7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXMubG9hZCggc291cmNlTWFwICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5tZXNzYWdlU3RvcmUubG9hZCggc291cmNlLCBsb2NhbGUgKTtcblx0XHRcdH1cblxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBEb2VzIHBhcmFtZXRlciBhbmQgbWFnaWMgd29yZCBzdWJzdGl0dXRpb24uXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IE1lc3NhZ2Uga2V5XG5cdFx0ICogQHBhcmFtIHtBcnJheX0gcGFyYW1ldGVycyBNZXNzYWdlIHBhcmFtZXRlcnNcblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdFx0ICovXG5cdFx0cGFyc2U6IGZ1bmN0aW9uICgga2V5LCBwYXJhbWV0ZXJzICkge1xuXHRcdFx0dmFyIG1lc3NhZ2UgPSB0aGlzLmxvY2FsaXplKCBrZXkgKTtcblx0XHRcdC8vIEZJWE1FOiBUaGlzIGNoYW5nZXMgdGhlIHN0YXRlIG9mIHRoZSBJMThOIG9iamVjdCxcblx0XHRcdC8vIHNob3VsZCBwcm9iYWJseSBub3QgY2hhbmdlIHRoZSAndGhpcy5wYXJzZXInIGJ1dCBqdXN0XG5cdFx0XHQvLyBwYXNzIGl0IHRvIHRoZSBwYXJzZXIuXG5cdFx0XHR0aGlzLnBhcnNlci5sYW5ndWFnZSA9ICQuaTE4bi5sYW5ndWFnZXNbICQuaTE4bigpLmxvY2FsZSBdIHx8ICQuaTE4bi5sYW5ndWFnZXNbICdkZWZhdWx0JyBdO1xuXHRcdFx0aWYgKCBtZXNzYWdlID09PSAnJyApIHtcblx0XHRcdFx0bWVzc2FnZSA9IGtleTtcblx0XHRcdH1cblx0XHRcdHJldHVybi
4060B0aGlzLnBhcnNlci5wYXJzZSggbWVzc2FnZSwgcGFyYW1ldGVycyApO1xuXHRcdH1cblx0fTtcblxuXHQvKipcblx0ICogUHJvY2VzcyBhIG1lc3NhZ2UgZnJvbSB0aGUgJC5JMThOIGluc3RhbmNlXG5cdCAqIGZvciB0aGUgY3VycmVudCBkb2N1bWVudCwgc3RvcmVkIGluIGpRdWVyeS5kYXRhKGRvY3VtZW50KS5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgb2YgdGhlIG1lc3NhZ2UuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbTEgW3BhcmFtLi4uXSBWYXJpYWRpYyBsaXN0IG9mIHBhcmFtZXRlcnMgZm9yIHtrZXl9LlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd8JC5JMThOfSBQYXJzZWQgbWVzc2FnZSwgb3IgaWYgbm8ga2V5IHdhcyBnaXZlblxuXHQgKiB0aGUgaW5zdGFuY2Ugb2YgJC5JMThOIGlzIHJldHVybmVkLlxuXHQgKi9cblx0JC5pMThuID0gZnVuY3Rpb24gKCBrZXksIHBhcmFtMSApIHtcblx0XHR2YXIgcGFyYW1ldGVycyxcblx0XHRcdGkxOG4gPSAkLmRhdGEoIGRvY3VtZW50LCAnaTE4bicgKSxcblx0XHRcdG9wdGlvbnMgPSB0eXBlb2Yga2V5ID09PSAnb2JqZWN0JyAmJiBrZXk7XG5cblx0XHQvLyBJZiB0aGUgbG9jYWxlIG9wdGlvbiBmb3IgdGhpcyBjYWxsIGlzIGRpZmZlcmVudCB0aGVuIHRoZSBzZXR1cCBzbyBmYXIsXG5cdFx0Ly8gdXBkYXRlIGl0IGF1dG9tYXRpY2FsbHkuIFRoaXMgZG9lc24ndCBqdXN0IGNoYW5nZSB0aGUgY29udGV4dCBmb3IgdGhpc1xuXHRcdC8vIGNhbGwgYnV0IGZvciBhbGwgZnV0dXJlIGNhbGwgYXMgd2VsbC5cblx0XHQvLyBJZiB0aGVyZSBpcyBubyBpMThuIHNldHVwIHlldCwgZG9uJ3QgZG8gdGhpcy4gSXQgd2lsbCBiZSB0YWtlbiBjYXJlIG9mXG5cdFx0Ly8gYnkgdGhlIGBuZXcgSTE4TmAgY29uc3RydWN0aW9uIGJlbG93LlxuXHRcdC8vIE5PVEU6IEl0IHNob3VsZCBvbmx5IGNoYW5nZSBsYW5ndWFnZSBmb3IgdGhpcyBvbmUgY2FsbC5cblx0XHQvLyBUaGVuIGNhY2hlIGluc3RhbmNlcyBvZiBJMThOIHNvbWV3aGVyZS5cblx0XHRpZiAoIG9wdGlvbnMgJiYgb3B0aW9ucy5sb2NhbGUgJiYgaTE4biAmJiBpMThuLmxvY2FsZSAhPT0gb3B0aW9ucy5sb2NhbGUgKSB7XG5cdFx0XHRpMThuLmxvY2FsZSA9IG9wdGlvbnMubG9jYWxlO1xuXHRcdH1cblxuXHRcdGlmICggIWkxOG4gKSB7XG5cdFx0XHRpMThuID0gbmV3IEkxOE4oIG9wdGlvbnMgKTtcblx0XHRcdCQuZGF0YSggZG9jdW1lbnQsICdpMThuJywgaTE4biApO1xuXHRcdH1cblxuXHRcdGlmICggdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgKSB7XG5cdFx0XHRpZiAoIHBhcmFtMSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRwYXJhbWV0ZXJzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzLCAxICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwYXJhbWV0ZXJzID0gW107XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBpMThuLnBhcnNlKCBrZXksIHBhcmFtZXRlcnMgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gRklYTUU6IHJlbW92ZSB0aGlzIGZlYXR1cmUvYnVnLlxuXHRcdFx0cmV0dXJuIGkxOG47XG5cdFx0fVxuXHR9O1xuXG5cdCQuZm4uaTE4biA9IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgaTE4biA9ICQuZGF0YSggZG9jdW1lbnQsICdpMThuJyApO1xuXG5cdFx0aWYgKCAhaTE4biApIHtcblx0XHRcdGkxOG4gPSBuZXcgSTE4TigpO1xuXHRcdFx0JC5kYXRhKCBkb2N1bWVudCwgJ2kxOG4nLCBpMThuICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24gKCkge1xuXHRcdFx0dmFyICR0aGlzID0gJCggdGhpcyApLFxuXHRcdFx0XHRtZXNzYWdlS2V5ID0gJHRoaXMuZGF0YSggJ2kxOG4nICksXG5cdFx0XHRcdGxCcmFja2V0LCByQnJhY2tldCwgdHlwZSwga2V5O1xuXG5cdFx0XHRpZiAoIG1lc3NhZ2VLZXkgKSB7XG5cdFx0XHRcdGxCcmFja2V0ID0gbWVzc2FnZUtleS5pbmRleE9mKCAnWycgKTtcblx0XHRcdFx0ckJyYWNrZXQgPSBtZXNzYWdlS2V5LmluZGV4T2YoICddJyApO1xuXHRcdFx0XHRpZiAoIGxCcmFja2V0ICE9PSAtMSAmJiByQnJhY2tldCAhPT0gLTEgJiYgbEJyYWNrZXQgPCByQnJhY2tldCApIHtcblx0XHRcdFx0XHR0eXBlID0gbWVzc2FnZUtleS5zbGljZSggbEJyYWNrZXQgKyAxLCByQnJhY2tldCApO1xuXHRcdFx0XHRcdGtleSA9IG1lc3NhZ2VLZXkuc2xpY2UoIHJCcmFja2V0ICsgMSApO1xuXHRcdFx0XHRcdGlmICggdHlwZSA9PT0gJ2h0bWwnICkge1xuXHRcdFx0XHRcdFx0JHRoaXMuaHRtbCggaTE4bi5wYXJzZSgga2V5ICkgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0JHRoaXMuYXR0ciggdHlwZSwgaTE4bi5wYXJzZSgga2V5ICkgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0JHRoaXMudGV4dCggaTE4bi5wYXJzZSggbWVzc2FnZUtleSApICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdCR0aGlzLmZpbmQoICdbZGF0YS1pMThuXScgKS5pMThuKCk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9O1xuXG5cdGZ1bmN0aW9uIGdldERlZmF1bHRMb2NhbGUoKSB7XG5cdFx0dmFyIG5hdiwgbG9jYWxlID0gJCggJ2h0bWwnICkuYXR0ciggJ2xhbmcnICk7XG5cblx0XHRpZiAoICFsb2NhbGUgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiB3aW5kb3cubmF2aWdhdG9yICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdG5hdiA9IHdpbmRvdy5uYXZpZ2F0b3I7XG5cdFx0XHRcdGxvY2FsZSA9IG5hdi5sYW5ndWFnZSB8fCBuYXYudXNlckxhbmd1YWdlIHx8ICcnO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bG9jYWxlID0gJyc7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBsb2NhbGU7XG5cdH1cblxuXHQkLmkxOG4ubGFuZ3VhZ2VzID0ge307XG5cdCQuaTE4bi5tZXNzYWdlU3RvcmUgPSAkLmkxOG4ubWVzc2FnZVN0b3JlIHx8IHt9O1xuXHQkLmkxOG4ucGFyc2VyID0ge1xuXHRcdC8vIFRoZSBkZWZhdWx0IHBhcnNlciBvbmx5IGhhbmRsZXMgdmFyaWFibGUgc3Vic3RpdHV0aW9uXG5cdFx0cGFyc2U6IGZ1bmN0aW9uICggbWVzc2FnZSwgcGFyYW1ldGVycyApIHtcblx0XHRcdHJldHVybi
4060BtZXNzYWdlLnJlcGxhY2UoIC9cXCQoXFxkKykvZywgZnVuY3Rpb24gKCBzdHIsIG1hdGNoICkge1xuXHRcdFx0XHR2YXIgaW5kZXggPSBwYXJzZUludCggbWF0Y2gsIDEwICkgLSAxO1xuXHRcdFx0XHRyZXR1cm4gcGFyYW1ldGVyc1sgaW5kZXggXSAhPT0gdW5kZWZpbmVkID8gcGFyYW1ldGVyc1sgaW5kZXggXSA6ICckJyArIG1hdGNoO1xuXHRcdFx0fSApO1xuXHRcdH0sXG5cdFx0ZW1pdHRlcjoge31cblx0fTtcblx0JC5pMThuLmZhbGxiYWNrcyA9IHt9O1xuXHQkLmkxOG4uZGVidWcgPSBmYWxzZTtcblx0JC5pMThuLmxvZyA9IGZ1bmN0aW9uICggLyogYXJndW1lbnRzICovICkge1xuXHRcdGlmICggd2luZG93LmNvbnNvbGUgJiYgJC5pMThuLmRlYnVnICkge1xuXHRcdFx0d2luZG93LmNvbnNvbGUubG9nLmFwcGx5KCB3aW5kb3cuY29uc29sZSwgYXJndW1lbnRzICk7XG5cdFx0fVxuXHR9O1xuXHQvKiBTdGF0aWMgbWVtYmVycyAqL1xuXHRJMThOLmRlZmF1bHRzID0ge1xuXHRcdGxvY2FsZTogZ2V0RGVmYXVsdExvY2FsZSgpLFxuXHRcdGZhbGxiYWNrTG9jYWxlOiAnZW4nLFxuXHRcdHBhcnNlcjogJC5pMThuLnBhcnNlcixcblx0XHRtZXNzYWdlU3RvcmU6ICQuaTE4bi5tZXNzYWdlU3RvcmVcblx0fTtcblxuXHQvLyBFeHBvc2UgY29uc3RydWN0b3Jcblx0JC5pMThuLmNvbnN0cnVjdG9yID0gSTE4Tjtcbn0oIGpRdWVyeSApICk7IiwiLyogZ2xvYmFsIHBsdXJhbFJ1bGVQYXJzZXIgKi9cbiggZnVuY3Rpb24gKCAkICkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0Ly8ganNjczpkaXNhYmxlXG5cdHZhciBsYW5ndWFnZSA9IHtcblx0XHQvLyBDTERSIHBsdXJhbCBydWxlcyBnZW5lcmF0ZWQgdXNpbmdcblx0XHQvLyBsaWJzL0NMRFJQbHVyYWxSdWxlUGFyc2VyL3Rvb2xzL1BsdXJhbFhNTDJKU09OLmh0bWxcblx0XHRwbHVyYWxSdWxlczoge1xuXHRcdFx0YWs6IHtcblx0XHRcdFx0b25lOiAnbiA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0YW06IHtcblx0XHRcdFx0b25lOiAnaSA9IDAgb3IgbiA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0YXI6IHtcblx0XHRcdFx0emVybzogJ24gPSAwJyxcblx0XHRcdFx0b25lOiAnbiA9IDEnLFxuXHRcdFx0XHR0d286ICduID0gMicsXG5cdFx0XHRcdGZldzogJ24gJSAxMDAgPSAzLi4xMCcsXG5cdFx0XHRcdG1hbnk6ICduICUgMTAwID0gMTEuLjk5J1xuXHRcdFx0fSxcblx0XHRcdGFyczoge1xuXHRcdFx0XHR6ZXJvOiAnbiA9IDAnLFxuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJyxcblx0XHRcdFx0ZmV3OiAnbiAlIDEwMCA9IDMuLjEwJyxcblx0XHRcdFx0bWFueTogJ24gJSAxMDAgPSAxMS4uOTknXG5cdFx0XHR9LFxuXHRcdFx0YXM6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAgb3IgbiA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0YmU6IHtcblx0XHRcdFx0b25lOiAnbiAlIDEwID0gMSBhbmQgbiAlIDEwMCAhPSAxMScsXG5cdFx0XHRcdGZldzogJ24gJSAxMCA9IDIuLjQgYW5kIG4gJSAxMDAgIT0gMTIuLjE0Jyxcblx0XHRcdFx0bWFueTogJ24gJSAxMCA9IDAgb3IgbiAlIDEwID0gNS4uOSBvciBuICUgMTAwID0gMTEuLjE0J1xuXHRcdFx0fSxcblx0XHRcdGJoOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdGJuOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwIG9yIG4gPSAxJ1xuXHRcdFx0fSxcblx0XHRcdGJyOiB7XG5cdFx0XHRcdG9uZTogJ24gJSAxMCA9IDEgYW5kIG4gJSAxMDAgIT0gMTEsNzEsOTEnLFxuXHRcdFx0XHR0d286ICduICUgMTAgPSAyIGFuZCBuICUgMTAwICE9IDEyLDcyLDkyJyxcblx0XHRcdFx0ZmV3OiAnbiAlIDEwID0gMy4uNCw5IGFuZCBuICUgMTAwICE9IDEwLi4xOSw3MC4uNzksOTAuLjk5Jyxcblx0XHRcdFx0bWFueTogJ24gIT0gMCBhbmQgbiAlIDEwMDAwMDAgPSAwJ1xuXHRcdFx0fSxcblx0XHRcdGJzOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExIG9yIGYgJSAxMCA9IDEgYW5kIGYgJSAxMDAgIT0gMTEnLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwID0gMi4uNCBhbmQgaSAlIDEwMCAhPSAxMi4uMTQgb3IgZiAlIDEwID0gMi4uNCBhbmQgZiAlIDEwMCAhPSAxMi4uMTQnXG5cdFx0XHR9LFxuXHRcdFx0Y3M6IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0ZmV3OiAnaSA9IDIuLjQgYW5kIHYgPSAwJyxcblx0XHRcdFx0bWFueTogJ3YgIT0gMCdcblx0XHRcdH0sXG5cdFx0XHRjeToge1xuXHRcdFx0XHR6ZXJvOiAnbiA9IDAnLFxuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJyxcblx0XHRcdFx0ZmV3OiAnbiA9IDMnLFxuXHRcdFx0XHRtYW55OiAnbiA9IDYnXG5cdFx0XHR9LFxuXHRcdFx0ZGE6IHtcblx0XHRcdFx0b25lOiAnbiA9IDEgb3IgdCAhPSAwIGFuZCBpID0gMCwxJ1xuXHRcdFx0fSxcblx0XHRcdGRzYjoge1xuXHRcdFx0XHRvbmU6ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDEgb3IgZiAlIDEwMCA9IDEnLFxuXHRcdFx0XHR0d286ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDIgb3IgZiAlIDEwMCA9IDInLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDMuLjQgb3IgZiAlIDEwMCA9IDMuLjQnXG5cdFx0XHR9LFxuXHRcdFx0ZmE6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAgb3IgbiA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0ZmY6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAsMSdcblx0XHRcdH0sXG5cdFx0XHRmaWw6IHtcblx0XHRcdFx0b25lOiAndiA9IDAgYW5kIGkgPSAxLDIsMyBvciB2ID0gMCBhbmQgaSAlIDEwICE9IDQsNiw5IG9yIHYgIT0gMCBhbmQgZiAlIDEwICE9IDQsNiw5J1xuXHRcdFx0fSxcblx0XHRcdGZyOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwLDEnXG5cdFx0XHR9LFxuXHRcdFx0Z2E6IHtcblx0XHRcdFx0b25lOiAnbiA9IDEnLFxuXHRcdFx0XHR0d286ICduID0gMicsXG5cdFx0XHRcdGZldzogJ24gPSAzLi42Jyxcblx0XHRcdFx0bWFueTogJ24gPSA3Li4xMCdcblx0XHRcdH0sXG5cdFx0XHRnZDoge1xuXHRcdFx0XHRvbmU6ICduID0gMSwxMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyLDEyJyxcblx0XHRcdFx0ZmV3OiAnbiA9IDMuLjEwLDEzLi4xOSdcblx0XHRcdH0sXG5cdFx0XHRndToge1xuXHRcdFx0XHRvbmU6ICdpID0gMCBvciBuID0gMSdcblx0XHRcdH0sXG5cdFx0XHRndXc6IHtcblx0XHRcdFx0b25lOiAnbiA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0Z3Y6IHtcblx0XHRcdFx0b25lOiAndiA9IDAgYW5kIGkgJSAxMCA9IDEnLFxuXHRcdFx0XHR0d286ICd2ID0gMCBhbmQgaSAlIDEwID0gMicsXG5cdFx0XHRcdGZldzogJ3YgPSAwIGFuZCBpICUgMTAwID0gMCwyMCw0MCw2MCw4MCcsXG5cdFx0XHRcdG1hbnk6ICd2ICE9IDAnXG5cdFx0XHR9LFxuXHRcdFx0aGU6IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0dHdvOiAnaSA9IDIgYW5kIHYgPSAwJyxcblx0XHRcdFx0bWFueTogJ3YgPSAwIGFuZCBuICE9IDAuLjEwIGFuZCBuICUgMTAgPSAwJ1xuXHRcdFx0fSxcblx0XHRcdGhpOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwIG9yIG4gPSAxJ1xuXHRcdFx0fSxcblx0XHRcdGhyOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExIG9yIGYgJSAxMCA9IDEgYW5kIGYgJSAxMDAgIT0gMTEnLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwID0gMi4uNCBhbmQgaSAlIDEwMCAhPSAxMi4uMTQgb3IgZiAlIDEwID0gMi4uNCBhbmQgZiAlIDEwMCAhPSAxMi4uMTQnXG5cdFx0XHR9LFxuXHRcdFx0aHNiOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAwID0gMSBvciBmICUgMTAwID0gMScsXG5cdFx0XHRcdHR3bzogJ3YgPSAwIGFuZCBpICUgMTAwID0gMiBvciBmICUgMTAwID0gMicsXG5cdFx0XHRcdGZldzogJ3YgPSAwIGFuZCBpICUgMTAwID0gMy4uNCBvciBmICUgMTAwID0gMy4uNCdcblx0XHRcdH0sXG5cdFx0XHRoeToge1xuXHRcdFx0XHRvbmU6ICdpID0gMCwxJ1xuXHRcdFx0fSxcblx0XHRcdGlzOiB7XG5cdFx0XHRcdG9uZTogJ3QgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExIG9yIHQgIT0gMCdcblx0XHRcdH0sXG5cdFx0XHRpdToge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdGl3OiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAxIGFuZCB2ID0gMCcsXG5cdFx0XHRcdHR3bzogJ2kgPSAyIGFuZCB2ID0gMCcsXG5cdFx0XHRcdG1hbnk6ICd2ID0gMCBhbmQgbiAhPSAwLi4xMCBhbmQgbiAlIDEwID0gMCdcblx0XHRcdH0sXG5cdFx0XHRrYWI6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAsMSdcblx0XHRcdH0sXG5cdFx0XHRrbjoge1xuXHRcdFx0XHRvbmU6ICdpID0gMCBvciBuID0gMSdcblx0XHRcdH0sXG5cdFx0XHRrdzoge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdGxhZzoge1xuXHRcdFx0XHR6ZXJvOiAnbiA9IDAnLFxuXHRcdFx0XHRvbmU6ICdpID0gMCwxIGFuZCBuICE9IDAnXG5cdFx0XHR9LFxuXHRcdFx0bG46IHtcblx0XHRcdFx0b25lOiAnbiA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0bHQ6IHtcblx0XHRcdFx0b25lOiAnbiAlIDEwID0gMSBhbmQgbiAlIDEwMCAhPSAxMS4uMTknLFxuXHRcdFx0XHRmZXc6ICduICUgMTAgPSAyLi45IGFuZCBuICUgMTAwICE9IDExLi4xOScsXG5cdFx0XHRcdG1hbnk6ICdmICE9IDAnXG5cdFx0XHR9LFxuXHRcdFx0bHY6IHtcblx0XHRcdFx0emVybzogJ24gJSAxMCA9IDAgb3IgbiAlIDEwMCA9IDExLi4xOSBvciB2ID0gMiBhbmQgZiAlIDEwMCA9IDExLi4xOScsXG5cdFx0XHRcdG9uZTogJ24gJSAxMCA9IDEgYW5kIG4gJSAxMDAgIT0gMTEgb3IgdiA9IDIgYW5kIGYgJSAxMCA9IDEgYW5kIGYgJSAxMDAgIT0gMTEgb3IgdiAhPSAyIGFuZCBmICUgMTAgPSAxJ1xuXHRcdFx0fSxcblx0XHRcdG1nOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdG1rOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIG9yIGYgJSAxMCA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0bW86IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0ZmV3OiAndiAhPSAwIG9yIG4gPSAwIG9yIG4gIT0gMSBhbmQgbiAlIDEwMCA9IDEuLjE5J1xuXHRcdFx0fSxcblx0XHRcdG1yOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwIG9yIG4gPSAxJ1xuXHRcdFx0fSxcblx0XHRcdG10OiB7XG5cdFx0XHRcdG9uZTogJ24gPSAxJyxcblx0XHRcdFx0ZmV3OiAnbiA9IDAgb3IgbiAlIDEwMCA9IDIuLjEwJyxcblx0XHRcdFx0bWFueTogJ24gJSAxMDAgPSAxMS4uMTknXG5cdFx0XHR9LFxuXHRcdFx0bmFxOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAxJyxcblx0XHRcdFx0dHdvOiAnbiA9IDInXG5cdFx0XHR9LFxuXHRcdFx0bnNvOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdHBhOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdHBsOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAxIGFuZCB2ID0gMCcsXG5cdFx0XHRcdGZldzogJ3YgPSAwIGFuZCBpICUgMTAgPSAyLi40IGFuZCBpICUgMTAwICE9IDEyLi4xNCcsXG5cdFx0XHRcdG1hbnk6ICd2ID0gMCBhbmQgaSAhPSAxIGFuZCBpICUgMTAgPSAwLi4xIG9yIHYgPSAwIGFuZCBpICUgMTAgPSA1Li45IG9yIHYgPSAwIGFuZCBpICUgMTAwID0gMTIuLjE0J1xuXHRcdFx0fSxcblx0XHRcdHByZzoge1xuXHRcdFx0XHR6ZXJvOiAnbiAlIDEwID0gMCBvciBuICUgMTAwID0gMTEuLjE5IG9yIHYgPSAyIGFuZCBmICUgMTAwID0gMTEuLjE5Jyxcblx0XHRcdFx0b25lOiAnbiAlIDEwID0gMSBhbmQgbiAlIDEwMCAhPSAxMSBvciB2ID0gMiBhbmQgZiAlIDEwID0gMSBhbmQgZiAlIDEwMCAhPSAxMSBvciB2ICE9IDIgYW5kIGYgJSAxMCA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0cHQ6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0cm86IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0ZmV3OiAndiAhPSAwIG9yIG4gPSAwIG9yIG4gIT0gMSBhbmQgbiAlIDEwMCA9IDEuLjE5J1xuXHRcdFx0fSxcblx0XHRcdHJ1OiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExJyxcblx0XHRcdFx0ZmV3OiAndiA9IDAgYW5kIGkgJSAxMCA9IDIuLjQgYW5kIGkgJSAxMDAgIT0gMTIuLjE0Jyxcblx0XHRcdFx0bWFueTogJ3YgPSAwIGFuZCBpICUgMTAgPSAwIG9yIHYgPSAwIGFuZCBpICUgMTAgPSA1Li45IG9yIHYgPSAwIGFuZCBpICUgMTAwID0gMTEuLjE0J1xuXHRcdFx0fSxcblx0XHRcdHNlOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAxJyxcblx0XHRcdFx0dHdvOiAnbiA9IDInXG5cdFx0XHR9LFxuXHRcdFx0c2g6IHtcblx0XHRcdFx0b25lOiAndiA9IDAgYW5kIGkgJSAxMCA9IDEgYW5kIGkgJSAxMDAgIT0gMTEgb3IgZiAlIDEwID0gMSBhbmQgZiAlIDEwMCAhPSAxMScsXG5cdFx0XHRcdGZldzogJ3YgPSAwIGFuZCBpICUgMTAgPSAyLi40IGFuZCBpICUgMTAwICE9IDEyLi4xNCBvciBmICUgMTAgPSAyLi40IGFuZCBmICUgMTAwICE9IDEyLi4xNCdcblx0XHRcdH0sXG5cdFx0XHRzaGk6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAgb3IgbiA9IDEnLFxuXHRcdFx0XHRmZXc6ICduID0gMi4uMTAnXG5cdFx0XHR9LFxuXHRcdFx0c2k6IHtcblx0XHRcdFx0b25lOiAnbiA9IDAsMSBvciBpID0gMCBhbmQgZiA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0c2s6IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0ZmV3OiAnaSA9IDIuLjQgYW5kIHYgPSAwJyxcblx0XHRcdFx0bWFueTogJ3YgIT0gMCdcblx0XHRcdH0sXG5cdFx0XHRzbDoge1xuXHRcdFx0XHRvbmU6ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDEnLFxuXHRcdFx0XHR0d286ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDInLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDMuLjQgb3IgdiAhPSAwJ1xuXHRcdFx0fSxcblx0XHRcdHNtYToge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNtaToge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNtajoge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNtbjoge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNtczoge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNyOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExIG9yIGYgJSAxMCA9IDEgYW5kIGYgJSAxMDAgIT0gMTEnLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwID0gMi4uNCBhbmQgaSAlIDEwMCAhPSAxMi4uMTQgb3IgZiAlIDEwID0gMi4uNCBhbmQgZiAlIDEwMCAhPSAxMi4uMTQnXG5cdFx0XHR9LFxuXHRcdFx0dGk6IHtcblx0XHRcdFx0b25lOiAnbiA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0dGw6IHtcblx0XHRcdFx0b25lOiAndiA9IDAgYW5kIGkgPSAxLDIsMyBvciB2ID0gMCBhbmQgaSAlIDEwICE9IDQsNiw5IG9yIHYgIT0gMCBhbmQgZiAlIDEwICE9IDQsNiw5J1xuXHRcdFx0fSxcblx0XHRcdHR6bToge1xuXHRcdFx0XHRvbmU6ICduID0gMC4uMSBvciBuID0gMTEuLjk5J1xuXHRcdFx0fSxcblx0XHRcdHVrOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExJyxcblx0XHRcdFx0ZmV3OiAndiA9IDAgYW5kIGkgJSAxMCA9IDIuLjQgYW5kIGkgJSAxMDAgIT0gMTIuLjE0Jyxcblx0XHRcdFx0bWFueTogJ3YgPSAwIGFuZCBpICUgMTAgPSAwIG9yIHYgPSAwIGFuZCBpICUgMTAgPSA1Li45IG9yIHYgPSAwIGFuZCBpICUgMTAwID0gMTEuLjE0J1xuXHRcdFx0fSxcblx0XHRcdHdhOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdHp1OiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwIG9yIG4gPSAxJ1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0Ly8ganNjczplbmFibGVcblxuXHRcdC8qKlxuXHRcdCAqIFBsdXJhbCBmb3JtIHRyYW5zZm9ybWF0aW9ucywgbmVlZGVkIGZvciBzb21lIGxhbmd1YWdlcy5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7aW50ZWdlcn0gY291bnRcblx0XHQgKiAgICAgICAgICAgIE5vbi1sb2NhbGl6ZWQgcXVhbnRpZmllclxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IGZvcm1zXG5cdFx0ICogICAgICAgICAgICBMaXN0IG9mIHBsdXJhbCBmb3Jtc1xuXHRcdCAqIEByZXR1cm4ge3N0cmluZ30gQ29ycmVjdCBmb3JtIGZvciBxdWFudGlmaWVyIGluIHRoaXMgbGFuZ3VhZ2Vcblx0XHQgKi9cblx0XHRjb252ZXJ0UGx1cmFsOiBmdW5jdGlvbiAoIGNvdW50LCBmb3JtcyApIHtcblx0XHRcdHZhciBwbHVyYWxSdWxlcyxcblx0XHRcdFx0cGx1cmFsRm9ybUluZGV4LFxuXHRcdFx0XHRpbmRleCxcblx0XHRcdFx0ZXhwbGljaXRQbHVyYWxQYXR0ZXJuID0gbmV3IFJlZ0V4cCggJ1xcXFxkKz0nLCAnaScgKSxcblx0XHRcdFx0Zm9ybUNvdW50LFxuXHRcdFx0XHRmb3JtO1xuXG5cdFx0XHRpZiAoICFmb3JtcyB8fCBmb3Jtcy5sZW5ndGggPT09IDAgKSB7XG5cdFx0XHRcdHJldHVybiAnJztcblx0XHRcdH1cblxuXHRcdFx0Ly8gSGFuZGxlIGZvciBFeHBsaWNpdCAwPSAmIDE9IHZhbHVlc1xuXHRcdFx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGZvcm1zLmxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0Zm9ybSA9IGZvcm1zWyBpbmRleCBdO1xuXHRcdFx0XHRpZiAoIGV4cGxpY2l0UGx1cmFsUGF0dGVybi50ZXN0KCBmb3JtICkgKSB7XG5cdFx0XHRcdFx0Zm9ybUNvdW50ID0gcGFyc2VJbnQoIGZvcm0uc2xpY2UoIDAsIGZvcm0uaW5kZXhPZiggJz0nICkgKSwgMTAgKTtcblx0XHRcdFx0XHRpZiAoIGZvcm1Db3VudCA9PT0gY291bnQgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gKCBmb3JtLnNsaWNlKCBmb3JtLmluZGV4T2YoICc9JyApICsgMSApICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGZvcm1zWyBpbmRleCBdID0gdW5kZWZpbmVkO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGZvcm1zID0gJC5tYXAoIGZvcm1zLCBmdW5jdGlvbiAoIGZvcm0gKSB7XG5cdFx0XHRcdGlmICggZm9ybSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybi
4060Bmb3JtO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cblx0XHRcdHBsdXJhbFJ1bGVzID0gdGhpcy5wbHVyYWxSdWxlc1sgJC5pMThuKCkubG9jYWxlIF07XG5cblx0XHRcdGlmICggIXBsdXJhbFJ1bGVzICkge1xuXHRcdFx0XHQvLyBkZWZhdWx0IGZhbGxiYWNrLlxuXHRcdFx0XHRyZXR1cm4gKCBjb3VudCA9PT0gMSApID8gZm9ybXNbIDAgXSA6IGZvcm1zWyAxIF07XG5cdFx0XHR9XG5cblx0XHRcdHBsdXJhbEZvcm1JbmRleCA9IHRoaXMuZ2V0UGx1cmFsRm9ybSggY291bnQsIHBsdXJhbFJ1bGVzICk7XG5cdFx0XHRwbHVyYWxGb3JtSW5kZXggPSBNYXRoLm1pbiggcGx1cmFsRm9ybUluZGV4LCBmb3Jtcy5sZW5ndGggLSAxICk7XG5cblx0XHRcdHJldHVybiBmb3Jtc1sgcGx1cmFsRm9ybUluZGV4IF07XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEZvciB0aGUgbnVtYmVyLCBnZXQgdGhlIHBsdXJhbCBmb3IgaW5kZXhcblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7aW50ZWdlcn0gbnVtYmVyXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IHBsdXJhbFJ1bGVzXG5cdFx0ICogQHJldHVybiB7aW50ZWdlcn0gcGx1cmFsIGZvcm0gaW5kZXhcblx0XHQgKi9cblx0XHRnZXRQbHVyYWxGb3JtOiBmdW5jdGlvbiAoIG51bWJlciwgcGx1cmFsUnVsZXMgKSB7XG5cdFx0XHR2YXIgaSxcblx0XHRcdFx0cGx1cmFsRm9ybXMgPSBbICd6ZXJvJywgJ29uZScsICd0d28nLCAnZmV3JywgJ21hbnknLCAnb3RoZXInIF0sXG5cdFx0XHRcdHBsdXJhbEZvcm1JbmRleCA9IDA7XG5cblx0XHRcdGZvciAoIGkgPSAwOyBpIDwgcGx1cmFsRm9ybXMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggcGx1cmFsUnVsZXNbIHBsdXJhbEZvcm1zWyBpIF0gXSApIHtcblx0XHRcdFx0XHRpZiAoIHBsdXJhbFJ1bGVQYXJzZXIoIHBsdXJhbFJ1bGVzWyBwbHVyYWxGb3Jtc1sgaSBdIF0sIG51bWJlciApICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHBsdXJhbEZvcm1JbmRleDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRwbHVyYWxGb3JtSW5kZXgrKztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcGx1cmFsRm9ybUluZGV4O1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBDb252ZXJ0cyBhIG51bWJlciB1c2luZyBkaWdpdFRyYW5zZm9ybVRhYmxlLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtudW1iZXJ9IG51bSBWYWx1ZSB0byBiZSBjb252ZXJ0ZWRcblx0XHQgKiBAcGFyYW0ge2Jvb2xlYW59IGludGVnZXIgQ29udmVydCB0aGUgcmV0dXJuIHZhbHVlIHRvIGFuIGludGVnZXJcblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBudW1iZXIgY29udmVydGVkIGludG8gYSBTdHJpbmcuXG5cdFx0ICovXG5cdFx0Y29udmVydE51bWJlcjogZnVuY3Rpb24gKCBudW0sIGludGVnZXIgKSB7XG5cdFx0XHR2YXIgdG1wLCBpdGVtLCBpLFxuXHRcdFx0XHR0cmFuc2Zvcm1UYWJsZSwgbnVtYmVyU3RyaW5nLCBjb252ZXJ0ZWROdW1iZXI7XG5cblx0XHRcdC8vIFNldCB0aGUgdGFyZ2V0IFRyYW5zZm9ybSB0YWJsZTpcblx0XHRcdHRyYW5zZm9ybVRhYmxlID0gdGhpcy5kaWdpdFRyYW5zZm9ybVRhYmxlKCAkLmkxOG4oKS5sb2NhbGUgKTtcblx0XHRcdG51bWJlclN0cmluZyA9IFN0cmluZyggbnVtICk7XG5cdFx0XHRjb252ZXJ0ZWROdW1iZXIgPSAnJztcblxuXHRcdFx0aWYgKCAhdHJhbnNmb3JtVGFibGUgKSB7XG5cdFx0XHRcdHJldHVybiBudW07XG5cdFx0XHR9XG5cblx0XHRcdC8vIENoZWNrIGlmIHRoZSByZXN0b3JlIHRvIExhdGluIG51bWJlciBmbGFnIGlzIHNldDpcblx0XHRcdGlmICggaW50ZWdlciApIHtcblx0XHRcdFx0aWYgKCBwYXJzZUZsb2F0KCBudW0sIDEwICkgPT09IG51bSApIHtcblx0XHRcdFx0XHRyZXR1cm4gbnVtO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dG1wID0gW107XG5cblx0XHRcdFx0Zm9yICggaXRlbSBpbiB0cmFuc2Zvcm1UYWJsZSApIHtcblx0XHRcdFx0XHR0bXBbIHRyYW5zZm9ybVRhYmxlWyBpdGVtIF0gXSA9IGl0ZW07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0cmFuc2Zvcm1UYWJsZSA9IHRtcDtcblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBudW1iZXJTdHJpbmcubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggdHJhbnNmb3JtVGFibGVbIG51bWJlclN0cmluZ1sgaSBdIF0gKSB7XG5cdFx0XHRcdFx0Y29udmVydGVkTnVtYmVyICs9IHRyYW5zZm9ybVRhYmxlWyBudW1iZXJTdHJpbmdbIGkgXSBdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvbnZlcnRlZE51bWJlciArPSBudW1iZXJTdHJpbmdbIGkgXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gaW50ZWdlciA/IHBhcnNlRmxvYXQoIGNvbnZlcnRlZE51bWJlciwgMTAgKSA6IGNvbnZlcnRlZE51bWJlcjtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogR3JhbW1hdGljYWwgdHJhbnNmb3JtYXRpb25zLCBuZWVkZWQgZm9yIGluZmxlY3RlZCBsYW5ndWFnZXMuXG5cdFx0ICogSW52b2tlZCBieSBwdXR0aW5nIHt7Z3JhbW1hcjpmb3JtfHdvcmR9fSBpbiBhIG1lc3NhZ2UuXG5cdFx0ICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgZm9yIGxhbmd1YWdlcyB0aGF0IG5lZWQgc3BlY2lhbCBncmFtbWFyIHJ1bGVzXG5cdFx0ICogYXBwbGllZCBkeW5hbWljYWxseS5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSB3b3JkXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGZvcm1cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdFx0ICovXG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG5cdFx0Y29udmVydEdyYW1tYXI6IGZ1bmN0aW9uICggd29yZCwgZm9ybSApIHtcblx0XHRcdHJldHVybiB3b3JkO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBQcm92aWRlcyBhbiBhbHRlcm5hdGl2ZSB0ZXh0IGRlcGVuZGluZyBvbiBzcGVjaWZpZWQgZ2VuZGVyLiBVc2FnZVxuXHRcdCAqIHt7Z2VuZGVyOltnZW5kZXJ8dXNlciBvYmplY3RdfG1hc2N1bGluZXxmZW1pbmluZXxuZXV0cmFsfX0uIElmIHNlY29uZFxuXHRcdCAqIG9yIHRoaXJkIHBhcmFtZXRlciBhcmUgbm90IHNwZWNpZmllZCwgbWFzY3VsaW5lIGlzIHVzZWQuXG5cdFx0ICpcblx0XHQgKiBUaGVzZSBkZXRhaWxzIG1heSBiZSBvdmVycmlkZW4gcGVyIGxhbmd1YWdlLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGdlbmRlclxuXHRcdCAqICAgICAgbWFsZSwgZmVtYWxl
4060LCBvciBhbnl0aGluZyBlbHNlIGZvciBuZXV0cmFsLlxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IGZvcm1zXG5cdFx0ICogICAgICBMaXN0IG9mIGdlbmRlciBmb3Jtc1xuXHRcdCAqXG5cdFx0ICogQHJldHVybiB7c3RyaW5nfVxuXHRcdCAqL1xuXHRcdGdlbmRlcjogZnVuY3Rpb24gKCBnZW5kZXIsIGZvcm1zICkge1xuXHRcdFx0aWYgKCAhZm9ybXMgfHwgZm9ybXMubGVuZ3RoID09PSAwICkge1xuXHRcdFx0XHRyZXR1cm4gJyc7XG5cdFx0XHR9XG5cblx0XHRcdHdoaWxlICggZm9ybXMubGVuZ3RoIDwgMiApIHtcblx0XHRcdFx0Zm9ybXMucHVzaCggZm9ybXNbIGZvcm1zLmxlbmd0aCAtIDEgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGdlbmRlciA9PT0gJ21hbGUnICkge1xuXHRcdFx0XHRyZXR1cm4gZm9ybXNbIDAgXTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBnZW5kZXIgPT09ICdmZW1hbGUnICkge1xuXHRcdFx0XHRyZXR1cm4gZm9ybXNbIDEgXTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuICggZm9ybXMubGVuZ3RoID09PSAzICkgPyBmb3Jtc1sgMiBdIDogZm9ybXNbIDAgXTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogR2V0IHRoZSBkaWdpdCB0cmFuc2Zvcm0gdGFibGUgZm9yIHRoZSBnaXZlbiBsYW5ndWFnZVxuXHRcdCAqIFNlZSBodHRwOi8vY2xkci51bmljb2RlLm9yZy90cmFuc2xhdGlvbi9udW1iZXJpbmctc3lzdGVtc1xuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGxhbmd1YWdlXG5cdFx0ICogQHJldHVybiB7QXJyYXl8Ym9vbGVhbn0gTGlzdCBvZiBkaWdpdHMgaW4gdGhlIHBhc3NlZCBsYW5ndWFnZSBvciBmYWxzZVxuXHRcdCAqIHJlcHJlc2VudGF0aW9uLCBvciBib29sZWFuIGZhbHNlIGlmIHRoZXJlIGlzIG5vIGluZm9ybWF0aW9uLlxuXHRcdCAqL1xuXHRcdGRpZ2l0VHJhbnNmb3JtVGFibGU6IGZ1bmN0aW9uICggbGFuZ3VhZ2UgKSB7XG5cdFx0XHR2YXIgdGFibGVzID0ge1xuXHRcdFx0XHRhcjogJ9mg2aHZotmj2aTZpdmm2afZqNmpJyxcblx0XHRcdFx0ZmE6ICfbsNux27Lbs9u027Xbttu327jbuScsXG5cdFx0XHRcdG1sOiAn4LWm4LWn4LWo4LWp4LWq4LWr4LWs4LWt4LWu4LWvJyxcblx0XHRcdFx0a246ICfgs6bgs6fgs6jgs6ngs6rgs6vgs6zgs63gs67gs68nLFxuXHRcdFx0XHRsbzogJ+C7kOC7keC7kuC7k+C7lOC7leC7luC7l+C7mOC7mScsXG5cdFx0XHRcdG9yOiAn4K2m4K2n4K2o4K2p4K2q4K2r4K2s4K2t4K2u4K2vJyxcblx0XHRcdFx0a2g6ICfhn6Dhn6Hhn6Lhn6Phn6Thn6Xhn6bhn6fhn6jhn6knLFxuXHRcdFx0XHRwYTogJ+CppuCpp+CpqOCpqeCpquCpq+CprOCpreCpruCprycsXG5cdFx0XHRcdGd1OiAn4Kum4Kun4Kuo4Kup4Kuq4Kur4Kus4Kut4Kuu4KuvJyxcblx0XHRcdFx0aGk6ICfgpabgpafgpajgpangpargpavgpazgpa3gpa7gpa8nLFxuXHRcdFx0XHRteTogJ+GBgOGBgeGBguGBg+GBhOGBheGBhuGBh+GBiOGBiScsXG5cdFx0XHRcdHRhOiAn4K+m4K+n4K+o4K+p4K+q4K+r4K+s4K+t4K+u4K+vJyxcblx0XHRcdFx0dGU6ICfgsabgsafgsajgsangsargsavgsazgsa3gsa7gsa8nLFxuXHRcdFx0XHR0aDogJ+C5kOC5keC5kuC5k+C5lOC5leC5luC5l+C5mOC5mScsIC8vIEZJWE1FIHVzZSBpc28gNjM5IGNvZGVzXG5cdFx0XHRcdGJvOiAn4Lyg4Lyh4Lyi4Lyj4Lyk4Lyl4Lym4Lyn4Lyo4LypJyAvLyBGSVhNRSB1c2UgaXNvIDYzOSBjb2Rlc1xuXHRcdFx0fTtcblxuXHRcdFx0aWYgKCAhdGFibGVzWyBsYW5ndWFnZSBdICkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0YWJsZXNbIGxhbmd1YWdlIF0uc3BsaXQoICcnICk7XG5cdFx0fVxuXHR9O1xuXG5cdCQuZXh0ZW5kKCAkLmkxOG4ubGFuZ3VhZ2VzLCB7XG5cdFx0J2RlZmF1bHQnOiBsYW5ndWFnZVxuXHR9ICk7XG59KCBqUXVlcnkgKSApO1xuIiwiLyohXG4gKiBqUXVlcnkgSW50ZXJuYXRpb25hbGl6YXRpb24gbGlicmFyeSAtIE1lc3NhZ2UgU3RvcmVcbiAqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTIgU2FudGhvc2ggVGhvdHRpbmdhbFxuICpcbiAqIGpxdWVyeS5pMThuIGlzIGR1YWwgbGljZW5zZWQgR1BMdjIgb3IgbGF0ZXIgYW5kIE1JVC4gWW91IGRvbid0IGhhdmUgdG8gZG8gYW55dGhpbmcgc3BlY2lhbCB0b1xuICogY2hvb3NlIG9uZSBsaWNlbnNlIG9yIHRoZSBvdGhlciBhbmQgeW91IGRvbid0IGhhdmUgdG8gbm90aWZ5IGFueW9uZSB3aGljaCBsaWNlbnNlIHlvdSBhcmUgdXNpbmcuXG4gKiBZb3UgYXJlIGZyZWUgdG8gdXNlIFVuaXZlcnNhbExhbmd1YWdlU2VsZWN0b3IgaW4gY29tbWVyY2lhbCBwcm9qZWN0cyBhcyBsb25nIGFzIHRoZSBjb3B5cmlnaHRcbiAqIGhlYWRlciBpcyBsZWZ0IGludGFjdC4gU2VlIGZpbGVzIEdQTC1MSUNFTlNFIGFuZCBNSVQtTElDRU5TRSBmb3IgZGV0YWlscy5cbiAqXG4gKiBAbGljZW5jZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5jZSAyLjAgb3IgbGF0ZXJcbiAqIEBsaWNlbmNlIE1JVCBMaWNlbnNlXG4gKi9cblxuKCBmdW5jdGlvbiAoICQgKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuXHR2YXIgTWVzc2FnZVN0b3JlID0gZnVuY3Rpb24gKCkge1xuXHRcdHRoaXMubWVzc2FnZXMgPSB7fTtcblx0XHR0aGlzLnNvdXJjZXMgPSB7fTtcblx0fTtcblxuXHRmdW5jdGlvbiBqc29uTWVzc2FnZUxvYWRlciggdXJsICkge1xuXHRcdHZhciBkZWZlcnJlZCA9ICQuRGVmZXJyZWQoKTtcblxuXHRcdCQuZ2V0SlNPTiggdXJsIClcblx0XHRcdC5kb25lKCBkZWZlcnJlZC5yZXNvbHZlIClcblx0XHRcdC5mYWlsKCBmdW5jdGlvbiAoIGpxeGhyLCBzZXR0aW5ncywgZXhjZXB0aW9uICkge1xuXHRcdFx0XHQkLmkxOG4ubG9nKCAnRXJyb3IgaW4gbG9hZGluZyBtZXNzYWdlcyBmcm9tICcgKyB1cmwgKyAnIEV4Y2VwdGlvbj
4060ogJyArIGV4Y2VwdGlvbiApO1xuXHRcdFx0XHQvLyBJZ25vcmUgNDA0IGV4Y2VwdGlvbiwgYmVjYXVzZSB3ZSBhcmUgaGFuZGxpbmcgZmFsbGFiYWNrcyBleHBsaWNpdGx5XG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmUoKTtcblx0XHRcdH0gKTtcblxuXHRcdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XG5cdH1cblxuXHQvKipcblx0ICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS93aWtpbWVkaWEvanF1ZXJ5LmkxOG4vd2lraS9TcGVjaWZpY2F0aW9uI3dpa2ktTWVzc2FnZV9GaWxlX0xvYWRpbmdcblx0ICovXG5cdE1lc3NhZ2VTdG9yZS5wcm90b3R5cGUgPSB7XG5cblx0XHQvKipcblx0XHQgKiBHZW5lcmFsIG1lc3NhZ2UgbG9hZGluZyBBUEkgVGhpcyBjYW4gdGFrZSBhIFVSTCBzdHJpbmcgZm9yXG5cdFx0ICogdGhlIGpzb24gZm9ybWF0dGVkIG1lc3NhZ2VzLlxuXHRcdCAqIDxjb2RlPmxvYWQoJ3BhdGgvdG8vYWxsX2xvY2FsaXphdGlvbnMuanNvbicpOzwvY29kZT5cblx0XHQgKlxuXHRcdCAqIFRoaXMgY2FuIGFsc28gbG9hZCBhIGxvY2FsaXphdGlvbiBmaWxlIGZvciBhIGxvY2FsZSA8Y29kZT5cblx0XHQgKiBsb2FkKCAncGF0aC90by9kZS1tZXNzYWdlcy5qc29uJywgJ2RlJyApO1xuXHRcdCAqIDwvY29kZT5cblx0XHQgKiBBIGRhdGEgb2JqZWN0IGNvbnRhaW5pbmcgbWVzc2FnZSBrZXktIG1lc3NhZ2UgdHJhbnNsYXRpb24gbWFwcGluZ3Ncblx0XHQgKiBjYW4gYWxzbyBiZSBwYXNzZWQgRWc6XG5cdFx0ICogPGNvZGU+XG5cdFx0ICogbG9hZCggeyAnaGVsbG8nIDogJ0hlbGxvJyB9LCBvcHRpb25hbExvY2FsZSApO1xuXHRcdCAqIDwvY29kZT4gSWYgdGhlIGRhdGEgYXJndW1lbnQgaXNcblx0XHQgKiBudWxsL3VuZGVmaW5lZC9mYWxzZSxcblx0XHQgKiBhbGwgY2FjaGVkIG1lc3NhZ2VzIGZvciB0aGUgaTE4biBpbnN0YW5jZSB3aWxsIGdldCByZXNldC5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfE9iamVjdH0gc291cmNlXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsZSBMYW5ndWFnZSB0YWdcblx0XHQgKiBAcmV0dXJuIHtqUXVlcnkuUHJvbWlzZX1cblx0XHQgKi9cblx0XHRsb2FkOiBmdW5jdGlvbiAoIHNvdXJjZSwgbG9jYWxlICkge1xuXHRcdFx0dmFyIGtleSA9IG51bGwsXG5cdFx0XHRcdGRlZmVycmVkID0gbnVsbCxcblx0XHRcdFx0ZGVmZXJyZWRzID0gW10sXG5cdFx0XHRcdG1lc3NhZ2VTdG9yZSA9IHRoaXM7XG5cblx0XHRcdGlmICggdHlwZW9mIHNvdXJjZSA9PT0gJ3N0cmluZycgKSB7XG5cdFx0XHRcdC8vIFRoaXMgaXMgYSBVUkwgdG8gdGhlIG1lc3NhZ2VzIGZpbGUuXG5cdFx0XHRcdCQuaTE4bi5sb2coICdMb2FkaW5nIG1lc3NhZ2VzIGZyb206ICcgKyBzb3VyY2UgKTtcblx0XHRcdFx0ZGVmZXJyZWQgPSBqc29uTWVzc2FnZUxvYWRlciggc291cmNlIClcblx0XHRcdFx0XHQuZG9uZSggZnVuY3Rpb24gKCBsb2NhbGl6YXRpb24gKSB7XG5cdFx0XHRcdFx0XHRtZXNzYWdlU3RvcmUuc2V0KCBsb2NhbGUsIGxvY2FsaXphdGlvbiApO1xuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHRyZXR1cm4gZGVmZXJyZWQucHJvbWlzZSgpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGxvY2FsZSApIHtcblx0XHRcdFx0Ly8gc291cmNlIGlzIGFuIGtleS12YWx1ZSBwYWlyIG9mIG1lc3NhZ2VzIGZvciBnaXZlbiBsb2NhbGVcblx0XHRcdFx0bWVzc2FnZVN0b3JlLnNldCggbG9jYWxlLCBzb3VyY2UgKTtcblxuXHRcdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlc29sdmUoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIHNvdXJjZSBpcyBhIGtleS12YWx1ZSBwYWlyIG9mIGxvY2FsZXMgYW5kIHRoZWlyIHNvdXJjZVxuXHRcdFx0XHRmb3IgKCBrZXkgaW4gc291cmNlICkge1xuXHRcdFx0XHRcdGlmICggT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKCBzb3VyY2UsIGtleSApICkge1xuXHRcdFx0XHRcdFx0bG9jYWxlID0ga2V5O1xuXHRcdFx0XHRcdFx0Ly8gTm8ge2xvY2FsZX0gZ2l2ZW4sIGFzc3VtZSBkYXRhIGlzIGEgZ3JvdXAgb2YgbGFuZ3VhZ2VzLFxuXHRcdFx0XHRcdFx0Ly8gY2FsbCB0aGlzIGZ1bmN0aW9uIGFnYWluIGZvciBlYWNoIGxhbmd1YWdlLlxuXHRcdFx0XHRcdFx0ZGVmZXJyZWRzLnB1c2goIG1lc3NhZ2VTdG9yZS5sb2FkKCBzb3VyY2VbIGtleSBdLCBsb2NhbGUgKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gJC53aGVuLmFwcGx5KCAkLCBkZWZlcnJlZHMgKTtcblx0XHRcdH1cblxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBTZXQgbWVzc2FnZXMgdG8gdGhlIGdpdmVuIGxvY2FsZS5cblx0XHQgKiBJZiBsb2NhbGUgZXhpc3RzLCBhZGQgbWVzc2FnZXMgdG8gdGhlIGxvY2FsZS5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbGVcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZXNcblx0XHQgKi9cblx0XHRzZXQ6IGZ1bmN0aW9uICggbG9jYWxlLCBtZXNzYWdlcyApIHtcblx0XHRcdGlmICggIXRoaXMubWVzc2FnZXNbIGxvY2FsZSBdICkge1xuXHRcdFx0XHR0aGlzLm1lc3NhZ2VzWyBsb2NhbGUgXSA9IG1lc3NhZ2VzO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5tZXNzYWdlc1sgbG9jYWxlIF0gPSAkLmV4dGVuZCggdGhpcy5tZXNzYWdlc1sgbG9jYWxlIF0sIG1lc3NhZ2VzICk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsZVxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlS2V5XG5cdFx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0XHQgKi9cblx0XHRnZXQ6IGZ1bmN0aW9uICggbG9jYWxlLCBtZXNzYWdlS2V5ICkge1xuXHRcdFx0cmV0dXJuIHRoaXMubWVzc2FnZXNbIGxvY2FsZSBdICYmIHRoaXMubWVzc2FnZXNbIGxvY2FsZSBdWyBtZXNzYWdlS2V5IF07XG5cdFx0fVxuXHR9O1xuXG5cdCQuZXh0ZW5kKCAkLmkxOG4ubWVzc2FnZVN0b3JlLCBuZXcgTWVzc2FnZVN0b3JlKCkgKTtcbn0oIGpRdWVyeSApICk7XG4iLCIvKiFcbiAqIGpRdWVyeSBJbnRlcm5hdGlvbmFsaXphdGlvbiBsaWJyYXJ5XG4gKlxuICogQ29weXJpZ2h0IChDKSAyMDExLTIwMTMgU2FudGhvc2ggVGhvdHRpbmdhbCwgTmVpbCBLYW5kYWxnYW9ua2FyXG4gKlxuICoganF1ZXJ5LmkxOG4gaXMgZHVhbCBsaWNlbnNlZCBHUEx2MiBvciBsYXRlciBhbmQgTUlULiBZb3UgZG9uJ3QgaGF2ZSB0byBkb1xuICogYW55dGhpbmcgc3BlY2lhbCB0byBjaG9vc2Ugb25lIGxpY2Vuc2Ugb3IgdGhlIG90aGVyIGFuZCB5b3UgZG9uJ3QgaGF2ZSB0b1xuICogbm90aWZ5IGFueW9uZSB3aGljaCBsaWNlbnNlIHlvdSBhcmUgdXNpbmcuIFlvdSBhcmUgZnJlZSB0byB1c2VcbiAqIFVuaXZlcnNhbExhbmd1YWdlU2VsZWN0b3IgaW4gY29tbWVyY2lhbCBwcm9qZWN0cyBhcyBsb25nIGFzIHRoZSBjb3B5cmlnaHRcbiAqIGhlYWRlciBpcyBsZWZ0IGludGFjdC4gU2VlIGZpbGVzIEdQTC1MSUNFTlNFIGFuZCBNSVQtTElDRU5TRSBmb3IgZGV0YWlscy5cbiAqXG4gKiBAbGljZW5jZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5jZSAyLjAgb3IgbGF0ZXJcbiAqIEBsaWNlbmNlIE1JVCBMaWNlbnNlXG4gKi9cblxuKCBmdW5jdGlvbiAoICQgKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuXHR2YXIgTWVzc2FnZVBhcnNlciA9IGZ1bmN0aW9uICggb3B0aW9ucyApIHtcblx0XHR0aGlzLm9wdGlvbnMgPSAkLmV4dGVuZCgge30sICQuaTE4bi5wYXJzZXIuZGVmYXVsdHMsIG9wdGlvbnMgKTtcblx0XHR0aGlzLmxhbmd1YWdlID0gJC5pMThuLmxhbmd1YWdlc1sgU3RyaW5nLmxvY2FsZSBdIHx8ICQuaTE4bi5sYW5ndWFnZXNbICdkZWZhdWx0JyBdO1xuXHRcdHRoaXMuZW1pdHRlciA9ICQuaTE4bi5wYXJzZXIuZW1pdHRlcjtcblx0fTtcblxuXHRNZXNzYWdlUGFyc2VyLnByb3RvdHlwZSA9IHtcblxuXHRcdGNvbnN0cnVjdG9yOiBNZXNzYWdlUGFyc2VyLFxuXG5cdFx0c2ltcGxlUGFyc2U6IGZ1bmN0aW9uICggbWVzc2FnZSwgcGFyYW1ldGVycyApIHtcblx0XHRcdHJldHVybi
4060BtZXNzYWdlLnJlcGxhY2UoIC9cXCQoXFxkKykvZywgZnVuY3Rpb24gKCBzdHIsIG1hdGNoICkge1xuXHRcdFx0XHR2YXIgaW5kZXggPSBwYXJzZUludCggbWF0Y2gsIDEwICkgLSAxO1xuXG5cdFx0XHRcdHJldHVybiBwYXJhbWV0ZXJzWyBpbmRleCBdICE9PSB1bmRlZmluZWQgPyBwYXJhbWV0ZXJzWyBpbmRleCBdIDogJyQnICsgbWF0Y2g7XG5cdFx0XHR9ICk7XG5cdFx0fSxcblxuXHRcdHBhcnNlOiBmdW5jdGlvbiAoIG1lc3NhZ2UsIHJlcGxhY2VtZW50cyApIHtcblx0XHRcdGlmICggbWVzc2FnZS5pbmRleE9mKCAne3snICkgPCAwICkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5zaW1wbGVQYXJzZSggbWVzc2FnZSwgcmVwbGFjZW1lbnRzICk7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuZW1pdHRlci5sYW5ndWFnZSA9ICQuaTE4bi5sYW5ndWFnZXNbICQuaTE4bigpLmxvY2FsZSBdIHx8XG5cdFx0XHRcdCQuaTE4bi5sYW5ndWFnZXNbICdkZWZhdWx0JyBdO1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5lbWl0dGVyLmVtaXQoIHRoaXMuYXN0KCBtZXNzYWdlICksIHJlcGxhY2VtZW50cyApO1xuXHRcdH0sXG5cblx0XHRhc3Q6IGZ1bmN0aW9uICggbWVzc2FnZSApIHtcblx0XHRcdHZhciBwaXBlLCBjb2xvbiwgYmFja3NsYXNoLCBhbnlDaGFyYWN0ZXIsIGRvbGxhciwgZGlnaXRzLCByZWd1bGFyTGl0ZXJhbCxcblx0XHRcdFx0cmVndWxhckxpdGVyYWxXaXRob3V0QmFyLCByZWd1bGFyTGl0ZXJhbFdpdGhvdXRTcGFjZSwgZXNjYXBlZE9yTGl0ZXJhbFdpdGhvdXRCYXIsXG5cdFx0XHRcdGVzY2FwZWRPclJlZ3VsYXJMaXRlcmFsLCB0ZW1wbGF0ZUNvbnRlbnRzLCB0ZW1wbGF0ZU5hbWUsIG9wZW5UZW1wbGF0ZSxcblx0XHRcdFx0Y2xvc2VUZW1wbGF0ZSwgZXhwcmVzc2lvbiwgcGFyYW1FeHByZXNzaW9uLCByZXN1bHQsXG5cdFx0XHRcdHBvcyA9IDA7XG5cblx0XHRcdC8vIFRyeSBwYXJzZXJzIHVudGlsIG9uZSB3b3JrcywgaWYgbm9uZSB3b3JrIHJldHVybiBudWxsXG5cdFx0XHRmdW5jdGlvbiBjaG9pY2UoIHBhcnNlclN5bnRheCApIHtcblx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHR2YXIgaSwgcmVzdWx0O1xuXG5cdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBwYXJzZXJTeW50YXgubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHQgPSBwYXJzZXJTeW50YXhbIGkgXSgpO1xuXG5cdFx0XHRcdFx0XHRpZiAoIHJlc3VsdCAhPT0gbnVsbCApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVHJ5IHNldmVyYWwgcGFyc2VyU3ludGF4LWVzIGluIGEgcm93LlxuXHRcdFx0Ly8gQWxsIG11c3Qgc3VjY2VlZDsgb3RoZXJ3aXNlLCByZXR1cm4gbnVsbC5cblx0XHRcdC8vIFRoaXMgaXMgdGhlIG9ubHkgZWFnZXIgb25lLlxuXHRcdFx0ZnVuY3Rpb24gc2VxdWVuY2UoIHBhcnNlclN5bnRheCApIHtcblx0XHRcdFx0dmFyIGksIHJlcyxcblx0XHRcdFx0XHRvcmlnaW5hbFBvcyA9IHBvcyxcblx0XHRcdFx0XHRyZXN1bHQgPSBbXTtcblxuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IHBhcnNlclN5bnRheC5sZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0XHRyZXMgPSBwYXJzZXJTeW50YXhbIGkgXSgpO1xuXG5cdFx0XHRcdFx0aWYgKCByZXMgPT09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRwb3MgPSBvcmlnaW5hbFBvcztcblxuXHRcdFx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmVzdWx0LnB1c2goIHJlcyApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUnVuIHRoZSBzYW1lIHBhcnNlciBvdmVyIGFuZCBvdmVyIHVudGlsIGl0IGZhaWxzLlxuXHRcdFx0Ly8gTXVzdCBzdWNjZWVkIGEgbWluaW11bSBvZiBuIHRpbWVzOyBvdGhlcndpc2UsIHJldHVybiBudWxsLlxuXHRcdFx0ZnVuY3Rpb24gbk9yTW9yZSggbiwgcCApIHtcblx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHR2YXIgb3JpZ2luYWxQb3MgPSBwb3MsXG5cdFx0XHRcdFx0XHRyZXN1bHQgPSBbXSxcblx0XHRcdFx0XHRcdHBhcnNlZCA9IHAoKTtcblxuXHRcdFx0XHRcdHdoaWxlICggcGFyc2VkICE9PSBudWxsICkge1xuXHRcdFx0XHRcdFx0cmVzdWx0LnB1c2goIHBhcnNlZCApO1xuXHRcdFx0XHRcdFx0cGFyc2VkID0gcCgpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICggcmVzdWx0Lmxlbmd0aCA8IG4gKSB7XG5cdFx0XHRcdFx0XHRwb3MgPSBvcmlnaW5hbFBvcztcblxuXHRcdFx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSGVscGVycyAtLSBqdXN0IG1ha2UgcGFyc2VyU3ludGF4IG91dCBvZiBzaW1wbGVyIEpTIGJ1aWx0aW4gdHlwZXNcblxuXHRcdFx0ZnVuY3Rpb24gbWFrZVN0cmluZ1BhcnNlciggcyApIHtcblx0XHRcdFx0dmFyIGxlbiA9IHMubGVuZ3RoO1xuXG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIHJlc3VsdCA9IG51bGw7XG5cblx0XHRcdFx0XHRpZiAoIG1lc3NhZ2Uuc2xpY2UoIHBvcywgcG9zICsgbGVuICkgPT09IHMgKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHQgPSBzO1xuXHRcdFx0XHRcdFx0cG9zICs9IGxlbjtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRmdW5jdGlvbiBtYWtlUmVnZXhQYXJzZXIoIHJlZ2V4ICkge1xuXHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHZhciBtYXRjaGVzID0gbWVzc2FnZS5zbGljZSggcG9zICkubWF0Y2goIHJlZ2V4ICk7XG5cblx0XHRcdFx0XHRpZiAoIG1hdGNoZXMgPT09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRwb3MgKz0gbWF0Y2hlc1sgMCBdLmxlbmd0aDtcblxuXHRcdFx0XHRcdHJldHVybi
4060BtYXRjaGVzWyAwIF07XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdHBpcGUgPSBtYWtlU3RyaW5nUGFyc2VyKCAnfCcgKTtcblx0XHRcdGNvbG9uID0gbWFrZVN0cmluZ1BhcnNlciggJzonICk7XG5cdFx0XHRiYWNrc2xhc2ggPSBtYWtlU3RyaW5nUGFyc2VyKCAnXFxcXCcgKTtcblx0XHRcdGFueUNoYXJhY3RlciA9IG1ha2VSZWdleFBhcnNlciggL14uLyApO1xuXHRcdFx0ZG9sbGFyID0gbWFrZVN0cmluZ1BhcnNlciggJyQnICk7XG5cdFx0XHRkaWdpdHMgPSBtYWtlUmVnZXhQYXJzZXIoIC9eXFxkKy8gKTtcblx0XHRcdHJlZ3VsYXJMaXRlcmFsID0gbWFrZVJlZ2V4UGFyc2VyKCAvXltee31bXFxdJFxcXFxdLyApO1xuXHRcdFx0cmVndWxhckxpdGVyYWxXaXRob3V0QmFyID0gbWFrZVJlZ2V4UGFyc2VyKCAvXltee31bXFxdJFxcXFx8XS8gKTtcblx0XHRcdHJlZ3VsYXJMaXRlcmFsV2l0aG91dFNwYWNlID0gbWFrZVJlZ2V4UGFyc2VyKCAvXltee31bXFxdJFxcc10vICk7XG5cblx0XHRcdC8vIFRoZXJlIGlzIGEgZ2VuZXJhbCBwYXR0ZXJuOlxuXHRcdFx0Ly8gcGFyc2UgYSB0aGluZztcblx0XHRcdC8vIGlmIGl0IHdvcmtlZCwgYXBwbHkgdHJhbnNmb3JtLFxuXHRcdFx0Ly8gb3RoZXJ3aXNlIHJldHVybiBudWxsLlxuXHRcdFx0Ly8gQnV0IHVzaW5nIHRoaXMgYXMgYSBjb21iaW5hdG9yIHNlZW1zIHRvIGNhdXNlIHByb2JsZW1zXG5cdFx0XHQvLyB3aGVuIGNvbWJpbmVkIHdpdGggbk9yTW9yZSgpLlxuXHRcdFx0Ly8gTWF5IGJlIHNvbWUgc2NvcGluZyBpc3N1ZS5cblx0XHRcdGZ1bmN0aW9uIHRyYW5zZm9ybSggcCwgZm4gKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIHJlc3VsdCA9IHAoKTtcblxuXHRcdFx0XHRcdHJldHVybiByZXN1bHQgPT09IG51bGwgPyBudWxsIDogZm4oIHJlc3VsdCApO1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBVc2VkIHRvIGRlZmluZSBcImxpdGVyYWxzXCIgd2l0aGluIHRlbXBsYXRlIHBhcmFtZXRlcnMuIFRoZSBwaXBlXG5cdFx0XHQvLyBjaGFyYWN0ZXIgaXMgdGhlIHBhcmFtZXRlciBkZWxpbWV0ZXIsIHNvIGJ5IGRlZmF1bHRcblx0XHRcdC8vIGl0IGlzIG5vdCBhIGxpdGVyYWwgaW4gdGhlIHBhcmFtZXRlclxuXHRcdFx0ZnVuY3Rpb24gbGl0ZXJhbFdpdGhvdXRCYXIoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBuT3JNb3JlKCAxLCBlc2NhcGVkT3JMaXRlcmFsV2l0aG91dEJhciApKCk7XG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdCA9PT0gbnVsbCA/IG51bGwgOiByZXN1bHQuam9pbiggJycgKTtcblx0XHRcdH1cblxuXHRcdFx0ZnVuY3Rpb24gbGl0ZXJhbCgpIHtcblx0XHRcdFx0dmFyIHJlc3VsdCA9IG5Pck1vcmUoIDEsIGVzY2FwZWRPclJlZ3VsYXJMaXRlcmFsICkoKTtcblxuXHRcdFx0XHRyZXR1cm4gcmVzdWx0ID09PSBudWxsID8gbnVsbCA6IHJlc3VsdC5qb2luKCAnJyApO1xuXHRcdFx0fVxuXG5cdFx0XHRmdW5jdGlvbiBlc2NhcGVkTGl0ZXJhbCgpIHtcblx0XHRcdFx0dmFyIHJlc3VsdCA9IHNlcXVlbmNlKCBbIGJhY2tzbGFzaCwgYW55Q2hhcmFjdGVyIF0gKTtcblxuXHRcdFx0XHRyZXR1cm4gcmVzdWx0ID09PSBudWxsID8gbnVsbCA6IHJlc3VsdFsgMSBdO1xuXHRcdFx0fVxuXG5cdFx0XHRjaG9pY2UoIFsgZXNjYXBlZExpdGVyYWwsIHJlZ3VsYXJMaXRlcmFsV2l0aG91dFNwYWNlIF0gKTtcblx0XHRcdGVzY2FwZWRPckxpdGVyYWxXaXRob3V0QmFyID0gY2hvaWNlKCBbIGVzY2FwZWRMaXRlcmFsLCByZWd1bGFyTGl0ZXJhbFdpdGhvdXRCYXIgXSApO1xuXHRcdFx0ZXNjYXBlZE9yUmVndWxhckxpdGVyYWwgPSBjaG9pY2UoIFsgZXNjYXBlZExpdGVyYWwsIHJlZ3VsYXJMaXRlcmFsIF0gKTtcblxuXHRcdFx0ZnVuY3Rpb24gcmVwbGFjZW1lbnQoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBzZXF1ZW5jZSggWyBkb2xsYXIsIGRpZ2l0cyBdICk7XG5cblx0XHRcdFx0aWYgKCByZXN1bHQgPT09IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gWyAnUkVQTEFDRScsIHBhcnNlSW50KCByZXN1bHRbIDEgXSwgMTAgKSAtIDEgXTtcblx0XHRcdH1cblxuXHRcdFx0dGVtcGxhdGVOYW1lID0gdHJhbnNmb3JtKFxuXHRcdFx0XHQvLyBzZWUgJHdnTGVnYWxUaXRsZUNoYXJzXG5cdFx0XHRcdC8vIG5vdCBhbGxvd2luZyA6IGR1ZSB0byB0aGUgbmVlZCB0byBjYXRjaCBcIlBMVVJBTDokMVwiXG5cdFx0XHRcdG1ha2VSZWdleFBhcnNlciggL15bICFcIiQmJygpKiwuLzAtOTs9P0BBLVpeX2BhLXp+XFx4ODAtXFx4RkYrLV0rLyApLFxuXG5cdFx0XHRcdGZ1bmN0aW9uICggcmVzdWx0ICkge1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQudG9TdHJpbmcoKTtcblx0XHRcdFx0fVxuXHRcdFx0KTtcblxuXHRcdFx0ZnVuY3Rpb24gdGVtcGxhdGVQYXJhbSgpIHtcblx0XHRcdFx0dmFyIGV4cHIsXG5cdFx0XHRcdFx0cmVzdWx0ID0gc2VxdWVuY2UoIFsgcGlwZSwgbk9yTW9yZSggMCwgcGFyYW1FeHByZXNzaW9uICkgXSApO1xuXG5cdFx0XHRcdGlmICggcmVzdWx0ID09PSBudWxsICkge1xuXHRcdFx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZXhwciA9IHJlc3VsdFsgMSBdO1xuXG5cdFx0XHRcdC8vIHVzZSBhIFwiQ09OQ0FUXCIgb3BlcmF0b3IgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG5vZGVzLFxuXHRcdFx0XHQvLyBvdGhlcndpc2UgcmV0dXJuIHRoZSBmaXJzdCBub2RlLCByYXcuXG5cdFx0XHRcdHJldHVybiBleHByLmxlbmd0aCA+IDEgPyBbICdDT05DQVQnIF0uY29uY2F0KCBleHByICkgOiBleHByWyAwIF07XG5cdFx0XHR9XG5cblx0XHRcdGZ1bmN0aW9uIHRlbXBsYXRlV2l0aFJlcGxhY2VtZW50KCkge1xuXHRcdFx0XHR2YXIgcmVzdWx0ID0gc2VxdWVuY2UoIFsgdGVtcGxhdGVOYW1lLCBjb2xvbiwgcmVwbGFjZW1lbnQgXSApO1xuXG5cdFx0XHRcdHJldHVybiByZXN1bHQgPT09IG51bGwgPyBudWxsIDogWyByZXN1bHRbIDAgXSwgcmVzdWx0WyAyIF0gXTtcblx0XHRcdH1cblxuXHRcdFx0ZnVuY3Rpb24gdGVtcGxhdGVXaXRoT3V0UmVwbGFjZW1lbnQoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBzZXF1ZW5jZSggWyB0ZW1wbGF0ZU5hbWUsIGNvbG9uLCBwYXJhbUV4cHJlc3Npb24gXSApO
40601xuXG5cdFx0XHRcdHJldHVybiByZXN1bHQgPT09IG51bGwgPyBudWxsIDogWyByZXN1bHRbIDAgXSwgcmVzdWx0WyAyIF0gXTtcblx0XHRcdH1cblxuXHRcdFx0dGVtcGxhdGVDb250ZW50cyA9IGNob2ljZSggW1xuXHRcdFx0XHRmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIHJlcyA9IHNlcXVlbmNlKCBbXG5cdFx0XHRcdFx0XHQvLyB0ZW1wbGF0ZXMgY2FuIGhhdmUgcGxhY2Vob2xkZXJzIGZvciBkeW5hbWljXG5cdFx0XHRcdFx0XHQvLyByZXBsYWNlbWVudCBlZzoge3tQTFVSQUw6JDF8b25lIGNhcnwkMSBjYXJzfX1cblx0XHRcdFx0XHRcdC8vIG9yIG5vIHBsYWNlaG9sZGVycyBlZzpcblx0XHRcdFx0XHRcdC8vIHt7R1JBTU1BUjpnZW5pdGl2ZXx7e1NJVEVOQU1FfX19XG5cdFx0XHRcdFx0XHRjaG9pY2UoIFsgdGVtcGxhdGVXaXRoUmVwbGFjZW1lbnQsIHRlbXBsYXRlV2l0aE91dFJlcGxhY2VtZW50IF0gKSxcblx0XHRcdFx0XHRcdG5Pck1vcmUoIDAsIHRlbXBsYXRlUGFyYW0gKVxuXHRcdFx0XHRcdF0gKTtcblxuXHRcdFx0XHRcdHJldHVybiByZXMgPT09IG51bGwgPyBudWxsIDogcmVzWyAwIF0uY29uY2F0KCByZXNbIDEgXSApO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIHJlcyA9IHNlcXVlbmNlKCBbIHRlbXBsYXRlTmFtZSwgbk9yTW9yZSggMCwgdGVtcGxhdGVQYXJhbSApIF0gKTtcblxuXHRcdFx0XHRcdGlmICggcmVzID09PSBudWxsICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIFsgcmVzWyAwIF0gXS5jb25jYXQoIHJlc1sgMSBdICk7XG5cdFx0XHRcdH1cblx0XHRcdF0gKTtcblxuXHRcdFx0b3BlblRlbXBsYXRlID0gbWFrZVN0cmluZ1BhcnNlciggJ3t7JyApO1xuXHRcdFx0Y2xvc2VUZW1wbGF0ZSA9IG1ha2VTdHJpbmdQYXJzZXIoICd9fScgKTtcblxuXHRcdFx0ZnVuY3Rpb24gdGVtcGxhdGUoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBzZXF1ZW5jZSggWyBvcGVuVGVtcGxhdGUsIHRlbXBsYXRlQ29udGVudHMsIGNsb3NlVGVtcGxhdGUgXSApO1xuXG5cdFx0XHRcdHJldHVybiByZXN1bHQgPT09IG51bGwgPyBudWxsIDogcmVzdWx0WyAxIF07XG5cdFx0XHR9XG5cblx0XHRcdGV4cHJlc3Npb24gPSBjaG9pY2UoIFsgdGVtcGxhdGUsIHJlcGxhY2VtZW50LCBsaXRlcmFsIF0gKTtcblx0XHRcdHBhcmFtRXhwcmVzc2lvbiA9IGNob2ljZSggWyB0ZW1wbGF0ZSwgcmVwbGFjZW1lbnQsIGxpdGVyYWxXaXRob3V0QmFyIF0gKTtcblxuXHRcdFx0ZnVuY3Rpb24gc3RhcnQoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBuT3JNb3JlKCAwLCBleHByZXNzaW9uICkoKTtcblxuXHRcdFx0XHRpZiAoIHJlc3VsdCA9PT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBbICdDT05DQVQnIF0uY29uY2F0KCByZXN1bHQgKTtcblx0XHRcdH1cblxuXHRcdFx0cmVzdWx0ID0gc3RhcnQoKTtcblxuXHRcdFx0Lypcblx0XHRcdCAqIEZvciBzdWNjZXNzLCB0aGUgcG9zIG11c3QgaGF2ZSBnb3R0ZW4gdG8gdGhlIGVuZCBvZiB0aGUgaW5wdXRcblx0XHRcdCAqIGFuZCByZXR1cm5lZCBhIG5vbi1udWxsLlxuXHRcdFx0ICogbi5iLiBUaGlzIGlzIHBhcnQgb2YgbGFuZ3VhZ2UgaW5mcmFzdHJ1Y3R1cmUsIHNvIHdlIGRvIG5vdCB0aHJvdyBhblxuXHRcdFx0ICogaW50ZXJuYXRpb25hbGl6YWJsZSBtZXNzYWdlLlxuXHRcdFx0ICovXG5cdFx0XHRpZiAoIHJlc3VsdCA9PT0gbnVsbCB8fCBwb3MgIT09IG1lc3NhZ2UubGVuZ3RoICkge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoICdQYXJzZSBlcnJvciBhdCBwb3NpdGlvbiAnICsgcG9zLnRvU3RyaW5nKCkgKyAnIGluIGlucHV0OiAnICsgbWVzc2FnZSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH1cblxuXHR9O1xuXG5cdCQuZXh0ZW5kKCAkLmkxOG4ucGFyc2VyLCBuZXcgTWVzc2FnZVBhcnNlcigpICk7XG59KCBqUXVlcnkgKSApOyIsInZhciBjb2RlRXhlcmNpc2VzO1xudmFyIHByZXNlbnRlckNzc0xpbms7XG52YXIgcHJlc2VudE1vZGVJbml0aWFsaXplZCA9IGZhbHNlO1xuXG5mdW5jdGlvbiBwcmVzZW50VG9nZ2xlKCkge1xuICAgIGlmICghcHJlc2VudE1vZGVJbml0aWFsaXplZCkge1xuICAgICAgICBwcmVzZW50TW9kZVNldHVwKCk7XG4gICAgICAgIHByZXNlbnRNb2RlSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIH1cbiAgICBsZXQgYm9kID0gJChcImJvZHlcIik7XG4gICAgbGV0IHByZXNlbnRDbGFzcyA9IFwicHJlc2VudFwiO1xuICAgIGxldCBmdWxsSGVpZ2h0Q2xhc3MgPSBcImZ1bGwtaGVpZ2h0XCI7XG4gICAgbGV0IGJvdHRvbUNsYXNzID0gXCJib3R0b21cIjtcbiAgICBpZiAoYm9kLmhhc0NsYXNzKHByZXNlbnRDbGFzcykpIHtcbiAgICAgICAgJChcInNlY3Rpb24gKlwiKVxuICAgICAgICAgICAgLm5vdChcbiAgICAgICAgICAgICAgICBcImgxLCAucHJlc2VudGF0aW9uLXRpdGxlLCAuYnRuLXByZXNlbnRlciwgLnJ1bmVzdG9uZSwgLnJ1bmVzdG9uZSAqLCBzZWN0aW9uLCAucHJlLCBjb2RlXCJcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhcImhpZGRlblwiKTsgLy9zaG93IGV2ZXJ5dGhpbmdcbiAgICAgICAgJChcIiNjb21wbGV0aW9uQnV0dG9uXCIpLnJlbW92ZUNsYXNzKFwiaGlkZGVuXCIpO1xuICAgICAgICBib2QucmVtb3ZlQ2xhc3MocHJlc2VudENsYXNzKTtcbiAgICAgICAgJChcIi5cIiArIGZ1bGxIZWlnaHRDbGFzcykucmVtb3ZlQ2xhc3MoZnVsbEhlaWdodENsYXNzKTtcbiAgICAgICAgJChcIi5cIiArIGJvdHRvbUNsYXNzKS5yZW1vdmVDbGFzcyhib3R0b21DbGFzcyk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFwicHJlc2VudE1vZGVcIiwgXCJ0ZXh0XCIpO1xuICAgICAgICBjb2RlRXhlcmNpc2VzLnJlbW92ZUNsYXNzKFwiaGlkZGVuXCIpO1xuICAgICAgICBwcmVzZW50ZXJDc3NMaW5rLmRpc2FibGVkID0gdHJ1ZTsgLy8gZGlzYWJsZSBwcmVzZW50X21vZGUuY3NzXG4gICAgfSBlbHNlIHtcbiAgICAgICAgJChcInNlY3Rpb24gKlwiKVxuICAgICAgICAgICAgLm5vdChcbiAgICAgICAgICAgICAgICBcImgxLCAucHJlc2VudGF0aW9uLXRpdGxlLCAuYnRuLXByZXNlbnRlciwgLnJ1bmVzdG9uZSwgLnJ1bmVzdG9uZSAqLCBzZWN0aW9uLCAucHJlLCBjb2RlXCJcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5hZGRDbGFzcyhcImhpZGRlblwiKTsgLy8gaGlkZSBleHRyYW5lb3VzIHN0dWZmXG4gICAgICAgICQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5hZGRDbGFzcyhcImhpZGRlblwiKTtcbiAgICAgICAgYm9kLmFkZENsYXNzKHByZXNlbnRDbGFzcyk7XG4gICAgICAgIGJvZC5hZGRDbGFzcyhmdWxsSGVpZ2h0Q2xhc3MpO1xuICAgICAgICAkKFwiaHRtbFwiKS5hZGRDbGFzcyhmdWxsSGVpZ2h0Q2xhc3MpO1xuICAgICAgICAkKFwic2VjdGlvbiAucnVuZXN0b25lXCIpLmFkZENsYXNzKGZ1bGxIZWlnaHRDbGFzcyk7XG4gICAgICAgICQoXCIuYWMtY2FwdGlvblwiKS5hZGRDbGFzcyhib3R0b21DbGFzcyk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFwicHJlc2VudE1vZGVcIiwgcHJlc2VudENsYXNzKTtcbiAgICAgICAgLy8gcHJlc2VudGVyX21vZGUuY3NzIGlzIGxvYWRlZCBieSB3ZWJwYWNrXG4gICAgICAgIC8vbG9hZFByZXNlbnRlckNzcygpOyAvLyBwcmVzZW50X21vZGUuY3NzIHNob3VsZCBvbmx5IGFwcGx5IHdoZW4gaW4gcHJlc2VudGVyIG1vZGUuXG4gICAgICAgIGFjdGl2YXRlRXhlcmNpc2UoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvYWRQcmVzZW50ZXJDc3MoKSB7XG4gICAgcHJlc2VudGVyQ3NzTGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJsaW5rXCIpO1xuICAgIHByZXNlbnRlckNzc0xpbmsudHlwZSA9IFwidGV4dC9jc3NcIjtcbiAgICBwcmVzZW50ZXJDc3NMaW5rLmhyZWYgPSBcIi4uL19zdGF0aWMvcHJlc2VudGVyX21vZGUuY3NzXCI7XG4gICAgcHJlc2VudGVyQ3NzTGluay5yZWwgPSBcInN0eWxlc2hlZXRcIjtcbiAgICBkb2
4060N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQocHJlc2VudGVyQ3NzTGluayk7XG59XG5cbmZ1bmN0aW9uIHByZXNlbnRNb2RlU2V0dXAoKSB7XG4gICAgLy8gbW92ZWQgdGhpcyBvdXQgb2YgY29uZmlndXJlXG4gICAgbGV0IGRhdGFDb21wb25lbnQgPSAkKFwiW2RhdGEtY2hpbGRjb21wb25lbnRdXCIpO1xuXG4gICAgLy8gdGhpcyBzdGlsbCBsZWF2ZXMgc29tZSB0aGluZ3Mgc2VtaS1tZXNzZWQgdXAgd2hlbiB5b3UgZXhpdCBwcmVzZW50ZXIgbW9kZS5cbiAgICAvLyBidXQgaW5zdHJ1Y3RvcnMgd2lsbCBwcm9iYWJseSBqdXN0IGxlYXJuIHRvIHJlZnJlc2ggdGhlIHBhZ2UuXG4gICAgZGF0YUNvbXBvbmVudC5hZGRDbGFzcyhcInJ1bmVzdG9uZVwiKTtcbiAgICBkYXRhQ29tcG9uZW50LnBhcmVudCgpLmNsb3Nlc3QoXCJkaXZcIikubm90KFwic2VjdGlvblwiKS5hZGRDbGFzcyhcInJ1bmVzdG9uZVwiKTtcbiAgICBkYXRhQ29tcG9uZW50LnBhcmVudCgpLmNsb3Nlc3QoXCJkaXZcIikuY3NzKFwibWF4LXdpZHRoXCIsIFwibm9uZVwiKTtcblxuICAgIGRhdGFDb21wb25lbnQuZWFjaChmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICAgICAgbGV0IG1lID0gJCh0aGlzKTtcbiAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgLmZpbmQoXCIuYWNfY29kZV9kaXYsIC5hY19vdXRwdXRcIilcbiAgICAgICAgICAgIC53cmFwQWxsKFwiPGRpdiBjbGFzcz0nYWMtYmxvY2snIHN0eWxlPSd3aWR0aDogMTAwJTsnPjwvZGl2PlwiKTtcbiAgICB9KTtcblxuICAgIGNvZGVsZW5zTGlzdGVuZXIoNTAwKTtcbiAgICAkKFwic2VjdGlvbiBpbWdcIikud3JhcCgnPGRpdiBjbGFzcz1cInJ1bmVzdG9uZVwiPicpO1xuICAgIGNvZGVFeGVyY2lzZXMgPSAkKFwiLnJ1bmVzdG9uZVwiKS5ub3QoXCIucnVuZXN0b25lIC5ydW5lc3RvbmVcIik7XG4gICAgLy8gY29
4060kZUV4ZXJjaXNlcy5lYWNoKGZ1bmN0aW9uKCl7XG4gICAgJChcImgxXCIpLmJlZm9yZShcbiAgICAgICAgXCI8ZGl2IGNsYXNzPSdwcmVzZW50YXRpb24tdGl0bGUnPiBcXFxuICAgICAgICA8YnV0dG9uIGNsYXNzPSdwcmV2LWV4ZXJjaXNlIGJ0bi1wcmVzZW50ZXIgYnRuLWdyZXktb3V0bGluZScgb25jbGljaz0ncHJldkV4ZXJjaXNlKCknPkJhY2s8L2J1dHRvbj4gXFxcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz0nbmV4dC1leGVyY2lzZSBidG4tcHJlc2VudGVyIGJ0bi1ncmV5LXNvbGlkJyBvbmNsaWNrPSduZXh0RXhlcmNpc2UoKSc+TmV4dDwvYnV0dG9uPiBcXFxuICAgICAgPC9kaXY+XCJcbiAgICApO1xufVxuZnVuY3Rpb24gZ2V0QWN0aXZlRXhlcmNpc2UoKSB7XG4gICAgcmV0dXJuIChhY3RpdmUgPSBjb2RlRXhlcmNpc2VzLmZpbHRlcihcIi5hY3RpdmVcIikpO1xufVxuXG5mdW5jdGlvbiBhY3RpdmF0ZUV4ZXJjaXNlKGluZGV4KSB7XG4gICAgaWYgKHR5cGVvZiBpbmRleCA9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIGluZGV4ID0gMDtcbiAgICB9XG5cbiAgICBsZXQgYWN0aXZlID0gZ2V0QWN0aXZlRXhlcmNpc2UoKTtcblxuICAgIGlmIChjb2RlRXhlcmNpc2VzLmxlbmd0aCkge1xuICAgICAgICBhY3RpdmUucmVtb3ZlQ2xhc3MoXCJhY3RpdmVcIik7XG4gICAgICAgIGFjdGl2ZSA9ICQoY29kZUV4ZXJjaXNlc1tpbmRleF0pLmFkZENsYXNzKFwiYWN0aXZlXCIpO1xuICAgICAgICBhY3RpdmUucmVtb3ZlQ2xhc3MoXCJoaWRkZW5cIik7XG4gICAgICAgIGNvZGVFeGVyY2lzZXMubm90KGNvZGVFeGVyY2lzZXMuZmlsdGVyKFwiLmFjdGl2ZVwiKSkuYWRkQ2xhc3MoXCJoaWRkZW5cIik7XG4gICAgfVxufVxuXG53aW5kb3cubmV4dEV4ZXJjaXNlID0gZnVuY3Rpb24oKSB7XG4gICAgbGV0IGFjdGl2ZSA9IGdldEFjdGl2ZUV4ZXJjaXNlKCk7XG4gICAgbGV0IG5leHRJbmRleCA9IGNvZGVFeGVyY2lzZXMuaW5kZXgoYWN0aXZlKSArIDE7XG4gICAgaWYgKG5leHRJbmRleCA8IGNvZGVFeGVyY2lzZXMubGVuZ3RoKSB7XG4gICAgICAgIGFjdGl2YXRlRXhlcmNpc2UobmV4dEluZGV4KTtcbiAgICB9XG59XG5cbndpbmRvdy5wcmV2RXhlcmNpc2UgPSBmdW5jdGlvbigpIHtcbiAgICBsZXQgYWN0aXZlID0gZ2V0QWN0aXZlRXhlcmNpc2UoKTtcbiAgICBsZXQgcHJldkluZGV4ID0gY29kZUV4ZXJjaXNlcy5pbmRleChhY3RpdmUpIC0gMTtcbiAgICBpZiAocHJldkluZGV4ID49IDApIHtcbiAgICAgICAgYWN0aXZhdGVFeGVyY2lzZShwcmV2SW5kZXgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY29uZmlndXJlKCkge1xuICAgIGxldCByaWdodE5hdiA9ICQoXCIubmF2YmFyLXJpZ2h0XCIpO1xuICAgIHJpZ2h0TmF2LnByZXBlbmQoXG4gICAgICAgIFwiPGxpIGNsYXNzPSdkcm9wZG93biB2aWV3LXRvZ2dsZSc+IFxcXG4gICAgICA8bGFiZWw+VmlldzogXFxcbiAgICAgICAgPHNlbGVjdCBjbGFzcz0nbW9kZS1zZWxlY3QnPiBcXFxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9J3RleHQnPlRleHRib29rPC9vcHRpb24+IFxcXG4gICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ncHJlc2VudCc+Q29kZSBQcmVzZW50ZXI8L29wdGlvbj4gXFxcbiAgICAgICAgPC9zZWxlY3Q+IFxcXG4gICAgICA8L2xhYmVsPiBcXFxuICAgIDwvbGk+XCJcbiAgICApO1xuXG4gICAgbGV0IG1vZGVTZWxlY3QgPSAkKFwiLm1vZGUtc2VsZWN0XCIpLmNoYW5nZShwcmVzZW50VG9nZ2xlKTtcbn1cblxuZnVuY3Rpb24gY29kZWxlbnNMaXN0ZW5lcihkdXJhdGlvbikge1xuICAgIC8vICQoXCIuRXhlY3V0aW9uVmlzdWFsaXplclwiKS5sZW5ndGggPyBjb25maWd1cmVDb2RlbGVucygpIDogc2V0VGltZW91dChjb2RlbGVuc0xpc3RlbmVyLCBkdXJhdGlvbik7XG4gICAgLy8gY29uZmlndXJlQ29kZWxlbnMoKTtcbn1cblxuZnVuY3Rpb24gY29uZmlndXJlQ29kZWxlbnMoKSB7XG4gICAgbGV0IGFjQ29kZVRpdGxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImg0XCIpO1xuICAgIGFjQ29kZVRpdGxlLnRleHRDb250ZW50ID0gXCJBY3RpdmUgQ29kZSBXaW5kb3dcIjtcbiAgICBsZXQgYWNDb2RlID0gJChcIi5hY19jb2RlX2RpdlwiKTtcbiAgICAkKFwiLmFjX2NvZGVfZGl2XCIpLmFkZENsYXNzKFwiY29sLW1kLTZcIik7XG4gICAgYWNDb2RlLnByZXBlbmQoYWNDb2RlVGl0bGUpO1xuXG4gICAgYWNPdXRUaXRsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJoNFwiKTtcbiAgICBhY091dFRpdGxlLnRleHRDb250ZW50ID0gXCJPdXRwdXQgV2luZG93XCI7XG4gICAgbGV0IGFjT3V0ID0gJChcIi5hY19vdXRwdXRcIikuYWRkQ2xhc3MoXCJjb2wtbWQtNlwiKTtcbiAgICAkKFwiLmFjX291dHB1dFwiKS5wcmVwZW5kKGFjT3V0VGl0bGUpO1xuXG4gICAgbGV0IHNrZXRjaHBhZFRpdGxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImg0XCIpO1xuICAgIHNrZXRjaHBhZFRpdGxlLnRleHRDb250ZW50ID0gXCJTa2V0Y2hwYWRcIjtcbiAgICBsZXQgc2tldGNocGFkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIik7XG4gICAgJChza2V0Y2hwYWQpLmFkZENsYXNzKFwic2tldGNocGFkXCIpO1xuICAgIGxldCBza2V0Y2hwYWRDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICQoc2tldGNocGFkQ29udGFpbmVyKS5hZGRDbGFzcyhcInNrZXRjaHBhZC1jb250YWluZXJcIik7XG4gICAgc2tldGNocGFkQ29udGFpbmVyLmFwcGVuZENoaWxkKHNrZXRjaHBhZFRpdGxlKTtcbiAgICBza2V0Y2hwYWRDb250YWluZXIuYXBwZW5kQ2hpbGQoc2tldGNocGFkKTtcbiAgICAvLyQoJ
4060y5hY19vdXRwdXQnKS5hcHBlbmQoc2tldGNocGFkQ29udGFpbmVyKTtcblxuICAgIGxldCB2aXN1YWxpemVycyA9ICQoXCIuRXhlY3V0aW9uVmlzdWFsaXplclwiKTtcblxuICAgIGNvbnNvbGUubG9nKFwiRWNvbnRhaW5lcjogXCIsIHRoaXMuZUNvbnRhaW5lcik7XG5cbiAgICAkKFwiW2RhdGEtY2hpbGRjb21wb25lbnRdXCIpLm9uKFwiY2xpY2tcIiwgXCJidXR0b24ucm93LW1vZGVcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAkKHRoaXMpLmNsb3Nlc3QoXCJbZGF0YS1jaGlsZGNvbXBvbmVudF1cIikucmVtb3ZlQ2xhc3MoXCJjYXJkLW1vZGVcIik7XG4gICAgICAgICQodGhpcykuY2xvc2VzdChcIltkYXRhLWNoaWxkY29tcG9uZW50XVwiKS5hZGRDbGFzcyhcInJvdy1tb2RlXCIpO1xuICAgICAgICAkKHRoaXMpLm5leHQoXCIuY2FyZC1tb2RlXCIpLnJlbW92ZUNsYXNzKFwiYWN0aXZlLWxheW91dFwiKTtcbiAgICAgICAgJCh0aGlzKS5hZGRDbGFzcyhcImFjdGl2ZS1sYXlvdXRcIik7XG4gICAgfSk7XG5cbiAgICAkKFwiW2RhdGEtY2hpbGRjb21wb25lbnRdXCIpLm9uKFwiY2xpY2tcIiwgXCJidXR0b24uY2FyZC1tb2RlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCh0aGlzKS5jbG9zZXN0KFwiW2RhdGEtY2hpbGRjb21wb25lbnRdXCIpLnJlbW92ZUNsYXNzKFwicm93LW1vZGVcIik7XG4gICAgICAgICQodGhpcykuY2xvc2VzdChcIltkYXRhLWNoaWxkY29tcG9uZW50XVwiKS5hZGRDbGFzcyhcImNhcmQtbW9kZVwiKTtcbiAgICAgICAgJCh0aGlzKS5wcmV2KFwiLnJvdy1tb2RlXCIpLnJlbW92ZUNsYXNzKFwiYWN0aXZlLWxheW91dFwiKTtcbiAgICAgICAgJCh0aGlzKS5hZGRDbGFzcyhcImFjdGl2ZS1sYXlvdXRcIik7XG4gICAgfSk7XG5cbiAgICAkK
4060FwiW2RhdGEtY2hpbGRjb21wb25lbnRdIC5hY19zZWN0aW9uXCIpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAkKHRoaXMpLnByZXBlbmQoXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cInByZXNlbnRhdGlvbi1vcHRpb25zXCI+PGJ1dHRvbiBjbGFzcz1cInJvdy1tb2RlIGxheW91dC1idG5cIj48aW1nIHNyYz1cIi4uL19pbWFnZXMvcm93LWJ0bi1jb250ZW50LnBuZ1wiIGFsdD1cIlJvd3NcIj48L2J1dHRvbj48YnV0dG9uIGNsYXNzPVwiY2FyZC1tb2RlIGxheW91dC1idG5cIj48aW1nIHNyYz1cIi4uL19pbWFnZXMvY2FyZC1idG4tY29udGVudC5wbmdcIiBhbHQ9XCJDYXJkXCI+PC9idXR0b24+PC9kaXY+J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgdmlzdWFsaXplcnMuZWFjaChmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICAgICAgbGV0IG1lID0gJCh0aGlzKTtcbiAgICAgICAgbGV0IGNvbDEgPSBtZS5maW5kKFwiI3ZpekxheW91dFRkRmlyc3RcIik7XG4gICAgICAgIGxldCBjb2wyID0gbWUuZmluZChcIiN2aXpMYXlvdXRUZFNlY29uZFwiKTtcbiAgICAgICAgbGV0IGRhdGFWaXMgPSBtZS5maW5kKFwiI2RhdGFWaXpcIik7XG4gICAgICAgIGxldCBzdGFja0hlYXBUYWJsZSA9IG1lLmZpbmQoXCIjc3RhY2tIZWFwVGFibGVcIik7XG4gICAgICAgIGxldCBvdXRwdXQgPSBtZS5maW5kKFwiI3Byb2dPdXRwdXRzXCIpO1xuICAgICAgICBvdXRwdXQuY3NzKFwiZGlzcGxheVwiLCBcImJsb2NrXCIpO1xuICAgICAgICBtZS5wYXJlbnQoKS5wcmVwZW5kKFxuICAgICAgICAgICAgXCI8ZGl2IGNsYXNzPSdwcmVzZW50YXRpb24tdGl0bGUnPjxkaXYgY2xhc3M9J3RpdGxlLXRleHQnPiBFeGFtcGxlIFwiICtcbiAgICAgICAgICAgICAgICAoTnVtYmVyKGluZGV4KSArIDEpICtcbiAgICAgICAgICAgICAgICBcIjwvZGl2PjwvZGl2PlwiXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBhY0NvZGUuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBzZWN0aW9uID0gJCh0aGlzKS5jbG9zZXN0KFwiLmFjLWJsb2NrXCIpLnBhcmVudCgpO1xuICAgICAgICBjb25zb2xlLmxvZyhzZWN0aW9uLCBzZWN0aW9uLmxlbmd0aCk7XG4gICAgICAgIHNlY3Rpb24uYXBwZW5kKHNrZXRjaHBhZENvbnRhaW5lcik7XG4gICAgfSk7XG5cbiAgICAkK
4060FwiYnV0dG9uLmNhcmQtbW9kZVwiKS5jbGljaygpO1xuXG4gICAgbGV0IG1vZGVTZWxlY3QgPSAkKFwiLm1vZGUtc2VsZWN0XCIpO1xuICAgIGxldCBtb2RlID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJwcmVzZW50TW9kZVwiKTtcbiAgICBpZiAobW9kZSA9PSBcInByZXNlbnRcIikge1xuICAgICAgICBtb2RlU2VsZWN0LnZhbChcInByZXNlbnRcIik7XG4gICAgICAgIG1vZGVTZWxlY3QuY2hhbmdlKCk7XG4gICAgfVxufVxuXG4kKGRvY3VtZW50KS5vbihcInJ1bmVzdG9uZTpsb2dpbi1jb21wbGV0ZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgLy8gaWYgdXNlciBpcyBpbnN0cnVjdG9yLCBlbmFibGUgcHJlc2VudGVyIG1vZGVcbiAgICBpZiAoZUJvb2tDb25maWcuaXNJbnN0cnVjdG9yKSB7XG4gICAgICAgIGNvbmZpZ3VyZSgpO1xuICAgIH1cbn0pO1xuIiwiLypcbiAgICBTdXBwb3J0IGZ1bmN0aW9ucyBmb3IgUHJlVGVYdCBib29rcyBydW5uaW5nIG9uIFJ1bmVzdG9uZVxuXG4qL1xuXG5pbXBvcnQgUnVuZXN0b25lQmFzZSBmcm9tIFwiLi9ydW5lc3RvbmViYXNlLmpzXCI7XG5cbmZ1bmN0aW9uIHNldHVwUFRYRXZlbnRzKCkge1xuICAgIGxldCByYiA9IG5ldyBSdW5lc3RvbmVCYXNlKCk7XG4gICAgLy8gbG9nIGFuIGV2ZW50IHdoZW4gYSBrbm93bCBpcyBvcGVuZWQuXG4gICAgJChcIltkYXRhLWtub3dsXCIpLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgZGl2X2lkID0gJCh0aGlzKS5kYXRhKFwicmVmaWRcIik7XG4gICAgICAgIHJiLmxvZ0Jvb2tFdmVudCh7IGV2ZW50OiBcImtub3dsXCIsIGFjdDogXCJjbGlja1wiLCBkaXZfaWQ6IGRpdl9pZCB9KTtcbiAgICB9KTtcbiAgICAvLyBsb2cgYW4gZXZlbnQgd2hlbiBhIHNhZ2UgY2VsbCBpcyBldmFsdWF0ZWRcbiAgICAkKFwiLnNhZ2VjZWxsX2V2YWxCdXR0b25cIikub24oXCJjbGlja1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIGZpbmQgcGFyZW50c1xuICAgICAgICBsZXQgY29udGFpbmVyID0gJCh0aGlzKS5jbG9zZXN0KFwiLnNhZ2VjZWxsLXNhZ2VcIik7XG4gICAgICAgIGxldCBjb2RlID0gJChjb250YWluZXJbMF0pLmZpbmQoXCIuc2FnZWNlbGxfaW5wdXRcIilbMF0udGV4dENvbnRlbnQ7XG4gICAgICAgIHJiLmxvZ0Jvb2tFdmVudCh7IGV2ZW50OiBcInNhZ2VcIiwgYWN0OiBcInJ1blwiLCBkaXZfaWQ6IGNvbnRhaW5lclswXS5pZCB9KTtcbiAgICB9KTtcbiAgICBpZiAoIWVCb29rQ29uZmlnLmlzSW5zdHJ1Y3Rvcikge1xuICAgICAgICAkKFwiLmNvbW1lbnRhcnlcIikuaGlkZSgpO1xuICAgIH1cbn1cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zb2xlLmxvZyhcInNldHRpbmcgdXAgcHJldGV4dFwiKTtcbiAgICBzZXR1cFBUWEV2ZW50cygpO1xuICAgIGxldCB3cmFwID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwcmltYXJ5LW5hdmJhci1zdGlja3ktd3JhcHBlclwiKTtcbiAgICBpZiAod3JhcCkge1xuICAgICAgICB3cmFwLnN0eWxlLm92ZXJmbG93PVwidmlzaWJsZVwiO1xuICAgIH1cbn0pO1xuIiwiLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIHxkb2NuYW1lfCAtIFJ1bmVzdG9uZSBCYXNlIENsYXNzXG4gKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogQWxsIHJ1bmVzdG9uZSBjb21wb25lbnRzIHNob3VsZCBpbmhlcml0IGZyb20gUnVuZXN0b25lQmFzZS4gSW4gYWRkaXRpb24gYWxsIHJ1bmVzdG9uZSBjb21wb25lbnRzIHNob3VsZCBkbyB0aGUgZm9sbG93aW5nIHRoaW5nczpcbiAqXG4gKiAxLiAgIEVuc3VyZSB0aGF0IHRoZXkgYXJlIHdyYXBwZWQgaW4gYSBkaXYgd2l0aCB0aGUgY2xhc3MgcnVuZXN0b25lXG4gKiAyLiAgIFdyaXRlIHRoZWlyIHNvdXJjZSBBTkQgdGhlaXIgZ2VuZXJhdGVkIGh0bWwgdG8gdGhlIGRhdGFiYXNlIGlmIHRoZSBkYXRhYmFzZSBpcyBjb25maWd1cmVkXG4gKiAzLiAgIFByb3Blcmx5IHNhdmUgYW5kIHJlc3RvcmUgdGhlaXIgYW5zd2VycyB1c2luZyB0aGUgY2hlY2tTZXJ2ZXIgbWVjaGFuaXNtIGluIHRoaXMgYmFzZSBjbGFzcy4gRWFjaCBjb21wb25lbnQgbXVzdCBwcm92aWRlIGFuIGltcGxlbWVudGF0aW9uIG9mOlxuICpcbiAqICAgICAgLSAgICBjaGVja0xvY2FsU3RvcmFnZVxuICogICAgICAtICAgIHNldExvY2FsU3RvcmFnZVxuICogICAgICAtICAgIHJlc3RvcmVBbnN3ZXJzXG4gKiAgICAgIC0gICAgZGlzYWJsZUludGVyYWN0aW9uXG4gKlxuICogNC4gICBwcm92aWRlIGEgU2VsZW5pdW0gYmFzZWQgdW5pdCB0ZXN0XG4gKi9cblxuaW1wb3J0IHsgcGFnZVByb2dyZXNzVHJhY2tlciB9IGZyb20gXCIuL2Jvb2tmdW5jcy5qc1wiO1xuLy9pbXBvcnQgXCIuLy4uL3N0eWxlcy9ydW5lc3RvbmUtY3VzdG9tLXNwaGlueC1ib290c3RyYXAuY3NzXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJ1bmVzdG9uZUJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKG9wdHMpIHtcbiAgICAgICAgdGhpcy5jb21wb25lbnRfcmVhZHlfcHJvbWlzZSA9IG5ldyBQcm9taXNlKFxuICAgICAgICAgICAgKHJlc29sdmUpID0+ICh0aGlzLl9jb21wb25lbnRfcmVhZHlfcmVzb2x2ZV9mbiA9IHJlc29sdmUpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMub3B0aW9uYWwgPSBmYWxzZTtcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cuYWxsQ29tcG9uZW50cyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgd2luZG93LmFsbENvbXBvbmVudHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB3aW5kb3cuYWxsQ29tcG9uZW50cy5wdXNoKHRoaXMpO1xuICAgICAgICBpZiAob3B0cykge1xuICAgICAgICAgICAgdGhpcy5zaWQgPSBvcHRzLnNpZDtcbiAgICAgICAgICAgIHRoaXMuZ3JhZGVyYWN0aXZlID0gb3B0cy5ncmFkZXJhY3RpdmU7XG4gICAgICAgICAgICB0aGlzLnNob3dmZWVkYmFjayA9IHRydWU7XG4gICAgICAgICAgICBpZiAob3B0cy50aW1lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaXNUaW1lZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5lbmZvcmNlRGVhZGxpbmUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlYWRsaW5lID0gb3B0cy5kZWFkbGluZTtcbiAgICAgICAgICAgI
4060H1cbiAgICAgICAgICAgIGlmICgkKG9wdHMub3JpZykuZGF0YShcIm9wdGlvbmFsXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25hbCA9IHRydWU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9uYWwgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvcHRzLnNlbGVjdG9yX2lkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rvcl9pZCA9IG9wdHMuc2VsZWN0b3JfaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdHMuYXNzZXNzbWVudFRha2VuICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hc3Nlc3NtZW50VGFrZW4gPSBvcHRzLmFzc2Vzc21lbnRUYWtlbjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gZGVmYXVsdCB0byB0cnVlIGFzIHRoaXMgb3B0IGlzIG9ubHkgcHJvdmlkZWQgZnJvbSBhIHRpbWVkQXNzZXNzbWVudFxuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXNzbWVudFRha2VuID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRoaXMgaXMgZm9yIHRoZSBzZWxlY3RxdWVzdGlvbiBwb2ludHNcbiAgICAgICAgICAgIC8vIElmIGEgc2VsZWN0cXVlc3Rpb24gaXMgcGFydCBvZiBhIHRpbWVkIGV4YW0gaXQgd2lsbCBnZXRcbiAgICAgICAgICAgIC8vIHRoZSB0aW1lZFdyYXBwZXIgb3B0aW9ucy5cbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0cy50aW1lZFdyYXBwZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWVkV3JhcHBlciA9IG9wdHMudGltZWRXcmFwcGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBIb3dldmVyIHNvbWV0aW1lcyBzZWxlY3RxdWVzdGlvbnNcbiAgICAgICAgICAgICAgICAvLyBhcmUgdXNlZCBpbiByZWd1bGFyIGFzc2lnbm1lbnRzLiAgVGhlIGhhY2t5IHdheSB0byBkZXRlY3QgdGhpc1xuICAgICAgICAgICAgICAgIC8vIGlzIHRvIGxvb2sgZm9yIGRvQXNzaWdubWVudCBpbiB0aGUgVVJMIGFuZCB0aGVuIGdyYWJcbiAgICAgICAgICAgICAgICAvLyB0aGUgYXNzaWdubWVudCBuYW1lIGZyb20gdGhlIGhlYWRpbmcuXG4gICAgICAgICAgICAgICAgaWYgKGxvY2F0aW9uLmhyZWYuaW5kZXhPZihcImRvQXNzaWdubWVudFwiKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGltZWRXcmFwcGVyID0gJChcImgxI2Fzc2lnbm1lbnRfbmFtZVwiKS50ZXh0KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50aW1lZFdyYXBwZXIgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICgkKG9wdHMub3JpZykuZGF0YShcInF1ZXN0aW9uX2xhYmVsXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWVzdGlvbl9sYWJlbCA9ICQob3B0cy5vcmlnKS5kYXRhKFwicXVlc3Rpb25fbGFiZWxcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmlzX3RvZ2dsZSA9IHRydWUgPyBvcHRzLmlzX3RvZ2dsZSA6IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5pc19zZWxlY3QgPSB0cnVlID8gb3B0cy5pc19zZWxlY3QgOiBmYWxzZTtcblxuICAgICAgICB9XG4gICAgICAgIHRoaXMubWplbGVtZW50cyA9IFtdO1xuICAgICAgICBsZXQgc2VsZiA9IHRoaXM7XG4gICAgICAgIHRoaXMubWpSZWFkeSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgc2VsZi5tanJlc29sdmVyID0gcmVzb2x2ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYVF1ZXVlID0gbmV3IEF1dG9RdWV1ZSgpO1xuICAgICAgICB0aGlzLmpzb25IZWFkZXJzID0gbmV3IEhlYWRlcnMoe1xuICAgICAgICAgICAgXCJDb250ZW50LXR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XCIsXG4gICAgICAgICAgICBBY2NlcHQ6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBfYGxvZ0Jvb2tFdmVudGBcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHNlbmRzIHRoZSBwcm92aWRlZCBgYGV2ZW50SW5mb2BgIHRvIHRoZSBgaHNibG9nIGVuZHBvaW50YCBvZiB0aGUgc2VydmVyLiBBd2FpdGluZyB0aGlzIGZ1bmN0aW9uIHJldHVybnMgZWl0aGVyIGBgdW5kZWZpbmVkYGAgKGlmIFJ1bmVzdG9uZSBzZXJ2aWNlcyBhcmUgbm90IGF2YWlsYWJsZSkgb3IgdGhlIGRhdGEgcmV0dXJuZWQgYnkgdGhlIHNlcnZlciBhcyBhIEphdmFTY3JpcHQgb2JqZWN0IChhbHJlYWR5IEpTT04tZGVjb2RlZCkuXG4gICAgYXN5bmMgbG9nQm9va0V2ZW50KGV2ZW50SW5mbykge1xuICAgICAgICBpZiAodGhpcy5ncmFkZXJhY3RpdmUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcG9zdF9yZXR1cm47XG4gICAgICAgIGV2ZW50SW5mby5jb3Vyc2VfbmFtZSA9IGVCb29rQ29uZmlnLmNvdXJzZTtcbiAgICAgICAgZXZlbnRJbmZvLmNsaWVudExvZ2luU3RhdHVzID0gZUJvb2tDb25maWcuaXNMb2dnZWRJb
4060jtcbiAgICAgICAgZXZlbnRJbmZvLnRpbWV6b25lb2Zmc2V0ID0gbmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpIC8gNjA7XG4gICAgICAgIGlmICh0eXBlb2YodGhpcy5wZXJjZW50KSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgZXZlbnRJbmZvLnBlcmNlbnQgPSB0aGlzLnBlcmNlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgZUJvb2tDb25maWcuaXNMb2dnZWRJbiAmJlxuICAgICAgICAgICAgZUJvb2tDb25maWcudXNlUnVuZXN0b25lU2VydmljZXMgJiZcbiAgICAgICAgICAgIGVCb29rQ29uZmlnLmxvZ0xldmVsID4gMFxuICAgICAgICApIHtcbiAgICAgICAgICAgIHBvc3RfcmV0dXJuID0gdGhpcy5wb3N0TG9nTWVzc2FnZShldmVudEluZm8pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5pc1RpbWVkIHx8IGVCb29rQ29uZmlnLmRlYnVnKSB7XG4gICAgICAgICAgICBsZXQgcHJlZml4ID0gZUJvb2tDb25maWcuaXNMb2dnZWRJbiA/IFwiU2F2ZVwiIDogXCJOb3RcIjtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAke3ByZWZpeH0gbG9nZ2luZyBldmVudCBgICsgSlNPTi5zdHJpbmdpZnkoZXZlbnRJbmZvKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gV2hlbiBzZWxlY3RxdWVzdGlvbnMgYXJlIHBhcnQgb2YgYW4gYXNzaWdubWVudCBlc3BlY2lhbGx5IHRvZ2dsZSBxdWVzdGlvbnNcbiAgICAgICAgLy8gd2UgbmVlZCB0byBjb3VudCB1c2luZyB0aGUgc2VsZWN0b3JfaWQgb2YgdGhlIHNlbGVjdCBxdWVzdGlvbi5cbiAgICAgICAgLy8gV2UgIGFsc28gbmVlZCB0byBsb2cgYW4gZXZlbnQgZm9yIHRoYXQgc2VsZWN0b3Igc28gdGhhdCB3ZSB3aWxsIGtub3dcbiAgICAgICAgLy8gdGhhdCBpbnRlcmFjdGlvbiBoYXMgdGFrZW4gcGxhY2UuICBUaGlzIGlzICoqaW5kZXBlbmRlbnQqKiBvZiBob3cgdGhlXG4gICAgICAgIC8vIGF1dG9ncmFkZXIgd2lsbCB1bHRpbWF0ZWx5IGdyYWRlIHRoZSBxdWVzdGlvbiFcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0b3JfaWQpIHtcbiAgICAgICAgICAgIGV2ZW50SW5mby5kaXZfaWQgPSB0aGlzLnNlbGVjdG9yX2lkLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgXCItdG9nZ2xlU2VsZWN0ZWRRdWVzdGlvblwiLFxuICAgICAgICAgICAgICAgIFwiXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBldmVudEluZm8uZXZlbnQgPSBcInNlbGVjdHF1ZXN0aW9uXCI7XG4gICAgICAgICAgICBldmVudEluZm8uYWN0ID0gXCJpbnRlcmFjdGlvblwiO1xuICAgICAgICAgICAgdGhpcy5wb3N0TG9nTWVzc2FnZShldmVudEluZm8pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYWdlUHJvZ3Jlc3NUcmFja2VyLnVwZGF0ZVByb2dyZXNzID09PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgICAgIGV2ZW50SW5mby5hY3QgIT0gXCJlZGl0XCIgJiZcbiAgICAgICAgICAgIHRoaXMub3B0aW9uYWwgPT0gZmFsc2VcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBwYWdlUHJvZ3Jlc3NUcmFja2VyLnVwZGF0ZVByb2dyZXNzKGV2ZW50SW5mby5kaXZfaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb3N0X3JldHVybjtcbiAgICB9XG5cbiAgICBhc3luYyBwb3N0TG9nTWVzc2FnZShldmVudEluZm8pIHtcbiAgICAgICAgdmFyIHBvc3RfcmV0dXJuO1xuICAgICAgICBsZXQgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KFxuICAgICAgICAgICAgYCR7ZUJvb2tDb25maWcubmV3X3NlcnZlcl9wcmVmaXh9L2xvZ2dlci9ib29rZXZlbnRgLCB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLmpzb25IZWFkZXJzLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGV2ZW50SW5mbyksXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2Y
4060XIgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChyZXF1ZXN0KTtcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MjIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IGRldGFpbHMgYWJvdXQgd2h5IHRoaXMgaXMgdW5wcm9jZXNhYmxlLlxuICAgICAgICAgICAgICAgICAgICBwb3N0X3JldHVybiA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocG9zdF9yZXR1cm4uZGV0YWlsKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5wcm9jZXNzYWJsZSBSZXF1ZXN0XCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICBwb3N0X3JldHVybiA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICBgTWlzc2luZyBhdXRoZW50aWNhdGlvbiB0b2tlbiAke3Bvc3RfcmV0dXJuLmRldGFpbH1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXV0aGVudGljYXRpb24gdG9rZW5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHNhdmUgdGhlIGxvZyBlbnRyeVxuICAgICAgICAgICAgICAgICAgICBTdGF0dXM6ICR7cmVzcG9uc2Uuc3RhdHVzfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcG9zdF9yZXR1cm4gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGxldCBkZXRhaWwgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgIGlmIChwb3N0X3JldHVybiAmJiBwb3N0X3JldHVybi5kZXRhaWwpIHtcbiAgICAgICAgICAgICAgICBkZXRhaWwgPSBwb3N0X3JldHVybi5kZXRhaWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZUJvb2tDb25maWcubG9naW5SZXF1aXJlZCkge1xuICAgICAgICAgICAgICAgIGFsZXJ0KGBFcnJvcjogWW91ciBhY3Rpb24gd2FzIG5vdCBzYXZlZCFcbiAgICAgICAgICAgICAgICAgICAgVGhlIGVycm9yIHdhcyAke2V9XG4gICAgICAgICAgICAgICAgICAgIFN0YXR1cyBDb2RlOiAke3Jlc3BvbnNlLnN0YXR1c31cbiAgICAgICAgICAgICAgICAgICAgRGV0YWlsOiAke2RldGFpbH0uXG4gICAgICAgICAgICAgICAgICAgIFBsZWFzZSByZXBvcnQgdGhpcyBlcnJvciFgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHNlbmQgYSByZXF1ZXN0IHRvIHNhdmUgdGhpcyBlcnJvclxuICAgICAgICAgICAgY29uc29sZS5sb2coYEVycm9yOiAke2V9IERldGFpbDogJHtkZXRhaWx9IFN0YXR1cyBDb2RlOiAke3Jlc3BvbnNlLnN0YXR1c31gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcG9zdF9yZXR1cm47XG4gICAgfVxuICAgIC8vIC4uIF9sb2dSdW5FdmVudDpcbiAgICAvL1xuICAgIC8vIGxvZ1J1bkV2ZW50XG4gICAgLy8gLS0tLS0tLS0tLS1cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHNlbmRzIHRoZSBwcm92aWRlZCBgYGV2ZW50SW5mb2BgIHRvIHRoZSBgcnVubG9nIGVuZHBvaW50YC4gV2hlbiBhd2FpdGVkLCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIGRhdGEgKGRlY29kZWQgZnJvbSBKU09OKSB0aGUgc2VydmVyIHNlbnQgYmFjay5cbiAgICBhc3luYyBsb2dSdW5FdmVudChldmVudEluZm8pIHtcbiAgICAgICAgbGV0IHBvc3RfcHJvbWlzZSA9IFwiZG9uZVwiO1xuICAgICAgICBpZiAodGhpcy5ncmFkZXJhY3RpdmUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBldmVudEluZm8uY291cnNlID0gZUJvb2tDb25maWcuY291cnNlO1xuICAgICAgICBldmVudEluZm8uY2xpZW50TG9naW5TdGF0dXMgPSBlQm9va0NvbmZpZy5pc0xvZ2dlZEluO1xuICAgICAgICBldmVudEluZm8udGltZXpvbmVvZmZzZXQgPSBuZXcgRGF0ZSgpLmdldFRpbWV6b25lT2Zmc2V0KCkgLyA2MDtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VTYXZlIHx8IFwidG9fc2F2ZVwiIGluIGV2ZW50SW5mbyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGV2ZW50SW5mby5zYXZlX2NvZGUgPSBcIlRydWVcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5pc0xvZ2dlZEluICYmXG4gICAgICAgICAgICBlQm9va0NvbmZpZy51c2VSdW5lc3RvbmVTZXJ2aWNlcyAmJlxuICAgICAgICAgICAgZUJvb2tDb25maWcubG9nTGV2ZWwgPiAwXG4gICAgICAgICkge1xuICAgICAgICAgICAgbGV0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdChcbiAgICAgICAgICAgICAgICBgJHtlQm9va0NvbmZpZy5uZXdfc2VydmVyX3ByZWZpeH0vbG9nZ2VyL3J1bmxvZ2AsIHtcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5qc29uSGVhZGVycyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoZXZlbnRJbmZvKSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocmVxdWVzdCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgcG9zdF9wcm9taXNlID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgICAgIGlmIChlQm9va0NvbmZpZy5sb2dpblJlcXVpcmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KGBGYWlsZWQgdG8gc2F2ZSB5b3VyIGNvZGVcbiAgICAgICAgICAgICAgICAgICAgICAgIFN0YXR1cyBpcyAke3Jlc3BvbnNlLnN0YXR1c31cbiAgICAgICAgICAgICAgICAgICAgICAgIERldGFpbDogJHtwb3N0X3Byb21pc2UuZGV0YWlsfWApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgYERpZCBub3Qgc2F2ZSB0aGUgY29kZS4gU3RhdHVzOiAke3Jlc3BvbnNlLnN0YXR1c31gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwb3N0X3Byb21pc2UgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgI
4060H1cbiAgICAgICAgaWYgKCF0aGlzLmlzVGltZWQgfHwgZUJvb2tDb25maWcuZGVidWcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwicnVubmluZyBcIiArIEpTT04uc3RyaW5naWZ5KGV2ZW50SW5mbykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYWdlUHJvZ3Jlc3NUcmFja2VyLnVwZGF0ZVByb2dyZXNzID09PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgICAgIHRoaXMub3B0aW9uYWwgPT0gZmFsc2VcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBwYWdlUHJvZ3Jlc3NUcmFja2VyLnVwZGF0ZVByb2dyZXNzKGV2ZW50SW5mby5kaXZfaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb3N0X3Byb21pc2U7XG4gICAgfVxuICAgIC8qIENoZWNraW5nL2xvYWRpbmcgZnJvbSBzdG9yYWdlXG4gICAgKipXQVJOSU5HOioqICBETyBOT1QgYGF3YWl0YCB0aGlzIGZ1bmN0aW9uIVxuICAgIFRoaXMgZnVuY3Rpb24sIGFsdGhvdWdoIGFzeW5jLCBkb2VzIG5vdCBleHBsaWNpdGx5IHJlc29sdmUgaXRzIHByb21pc2UgYnkgcmV0dXJuaW5nIGEgdmFsdWUuICBUaGUgcmVhc29uIGZvciB0aGlzIGlzIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGJ5IHRoZSBjb25zdHJ1Y3RvciBmb3IgbmVhcmx5IGV2ZXJ5IGNvbXBvbmVudC4gIEluIEphdmFzY3JpcHQgY29uc3RydWN0b3JzIGNhbm5vdCBiZSBhc3luYyFcblxuICAgIE9uZSBvZiB0aGUgcmVjb21tZW5kZWQgd2F5cyB0byBoYW5kbGUgdGhlIGFzeW5jIHJlcXVpcmVtZW50cyBmcm9tIHdpdGhpbiBhIGNvbnN0cnVjdG9yIGlzIHRvIHVzZSBhbiBhdHRyaWJ1dGUgYXMgYSBwcm9taXNlIGFuZCByZXNvbHZlIHRoYXQgYXR0cmlidXRlIGF0IHRoZSBhcHByb3ByaWF0ZSB0aW1lLlxuICAgICovXG4gICAgYXN5bmMgY2hlY2tTZXJ2ZXIoXG4gICAgICAgIC8vIEEgc3RyaW5nIHNwZWNpZnlpbmcgdGhlIGV2ZW50IG5hbWUgdG8gdXNlIGZvciBxdWVyeWluZyB0aGUgOnJlZjpgZ2V0QXNzZXNzUmVzdWx0c2AgZW5kcG9pbnQuXG4gICAgICAgIGV2ZW50SW5mbyxcbiAgICAgICAgLy8gSWYgdHJ1ZSwgdGhpcyBmdW5jdGlvbiB3aWxsIGludm9rZSBgYGluZGljYXRlX2NvbXBvbmVudF9yZWFkeSgpYGAganVzdCBiZWZvcmUgaXQgcmV0dXJucy4gVGhpcyBpcyBwcm92aWRlZCBzaW5jZSBtb3N0IGNvbXBvbmVudHMgYXJlIHJlYWR5IGFmdGVyIHRoaXMgZnVuY3Rpb24gY29tcGxldGVzIGl0cyB3b3JrLlxuICAgICAgICAvL1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGRlZmF1bHRzIHRvIGZhbHNlLCB0byBhdm9pZCBjYXVzaW5nIHByb2JsZW1zIHdpdGggYW55IGNvbXBvbmVudHMgdGhhdCBoYXZlbid0IGJlZW4gdXBkYXRlZCBhbmQgdGVzdGVkLiBBZnRlciBhbGwgUnVuZXN0b25lIGNvbXBvbmVudHMgaGF2ZSBiZWVuIHVwZGF0ZWQsIGRlZmF1bHQgdGhpcyB0byB0cnVlIGFuZCByZW1vdmUgdGhlIGV4dHJhIHBhcmFtZXRlciBmcm9tIG1vc3QgY2FsbHMgdG8gdGhpcyBmdW5jdGlvbi5cbiAgICAgICAgd2lsbF9iZV9yZWFkeSA9IGZhbHNlXG4gICAgKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIHRoZSBzZXJ2ZXIgaGFzIHN0b3JlZCBhbnN3ZXJcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgICAgICB0aGlzLmNoZWNrU2VydmVyQ29tcGxldGUgPSBuZXcgUHJvbWlzZS
4060hmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIHNlbGYuY3NyZXNvbHZlciA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5pc0xvZ2dlZEluICYmXG4gICAgICAgICAgICAodGhpcy51c2VSdW5lc3RvbmVTZXJ2aWNlcyB8fCB0aGlzLmdyYWRlcmFjdGl2ZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBsZXQgZGF0YSA9IHt9O1xuICAgICAgICAgICAgZGF0YS5kaXZfaWQgPSB0aGlzLmRpdmlkO1xuICAgICAgICAgICAgZGF0YS5jb3Vyc2UgPSBlQm9va0NvbmZpZy5jb3Vyc2U7XG4gICAgICAgICAgICBkYXRhLmV2ZW50ID0gZXZlbnRJbmZvO1xuICAgICAgICAgICAgaWYgKHRoaXMuZ3JhZGVyYWN0aXZlICYmIHRoaXMuZGVhZGxpbmUpIHtcbiAgICAgICAgICAgICAgICBkYXRhLmRlYWRsaW5lID0gdGhpcy5kZWFkbGluZTtcbiAgICAgICAgICAgICAgICBkYXRhLnJhd2RlYWRsaW5lID0gdGhpcy5yYXdkZWFkbGluZTtcbiAgICAgICAgICAgICAgICBkYXRhLnR6b2ZmID0gdGhpcy50em9mZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnNpZCkge1xuICAgICAgICAgICAgICAgIGRhdGEuc2lkID0gdGhpcy5zaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIShkYXRhLmRpdl9pZCAmJiBkYXRhLmNvdXJzZSAmJiBkYXRhLmV2ZW50KSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgICBgQSByZXF1aXJlZCBmaWVsZCBpcyBtaXNzaW5nIGRhdGEgJHtkYXRhLmRpdl9pZH06JHtkYXRhLmNvdXJzZX06JHtkYXRhLmV2ZW50fWBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gSWYgd2UgYXJlIE5PVCBpbiBwcmFjdGljZSBtb2RlIGFuZCB3ZSBhcmUgbm90IGluIGEgcGVlciBleGVyY2lzZVxuICAgICAgICAgICAgLy8gYW5kIGFzc2Vzc21lbnRUYWtlbiBpcyB0cnVlXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgIWVCb29rQ29uZmlnLnByYWN0aWNlX21vZGUgJiZcbiAgICAgICAgICAgICAgICAhZUJvb2tDb25maWcucGVlciAmJlxuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXNzbWVudFRha2VuXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICBgJHtlQm9va0NvbmZpZy5uZXdfc2VydmVyX3ByZWZpeH0vYXNzZXNzbWVudC9yZXN1bHRzYCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGRhdGEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5qc29uSGVhZGVycyxcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLmRldGFpbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVwb3B1bGF0ZUZyb21TdG9yYWdlKGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hdHRlbXB0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZihkYXRhLmNvcnJlY3QpICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3JyZWN0ID0gZGF0YS5jb3JyZWN0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvcnJlY3QgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jc3Jlc29sdmVyKFwic2VydmVyXCIpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYEhUVFAgRXJyb3IgZ2V0dGluZyByZXN1bHRzOiAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tMb2NhbFN0b3JhZ2UoKTsgLy8ganVzdCBnbyByaWdodCB0byBsb2NhbCBzdG9yYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNzcmVzb2x2ZXIoXCJsb2NhbFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVja0xvY2FsU3RvcmFnZSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZERhdGEoe30pO1xuICAgICAgICAgICAgICAgIHRoaXMuY3NyZXNvbHZlcihcIm5vdCB0YWtlblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tMb2NhbFN0b3JhZ2UoKTsgLy8ganVzdCBnbyByaWdodCB0byBsb2NhbCBzdG9yYWdlXG4gICAgICAgICAgICB0aGlzLmNzcmVzb2x2ZXIoXCJsb2NhbFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh3aWxsX2JlX3JlYWR5KSB7XG4gICAgICAgICAgICB0aGlzLmluZGljYXRlX2NvbXBvbmVudF9yZWFkeSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGhpcyBtZXRob2QgYXNzdW1lcyB0aGF0IGBgdGhpcy5jb21wb25lbnREaXZgYCByZWZlcnMgdG8gdGhlIGBgZGl2YGAgY29udGFpbmluZyB0aGUgY29tcG9uZW50LCBhbmQgdGhhdCB0aGlzIGNvbXBvbmVudCdzIElEIGlzIHNldC5cbiAgICBpbmRpY2F0ZV9jb21wb25lbnRfcmVhZHkoKSB7XG4gICAgICAgIC8vIEFkZCBhIGNsYXNzIHRvIGluZGljYXRlIHRoZSBjb21wb25lbnQgaXMgbm93IHJlYWR5LlxuICAgICAgICB0aGlzLmNvbnRhaW5lckRpdi5jbGFzc0xpc3QuYWRkKFwicnVuZXN0b25lLWNvbXBvbmVudC1yZWFkeVwiKTtcbiAgICAgICAgLy8gUmVzb2x2ZSB0aGUgYGB0aGlzLmNvbXBvbmVudF9yZWFkeV9wcm9taXNlYGAuXG4gICAgICAgI
4060HRoaXMuX2NvbXBvbmVudF9yZWFkeV9yZXNvbHZlX2ZuKCk7XG4gICAgfVxuXG4gICAgbG9hZERhdGEoZGF0YSkge1xuICAgICAgICAvLyBmb3IgbW9zdCBjbGFzc2VzLCBsb2FkRGF0YSBkb2Vzbid0IGRvIGFueXRoaW5nLiBCdXQgZm9yIFBhcnNvbnMsIGFuZCBwZXJoYXBzIG90aGVycyBpbiB0aGUgZnV0dXJlLFxuICAgICAgICAvLyBpbml0aWFsaXphdGlvbiBjYW4gaGFwcGVuIGV2ZW4gd2hlbiB0aGVyZSdzIG5vIGhpc3RvcnkgdG8gYmUgbG9hZGVkXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJlcG9wdWxhdGVGcm9tU3RvcmFnZSBpcyBjYWxsZWQgYWZ0ZXIgYSBzdWNjZXNzZnVsIEFQSSBjYWxsIGlzIG1hZGUgdG8gYGBnZXRBc3Nlc3NSZXN1bHRzYGAgaW5cbiAgICAgKiB0aGUgY2hlY2tTZXJ2ZXIgbWV0aG9kIGluIHRoaXMgY2xhc3NcbiAgICAgKlxuICAgICAqIGBgcmVzdG9yZUFuc3dlcnMsYGAgYGBzZXRMb2NhbFN0b3JhZ2VgYCBhbmQgYGBjaGVja0xvY2FsU3RvcmFnZWBgIGFyZSBkZWZpbmVkIGluIHRoZSBjaGlsZCBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBkYXRhIC0gYSBKU09OIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGRhdGEgbmVlZGVkIHRvIHJlc3RvcmUgYSBwcmV2aW91cyBhbnN3ZXIgZm9yIGEgY29tcG9uZW50XG4gICAgICogQHBhcmFtIHsqfSBzdGF0dXMgLSB0aGUgaHR0cCBzdGF0dXNcbiAgICAgKiBAcGFyYW0geyp9IHdoYXRldmVyIC0gaWdub3JlZFxuICAgICAqL1xuICAgIHJlcG9wdWxhdGVGcm9tU3RvcmFnZShkYXRhKSB7XG4gICAgICAgIC8vIGRlY2lkZSB3aGV0aGVyIHRvIHVzZSB0aGUgc2VydmVyJ3MgYW5zd2VyIChpZiB0aGVyZSBpcyBvbmUpIG9yIHRvIGxvYWQgZnJvbSBzdG9yYWdlXG4gICAgICAgIGlmIChkYXRhICE9PSBudWxsICYmIGRhdGEgIT09IFwibm8gZGF0YVwiICYmIHRoaXMuc2hvdWxkVXNlU2VydmVyKGRhdGEpKSB7XG4gICAgICAgICAgICB0aGlzLnJlc3RvcmVBbnN3ZXJzKGRhdGEpO1xuICAgICAgICAgICAgdGhpcy5zZXRMb2NhbFN0b3JhZ2UoZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNoZWNrTG9jYWxTdG9yYWdlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2hvdWxkVXNlU2VydmVyKGRhdGEpIHtcbiAgICAgICAgLy8gcmV0dXJucyB0cnVlIGlmIHNlcnZlciBkYXRhIGlzIG1vcmUgcmVjZW50IHRoYW4gbG9jYWwgc3RvcmFnZSBvciBpZiBzZXJ2ZXIgc3RvcmFnZSBpcyBjb3JyZWN0XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIGRhdGEuY29ycmVjdCA9PT0gXCJUXCIgfHxcbiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5sZW5ndGggPT09IDAgfHxcbiAgICAgICAgICAgIHRoaXMuZ3JhZGVyYWN0aXZlID09PSB0cnVlIHx8XG4gICAgICAgICAgICB0aGlzLmlzVGltZWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZXggPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmxvY2FsU3RvcmFnZUtleSgpKTtcbiAgICAgICAgaWYgKGV4ID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc3RvcmVkRGF0YTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHN0b3JlZERhdGEgPSBKU09OLnBhcnNlKGV4KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAvLyBlcnJvciB3aGlsZSBwYXJzaW5nOyBsaWtlbHkgZHVlIHRvIGJhZCB2YWx1ZSBzdG9yZWQgaW4gc3RvcmFnZVxuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyLm1lc3NhZ2UpO1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5sb2NhbFN0b3JhZ2VLZXkoKSk7XG4gICAgICAgICAgICAvLyBkZWZpbml0ZWx5IGRvbid0IHdhbnQgdG8gdXNlIGxvY2FsIHN0b3JhZ2UgaGVyZVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGEuYW5zd2VyID09IHN0b3JlZERhdGEuYW5zd2VyKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgbGV0IHN0b3JhZ2VEYXRlID0gbmV3IERhdGUoc3RvcmVkRGF0YS50aW1lc3RhbXApO1xuICAgICAgICBsZXQgc2VydmVyRGF0ZSA9IG5ldyBEYXRlKGRhdGEudGltZXN0YW1wKTtcbiAgICAgICAgcmV0dXJuIHNlcnZlckRhdGUgPj0gc3RvcmFnZURhdGU7XG4gICAgfVxuICAgIC8vIFJldHVybiB0aGUga2V5IHdoaWNoIHRvIGJlIHVzZWQgd2hlbiBhY2Nlc3NpbmcgbG9jYWwgc3RvcmFnZS5cbiAgICBsb2NhbFN0b3JhZ2VLZXkoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5lbWFpbCArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5jb3Vyc2UgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5kaXZpZCArXG4gICAgICAgICAgICBcIi1naXZlblwiXG4gICAgICAgICk7XG4gICAgfVxuICAgIGFkZENhcHRpb24oZWxUeXBlKSB7XG4gICAgICAgIC8vc29tZUVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3RWxlbWVudCwgc29tZUVsZW1lbnQubmV4dFNpYmxpbmcpO1xuICAgICAgICBpZiAoIXRoaXMuaXNUaW1lZCkge1xuICAgICAgICAgICAgdmFyIGNhcERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJwXCIpO1xuICAgICAgICAgICAgaWYgKHRoaXMucXVlc3Rpb25fbGFiZWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhcHRpb24gPSBgQWN0aXZpdHk6ICR7dGhpcy5xdWVzdGlvbl9sYWJlbH0gJHt0aGlzLmNhcHRpb259ICA8c3BhbiBjbGFzcz1cInJ1bmVzdG9uZV9jYXB0aW9uX2RpdmlkXCI+KCR7dGhpcy5kaXZpZH0pPC9zcGFuPmA7XG4gICAgICAgICAgICAgICAgJChjYXBEaXYpLmh0bWwodGhpcy5jYXB0aW9uKTtcbiAgICAgICAgICAgICAgICAkKGNhcERpdikuYWRkQ2xhc3MoYCR7ZWxUeXBlfV9jYXB0aW9uYCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICQoY2FwRGl2KS5odG1sKHRoaXMuY2FwdGlvbiArIFwiIChcIiArIHRoaXMuZGl2aWQgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgJChjYXBEaXYpLmFkZENsYXNzKGAke2VsVHlwZX1fY2FwdGlvbmApO1xuICAgICAgICAgICAgICAgICQoY2FwRGl2KS5hZGRDbGFzcyhgJHtlbFR5cGV9X2NhcHRpb25fdGV4dGApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jYXBEaXYgPSBjYXBEaXY7XG4gICAgICAgICAgICAvL3RoaXMub3V0ZXJEaXYucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoY2FwRGl2LCB0aGlzLm91dGVyRGl2Lm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgI
4060HRoaXMuY29udGFpbmVyRGl2LmFwcGVuZENoaWxkKGNhcERpdik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoYXNVc2VyQWN0aXZpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzQW5zd2VyZWQ7XG4gICAgfVxuXG4gICAgY2hlY2tDdXJyZW50QW5zd2VyKCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIFwiRWFjaCBjb21wb25lbnQgc2hvdWxkIHByb3ZpZGUgYW4gaW1wbGVtZW50YXRpb24gb2YgY2hlY2tDdXJyZW50QW5zd2VyXCJcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBhc3luYyBsb2dDdXJyZW50QW5zd2VyKCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIFwiRWFjaCBjb21wb25lbnQgc2hvdWxkIHByb3ZpZGUgYW4gaW1wbGVtZW50YXRpb24gb2YgbG9nQ3VycmVudEFuc3dlclwiXG4gICAgICAgICk7XG4gICAgfVxuICAgIHJlbmRlckZlZWRiYWNrKCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIFwiRWFjaCBjb21wb25lbnQgc2hvdWxkIHByb3ZpZGUgYW4gaW1wbGVtZW50YXRpb24gb2YgcmVuZGVyRmVlZGJhY2tcIlxuICAgICAgICApO1xuICAgIH1cbiAgICBkaXNhYmxlSW50ZXJhY3Rpb24oKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgXCJFYWNoIGNvbXBvbmVudCBzaG91bGQgcHJvdmlkZSBhbiBpbXBsZW1lbnRhdGlvbiBvZiBkaXNhYmxlSW50ZXJhY3Rpb25cIlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfTogJHt0aGlzLmRpdmlkfWA7XG4gICAgfVxuXG4gICAgcXVldWVNYXRoSmF4KGNvbXBvbmVudCkge1xuICAgICAgICBpZiAodHlwZW9mKE1hdGhKYXgpID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIkVycm9yIC0tIE1hdGhKYXggaXMgbm90IGxvYWRlZFwiKVxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNlZSAtIGh0dHBzOi8vZG9jcy5tYXRoamF4Lm9yZy9lbi9sYXRlc3QvYWR2YW5jZWQvdHlwZXNldC5odG1sXG4gICAgICAgICAgICAvLyBQZXIgdGhlIGFib3ZlIHdlIHNob3VsZCBrZWVwIHRyYWNrIG9mIHRoZSBwcm9taXNlcyBhbmQgb25seSBjYWxsIHRoaXNcbiAgICAgICAgICAgIC8vIGEgc2Vjb25kIHRpbWUgaWYgYWxsIHByZXZpb3VzIHByb21pc2VzIGhhdmUgcmVzb2x2ZWQuXG4gICAgICAgICAgICAvLyBDcmVhdGUgYSBxdWV1ZSBvZiBjb21wb25lbnRzXG4gICAgICAgICAgICAvLyBzaG91bGQgd2FpdCB1bnRpbCBkZWZhdWx0UGFnZVJlYWR5IGlzIGRlZmluZWRcbiAgICAgICAgICAgIC8vIElmIGRlZmF1bHRQYWdlUmVhZHkgaXMgbm90IGRlZmluZWQgdGhlbiBqdXN0IGVucXVldWUgdGhlIGNvbXBvbmVudHMuXG4gICAgICAgICAgICAvLyBPbmNlIGRlZmF1bHRQYWdlUmVhZHkgaXMgZGVmaW5lZFxuICAgICAgICAgICAgLy8gdGhlIHdpbmRvdy5ydW5lc3RvbmVNYXRoUmVhZHkgcHJvbWlzZSB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZVxuICAgICAgICAgICAgLy8gaW5pdGlhbCB0eXBlc2V0dGluZyBpcyBjb21wbGV0ZS5cbiAgICAgICAgICAgIGlmIChNYXRoSmF4LnR5cGVzZXRQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZih3aW5kb3cucnVuZXN0b25lTWF0aFJlYWR5KSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd2luZG93LnJ1bmVzdG9uZU1hdGhSZWFkeS50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgKCkgPT4gdGhpcy5tanJlc29sdmVyKHRoaXMuYVF1ZXVlLmVucXVldWUoY29tcG9uZW50KSlcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1qcmVzb2x2ZXIodGhpcy5hUXVldWUuZW5xdWV1ZShjb21wb25lbnQpKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFdhaXRpbmcgb24gTWF0aEpheCEhICR7TWF0aEpheC50eXBlc2V0UHJvbWlzZX1gKTtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMucXVldWVNYXRoSmF4KGNvbXBvbmVudCksIDIwMCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFJldHVybmluZyBtanJlYWR5IHByb21pc2U6ICR7dGhpcy5talJlYWR5fWApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubWpSZWFkeTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlY29yYXRlU3RhdHVzKCkge1xuICAgICAgICBsZXQgcnNEaXYgPSAkKHRoaXMuY29udGFpbmVyRGl2KS5jbG9zZXN0KFwiZGl2LnJ1bmVzdG9uZVwiKVswXTtcbiAgICAgICAgaWYgKHRoaXMuY29ycmVjdCkge1xuICAgICAgICAgICAgcnNEaXYuY2xhc3NMaXN0LmFkZChcImlzQ29ycmVjdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvcnJlY3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByc0Rpdi5jbGFzc0xpc3QuYWRkKFwibm90QW5zd2VyZWRcIik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJzRGl2LmNsYXNzTGlzdC5hZGQoXCJpc0luQ29ycmVjdFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxufVxuXG5cbi8vIEluc3BpcmF0aW9uIGFuZCBsb3RzIG9mIGNvZGUgZm9yIHRoaXMgc29sdXRpb24gY29tZSBmcm9tXG4vLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81MzU0MDM0OC9qcy1hc3luYy1hd2FpdC10YXNrcy1xdWV1ZVxuLy8gVGhlIGlkZWEgaGVyZSBpcyB0aGF0IHVudGlsIE1hdGhKYXggaXMgcmVhZHkgd2UgY2FuIGp1c3QgZW5xdWV1ZSB0aGluZ3Ncbi8vIG9uY2UgbWF0aGpheCBiZWNvbWVzIHJlYWR5IHRoZW4gd2UgY2FuIGRyYWluIHRoZSBxdWV1ZSBhbmQgY29udGludWUgYXMgdXN1YWwuXG5cbmNsYXNzIFF1ZXVlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHsgdGhpcy5faXRlbXMgPSBbXTsgfVxuICAgIGVucXVldWUoaXRlbSkgeyB0aGlzLl9pdGVtcy5wdXNoKGl0ZW0pOyB9XG4gICAgZGVxdWV1ZSgpIHsgcmV0dXJuIHRoaXMuX2l0ZW
40601zLnNoaWZ0KCk7IH1cbiAgICBnZXQgc2l6ZSgpIHsgcmV0dXJuIHRoaXMuX2l0ZW1zLmxlbmd0aDsgfVxufVxuXG5jbGFzcyBBdXRvUXVldWUgZXh0ZW5kcyBRdWV1ZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuX3BlbmRpbmdQcm9taXNlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgZW5xdWV1ZShjb21wb25lbnQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHN1cGVyLmVucXVldWUoeyBjb21wb25lbnQsIHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICAgICAgICAgIHRoaXMuZGVxdWV1ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBkZXF1ZXVlKCkge1xuICAgICAgICBpZiAodGhpcy5fcGVuZGluZ1Byb21pc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICBsZXQgaXRlbSA9IHN1cGVyLmRlcXVldWUoKTtcblxuICAgICAgICBpZiAoIWl0ZW0pIHJldHVybiBmYWxzZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fcGVuZGluZ1Byb21pc2UgPSB0cnVlO1xuXG4gICAgICAgICAgICBsZXQgcGF5bG9hZCA9IGF3YWl0IE1hdGhKYXguc3RhcnR1cC5kZWZhdWx0UGFnZVJlYWR5KCkudGhlbihcbiAgICAgICAgICAgICAgICBhc3luYyBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYE1hdGhKYXggUmVhZHkgLS0gZGVxdWVpbmcgYSB0eXBlc2V0dGluZyBydW4gZm9yICR7aXRlbS5jb21wb25lbnQuaWR9YClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IE1hdGhKYXgudHlwZXNldFByb21pc2UoW2l0ZW0uY29tcG9uZW50XSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5fcGVuZGluZ1Byb21pc2UgPSBmYWxzZTsgaXRlbS5yZXNvbHZlKHBheWxvYWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wZW5kaW5nUHJvbWlzZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGl0ZW0ucmVqZWN0KGUpO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlcXVldWUoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIHdpbmRvdy5SdW5lc3RvbmVCYXNlID0gUnVuZXN0b25lQmFzZTtcbiIsImV4cG9ydCBmdW5jdGlvbiBnZXRTd2l0Y2goKSB7XG4gICAgY29uc3QgdG9nZ2xlU3dpdGNoID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRoZW1lLXN3aXRjaCBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0nKTtcbiAgICBjb25zdCBjdXJyZW50VGhlbWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgndGhlbWUnKSA/IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCd0aGVtZScpIDogbnVsbDtcblxuICAgIGlmIChjdXJyZW50VGhlbWUpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS10aGVtZScsIGN1cnJlbnRUaGVtZSk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRUaGVtZSA9PT0gJ2RhcmsnKSB7XG4gICAgICAgICAgICB0b2dnbGVTd2l0Y2guY2hlY2tlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzd2l0Y2hUaGVtZSgpIHtcblxuXHR2YXIgY2hlY2tCb3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNoZWNrYm94XCIpO1xuICAgIGlmIChjaGVja0JveC5jaGVja2VkID09IHRydWUpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS10aGVtZScsICdkYXJrJyk
40607XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCd0aGVtZScsICdkYXJrJyk7IC8vYWRkIHRoaXNcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnLCAnbGlnaHQnKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ3RoZW1lJywgJ2xpZ2h0Jyk7IC8vYWRkIHRoaXNcbiAgICB9XG59XG4iLCIvKmdsb2JhbCB2YXJpYWJsZSBkZWNsYXJhdGlvbnMqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IFwiLi4vY3NzL3VzZXItaGlnaGxpZ2h0cy5jc3NcIjtcblxuZnVuY3Rpb24gZ2V0Q29tcGxldGlvbnMoKSB7XG4gICAgLy8gR2V0IHRoZSBjb21wbGV0aW9uIHN0YXR1c1xuICAgIGlmIChcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYubWF0Y2goXG4gICAgICAgICAgICAvKGluZGV4Lmh0bWx8dG9jdHJlZS5odG1sfGdlbmluZGV4Lmh0bWx8bmF2aGVscC5odG1sfHRvYy5odG1sfGFzc2lnbm1lbnRzLmh0bWx8RXhlcmNpc2VzLmh0bWwpL1xuICAgICAgICApXG4gICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY3VycmVudFBhdGhuYW1lID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lO1xuICAgIGlmIChjdXJyZW50UGF0aG5hbWUuaW5kZXhPZihcIj9cIikgIT09IC0xKSB7XG4gICAgICAgIGN1cnJlbnRQYXRobmFtZSA9IGN1cnJlbnRQYXRobmFtZS5zdWJzdHJpbmcoXG4gICAgICAgICAgICAwLFxuICAgICAgICAgICAgY3VycmVudFBhdGhuYW1lLmxhc3RJbmRleE9mKFwiP1wiKVxuICAgICAgICApO1xuICAgIH1cbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgICAgbGFzdFBhZ2VVcmw6IGN1cnJlbnRQYXRobmFtZSxcbiAgICAgICAgaXNQdHhCb29rOiBpc1ByZVRlWHQoKVxuICAgICB9O1xuICAgIGpRdWVyeVxuICAgICAgICAuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGAke2VCb29rQ29uZmlnLm5ld19zZXJ2ZXJfcHJlZml4fS9sb2dnZXIvZ2V0Q29tcGxldGlvblN0YXR1c2AsXG4gICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgYXN5bmM6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAuZG9uZShmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgaWYgKGRhdGEgIT0gXCJOb25lXCIpIHtcbiAgICAgICAgICAgICAgICB2Y
4060XIgY29tcGxldGlvbkRhdGEgPSBkYXRhLmRldGFpbDtcbiAgICAgICAgICAgICAgICB2YXIgY29tcGxldGlvbkNsYXNzLCBjb21wbGV0aW9uTXNnO1xuICAgICAgICAgICAgICAgIGlmIChjb21wbGV0aW9uRGF0YVswXS5jb21wbGV0aW9uU3RhdHVzID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkNsYXNzID0gXCJidXR0b25Db25maXJtQ29tcGxldGlvblwiO1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uTXNnID1cbiAgICAgICAgICAgICAgICAgICAgICAgIFwiPGkgY2xhc3M9J2dseXBoaWNvbiBnbHlwaGljb24tb2snPjwvaT4gQ29tcGxldGVkLiBXZWxsIERvbmUhXCI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkNsYXNzID0gXCJidXR0b25Bc2tDb21wbGV0aW9uXCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25Nc2cgPSBcIk1hcmsgYXMgQ29tcGxldGVkXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICQoXCIjc2Nwcm9ncmVzc2NvbnRhaW5lclwiKS5hcHBlbmQoXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjpjZW50ZXJcIj48YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1sZyAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25DbGFzcyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnXCIgaWQ9XCJjb21wbGV0aW9uQnV0dG9uXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uTXNnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiPC9idXR0b24+PC9kaXY+XCJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbn1cblxuZnVuY3Rpb24gc2hvd0xhc3RQb3NpdGlvbkJhbm5lcigpIHtcbiAgICB2YXIgbGFzdFBvc2l0aW9uVmFsID0gJC5nZXRVcmxWYXIoXCJsYXN0UG9zaXRpb25cIik7XG4gICAgaWYgKHR5cGVvZiBsYXN0UG9zaXRpb25WYWwgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgJChcImJvZHlcIikuYXBwZW5kKFxuICAgICAgICAgICAgJzxpbWcgc3JjPVwiLi4vX3N0YXRpYy9sYXN0LXBvaW50LnBuZ1wiIHN0eWxlPVwicG9zaXRpb246YWJzb2x1dGU7IHBhZGRpbmctdG9wOjU1cHg7IGxlZnQ6IDEwcHg7IHRvcDogJyArXG4gICAgICAgICAgICAgICAgcGFyc2VJbnQobGFzdFBvc2l0aW9uVmFsKSArXG4gICAgICAgICAgICAgICAgJ3B4O1wiLz4nXG4gICAgICAgICk7XG4gICAgICAgICQoXCJodG1sLCBib2R5XCIpLmFuaW1hdGUoeyBzY3JvbGxUb3A6IHBhcnNlSW50KGxhc3RQb3NpdGlvblZhbCkgfSwgMTAwMCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBhZGROYXZpZ2F0aW9uQW5kQ29tcGxldGlvbkJ1dHRvbnMoKSB7XG4gICAgaWYgKFxuICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZi5tYXRjaChcbiAgICAgICAgICAgIC8oaW5kZXguaHRtbHxnZW5pbmRleC5odG1sfG5hdmhlbHAuaHRtbHx0b2MuaHRtbHxhc3NpZ25tZW50cy5odG1sfEV4ZXJjaXNlcy5odG1sfHRvY3RyZWUuaHRtbCkvXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgbmF2TGlua0JnUmlnaHRIaWRkZW5Qb3NpdGlvbiA9IC0kKFwiI25hdkxpbmtCZ1JpZ2h0XCIpLm91dGVyV2lkdGgoKSAtIDU7XG4gICAgdmFyIG5hdkxpbmtCZ1JpZ2h0SGFsZk9wZW47XG4gICAgdmFyIG5hdkxpbmtCZ1JpZ2h0RnVsbE9wZW4gPSAwO1xuXG4gICAgaWYgKCQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5oYXNDbGFzcyhcImJ1dHRvbkFza0NvbXBsZXRpb25cIikpIHtcbiAgICAgICAgbmF2TGlua0JnUmlnaHRIYWxmT3BlbiA9IG5hdkxpbmtCZ1JpZ2h0SGlkZGVuUG9zaXRpb24gKyA3MDtcbiAgICB9IGVsc2UgaWYgKCQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5oYXNDbGFzcyhcImJ1dHRvbkNvbmZpcm1Db21wbGV0aW9uXCIpKSB7XG4gICAgICAgIG5hdkxpbmtCZ1JpZ2h0SGFsZk9wZW4gPSAwO1xuICAgIH1cbiAgICB2YXIgcmVsYXRpb25zTmV4dEljb25Jbml0aWFsUG9zaXRpb24gPSAkKFwiI3JlbGF0aW9ucy1uZXh0XCIpLmNzcyhcInJpZ2h0XCIpO1xuICAgIHZhciByZWxhdGlvbnNOZXh0SWNvbk5ld1Bvc2l0aW9uID0gLShuYXZMaW5rQmdSaWdodEhpZGRlblBvc2l0aW9uICsgMzUpO1xuXG4gICAgJChcIiNuYXZMaW5rQmdSaWdodFwiKS5jc3MoXCJyaWdodFwiLCBuYXZMaW5rQmdSaWdodEhpZGRlblBvc2l0aW9uKS5zaG93KCk7XG4gICAgdmFyIG5hdkJnU2hvd24gPSBmYWxzZTtcbiAgICAkKHdpbmRvdykuc2Nyb2xsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgJCh3aW5kb3cpLnNjcm9sbFRvcCgpICsgJCh3aW5kb3cpLmhlaWdodCgpID09XG4gICAgICAgICAgICAkKGRvY3VtZW50KS5oZWlnaHQoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgICQoXCIjbmF2TGlua0JnUmlnaHRcIikuYW5pbWF0ZShcbiAgICAgICAgICAgICAgICB7IHJpZ2h0OiBuYXZMaW5rQmdSaWdodEhhbGZPcGVuIH0sXG4gICAgICAgICAgICAgICAgMjAwXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgJChcIiNuYXZMaW5rQmdMZWZ0XCIpLmFuaW1hdGUoeyBsZWZ0OiBcIjBweFwiIH0sIDIwMCk7XG4gICAgICAgICAgICBpZiAoJChcIiNjb21wbGV0aW9uQnV0dG9uXCIpLmhhc0NsYXNzKFwiYnV0dG9uQ29uZmlybUNvbXBsZXRpb25cIikpIHtcbiAgICAgICAgICAgICAgICAkKFwiI3JlbGF0aW9ucy1uZXh0XCIpLmFuaW1hdGUoXG4gICAgICAgICAgICAgICAgICAgIHsgcmlnaHQ6IHJlbGF0aW9uc05leHRJY29uTmV3UG9zaXRpb24gfSxcbiAgICAgICAgICAgICAgICAgICAgMjAwXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5hdkJnU2hvd24gPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKG5hdkJnU2hvd24pIHtcbiAgICAgICAgICAgICQoXCIjbmF2TGlua0JnUmlnaHRcIikuYW5pbWF0ZShcbiAgICAgICAgICAgICAgICB7IHJpZ2h0OiBuYXZMaW5rQmdSaWdodEhpZGRlblBvc2l0aW9uIH0sXG4gICAgICAgICAgICAgICAgMjAwXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgJChcIiNuYXZMaW5rQmdMZWZ0XCIpLmFuaW1hdGUoeyBsZWZ0OiBcIi02NXB4XCIgfSwgMjAwKTtcbiAgICAgICAgICAgICQoXCIjcmVsYXRpb25zLW5leHRcIikuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgcmlnaHQ6IHJlbGF0aW9uc05leHRJY29uSW5pdGlhbFBvc2l0aW9uLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBuYXZCZ1Nob3duID0gZmFsc2U7XG4gICAgICAgI
4060H1cbiAgICB9KTtcblxuICAgIHZhciBjb21wbGV0aW9uRmxhZyA9IDA7XG4gICAgaWYgKCQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5oYXNDbGFzcyhcImJ1dHRvbkFza0NvbXBsZXRpb25cIikpIHtcbiAgICAgICAgY29tcGxldGlvbkZsYWcgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbXBsZXRpb25GbGFnID0gMTtcbiAgICB9XG4gICAgLy8gTWFrZSBzdXJlIHdlIG1hcmsgdGhpcyBwYWdlIGFzIHZpc2l0ZWQgcmVnYXJkbGVzcyBvZiBob3cgZmxha2V5XG4gICAgLy8gdGhlIG9udW5sb2FkIGhhbmRsZXJzIGJlY29tZS5cbiAgICBwcm9jZXNzUGFnZVN0YXRlKGNvbXBsZXRpb25GbGFnKTtcbiAgICAkKFwiI2NvbXBsZXRpb25CdXR0b25cIikub24oXCJjbGlja1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICgkKHRoaXMpLmhhc0NsYXNzKFwiYnV0dG9uQXNrQ29tcGxldGlvblwiKSkge1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhcImJ1dHRvbkFza0NvbXBsZXRpb25cIilcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJidXR0b25Db25maXJtQ29tcGxldGlvblwiKVxuICAgICAgICAgICAgICAgIC5odG1sKFxuICAgICAgICAgICAgICAgICAgICBcIjxpIGNsYXNzPSdnbHlwaGljb24gZ2x5cGhpY29uLW9rJz48L2k+IENvbXBsZXRlZC4gV2VsbCBEb25lIVwiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICQoXCIjbmF2TGlua0JnUmlnaHRcIikuYW5pbWF0ZSh7IHJpZ2h0OiBuYXZMaW5rQmdSaWdodEZ1bGxPcGVuIH0pO1xuICAgICAgICAgICAgJChcIiNyZWxhdGlvbnMtbmV4dFwiKS5hbmltYXRlKHtcbiAgICAgICAgICAgICAgICByaWdodDogcmVsYXRpb25zTmV4dEljb25OZXdQb3NpdGlvbixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbmF2TGlua0JnUmlnaHRIYWxmT3BlbiA9IDA7XG4gICAgICAgICAgICBjb21wbGV0aW9uRmxhZyA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAoJCh0aGlzKS5oYXNDbGFzcyhcImJ1dHRvbkNvbmZpcm1Db21wbGV0aW9uXCIpKSB7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKFwiYnV0dG9uQ29uZmlybUNvbXBsZXRpb25cIilcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJidXR0b25Bc2tDb21wbGV0aW9uXCIpXG4gICAgICAgICAgICAgICAgLmh0bWwoXCJNYXJrIGFzIENvbXBsZXRlZFwiKTtcbiAgICAgICAgICAgIG5hdkxpbmtCZ1JpZ2h0SGFsZk9wZW4gPSBuYXZMaW5rQmdSaWdodEhpZGRlblBvc2l0aW9uICsgNzA7XG4gICAgICAgICAgICAkKFwiI25hdkxpbmtCZ1JpZ2h0XCIpLmFuaW1hdGUoeyByaWdodDogbmF2TGlua0JnUmlnaHRIYWxmT3BlbiB9KTtcbiAgICAgICAgICAgICQoXCIjcmVsYXRpb25zLW5leHRcIikuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgcmlnaHQ6IHJlbGF0aW9uc05leHRJY29uSW5pdGlhbFBvc2l0aW9uLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb21wbGV0aW9uRmxhZyA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgcHJvY2Vzc1BhZ2VTdGF0ZShjb21wbGV0aW9uRmxhZyk7XG4gICAgfSk7XG5cbiAgICAkKHdpbmRvdykub24oXCJiZWZvcmV1bmxvYWRcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25GbGFnID09IDApIHtcbiAgICAgICAgICAgIHByb2Nlc3NQYWdlU3RhdGUoY29tcGxldGlvbkZsYWcpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cbi8vIF8gZGVjb3JhdGVUYWJsZU9mQ29udGVudHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGRlY29yYXRlVGFibGVPZkNvbnRlbnRzKCkge1xuICAgIGlmIChcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYudG9Mb3dlckNhc2UoKS5pbmRleE9mKFwidG9jLmh0bWxcIikgIT0gLTEgfHxcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYudG9Mb3dlckNhc2UoKS5pbmRleE9mKFwiaW5kZXguaHRtbFwiKSAhPSAtMVxuICAgICkge1xuICAgICAgICBqUXVlcnkuZ2V0KFxuICAgICAgICAgICAgYCR7ZUJvb2tDb25maWcubmV3X3NlcnZlcl9wcmVmaXh9L2xvZ2dlci9nZXRBbGxDb21wbGV0aW9uU3RhdHVzYCxcbiAgICAgICAgICAgIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN1YkNoYXB0ZXJMaXN0O1xuICAgICAgICAgICAgICAgIGlmIChkYXRhICE9IFwiTm9uZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1YkNoYXB0ZXJMaXN0ID0gZGF0YS5kZXRhaWw7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIGFsbFN1YkNoYXB0ZXJVUkxzID0gJChcIiNtYWluLWNvbnRlbnQgZGl2IGxpIGFcIik7XG4gICAgICAgICAgICAgICAgICAgICQuZWFjaChzdWJDaGFwdGVyTGlzdCwgZnVuY3Rpb24gKGluZGV4LCBpdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBzID0gMDsgcyA8IGFsbFN1YkNoYXB0ZXJVUkxzLmxlbmd0aDsgcysrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxTdWJDaGFwdGVyVVJMc1tzXS5ocmVmLmluZGV4T2YoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmNoYXB0ZXJOYW1lICsgXCIvXCIgKyBpdGVtLnN1YkNoYXB0ZXJOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgIT0gLTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKGFsbFN1YkNoYXB0ZXJVUkxzW3NdLnBhcmVudEVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKFwiY29tcGxldGVkXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwiaW5mb1RleHRDb21wbGV0ZWRcIj4tIENvbXBsZXRlZCB0aGlzIHRvcGljIG9uICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5lbmREYXRlICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiPC9zcGFuPlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jaGlsZHJlbigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpcnN0KClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaG92ZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQo
4060dGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV4dChcIi5pbmZvVGV4dENvbXBsZXRlZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV4dChcIi5pbmZvVGV4dENvbXBsZXRlZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKGFsbFN1YkNoYXB0ZXJVUkxzW3NdLnBhcmVudEVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKFwiYWN0aXZlXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwiaW5mb1RleHRBY3RpdmVcIj5MYXN0IHJlYWQgdGhpcyB0b3BpYyBvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uZW5kRGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIjwvc3Bhbj5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2hpbGRyZW4oKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maXJzdCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmhvdmVyKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm5leHQoXCIuaW5mb1RleHRBY3RpdmVcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm5leHQoXCIuaW5mb1RleHRBY3RpdmVcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICB2Y
4060XIgZGF0YSA9IHsgY291cnNlOiBlQm9va0NvbmZpZy5jb3Vyc2UgfTtcbiAgICAgICAgalF1ZXJ5LmdldChcbiAgICAgICAgICAgIGAke2VCb29rQ29uZmlnLm5ld19zZXJ2ZXJfcHJlZml4fS9sb2dnZXIvZ2V0bGFzdHBhZ2VgLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgdmFyIGxhc3RQYWdlRGF0YTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YSAhPSBcIk5vbmVcIikge1xuICAgICAgICAgICAgICAgICAgICBsYXN0UGFnZURhdGEgPSBkYXRhLmRldGFpbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RQYWdlRGF0YS5sYXN0UGFnZUNoYXB0ZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgJChcIiNjb250aW51ZS1yZWFkaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5odG1sKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBpZD1cImp1bXAtdG8tY2hhcHRlclwiIGNsYXNzPVwiYWxlcnQgYWxlcnQtaW5mb1wiID48c3Ryb25nPllvdSB3ZXJlIExhc3QgUmVhZGluZzo8L3N0cm9uZz4gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0UGFnZURhdGEubGFzdFBhZ2VDaGFwdGVyICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsYXN0UGFnZURhdGEubGFzdFBhZ2VTdWJjaGFwdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBcIiAmZ3Q7IFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQYWdlRGF0YS5sYXN0UGFnZVN1YmNoYXB0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFwiXCIpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgPGEgaHJlZj1cIicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFBhZ2VEYXRhLmxhc3RQYWdlVXJsICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiP2xhc3RQb3NpdGlvbj1cIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0UGFnZURhdGEubGFzdFBhZ2VTY3JvbGxMb2NhdGlvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCI+Q29udGludWUgUmVhZGluZzwvYT48L2Rpdj4nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGVuYWJsZUNvbXBsZXRpb25zKCkge1xuICAgIGdldENvbXBsZXRpb25zKCk7XG4gICAgc2hvd0xhc3RQb3NpdGlvbkJhbm5lcigpO1xuICAgIGFkZE5hdmlnYXRpb25BbmRDb21wbGV0aW9uQnV0dG9ucygpO1xuICAgIGRlY29yYXRlVGFibGVPZkNvbnRlbnRzKCk7XG59XG5cbi8vIGNhbGwgZW5hYmxlIHVzZXIgaGlnaGxpZ2h0cyBhZnRlciBsb2dpblxuJChkb2N1bWVudCkub24oXCJydW5lc3RvbmU6bG9naW5cIiwgZW5hYmxlQ29tcGxldGlvbnMpO1xuXG5mdW5jdGlvbiBpc1ByZVRlWHQoKSB7XG4gICAgbGV0IHB0eE1hcmtlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJib2R5LnByZXRleHRcIik7XG4gICAgaWYgKHB0eE1hcmtlcikge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuLy8gXyBwcm9jZXNzUGFnZVN0YXRlXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBwcm9jZXNzUGFnZVN0YXRlKGNvbXBsZXRpb25GbGFnKSB7XG4gICAgLypMb2cgbGFzdCBwYWdlIHZpc2l0ZWQqL1xuICAgIHZhciBjdXJyZW50UGF0aG5hbWUgPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWU7XG4gICAgaWYgKGN1cnJlbnRQYXRobmFtZS5pbmRleE9mKFwiP1wiKSAhPT0gLTEpIHtcbiAgICAgICAgY3VycmVudFBhdGhuYW1lID0gY3VycmVudFBhdGhuYW1lLnN1YnN0cmluZyhcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICBjdXJyZW50UGF0aG5hbWUubGFzdEluZGV4T2YoXCI/XCIpXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8vIElzIHRoaXMgYSBwdHggYm9vaz9cbiAgICBsZXQgaXNQdHhCb29rID0gaXNQcmVUZVh0KClcbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgICAgbGFzdFBhZ2VVcmw6IGN1cnJlbnRQYXRobmFtZSxcbiAgICAgICAgbGFzdFBhZ2VTY3JvbGxMb2NhdGlvbjogJCh3aW5kb3cpLnNjcm9sbFRvcCgpLFxuICAgICAgICBjb21wbGV0aW9uRmxhZzogY29tcGxldGlvbkZsYWcsXG4gICAgICAgIGNvdXJzZTogZUJvb2tDb25maWcuY291cnNlLFxuICAgICAgICBpc1B0eEJvb2s6IGlzUHR4Qm9vayxcbiAgICB9O1xuICAgICQoZG9jdW1lbnQpLmFqYXhFcnJvcihmdW5jdGlvbiAoZSwganFoeHIsIHNldHRpbmdzLCBleGNlcHRpb24pIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJSZXF1ZXN0IEZhaWxlZCBmb3IgXCIgKyBzZXR0aW5ncy51cmwpO1xuICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICB9KTtcbiAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgIHVybDogYCR7ZUJvb2tDb25maWcubmV3X3NlcnZlcl9wcmVmaXh9L2xvZ2dlci91cGRhdGVsYXN0cGFnZWAsXG4gICAgICAgIGNvbnRlbnRUeXBlOiBcImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLThcIixcbiAgICAgICAgZGF0YVR5cGU6IFwianNvblwiLFxuICAgICAgICBkYXRhOiBKU09OLnN0cmluZ2lmeShkYXRhKSxcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgYXN5bmM6IHRydWUsXG4gICAgfSk7XG59XG5cbiQuZXh0ZW5kKHtcbiAgICBnZXRVcmxWYXJzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2YXJzID0gW10sXG4gICAgICAgICAgICBoYXNoO1xuICAgICAgICB2Y
4060XIgaGFzaGVzID0gd2luZG93LmxvY2F0aW9uLnNlYXJjaFxuICAgICAgICAgICAgLnNsaWNlKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guaW5kZXhPZihcIj9cIikgKyAxKVxuICAgICAgICAgICAgLnNwbGl0KFwiJlwiKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGhhc2ggPSBoYXNoZXNbaV0uc3BsaXQoXCI9XCIpO1xuICAgICAgICAgICAgdmFycy5wdXNoKGhhc2hbMF0pO1xuICAgICAgICAgICAgdmFyc1toYXNoWzBdXSA9IGhhc2hbMV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhcnM7XG4gICAgfSxcbiAgICBnZXRVcmxWYXI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiAkLmdldFVybFZhcnMoKVtuYW1lXTtcbiAgICB9LFxufSk7XG4iLCIoZnVuY3Rpb24gKCQpIHtcbiAgLyoqXG4gICAqIFBhdGNoIFRPQyBsaXN0LlxuICAgKlxuICAgKiBXaWxsIG11dGF0ZSB0aGUgdW5kZXJseWluZyBzcGFuIHRvIGhhdmUgYSBjb3JyZWN0IHVsIGZvciBuYXYuXG4gICAqXG4gICAqIEBwYXJhbSAkc3BhbjogU3BhbiBjb250YWluaW5nIG5lc3RlZCBVTCdzIHRvIG11dGF0ZS5cbiAgICogQHBhcmFtIG1pbkxldmVsOiBTdGFydGluZyBsZXZlbCBmb3IgbmVzdGVkIGxpc3RzLiAoMTogZ2xvYmFsLCAyOiBsb2NhbCkuXG4gICAqL1xuICB2YXIgcGF0Y2hUb2MgPSBmdW5jdGlvbiAoJHVsLCBtaW5MZXZlbCkge1xuICAgIHZhciBmaW5kQSxcbiAgICAgIHBhdGNoVGFibGVzLFxuICAgICAgJGxvY2FsTGk7XG5cbiAgICAvLyBGaW5kIGFsbCBhIFwiaW50ZXJuYWxcIiB0YWdzLCB0cmF2ZXJzaW5nIHJlY3Vyc2l2ZWx5LlxuICAgIGZpbmRBID0gZnVuY3Rpb24gKCRlbGVtLCBsZXZlbCkge1xuICAgICAgbGV2ZWwgPSBsZXZlbCB8fCAwO1xuICAgICAgdmFyICRpdGVtcyA9ICRlbGVtLmZpbmQoXCI+IGxpID4gYS5pbnRlcm5hbCwgPiB1bCwgPiBsaSA+IHVsXCIpO1xuXG4gICAgICAvLyBJdGVyYXRlIGV2ZXJ5dGhpbmcgaW4gb3JkZXIuXG4gICAgICAkaXRlbXMuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGl0ZW0pIHtcbiAgICAgICAgdmFyICRpdGVtID0gJChpdGVtKSxcbiAgICAgICAgICB0YWcgPSBpdGVtLnRhZ05hbWUudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICAkY2hpbGRyZW5MaSA9ICRpdGVtLmNoaWxkcmVuKCdsaScpLFxuICAgICAgICAgICRwYXJlbnRMaSA9ICQoJGl0ZW0ucGFyZW50KCdsaScpLCAkaXRlbS5wYXJlbnQoKS5wYXJlbnQoJ2xpJykpO1xuXG4gICAgICAgIC8vIEFkZCBkcm9wZG93bnMgaWYgbW9yZSBjaGlsZHJlbiBhbmQgYWJvdmUgbWluaW11bSBsZXZlbC5cbiAgICAgICAgaWYgKHRhZyA9PT0gJ3VsJyAmJiBsZXZlbCA+PSBtaW5MZXZlbCAmJiAkY2hpbGRyZW5MaS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgJHBhcmVudExpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ2Ryb3Bkb3duLXN1Ym1lbnUnKVxuICAgICAgICAgICAgLmNoaWxkcmVuKCdhJykuZmlyc3QoKS5hdHRyKCd0YWJpbmRleCcsIC0xKTtcblxuICAgICAgICAgICRpdGVtLmFkZENsYXNzKCdkcm9wZG93bi1tZW51Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBmaW5kQSgkaXRlbSwgbGV2ZWwgKyAxKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBmaW5kQSgkdWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBQYXRjaCBhbGwgdGFibGVzIHRvIHJlbW92ZSBgYGRvY3V0aWxzYGAgY2xhc3MgYW5kIGFkZCBCb290c3RyYXAgYmFzZVxuICAgKiBgYHRhYmxlYGAgY2xhc3MuXG4gICAqL1xuICBwYXRjaFRhYmxlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAkKFwidGFibGUuZG9jdXRpbHNcIilcbiAgICAgIC5yZW1vdmVDbGFzcyhcImRvY3V0aWxzXCIpXG4gICAgICAuYWRkQ2xhc3MoXCJ0YWJsZVwiKVxuICAgICAgLmF0dHIoXCJib3JkZXJcIiwgMCk7XG4gIH07XG5cbiQoZnVuY3Rpb24gKCkge1xuXG4gICAgLypcbiAgICAgKiBTY3JvbGwgdGhlIHdpbmRvdyB0byBhdm9pZCB0aGUgdG9wbmF2IGJhclxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS90d2l0dGVyL2Jvb3RzdHJhcC9pc3N1ZXMvMTc2OFxuICAgICAqL1xuICAgIGlmICgkKFwiI25hdmJhci5uYXZiYXItZml4ZWQtdG9wXCIpLmxlbmd0aCA+IDApIHtcbiAgICAgIHZhciBuYXZIZWlnaHQgPSAkKFwiI25hdmJhclwiKS5oZWlnaHQoKSxcbiAgICAgICAgc2hpZnRXaW5kb3cgPSBmdW5jdGlvbigpIHsgc2Nyb2xsQnkoMCwgLW5hdkhlaWdodCAtIDEwKTsgfTtcblxuICAgICAgaWYgKGxvY2F0aW9uLmhhc2gpIHtcbiAgICAgICAgc2hpZnRXaW5kb3coKTtcbiAgICAgIH1cblxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJoYXNoY2hhbmdlXCIsIHNoaWZ0V2luZG93KTtcbiAgICB9XG5cbiAgICAvLyBBZGQgc3R5bGluZywgc3RydWN0dXJlIHRvIFRPQydzLlxuICAgICQoXCIuZHJvcGRvd24tbWVudVwiKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICQodGhpcykuZmluZChcInVsXCIpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBpdGVtKXtcbiAgICAgICAgdmFyICRpdGVtID0gJChpdGVtKTtcbiAgICAgICAgJGl0ZW0uYWRkQ2xhc3MoJ3Vuc3R5bGVkJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIEdsb2JhbCBUT0MuXG4gICAgaWYgKCQoXCJ1bC5nbG9iYWx0b2MgbGlcIikubGVuZ3RoKSB7XG4gICAgICBwYXRjaFRvYygkKFwidWwuZ2xvYmFsdG9jXCIpLCAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmVtb3ZlIEdsb2JhbCBUT0MuXG4gICAgICAkKFwiLmdsb2JhbHRvYy1jb250YWluZXJcIikucmVtb3ZlKCk7XG4gICAgfVxuXG4gICAgLy8gTG9jYWwgVE9DLlxuICAgIHBhdGNoVG9jKCQoXCJ1bC5sb2NhbHRvY1wiKSwgMik7XG5cbiAgICAvLyBNdXRhdGUgc3ViLWxpc3RzIChmb3IgYnMtMi4zLjApLlxuICAgICQoXCIuZHJvcGRvd24tbWVudSB1bFwiKS5ub3QoXCIuZHJvcGRvd24tbWVudVwiKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdWwgPSAkKHRoaXMpLFxuICAgICAgICAkcGFyZW50ID0gJHVsLnBhcmVudCgpLFxuICAgICAgICB0YWcgPSAkcGFyZW50WzBdLnRhZ05hbWUudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgJGtpZHMgPSAkdWwuY2hpbGRyZW4oKS5kZXRhY2goKTtcblxuICAgICAgLy8gUmVwbGFjZSBsaXN0IHdpdGggaXRlbXMgaWYgc3VibWVudSBoZWFkZXIuXG4gICAgICBpZiAodGFnID09PSBcInVsXCIpIHtcbiAgICAgICAgJHVsLnJlcGxhY2VXaXRoKCRraWRzKTtcbiAgICAgIH0gZWxzZSBpZiAodGFnID09PSBcImxpXCIpIHtcbiAgICAgICAgLy8gSW5zZXJ0IGludG8gcHJldmlvdXMgbGlzdC5cbiAgICAgICAgJHBhcmVudC5hZnRlcigka2lkcyk7XG4gICAgICAgICR1bC5yZW1vdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEFkZCBkaXZpZGVyIGluIHBhZ2UgVE9DLlxuICAgICRsb2NhbExpID0gJChcInVsLmxvY2FsdG9jIGxpXCIpO1xuICAgIGlmICgkbG9jYWxMaS5sZW5ndGggPiAyKSB7XG4gICAgICAkbG9jYWxMaS5maXJzdCgpLmFmdGVyKCc8bGkgY2xhc3M9XCJkaXZpZGVyXCI+PC9saT4nKTtcbiAgICB9XG5cbiAgICAvLyBFbmFibGUgZHJvcGRvd24uXG4gICAgJCgnLmRyb3Bkb3duLXRvZ2dsZScpLmRyb3Bkb3duKCk7XG5cbiAgICAvLyBQYXRjaCB0YWJsZXMuXG4gICAgcGF0Y2hUYWJsZXMoKTtcblxuICAgIC8vIEFkZCBOb3RlLCBXYXJuaW5nIHN0eWxlcy5cbiAgICAkKCdkaXYubm90ZScpLmFkZENsYXNzKCdhbGVydCcpLmFkZENsYXNzKCdhbGVydC1pbmZvJyk7XG4gICAgJCgnZGl2Lndhcm5pbmcnKS5hZGRDbGFzcygnYWxlcnQnKS5hZGRDbGFzcygnYWxlcnQtd2FybmluZycpO1xuXG4gICAgLy8gSW5saW5lIGNvZGUgc3R5bGVzIHRvIEJvb3RzdHJhcCBzdHlsZS5cbiAgICAkKCd0dC5kb2N1dGlscy5saXRlcmFsJykubm90KFwiLnhyZWZcIikuZWFjaChmdW5jdGlvbiAoaSwgZSkge1xuICAgICAgLy8gaWdub3JlIHJlZmVyZW5jZXNcbiAgICAgIGlmICghJChlKS5wYXJlbnQoKS5oYXNDbGFzcyhcInJlZmVyZW5jZVwiKSkge1xuICAgICAgICAkKGUpLnJlcGxhY2VXaXRoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gJChcIjxjb2RlIC8+XCIpLnRleHQoJCh0aGlzKS50ZXh0KCkpO1xuICAgICAgICB9KTtcbiAgICAgIH19KTtcbiAgfSk7XG59KHdpbmRvdy5qUXVlcnkpKTtcbiIsIi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4vLyB8ZG9jbmFtZXwgLSBBIGZyYW1ld29yayBhbGxvd2luZyBhIFJ1bmVzdG9uZSBjb21wb25lbnQgdG8gbG9hZCBvbmx5IHRoZSBKUyBpdCBuZWVkc1xuLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbi8vIFRoZSBKYXZhU2NyaXB0IHJlcXVpcmVkIGJ5IGFsbCBSdW5lc3RvbmUgY29tcG9uZW50cyBpcyBxdWl0ZSBsYXJnZSBhbmQgcmVzdWx0cyBpbiBzbG93IHBhZ2UgbG9hZHMuIFRoaXMgYXBwcm9hY2ggZW5hYmxlcyBhIFJ1bmVzdG9uZSBjb21wb25lbnQgdG8gbG9hZCBvbmx5IHRoZSBKYXZhU2NyaXB0IGl0IG5lZWRzLCByYXRoZXIgdGhhbiBsb2FkaW5nIEphdmFTY3JpcHQgZm9yIGFsbCB0aGUgY29tcG9uZW50cyByZWdhcmRsZXNzIG9mIHdoaWNoIGFyZSBhY3R1YWxseSB1c2VkLlxuLy9cbi8vIFRvIGFjY29tcGxpc2ggdGhpcywgd2VicGFjaydzIHNwbGl0LWNodW5rcyBhYmlsaXR5IGFuYWx5emVzIGFsbCBKUywgc3RhcnRpbmcgZnJvbSB0aGlzIGZpbGUuIFRoZSBkeW5hbWljIGltcG9ydHMgYmVsb3cgYXJlIHRyYW5zZm9ybWVkIGJ5IHdlYnBhY2sgaW50byB0aGUgZHluYW1pYyBmZXRjaGVzIG9mIGp1c3QgdGhlIE
4060pTIHJlcXVpcmVkIGJ5IGVhY2ggZmlsZSBhbmQgYWxsIGl0cyBkZXBlbmRlbmNpZXMuIChJZiB1c2luZyBzdGF0aWMgaW1wb3J0cywgd2VicGFjayB3aWxsIGFzc3VtZSB0aGF0IGFsbCBmaWxlcyBhcmUgYWxyZWFkeSBzdGF0aWNhbGx5IGxvYWRlZCB2aWEgc2NyaXB0IHRhZ3MsIGRlZmVhdGluZyB0aGUgcHVycG9zZSBvZiB0aGlzIGZyYW1ld29yay4pXG4vL1xuLy8gSG93ZXZlciwgdGhpcyBhcHByb2FjaCBsZWFkcyB0byBjb21wbGV4aXR5OlxuLy9cbi8vIC0gICAgVGhlIGBgZGF0YS1jb21wb25lbnRgYCBhdHRyaWJ1dGUgb2YgZWFjaCBjb21wb25lbnQgbXVzdCBiZSBrZXB0IGluIHN5bmMgd2l0aCB0aGUga2V5cyBvZiB0aGUgYGBtb2R1bGVfbWFwYGAgYmVsb3cuXG4vLyAtICAgIFRoZSB2YWx1ZXMgaW4gdGhlIGBgbW9kdWxlX21hcGBgIG11c3QgYmUga2VwdCBpbiBzeW5jIHdpdGggdGhlIEphdmFTY3JpcHQgZmlsZXMgd2hpY2ggaW1wbGVtZW50IGVhY2ggb2YgdGhlIGNvbXBvbmVudHMuXG5cblwidXNlIHN0cmljdFwiO1xuXG4vLyBTdGF0aWMgaW1wb3J0c1xuLy8gPT09PT09PT09PT09PT1cbi8vIFRoZXNlIGltcG9ydHMgYXJlICh3ZSBhc3N1bWUpIG5lZWRlZCBieSBhbGwgcGFnZXMuIEhvd2V2ZXIsIGl0IHdvdWxkIGJlIG11Y2ggYmV0dGVyIHRvIGxvYWQgdGhlc2UgaW4gdGhlIG1vZHVsZXMgdGhhdCBhY3R1YWxseSB1c2UgdGhlbS5cbi8vXG4vLyBUaGVzZSBhcmUgc3RhdGljIGltcG9ydHM7IGNvZGUgaW4gYGR5bmFtaWNhbGx5IGxvYWRlZCBjb21wb25lbnRzYF8gZGVhbHMgd2l0aCBkeW5hbWljIGltcG9ydHMuXG4vL1xuLy8galF1ZXJ5LXJlbGF0ZWQgaW1wb3J0cy5cbmltcG9ydCBcImpxdWVyeS11aS9qcXVlcnktdWkuanNcIjtcbmltcG9ydCBcImpxdWVyeS11aS90aGVtZXMvYmFzZS9qcXVlcnkudWkuYWxsLmNzc1wiO1xuaW1wb3J0IFwiLi9ydW5lc3RvbmUvY29tbW9uL2pzL2pxdWVyeS5pZGxlLXRpbWVyLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4uanNcIjtcbmltcG9ydCBcIi4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5lbWl0dGVyLmJpZGkuanNcIjtcbmltcG9ydCBcIi4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5lbWl0dGVyLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4uZmFsbGJhY2tzLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4ubWVzc2FnZXN0b3JlLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4ucGFyc2VyLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4ubGFuZ3VhZ2UuanNcIjtcblxuLy8gQm9vdHN0cmFwXG5pbXBvcnQgXCJib290c3RyYXAvZGlzdC9qcy9ib290c3RyYXAuanNcIjtcbmltcG9ydCBcImJvb3RzdHJhcC9kaXN0L2Nzcy9ib290c3RyYXAuY3NzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vcHJvamVjdF90ZW1wbGF0ZS9fdGVtcGxhdGVzL3BsdWdpbl9sYXlvdXRzL3NwaGlueF9ib290c3RyYXAvc3RhdGljL2Jvb3RzdHJhcC1zcGhpbnguanNcIjtcbmltcG9ydCBcIi4vcnVuZXN0b25lL2NvbW1vbi9jc3MvcnVuZXN0b25lLWN1c3RvbS1zcGhpbngtYm9vdHN0cmFwLmNzc1wiO1xuXG4vLyBNaXNjXG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvYm9va2Z1bmNzLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvdXNlci1oaWdobGlnaHRzLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvcHJldGV4dC5qc1wiO1xuXG4vLyBUaGVzZSBiZWxvbmcgaW4gZHluYW1pYyBpbXBvcnRzIGZvciB0aGUgb2J2aW91cyBjb21wb25lbnQ7IGhvd2V2ZXIsIHRoZXNlIGNvbXBvbmVudHMgZG9uJ3QgaW5jbHVkZSBhIGBgZGF0YS1jb21wb25lbnRgYCBhdHRyaWJ1dGUuXG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9tYXRyaXhlcS9jc3MvbWF0cml4ZXEuY3NzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS93ZWJnbGRlbW8vY3NzL3dlYmdsaW50ZXJhY3RpdmUuY3NzXCI7XG5cbi8vIFRoZXNlIGFyZSBvbmx5IG5lZWRlZCBmb3IgdGhlIFJ1bmVzdG9uZSBib29rLCBidXQgbm90IGluIGEgbGlicmFyeSBtb2RlIChzdWNoIGFzIHByZXRleHQpLiBJIHdvdWxkIHByZWZlciB0byBkeW5hbWljYWxseSBsb2FkIHRoZW0uIEhvd2V2ZXIsIHRoZXNlIHNjcmlwdHMgYXJlIHNvIHNtYWxsIEkgaGF2ZW4ndCBib3RoZXJlZCB0byBkbyBzby5cbmltcG9ydCB7IGdldFN3aXRjaCwgc3dpdGNoVGhlbWUgfSBmcm9tIFwiLi9ydW5lc3RvbmUvY29tbW9uL2pzL3RoZW1lLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvcHJlc2VudGVyX21vZGUuanNcIjtcbmltcG9ydCBcIi4vcnVuZXN0b25lL2NvbW1vbi9jc3MvcHJlc2VudGVyX21vZGUuY3NzXCI7XG5cbi8vIER5bmFtaWNhbGx5IGxvYWRlZCBjb21wb25lbnRzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVGhpcyBwcm92aWRlcyBhIGxpc3Qgb2YgbW9kdWxlcyB0aGF0IGNvbXBvbmVudHMgY2FuIGR5bmFtaWNhbGx5IGltcG9ydC4gV2VicGFjayB3aWxsIGNyZWF0ZSBhIGxpc3Qgb2YgaW1wb3J0cyBmb3IgZWFjaCBiYXNlZCBvbiBpdHMgYW5hbHlzaXMuXG5jb25zdCBtb2R1bGVfbWFwID0ge1xuICAgIC8vIFdyYXAgZWFjaCBpbXBvcnQgaW4gYSBmdW5jdGlvbiwgc28gdGhhdCBpdCB3b24ndCBvY2N1ciB1bnRpbCB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkLiBXaGlsZSBzb21ldGhpbmcgY2xlYW5lciB3b3VsZCBiZSBuaWNlLCB3ZWJwYWNrIGNhbid0IGFuYWx5emUgdGhpbmdzIGxpa2UgYGBpbXBvcnQoZXhwcmVzc2lvbilgYC5cbiAgICAvL1xuICAgIC8vIFRoZSBrZXlzIG11c3QgbWF0Y2ggdGhlIHZhbHVlIG9mIGVhY2ggY29tcG9uZW50J3MgYGBkYXRhLWNvbXBvbmVudGBgIGF0dHJpYnV0ZSAtLSB0aGUgYGBydW5lc3RvbmVfaW1wb3J0YGAgYW5kIGBgcnVuZXN0b25lX2F1dG9faW1wb3J0YGAgZnVuY3Rpb25zIGFzc3VtZSB0aGlzLlxuICAgIGFjdGl2ZWNvZGU6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2FjdGl2ZWNvZGUvanMvYWNmYWN0b3J5LmpzXCIpLFxuICAgIGJsZTogKCkgPT4gaW1wb3J0KFwiLi9ydW5lc3RvbmUvY2VsbGJvdGljcy9qcy9ibGUuanNcIiksXG4gICAgLy8gQWx3YXlzIGltcG9ydCB0aGUgdGltZWQgdmVyc2lvbiBvZiBhIGNvbXBvbmVudCBpZiBhdmFpbGFibGUsIHNpbmNlIHRoZSB0aW1lZCBjb21wb25lbnRzIGFsc28gZGVmaW5lIHRoZSBjb21wb25lbnQncyBmYWN0b3J5IGFuZCBpbmNsdWRlIHRoZSBjb21wb25lbnQgYXMgd2VsbC4gTm90ZSB0aGF0IGBgYWNmYWN0b3J5YGAgaW1wb3J0cyB0aGUgdGltZWQgY29tcG9uZW50cyBvZiBBY3RpdmVDb2RlLCBzbyBpdCBmb2xsb3dzIHRoaXMgcGF0dGVybi5cbiAgICBjbGlja2FibGVhcmVhOiAoKSA9PlxuICAgICAgICBpbXBvcnQoXCIuL3J1bmVzdG9uZS9jbGlja2FibGVBcmVhL2pzL3RpbWVkY2xpY2thYmxlLmpzXCIpLFxuICAgIGNvZGVsZW5zOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9jb2RlbGVucy9qcy9jb2RlbGVucy5qc1wiKSxcbiAgICBkYXRhZmlsZTogKCkgPT4gaW1wb3J0KFwiLi9ydW5lc3RvbmUvZGF0YWZpbGUvanMvZGF0YWZpbGUuanNcIiksXG4gICAgZHJhZ25kcm9wOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9kcmFnbmRyb3AvanMvdGltZWRkbmQuanNcIiksXG4gICAgZmlsbGludGhlYmxhbms6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2ZpdGIvanMvdGltZWRmaXRiLmpzXCIpLFxuICAgIGdyb3Vwc3ViOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9ncm91cHN1Yi9qcy9ncm91cHN1Yi5qc1wiKSxcbiAgICBraGFuZXg6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2toYW5leC9qcy9raGFuZXguanNcIiksXG4gICAgbHBfYnVpbGQ6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2xwL2pzL2xwLmpzXCIpLFxuICAgIG11bHRpcGxlY2hvaWNlOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9tY2hvaWNlL2pzL3RpbWVkbWMuanNcIiksXG4gICAgaHBhcnNvbnM6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2hwYXJzb25zL2pzL2hwYXJzb25zLmpzXCIpLFxuICAgIHBhcnNvbnM6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3BhcnNvbnMvanMvdGltZWRwYXJzb25zLmpzXCIpLFxuICAgIHBvbGw6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3BvbGwvanMvcG9sbC5qc1wiKSxcbiAgICBxdWl6bHk6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3F1aXpseS9qcy9xdWl6bHkuanNcIiksXG4gICAgcmV2ZWFsOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9yZXZlYWwvanMvcmV2ZWFsLmpzXCIpLFxuICAgIHNlbGVjdHF1ZXN0aW9uOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9zZWxlY3RxdWVzdGlvbi9qcy9zZWxlY3RvbmUuanNcIiksXG4gICAgc2hvcnRhbnN3ZXI6ICgpID0+XG4gICAgICAgIGltcG9ydChcIi4vcnVuZXN0b25lL3Nob3J0YW5zd2VyL2pzL3RpbWVkX3Nob3J0YW5zd2VyLmpzXCIpLFxuICAgIHNob3dldmFsOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9zaG93ZXZhbC9qcy9zaG93RXZhbC5qc1wiKSxcbiAgICBzaW1wbGVf
4060c2Vuc29yOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9jZWxsYm90aWNzL2pzL3NpbXBsZV9zZW5zb3IuanNcIiksXG4gICAgc3ByZWFkc2hlZXQ6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3NwcmVhZHNoZWV0L2pzL3NwcmVhZHNoZWV0LmpzXCIpLFxuICAgIHRhYmJlZFN0dWZmOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS90YWJiZWRTdHVmZi9qcy90YWJiZWRzdHVmZi5qc1wiKSxcbiAgICB0aW1lZEFzc2Vzc21lbnQ6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3RpbWVkL2pzL3RpbWVkLmpzXCIpLFxuICAgIHdhdmVkcm9tOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS93YXZlZHJvbS9qcy93YXZlZHJvbS5qc1wiKSxcbiAgICAvLyBUT0RPOiBzaW5jZSB0aGlzIGlzbid0IGluIGEgYGBkYXRhLWNvbXBvbmVudGBgLCBuZWVkIHRvIHRyaWdnZXIgYW4gaW1wb3J0IG9mIHRoaXMgY29kZSBtYW51YWxseS5cbiAgICB3ZWJ3b3JrOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS93ZWJ3b3JrL2pzL3dlYndvcmsuanNcIiksXG4gICAgeW91dHViZTogKCkgPT4gaW1wb3J0KFwiLi9ydW5lc3RvbmUvdmlkZW8vanMvcnVuZXN0b25ldmlkZW8uanNcIiksXG59O1xuXG4vLyAuLiBfZHluYW1pYyBpbXBvcnQgbWFjaGluZXJ5OlxuLy9cbi8vIER5bmFtaWMgaW1wb3J0IG1hY2hpbmVyeVxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBGdWxmaWxsIGEgcHJvbWlzZSB3aGVuIHRoZSBSdW5lc3RvbmUgcHJlLWxvZ2luIGNvbXBsZXRlIGV2ZW50IG9jY3Vycy5cbmxldCBwcmVfbG9naW5fY29tcGxldGVfcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PlxuICAgICQoZG9jdW1lbnQpLm9uKFwicnVuZXN0b25lOnByZS1sb2dpbi1jb21wbGV0ZVwiLCByZXNvbHZlKVxuKTtcbmxldCBsb2FkZWRDb21wb25lbnRzO1xuLy8gUHJvdmlkZSBhIHNpbXBsZSBmdW5jdGlvbiB0byBpbXBvcnQgdGhlIEpTIGZvciBhbGwgY29tcG9uZW50cyBvbiB0aGUgcGFnZS5cbmV4cG9ydCBmdW5jdGlvbiBydW5lc3RvbmVfYXV0b19pbXBvcnQoKSB7XG4gICAgLy8gQ3JlYXRlIGEgc2V0IG9mIGBgZGF0YS1jb21wb25lbnRgYCB2YWx1ZXMsIHRvIGF2b2lkIGR1cGxpY2F0aW9uLlxuICAgIGNvbnN0IHMgPSBuZXcgU2V0KFxuICAgICAgICAvLyBBbGwgUnVuZXN0b25lIGNvbXBvbmVudHMgaGF2ZSBhIGBgZGF0YS1jb21wb25lbnRgYCBhdHRyaWJ1dGUuXG4gICAgICAgICQoXCJbZGF0YS1jb21wb25lbnRdXCIpXG4gICAgICAgICAgICAubWFwKFxuICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgdGhlIHZhbHVlIG9mIHRoZSBkYXRhLWNvbXBvbmVudCBhdHRyaWJ1dGUuXG4gICAgICAgICAgICAgICAgKGluZGV4LCBlbGVtZW50KSA9PiAkKGVsZW1lbnQpLmF0dHIoXCJkYXRhLWNvbXBvbmVudFwiKVxuICAgICAgICAgICAgICAgIC8vIFN3aXRjaCBmcm9tIGEgalF1ZXJ5IG9iamVjdCBiYWNrIHRvIGFuIGFycmF5LCBwYXNzaW5nIHRoYXQgdG8gdGhlIFNldCBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5nZXQoKVxuICAgICk7XG4gICAgLy8gd2Vid29yayBxdWVzdGlvbnMgYXJlIG5vdCB3cmFwcGVkIGluIGRpdiB3aXRoIGEgZGF0YS1jb21wb25lbnQgc28gd2UgaGF2ZSB0byBjaGVjayBhIGRpZmZlcmVudCB3YXlcbiAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi53ZWJ3b3JrLWJ1dHRvblwiKSkge1xuICAgICAgICBzLmFkZChcIndlYndvcmtcIik7XG4gICAgfVxuXG4gICAgLy8gTG9hZCBKUyBmb3IgZWFjaCBvZiB0aGUgY29tcG9uZW50cyBmb3VuZC5cbiAgICBjb25zdCBhID0gWy4uLnNdLm1hcCgodmFsdWUpID0+XG4gICAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gSlMgZm9yIHRoaXMgY29tcG9uZW50LCByZXR1cm4gYW4gZW1wdHkgUHJvbWlzZS5cbiAgICAgICAgKG1vZHVsZV9tYXBbdmFsdWVdIHx8ICgoKSA9PiBQcm9taXNlLnJlc29sdmUoKSkpKClcbiAgICApO1xuXG4gICAgLy8gU2VuZCB0aGUgUnVuZXN0b25lIGxvZ2luIGNvbXBsZXRlIGV2ZW50IHdoZW4gYWxsIEpTIGlzIGxvYWRlZCBhbmQgdGhlIHByZS1sb2dpbiBpcyBhbHNvIGNvbXBsZXRlLlxuICAgIFByb21pc2UuYWxsKFtwcmVfbG9naW5fY29tcGxldGVfcHJvbWlzZSwgLi4uYV0pLnRoZW4oKCkgPT5cbiAgICAgICAgJChkb2N1bWVudCkudHJpZ2dlcihcInJ1bmVzdG9uZTpsb2dpbi1jb21wbGV0ZVwiKVxuICAgICk7XG59XG5cbi8vIExvYWQgY29tcG9uZW50IEpTIHdoZW4gdGhlIGRvY3VtZW50IGlzIHJlYWR5LlxuJChkb2N1bWVudCkucmVhZHkocnVuZXN0b25lX2F1dG9faW1wb3J0KTtcblxuLy8gUHJvdmlkZSBhIGZ1bmN0aW9uIHRvIGltcG9ydCBvbmUgc3BlY2lmaWMgUnVuZXN0b25lIGNvbXBvbmVudC5cbi8vIHRoZSBpbXBvcnQgZnVuY3Rpb24gaW5zaWRlIG1vZHVsZV9tYXAgaXMgYXN5bmMgLS0gcnVuZXN0b25lX2ltcG9ydFxuLy8gc2hvdWxkIGJlIGF3YWl0ZWQgd2hlbiBuZWNlc3NhcnkgdG8gZW5zdXJlIHRoZSBpbXBvcnQgY29tcGxldGVzXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuZXN0b25lX2ltcG9ydChjb21wb25lbnRfbmFtZSkge1xuICAgIHJldHVybiBtb2R1bGVfbWFwW2NvbXBvbmVudF9uYW1lXSgpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwb3B1cFNjcmF0Y2hBQygpIHtcbiAgICAvLyBsb2FkIHRoZSBhY3RpdmVjb2RlIGJ1bmRsZVxuICAgIGF3YWl0IHJ1bmVzdG9uZV9pbXBvcnQoXCJhY3RpdmVjb2RlXCIpO1xuICAgIC8vIHNjcmF0Y2hEaXYgd2lsbCBiZSBkZWZpbmVkIGlmIHdlIGhhdmUgYWxyZWFkeSBjcmVhdGVkIGEgc2NyYXRjaFxuICAgIC8vIGFjdGl2ZWNvZGUuICBJZiBpdHMgbm90IGRlZmluZWQgdGhlbiB3ZSBuZWVkIHRvIGdldCBpdCByZWFkeSB0byB0b2dnbGVcbiAgICBpZiAoIWVCb29rQ29uZmlnLnNjcmF0Y2hEaXYpIHtcbiAgICAgICAgd2luZG93LkFDRmFjdG9yeS5jcmVhdGVTY3JhdGNoQWN0aXZlY29kZSgpO1xuICAgICAgICBsZXQgZGl2aWQgPSBlQm9va0NvbmZpZy5zY3JhdGNoRGl2O1xuICAgICAgICB3aW5kb3cuZWRMaXN0W2RpdmlkXSA9IEFDRmFjdG9yeS5jcmVhdGVBY3RpdmVDb2RlKFxuICAgICAgICAgICAgJChgIyR7ZGl2aWR9YClbMF0sXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5hY0RlZmF1bHRMYW5ndWFnZVxuICAgICAgICApO1xuICAgICAgICBpZiAoZUJvb2tDb25maWcuaXNMb2dnZWRJbikge1xuICAgICAgICAgICAgd2luZG93LmVkTGlzdFtkaXZpZF0uZW5hYmxlU2F2ZUxvYWQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB3aW5kb3cuQUNGYWN0b3J5LnRvZ2dsZVNjcmF0Y2hBY3RpdmVjb2RlKCk7XG59XG5cbi8vIFNldCB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhpcyBzY3JpcHQgYXMgdGhlIGBwYXRoIDxodHRwczovL3dlYnBhY2suanMub3JnL2d1aWRlcy9wdWJsaWMtcGF0aC8jb24tdGhlLWZseT5gXyBmb3IgYWxsIHdlYnBhY2tlZCBzY3JpcHRzLlxuY29uc3Qgc2NyaXB0X3NyYyA9IGRvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjO1xuX193ZWJwYWNrX3B1YmxpY19wYXRoX18gPSBzY3JpcHRfc3JjLnN1YnN0cmluZyhcbiAgICAwLFxuICAgIHNjcmlwdF9zcmMubGFzdEluZGV4T2YoXCIvXCIpICsgMVxuKTtcblxuLy8gTWFudWFsIGV4cG9ydHNcbi8vID09PT09PT09PT09PT09XG4vLyBXZWJwYWNrJ3MgYGBvdXRwdXQubGlicmFyeWBgIHNldHRpbmcgZG9lc24ndCBzZWVtIHRvIHdvcmsgd2l0aCB0aGUgc3BsaXQgY2h1bmtzIHBsdWdpbjsgZG8gYWxsIGV4cG9ydHMgbWFudWFsbHkgdGhyb3VnaCB0aGUgYGB3aW5kb3dgYCBvYmplY3QgaW5zdGVhZC5cbmNvbnN0IHJjID0ge307XG5yYy5ydW5lc3RvbmVfaW1wb3J0ID0gcnVuZXN0b25lX2ltcG9ydDtcbnJjLnJ1bmVzdG9uZV9hdXRvX2ltcG9ydCA9IHJ1bmVzdG9uZV9hdXRvX2ltcG9ydDtcbnJjLmdldFN3aXRjaCA9IGdldFN3aXRjaDtcbnJjLnN3aXRjaFRoZW1lID0gc3dpdGNoVGhlbWU7XG5yYy5wb3B1cFNjcmF0Y2hBQyA9IHBvcHVwU2NyYXRjaEFDO1xud2luZG93LnJ1bmVzdG9uZUNvbXBvbmVudHMgPSByYztcbiIsIm1vZHVsZS5leHBvcnRzID0galF1ZXJ5OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.