1"use strict"; 2 3function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 4/** 5 * ===================================================================================================================== 6 * JavaScript Util Functions ../includes/__js/utils/wpbc_utils.js 7 * ===================================================================================================================== 8 */ 9 10/** 11 * Trim strings and array joined with (,) 12 * 13 * @param string_to_trim string / array 14 * @returns string 15 */ 16function wpbc_trim(string_to_trim) { 17 if (Array.isArray(string_to_trim)) { 18 string_to_trim = string_to_trim.join(','); 19 } 20 if ('string' == typeof string_to_trim) { 21 string_to_trim = string_to_trim.trim(); 22 } 23 return string_to_trim; 24} 25 26/** 27 * Check if element in array 28 * 29 * @param array_here array 30 * @param p_val element to check 31 * @returns {boolean} 32 */ 33function wpbc_in_array(array_here, p_val) { 34 for (var i = 0, l = array_here.length; i < l; i++) { 35 if (array_here[i] == p_val) { 36 return true; 37 } 38 } 39 return false; 40} 41"use strict"; 42/** 43 * ===================================================================================================================== 44 * includes/__js/wpbc/wpbc.js 45 * ===================================================================================================================== 46 */ 47 48/** 49 * Deep Clone of object or array 50 * 51 * @param obj 52 * @returns {any} 53 */ 54function wpbc_clone_obj(obj) { 55 return JSON.parse(JSON.stringify(obj)); 56} 57 58/** 59 * Main _wpbc JS object 60 */ 61 62var _wpbc = function (obj, $) { 63 // Secure parameters for Ajax ------------------------------------------------------------------------------------ 64 var p_secure = obj.security_obj = obj.security_obj || { 65 user_id: 0, 66 nonce: '', 67 locale: '' 68 }; 69 obj.set_secure_param = function (param_key, param_val) { 70 p_secure[param_key] = param_val; 71 }; 72 obj.get_secure_param = function (param_key) { 73 return p_secure[param_key]; 74 }; 75 76 // Calendars ---------------------------------------------------------------------------------------------------- 77 var p_calendars = obj.calendars_obj = obj.calendars_obj || { 78 // sort : "booking_id", 79 // sort_type : "DESC", 80 // page_num : 1, 81 // page_items_count: 10, 82 // create_date : "", 83 // keyword : "", 84 // source : "" 85 }; 86 87 /** 88 * Check if calendar for specific booking resource defined :: true | false 89 * 90 * @param {string|int} resource_id 91 * @returns {boolean} 92 */ 93 obj.calendar__is_defined = function (resource_id) { 94 return 'undefined' !== typeof p_calendars['calendar_' + resource_id]; 95 }; 96 97 /** 98 * Create Calendar initializing 99 * 100 * @param {string|int} resource_id 101 */ 102 obj.calendar__init = function (resource_id) { 103 p_calendars['calendar_' + resource_id] = {}; 104 p_calendars['calendar_' + resource_id]['id'] = resource_id; 105 p_calendars['calendar_' + resource_id]['pending_days_selectable'] = false; 106 }; 107 108 /** 109 * Check if the type of this property is INT 110 * @param property_name 111 * @returns {boolean} 112 */ 113 obj.calendar__is_prop_int = function (property_name) { 114 // FixIn: 9.9.0.29. 115 116 var p_calendar_int_properties = ['dynamic__days_min', 'dynamic__days_max', 'fixed__days_num']; 117 var is_include = p_calendar_int_properties.includes(property_name); 118 return is_include; 119 }; 120 121 /** 122 * Set params for all calendars 123 * 124 * @param {object} calendars_obj Object { calendar_1: {} } 125 * calendar_3: {}, ... } 126 */ 127 obj.calendars_all__set = function (calendars_obj) { 128 p_calendars = calendars_obj; 129 }; 130 131 /** 132 * Get bookings in all calendars 133 * 134 * @returns {object|{}} 135 */ 136 obj.calendars_all__get = function () { 137 return p_calendars; 138 }; 139 140 /** 141 * Get calendar object :: { id: 1, ⦠} 142 * 143 * @param {string|int} resource_id '2' 144 * @returns {object|boolean} { id: 2 ,⦠} 145 */ 146 obj.calendar__get_parameters = function (resource_id) { 147 if (obj.calendar__is_defined(resource_id)) { 148 return p_calendars['calendar_' + resource_id]; 149 } else { 150 return false;
151 } 152 }; 153 154 /** 155 * Set calendar object :: { dates: Object { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} 156 * 157 * if calendar object not defined, then it's will be defined and ID set 158 * if calendar exist, then system set as new or overwrite only properties from calendar_property_obj parameter, but other properties will be existed and not overwrite, like 'id' 159 * 160 * @param {string|int} resource_id '2' 161 * @param {object} calendar_property_obj { dates: Object { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} } 162 * @param {boolean} is_complete_overwrite if 'true' (default: 'false'), then only overwrite or add new properties in calendar_property_obj 163 * @returns {*} 164 * 165 * Examples: 166 * 167 * Common usage in PHP: 168 * echo " _wpbc.calendar__set( " .intval( $resource_id ) . ", { 'dates': " . wp_json_encode( $availability_per_days_arr ) . " } );"; 169 */ 170 obj.calendar__set_parameters = function (resource_id, calendar_property_obj) { 171 var is_complete_overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 172 if (!obj.calendar__is_defined(resource_id) || true === is_complete_overwrite) { 173 obj.calendar__init(resource_id); 174 } 175 for (var prop_name in calendar_property_obj) { 176 p_calendars['calendar_' + resource_id][prop_name] = calendar_property_obj[prop_name]; 177 } 178 return p_calendars['calendar_' + resource_id]; 179 }; 180 181 /** 182 * Set property to calendar 183 * @param resource_id "1" 184 * @param prop_name name of property 185 * @param prop_value value of property 186 * @returns {*} calendar object 187 */ 188 obj.calendar__set_param_value = function (resource_id, prop_name, prop_value) { 189 if (!obj.calendar__is_defined(resource_id)) { 190 obj.calendar__init(resource_id); 191 } 192 p_calendars['calendar_' + resource_id][prop_name] = prop_value; 193 return p_calendars['calendar_' + resource_id]; 194 }; 195 196 /** 197 * Get calendar property value :: mixed | null 198 * 199 * @param {string|int} resource_id '1' 200 * @param {string} prop_name 'selection_mode' 201 * @returns {*|null} mixed | null 202 */ 203 obj.calendar__get_param_value = function (resource_id, prop_name) { 204 if (obj.calendar__is_defined(resource_id) && 'undefined' !== typeof p_calendars['calendar_' + resource_id][prop_name]) { 205 // FixIn: 9.9.0.29. 206 if (obj.calendar__is_prop_int(prop_name)) { 207 p_calendars['calendar_' + resource_id][prop_name] = parseInt(p_calendars['calendar_' + resource_id][prop_name]); 208 } 209 return p_calendars['calendar_' + resource_id][prop_name]; 210 } 211 return null; // If some property not defined, then null; 212 }; 213 // ----------------------------------------------------------------------------------------------------------------- 214 215 // Bookings ---------------------------------------------------------------------------------------------------- 216 var p_bookings = obj.bookings_obj = obj.bookings_obj || { 217 // calendar_1: Object { 218 // id: 1 219 // , dates: Object { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠220 // } 221 }; 222 223 /** 224 * Check if bookings for specific booking resource defined :: true | false 225 * 226 * @param {string|int} resource_id 227 * @returns {boolean} 228 */ 229 obj.bookings_in_calendar__is_defined = function (resource_id) { 230 return 'undefined' !== typeof p_bookings['calendar_' + resource_id]; 231 }; 232 233 /** 234 * Get bookings calendar object :: { id: 1 , dates: Object { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} 235 * 236 * @param {string|int} resource_id '2' 237 * @returns {object|boolean} { id: 2 , dates: Object { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} 238 */ 239 obj.bookings_in_calendar__get = function (resource_id) { 240 if (obj.bookings_in_calendar__is_defined(resource_id)) { 241 return p_bookings['calendar_' + resource_id]; 242 } else { 243 return false; 244 } 245 }; 246 247 /** 248 * Set bookings calendar object :: { dates: Object { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} 249 * 250 * if calendar object not defined, then it's will be defined and ID set
251 * if calendar exist, then system set as new or overwrite only properties from calendar_obj parameter, but other properties will be existed and not overwrite, like 'id' 252 * 253 * @param {string|int} resource_id '2' 254 * @param {object} calendar_obj { dates: Object { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} } 255 * @returns {*} 256 * 257 * Examples: 258 * 259 * Common usage in PHP: 260 * echo " _wpbc.bookings_in_calendar__set( " .intval( $resource_id ) . ", { 'dates': " . wp_json_encode( $availability_per_days_arr ) . " } );"; 261 */ 262 obj.bookings_in_calendar__set = function (resource_id, calendar_obj) { 263 if (!obj.bookings_in_calendar__is_defined(resource_id)) { 264 p_bookings['calendar_' + resource_id] = {}; 265 p_bookings['calendar_' + resource_id]['id'] = resource_id; 266 } 267 for (var prop_name in calendar_obj) { 268 p_bookings['calendar_' + resource_id][prop_name] = calendar_obj[prop_name]; 269 } 270 return p_bookings['calendar_' + resource_id]; 271 }; 272 273 // Dates 274 275 /** 276 * Get bookings data for ALL Dates in calendar :: false | { "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} 277 * 278 * @param {string|int} resource_id '1' 279 * @returns {object|boolean} false | Object { 280 "2023-07-24": Object { ['summary']['status_for_day']: "available", day_availability: 1, max_capacity: 1, ⦠} 281 "2023-07-26": Object { ['summary']['status_for_day']: "full_day_booking", ['summary']['status_for_bookings']: "pending", day_availability: 0, ⦠} 282 "2023-07-29": Object { ['summary']['status_for_day']: "resource_availability", day_availability: 0, max_capacity: 1, ⦠} 283 "2023-07-30": {â¦}, "2023-07-31": {â¦}, ⦠284 } 285 */ 286 obj.bookings_in_calendar__get_dates = function (resource_id) { 287 if (obj.bookings_in_calendar__is_defined(resource_id) && 'undefined' !== typeof p_bookings['calendar_' + resource_id]['dates']) { 288 return p_bookings['calendar_' + resource_id]['dates']; 289 } 290 return false; // If some property not defined, then false; 291 }; 292 293 /** 294 * Set bookings dates in calendar object :: { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} 295 * 296 * if calendar object not defined, then it's will be defined and 'id', 'dates' set 297 * if calendar exist, then system add a new or overwrite only dates from dates_obj parameter, 298 * but other dates not from parameter dates_obj will be existed and not overwrite. 299 * 300 * @param {string|int} resource_id '2' 301 * @param {object} dates_obj { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} 302 * @param {boolean} is_complete_overwrite if false, then only overwrite or add dates from dates_obj 303 * @returns {*} 304 * 305 * Examples: 306 * _wpbc.bookings_in_calendar__set_dates( resource_id, { "2023-07-21": {â¦}, "2023-07-22": {â¦}, ⦠} ); <- overwrite ALL dates 307 * _wpbc.bookings_in_calendar__set_dates( resource_id, { "2023-07-22": {â¦} }, false ); <- add or overwrite only "2023-07-22": {} 308 * 309 * Common usage in PHP: 310 * echo " _wpbc.bookings_in_calendar__set_dates( " . intval( $resource_id ) . ", " . wp_json_encode( $availability_per_days_arr ) . " ); "; 311 */ 312 obj.bookings_in_calendar__set_dates = function (resource_id, dates_obj) { 313 var is_complete_overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; 314 if (!obj.bookings_in_calendar__is_defined(resource_id)) { 315 obj.bookings_in_calendar__set(resource_id, { 316 'dates': {} 317 }); 318 } 319 if ('undefined' === typeof p_bookings['calendar_' + resource_id]['dates']) { 320 p_bookings['calendar_' + resource_id]['dates'] = {}; 321 } 322 if (is_complete_overwrite) { 323 // Complete overwrite all booking dates 324 p_bookings['calendar_' + resource_id]['dates'] = dates_obj; 325 } else { 326 // Add only new or overwrite exist booking dates from parameter. Booking dates not from parameter will be without chnanges 327 for (var prop_name in dates_obj) { 328 p_bookings['calendar_' + resource_id]['dates'][prop_name] = dates_obj[prop_name]; 329 } 330 } 331 return p_bookings['calendar_' + resource_id]; 332 }; 333 334 /** 335 * Get bookings data for specific date in calendar :: false | { day_availability: 1, ... } 336 * 337 * @param {string|int} resource_id '1' 338 * @param {string} sql_class_day '2023-07-21' 339 * @returns {object|boolean} false | { 340 day_availability: 4
341 max_capacity: 4 // >= Business Large 342 2: Object { is_day_unavailable: false, _day_status: "available" } 343 10: Object { is_day_unavailable: false, _day_status: "available" } // >= Business Large ... 344 11: Object { is_day_unavailable: false, _day_status: "available" } 345 12: Object { is_day_unavailable: false, _day_status: "available" } 346 } 347 */ 348 obj.bookings_in_calendar__get_for_date = function (resource_id, sql_class_day) { 349 if (obj.bookings_in_calendar__is_defined(resource_id) && 'undefined' !== typeof p_bookings['calendar_' + resource_id]['dates'] && 'undefined' !== typeof p_bookings['calendar_' + resource_id]['dates'][sql_class_day]) { 350 return p_bookings['calendar_' + resource_id]['dates'][sql_class_day]; 351 } 352 return false; // If some property not defined, then false; 353 }; 354 355 // Any PARAMS in bookings 356 357 /** 358 * Set property to booking 359 * @param resource_id "1" 360 * @param prop_name name of property 361 * @param prop_value value of property 362 * @returns {*} booking object 363 */ 364 obj.booking__set_param_value = function (resource_id, prop_name, prop_value) { 365 if (!obj.bookings_in_calendar__is_defined(resource_id)) { 366 p_bookings['calendar_' + resource_id] = {}; 367 p_bookings['calendar_' + resource_id]['id'] = resource_id; 368 } 369 p_bookings['calendar_' + resource_id][prop_name] = prop_value; 370 return p_bookings['calendar_' + resource_id]; 371 }; 372 373 /** 374 * Get booking property value :: mixed | null 375 * 376 * @param {string|int} resource_id '1' 377 * @param {string} prop_name 'selection_mode' 378 * @returns {*|null} mixed | null 379 */ 380 obj.booking__get_param_value = function (resource_id, prop_name) { 381 if (obj.bookings_in_calendar__is_defined(resource_id) && 'undefined' !== typeof p_bookings['calendar_' + resource_id][prop_name]) { 382 return p_bookings['calendar_' + resource_id][prop_name]; 383 } 384 return null; // If some property not defined, then null; 385 }; 386 387 /** 388 * Set bookings for all calendars 389 * 390 * @param {object} calendars_obj Object { calendar_1: { id: 1, dates: Object { "2023-07-22": {â¦}, "2023-07-23": {â¦}, "2023-07-24": {â¦}, ⦠} } 391 * calendar_3: {}, ... } 392 */ 393 obj.bookings_in_calendars__set_all = function (calendars_obj) { 394 p_bookings = calendars_obj; 395 }; 396 397 /** 398 * Get bookings in all calendars 399 * 400 * @returns {object|{}} 401 */ 402 obj.bookings_in_calendars__get_all = function () { 403 return p_bookings; 404 }; 405 // ----------------------------------------------------------------------------------------------------------------- 406 407 // Seasons ---------------------------------------------------------------------------------------------------- 408 var p_seasons = obj.seasons_obj = obj.seasons_obj || { 409 // calendar_1: Object { 410 // id: 1 411 // , dates: Object { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠412 // } 413 }; 414 415 /** 416 * Add season names for dates in calendar object :: { "2023-07-21": [ 'wpbc_season_september_2023', 'wpbc_season_september_2024' ], "2023-07-22": [...], ... } 417 * 418 * 419 * @param {string|int} resource_id '2' 420 * @param {object} dates_obj { "2023-07-21": {â¦}, "2023-07-22": {â¦}, "2023-07-23": {â¦}, ⦠} 421 * @param {boolean} is_complete_overwrite if false, then only add dates from dates_obj 422 * @returns {*} 423 * 424 * Examples: 425 * _wpbc.seasons__set( resource_id, { "2023-07-21": [ 'wpbc_season_september_2023', 'wpbc_season_september_2024' ], "2023-07-22": [...], ... } ); 426 */ 427 obj.seasons__set = function (resource_id, dates_obj) { 428 var is_complete_overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 429 if ('undefined' === typeof p_seasons['calendar_' + resource_id]) { 430 p_seasons['calendar_' + resource_id] = {}; 431 } 432 if (is_complete_overwrite) { 433 // Complete overwrite all season dates 434 p_seasons['calendar_' + resource_id] = dates_obj; 435 } else {
436 // Add only new or overwrite exist booking dates from parameter. Booking dates not from parameter will be without chnanges 437 for (var prop_name in dates_obj) { 438 if ('undefined' === typeof p_seasons['calendar_' + resource_id][prop_name]) { 439 p_seasons['calendar_' + resource_id][prop_name] = []; 440 } 441 for (var season_name_key in dates_obj[prop_name]) { 442 p_seasons['calendar_' + resource_id][prop_name].push(dates_obj[prop_name][season_name_key]); 443 } 444 } 445 } 446 return p_seasons['calendar_' + resource_id]; 447 }; 448 449 /** 450 * Get bookings data for specific date in calendar :: [] | [ 'wpbc_season_september_2023', 'wpbc_season_september_2024' ] 451 * 452 * @param {string|int} resource_id '1' 453 * @param {string} sql_class_day '2023-07-21' 454 * @returns {object|boolean} [] | [ 'wpbc_season_september_2023', 'wpbc_season_september_2024' ] 455 */ 456 obj.seasons__get_for_date = function (resource_id, sql_class_day) { 457 if ('undefined' !== typeof p_seasons['calendar_' + resource_id] && 'undefined' !== typeof p_seasons['calendar_' + resource_id][sql_class_day]) { 458 return p_seasons['calendar_' + resource_id][sql_class_day]; 459 } 460 return []; // If not defined, then []; 461 }; 462 463 // Other parameters ------------------------------------------------------------------------------------ 464 var p_other = obj.other_obj = obj.other_obj || {}; 465 obj.set_other_param = function (param_key, param_val) { 466 p_other[param_key] = param_val; 467 }; 468 obj.get_other_param = function (param_key) { 469 return p_other[param_key]; 470 }; 471 472 /** 473 * Get all other params 474 * 475 * @returns {object|{}} 476 */ 477 obj.get_other_param__all = function () { 478 return p_other; 479 }; 480 481 // Messages ------------------------------------------------------------------------------------ 482 var p_messages = obj.messages_obj = obj.messages_obj || {}; 483 obj.set_message = function (param_key, param_val) { 484 p_messages[param_key] = param_val; 485 }; 486 obj.get_message = function (param_key) { 487 return p_messages[param_key]; 488 }; 489 490 /** 491 * Get all other params 492 * 493 * @returns {object|{}} 494 */ 495 obj.get_messages__all = function () { 496 return p_messages; 497 }; 498 499 // ----------------------------------------------------------------------------------------------------------------- 500 501 return obj; 502}(_wpbc || {}, jQuery); 503 504/** 505 * Extend _wpbc with new methods // FixIn: 9.8.6.2. 506 * 507 * @type {*|{}} 508 * @private 509 */ 510_wpbc = function (obj, $) { 511 // Load Balancer ----------------------------------------------------------------------------------------------- 512 513 var p_balancer = obj.balancer_obj = obj.balancer_obj || { 514 'max_threads': 2, 515 'in_process': [], 516 'wait': [] 517 }; 518 519 /** 520 * Set max parallel request to load 521 * 522 * @param max_threads 523 */ 524 obj.balancer__set_max_threads = function (max_threads) { 525 p_balancer['max_threads'] = max_threads; 526 }; 527 528 /** 529 * Check if balancer for specific booking resource defined :: true | false 530 * 531 * @param {string|int} resource_id 532 * @returns {boolean} 533 */ 534 obj.balancer__is_defined = function (resource_id) { 535 return 'undefined' !== typeof p_balancer['balancer_' + resource_id]; 536 }; 537 538 /** 539 * Create balancer initializing 540 * 541 * @param {string|int} resource_id 542 */ 543 obj.balancer__init = function (resource_id, function_name) { 544 var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 545 var balance_obj = {}; 546 balance_obj['resource_id'] = resource_id; 547 balance_obj['priority'] = 1; 548 balance_obj['function_name'] = function_name; 549 balance_obj['params'] = wpbc_clone_obj(params); 550 if (obj.balancer__is_already_run(resource_id, function_name)) { 551 return 'run'; 552 } 553 if (obj.balancer__is_already_wait(resource_id, function_name)) { 554 return 'wait'; 555 } 556 if (obj.balancer__can_i_run()) { 557 obj.balancer__add_to__run(balance_obj); 558 return 'run'; 559 } else { 560 obj.balancer__add_to__wait(balance_obj); 561 return 'wait'; 562 } 563 }; 564 565 /** 566 * Can I Run ? 567 * @returns {boolean} 568 */ 569 obj.balancer__can_i_run = function () { 570 return p_balancer['in_process'].length < p_balancer['max_threads']; 571 }; 572 573 /** 574 * Add to WAIT 575 * @param balance_obj 576 */ 577 obj.balancer__add_to__wait = function (balance_obj) { 578 p_balancer['wait'].push(balance_obj); 579 }; 580 581 /** 582 * Remove from Wait 583 * 584 * @param resource_id 585 * @param function_name 586 * @returns {*|boolean} 587 */ 588 obj.balancer__remove_from__wait_list = function (resource_id, function_name) { 589 var removed_el = false;
590 if (p_balancer['wait'].length) { 591 // FixIn: 9.8.10.1. 592 for (var i in p_balancer['wait']) { 593 if (resource_id === p_balancer['wait'][i]['resource_id'] && function_name === p_balancer['wait'][i]['function_name']) { 594 removed_el = p_balancer['wait'].splice(i, 1); 595 removed_el = removed_el.pop(); 596 p_balancer['wait'] = p_balancer['wait'].filter(function (v) { 597 return v; 598 }); // Reindex array 599 return removed_el; 600 } 601 } 602 } 603 return removed_el; 604 }; 605 606 /** 607 * Is already WAIT 608 * 609 * @param resource_id 610 * @param function_name 611 * @returns {boolean} 612 */ 613 obj.balancer__is_already_wait = function (resource_id, function_name) { 614 if (p_balancer['wait'].length) { 615 // FixIn: 9.8.10.1. 616 for (var i in p_balancer['wait']) { 617 if (resource_id === p_balancer['wait'][i]['resource_id'] && function_name === p_balancer['wait'][i]['function_name']) { 618 return true; 619 } 620 } 621 } 622 return false; 623 }; 624 625 /** 626 * Add to RUN 627 * @param balance_obj 628 */ 629 obj.balancer__add_to__run = function (balance_obj) { 630 p_balancer['in_process'].push(balance_obj); 631 }; 632 633 /** 634 * Remove from RUN list 635 * 636 * @param resource_id 637 * @param function_name 638 * @returns {*|boolean} 639 */ 640 obj.balancer__remove_from__run_list = function (resource_id, function_name) { 641 var removed_el = false; 642 if (p_balancer['in_process'].length) { 643 // FixIn: 9.8.10.1. 644 for (var i in p_balancer['in_process']) { 645 if (resource_id === p_balancer['in_process'][i]['resource_id'] && function_name === p_balancer['in_process'][i]['function_name']) { 646 removed_el = p_balancer['in_process'].splice(i, 1); 647 removed_el = removed_el.pop(); 648 p_balancer['in_process'] = p_balancer['in_process'].filter(function (v) { 649 return v; 650 }); // Reindex array 651 return removed_el; 652 } 653 } 654 } 655 return removed_el; 656 }; 657 658 /** 659 * Is already RUN 660 * 661 * @param resource_id 662 * @param function_name 663 * @returns {boolean} 664 */ 665 obj.balancer__is_already_run = function (resource_id, function_name) { 666 if (p_balancer['in_process'].length) { 667 // FixIn: 9.8.10.1. 668 for (var i in p_balancer['in_process']) { 669 if (resource_id === p_balancer['in_process'][i]['resource_id'] && function_name === p_balancer['in_process'][i]['function_name']) { 670 return true; 671 } 672 } 673 } 674 return false; 675 }; 676 obj.balancer__run_next = function () { 677 // Get 1st from Wait list 678 var removed_el = false; 679 if (p_balancer['wait'].length) { 680 // FixIn: 9.8.10.1. 681 for (var i in p_balancer['wait']) { 682 removed_el = obj.balancer__remove_from__wait_list(p_balancer['wait'][i]['resource_id'], p_balancer['wait'][i]['function_name']); 683 break; 684 } 685 } 686 if (false !== removed_el) { 687 // Run 688 obj.balancer__run(removed_el); 689 } 690 }; 691 692 /** 693 * Run 694 * @param balance_obj 695 */ 696 obj.balancer__run = function (balance_obj) { 697 switch (balance_obj['function_name']) { 698 case 'wpbc_calendar__load_data__ajx': 699 // Add to run list 700 obj.balancer__add_to__run(balance_obj); 701 wpbc_calendar__load_data__ajx(balance_obj['params']); 702 break; 703 default: 704 } 705 }; 706 return obj; 707}(_wpbc || {}, jQuery); 708 709/** 710 * -- Help functions ---------------------------------------------------------------------------------------------- 711*/ 712 713function wpbc_balancer__is_wait(params, function_name) { 714 //console.log('::wpbc_balancer__is_wait',params , function_name ); 715 if ('undefined' !== typeof params['resource_id']) { 716 var balancer_status = _wpbc.balancer__init(params['resource_id'], function_name, params); 717 return 'wait' === balancer_status; 718 } 719 return false; 720} 721function wpbc_balancer__completed(resource_id, function_name) { 722 //console.log('::wpbc_balancer__completed',resource_id , function_name ); 723 _wpbc.balancer__remove_from__run_list(resource_id, function_name); 724 _wpbc.balancer__run_next(); 725} 726/** 727 * ===================================================================================================================== 728 * includes/__js/cal/wpbc_cal.js 729 * ===================================================================================================================== 730 */ 731 732/** 733 * Order or child booking resources saved here: _wpbc.booking__get_param_value( resource_id, 'resources_id_arr__in_dates' ) [2,10,12,11] 734 */ 735 736/** 737 * How to check booked times on specific date: ? 738 * 739 _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21'); 740 741 console.log( 742 _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[2].booked_time_slots.merged_seconds, 743 _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[10].booked_time_slots.merged_seconds, 744 _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[11].booked_time_slots.merged_seconds, 745 _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[12].booked_time_slots.merged_seconds 746 ); 747 * OR 748 console.log( 749 _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[2].booked_time_slots.merged_readable, 750 _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[10].booked_time_slots.merged_readable, 751 _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[11].booked_time_slots.merged_readable, 752 _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[12].booked_time_slots.merged_readable 753 ); 754 * 755 */ 756 757/** 758 * Days selection: 759 * wpbc_calendar__unselect_all_dates( resource_id ); 760 * 761 * var resource_id = 1; 762 * Example 1: var num_selected_days = wpbc_auto_select_dates_in_calendar( resource_id, '2024-05-15', '2024-05-25' ); 763 * Example 2: var num_selected_days = wpbc_auto_select_dates_in_calendar( resource_id, ['2024-05-09','2024-05-19','2024-05-25'] ); 764 * 765 */ 766 767/** 768 * C A L E N D A R --------------------------------------------------------------------------------------------------- 769 */ 770 771/** 772 * Show WPBC Calendar 773 * 774 * @param resource_id - resource ID 775 * @returns {boolean} 776 */
777function wpbc_calendar_show(resource_id) { 778 // If no calendar HTML tag, then exit 779 if (0 === jQuery('#calendar_booking' + resource_id).length) { 780 return false; 781 } 782 783 // If the calendar with the same Booking resource is activated already, then exit. 784 if (true === jQuery('#calendar_booking' + resource_id).hasClass('hasDatepick')) { 785 return false; 786 } 787 788 // ----------------------------------------------------------------------------------------------------------------- 789 // Days selection 790 // ----------------------------------------------------------------------------------------------------------------- 791 var local__is_range_select = false; 792 var local__multi_days_select_num = 365; // multiple | fixed 793 if ('dynamic' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) { 794 local__is_range_select = true; 795 local__multi_days_select_num = 0; 796 } 797 if ('single' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) { 798 local__multi_days_select_num = 0; 799 } 800 801 // ----------------------------------------------------------------------------------------------------------------- 802 // Min - Max days to scroll/show 803 // ----------------------------------------------------------------------------------------------------------------- 804 var local__min_date = 0; 805 local__min_date = new Date(_wpbc.get_other_param('today_arr')[0], parseInt(_wpbc.get_other_param('today_arr')[1]) - 1, _wpbc.get_other_param('today_arr')[2], 0, 0, 0); // FixIn: 9.9.0.17. 806 //console.log( local__min_date ); 807 var local__max_date = _wpbc.calendar__get_param_value(resource_id, 'booking_max_monthes_in_calendar'); 808 //local__max_date = new Date(2024, 5, 28); It is here issue of not selectable dates, but some dates showing in calendar as available, but we can not select it. 809 810 //// Define last day in calendar (as a last day of month (and not date, which is related to actual 'Today' date). 811 //// E.g. if today is 2023-09-25, and we set 'Number of months to scroll' as 5 months, then last day will be 2024-02-29 and not the 2024-02-25. 812 // var cal_last_day_in_month = jQuery.datepick._determineDate( null, local__max_date, new Date() ); 813 // cal_last_day_in_month = new Date( cal_last_day_in_month.getFullYear(), cal_last_day_in_month.getMonth() + 1, 0 ); 814 // local__max_date = cal_last_day_in_month; // FixIn: 10.0.0.26. 815 816 // Get start / end dates from the Booking Calendar shortcode. Example: [booking calendar_dates_start='2026-01-01' calendar_dates_end='2026-12-31' resource_id=1] // FixIn: 10.13.1.4. 817 if (false !== wpbc_calendar__get_dates_start(resource_id)) { 818 local__min_date = wpbc_calendar__get_dates_start(resource_id); // E.g. - local__min_date = new Date( 2025, 0, 1 ); 819 } 820 if (false !== wpbc_calendar__get_dates_end(resource_id)) { 821 local__max_date = wpbc_calendar__get_dates_end(resource_id); // E.g. - local__max_date = new Date( 2025, 11, 31 ); 822 } 823 824 // In case we edit booking in past or have specific parameter in URL. 825 if (location.href.indexOf('page=wpbc-new') != -1 && (location.href.indexOf('booking_hash') != -1 // Comment this line for ability to add booking in past days at Booking > Add booking page. 826 || location.href.indexOf('allow_past') != -1 // FixIn: 10.7.1.2. 827 )) { 828 // local__min_date = null; 829 // FixIn: 10.14.1.4. 830 local__min_date = new Date(_wpbc.get_other_param('time_local_arr')[0], parseInt(_wpbc.get_other_param('time_local_arr')[1]) - 1, _wpbc.get_other_param('time_local_arr')[2], _wpbc.get_other_param('time_local_arr')[3], _wpbc.get_other_param('time_local_arr')[4], 0); 831 local__max_date = null; 832 } 833 var local__start_weekday = _wpbc.calendar__get_param_value(resource_id, 'booking_start_day_weeek'); 834 var local__number_of_months = parseInt(_wpbc.calendar__get_param_value(resource_id, 'calendar_number_of_months')); 835 jQuery('#calendar_booking' + resource_id).text(''); // Remove all HTML in calendar tag 836 // ----------------------------------------------------------------------------------------------------------------- 837 // Show calendar 838 // ----------------------------------------------------------------------------------------------------------------- 839 jQuery('#calendar_booking' + resource_id).datepick({ 840 beforeShowDay: function beforeShowDay(js_date) { 841 return wpbc__calendar__apply_css_to_days(js_date, { 842 'resource_id': resource_id 843 }, this); 844 }, 845 onSelect: function onSelect(string_dates, js_dates_arr) { 846 /** 847 * string_dates = '23.08.2023 - 26.08.2023' | '23.08.2023 - 23.08.2023' | '19.09.2023, 24.08.2023, 30.09.2023' 848 * js_dates_arr = range: [ Date (Aug 23 2023), Date (Aug 25 2023)] | multiple: [ Date(Oct 24 2023), Date(Oct 20 2023), Date(Oct 16 2023) ] 849 */ 850 return wpbc__calendar__on_select_days(string_dates, { 851 'resource_id': resource_id 852 }, this); 853 }, 854 onHover: function onHover(string_date, js_date) { 855 return wpbc__calendar__on_hover_days(string_date, js_date, { 856 'resource_id': resource_id 857 }, this); 858 }, 859 onChangeMonthYear: function onChangeMonthYear(year, real_month, js_date__1st_day_in_month) {}, 860 showOn: 'both', 861 numberOfMonths: local__number_of_months, 862 stepMonths: 1, 863 // prevText : '«', 864 // nextText : '»', 865 prevText: '‹', 866 nextText: '›', 867 dateFormat: 'dd.mm.yy',
868 changeMonth: false, 869 changeYear: false, 870 minDate: local__min_date, 871 maxDate: local__max_date, 872 // '1Y', 873 // minDate: new Date(2020, 2, 1), maxDate: new Date(2020, 9, 31), // Ability to set any start and end date in calendar 874 showStatus: false, 875 multiSeparator: ', ', 876 closeAtTop: false, 877 firstDay: local__start_weekday, 878 gotoCurrent: false, 879 hideIfNoPrevNext: true, 880 multiSelect: local__multi_days_select_num, 881 rangeSelect: local__is_range_select, 882 // showWeeks: true, 883 useThemeRoller: false 884 }); 885 886 // ----------------------------------------------------------------------------------------------------------------- 887 // Clear today date highlighting 888 // ----------------------------------------------------------------------------------------------------------------- 889 setTimeout(function () { 890 wpbc_calendars__clear_days_highlighting(resource_id); 891 }, 500); // FixIn: 7.1.2.8. 892 893 // ----------------------------------------------------------------------------------------------------------------- 894 // Scroll calendar to specific month 895 // ----------------------------------------------------------------------------------------------------------------- 896 var start_bk_month = _wpbc.calendar__get_param_value(resource_id, 'calendar_scroll_to'); 897 if (false !== start_bk_month) { 898 wpbc_calendar__scroll_to(resource_id, start_bk_month[0], start_bk_month[1]); 899 } 900} 901 902/** 903 * Apply CSS to calendar date cells 904 * 905 * @param date - JavaScript Date Obj: Mon Dec 11 2023 00:00:00 GMT+0200 (Eastern European Standard Time) 906 * @param calendar_params_arr - Calendar Settings Object: { 907 * "resource_id": 4 908 * } 909 * @param datepick_this - this of datepick Obj 910 * @returns {(*|string)[]|(boolean|string)[]} - [ {true -available | false - unavailable}, 'CSS classes for calendar day cell' ] 911 */ 912function wpbc__calendar__apply_css_to_days(date, calendar_params_arr, datepick_this) { 913 var today_date = new Date(_wpbc.get_other_param('today_arr')[0], parseInt(_wpbc.get_other_param('today_arr')[1]) - 1, _wpbc.get_other_param('today_arr')[2], 0, 0, 0); // Today JS_Date_Obj. 914 var class_day = wpbc__get__td_class_date(date); // '1-9-2023' 915 var sql_class_day = wpbc__get__sql_class_date(date); // '2023-01-09' 916 var resource_id = 'undefined' !== typeof calendar_params_arr['resource_id'] ? calendar_params_arr['resource_id'] : '1'; // '1' 917 918 // Get Selected dates in calendar 919 var selected_dates_sql = wpbc_get__selected_dates_sql__as_arr(resource_id); 920 921 // Get Data -------------------------------------------------------------------------------------------------------- 922 var date_bookings_obj = _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_class_day); 923 924 // Array with CSS classes for date --------------------------------------------------------------------------------- 925 var css_classes__for_date = []; 926 css_classes__for_date.push('sql_date_' + sql_class_day); // 'sql_date_2023-07-21' 927 css_classes__for_date.push('cal4date-' + class_day); // 'cal4date-7-21-2023' 928 css_classes__for_date.push('wpbc_weekday_' + date.getDay()); // 'wpbc_weekday_4' 929 930 // Define Selected Check In/Out dates in TD ----------------------------------------------------------------------- 931 if (selected_dates_sql.length 932 //&& ( selected_dates_sql[ 0 ] !== selected_dates_sql[ (selected_dates_sql.length - 1) ] ) 933 ) { 934 if (sql_class_day === selected_dates_sql[0]) { 935 css_classes__for_date.push('selected_check_in'); 936 css_classes__for_date.push('selected_check_in_out'); 937 } 938 if (selected_dates_sql.length > 1 && sql_class_day === selected_dates_sql[selected_dates_sql.length - 1]) { 939 css_classes__for_date.push('selected_check_out'); 940 css_classes__for_date.push('selected_check_in_out'); 941 } 942 } 943 var is_day_selectable = false; 944 945 // If something not defined, then this date closed --------------------------------------------------------------- // FixIn: 10.12.4.6. 946 if (false === date_bookings_obj || 'undefined' === typeof date_bookings_obj[resource_id]) { 947 css_classes__for_date.push('date_user_unavailable'); 948 return [is_day_selectable, css_classes__for_date.join(' ')]; 949 } 950 951 // ----------------------------------------------------------------------------------------------------------------- 952 // date_bookings_obj - Defined. Dates can be selectable. 953 // ----------------------------------------------------------------------------------------------------------------- 954 955 // ----------------------------------------------------------------------------------------------------------------- 956 // Add season names to the day CSS classes -- it is required for correct work of conditional fields -------------- 957 var season_names_arr = _wpbc.seasons__get_for_date(resource_id, sql_class_day); 958 for (var season_key in season_names_arr) { 959 css_classes__for_date.push(season_names_arr[season_key]); // 'wpdevbk_season_september_2023' 960 } 961 // ----------------------------------------------------------------------------------------------------------------- 962 963 // Cost Rate ------------------------------------------------------------------------------------------------------- 964 css_classes__for_date.push('rate_' + date_bookings_obj[resource_id]['date_cost_rate'].toString().replace(/[\.\s]/g, '_')); // 'rate_99_00' -> 99.00 965 966 if (parseInt(date_bookings_obj['day_availability']) > 0) { 967 is_day_selectable = true; 968 css_classes__for_date.push('date_available'); 969 css_classes__for_date.push('reserved_days_count' + parseInt(date_bookings_obj['max_capacity'] - date_bookings_obj['day_availability'])); 970 } else { 971 is_day_selectable = false;
972 css_classes__for_date.push('date_user_unavailable'); 973 } 974 switch (date_bookings_obj['summary']['status_for_day']) { 975 case 'available': 976 break; 977 case 'time_slots_booking': 978 css_classes__for_date.push('timespartly', 'times_clock'); 979 break; 980 case 'full_day_booking': 981 css_classes__for_date.push('full_day_booking'); 982 break; 983 case 'season_filter': 984 css_classes__for_date.push('date_user_unavailable', 'season_unavailable'); 985 date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date 986 break; 987 case 'resource_availability': 988 css_classes__for_date.push('date_user_unavailable', 'resource_unavailable'); 989 date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date 990 break; 991 case 'weekday_unavailable': 992 css_classes__for_date.push('date_user_unavailable', 'weekday_unavailable'); 993 date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date 994 break; 995 case 'from_today_unavailable': 996 css_classes__for_date.push('date_user_unavailable', 'from_today_unavailable'); 997 date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date 998 break; 999 case 'limit_available_from_today': 1000 css_classes__for_date.push('date_user_unavailable', 'limit_available_from_today'); 1001 date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date 1002 break; 1003 case 'change_over': 1004 /* 1005 * 1006 // check_out_time_date2approve check_in_time_date2approve 1007 // check_out_time_date2approve check_in_time_date_approved 1008 // check_in_time_date2approve check_out_time_date_approved 1009 // check_out_time_date_approved check_in_time_date_approved 1010 */ 1011 1012 css_classes__for_date.push('timespartly', 'check_in_time', 'check_out_time'); 1013 // FixIn: 10.0.0.2. 1014 if (date_bookings_obj['summary']['status_for_bookings'].indexOf('approved_pending') > -1) { 1015 css_classes__for_date.push('check_out_time_date_approved', 'check_in_time_date2approve'); 1016 } 1017 if (date_bookings_obj['summary']['status_for_bookings'].indexOf('pending_approved') > -1) { 1018 css_classes__for_date.push('check_out_time_date2approve', 'check_in_time_date_approved'); 1019 } 1020 break; 1021 case 'check_in': 1022 css_classes__for_date.push('timespartly', 'check_in_time'); 1023 1024 // FixIn: 9.9.0.33. 1025 if (date_bookings_obj['summary']['status_for_bookings'].indexOf('pending') > -1) { 1026 css_classes__for_date.push('check_in_time_date2approve'); 1027 } else if (date_bookings_obj['summary']['status_for_bookings'].indexOf('approved') > -1) { 1028 css_classes__for_date.push('check_in_time_date_approved'); 1029 } 1030 break; 1031 case 'check_out': 1032 css_classes__for_date.push('timespartly', 'check_out_time'); 1033 1034 // FixIn: 9.9.0.33. 1035 if (date_bookings_obj['summary']['status_for_bookings'].indexOf('pending') > -1) { 1036 css_classes__for_date.push('check_out_time_date2approve'); 1037 } else if (date_bookings_obj['summary']['status_for_bookings'].indexOf('approved') > -1) { 1038 css_classes__for_date.push('check_out_time_date_approved'); 1039 } 1040 break; 1041 default: 1042 // mixed statuses: 'change_over check_out' .... variations.... check more in function wpbc_get_availability_per_days_arr() 1043 date_bookings_obj['summary']['status_for_day'] = 'available'; 1044 } 1045 if ('available' != date_bookings_obj['summary']['status_for_day']) { 1046 var is_set_pending_days_selectable = _wpbc.calendar__get_param_value(resource_id, 'pending_days_selectable'); // set pending days selectable // FixIn: 8.6.1.18. 1047 1048 switch (date_bookings_obj['summary']['status_for_bookings']) { 1049 case '': 1050 // Usually it's means that day is available or unavailable without the bookings 1051 break; 1052 case 'pending': 1053 css_classes__for_date.push('date2approve'); 1054 is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable; 1055 break; 1056 case 'approved': 1057 css_classes__for_date.push('date_approved'); 1058 break; 1059 1060 // Situations for "change-over" days: ---------------------------------------------------------------------- 1061 case 'pending_pending': 1062 css_classes__for_date.push('check_out_time_date2approve', 'check_in_time_date2approve'); 1063 is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable; 1064 break; 1065 case 'pending_approved': 1066 css_classes__for_date.push('check_out_time_date2approve', 'check_in_time_date_approved'); 1067 is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable; 1068 break; 1069 case 'approved_pending': 1070 css_classes__for_date.push('check_out_time_date_approved', 'check_in_time_date2approve'); 1071 is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable; 1072 break; 1073 case 'approved_approved': 1074 css_classes__for_date.push('check_out_time_date_approved', 'check_in_time_date_approved'); 1075 break; 1076 default: 1077 } 1078 } 1079 return [is_day_selectable, css_classes__for_date.join(' ')]; 1080} 1081 1082/** 1083 * Mouseover calendar date cells 1084 * 1085 * @param string_date 1086 * @param date - JavaScript Date Obj: Mon Dec 11 2023 00:00:00 GMT+0200 (Eastern European Standard Time) 1087 * @param calendar_params_arr - Calendar Settings Object: { 1088 * "resource_id": 4 1089 * } 1090 * @param datepick_this - this of datepick Obj 1091 * @returns {boolean} 1092 */
1093function wpbc__calendar__on_hover_days(string_date, date, calendar_params_arr, datepick_this) { 1094 if (null === date) { 1095 wpbc_calendars__clear_days_highlighting('undefined' !== typeof calendar_params_arr['resource_id'] ? calendar_params_arr['resource_id'] : '1'); // FixIn: 10.5.2.4. 1096 return false; 1097 } 1098 var class_day = wpbc__get__td_class_date(date); // '1-9-2023' 1099 var sql_class_day = wpbc__get__sql_class_date(date); // '2023-01-09' 1100 var resource_id = 'undefined' !== typeof calendar_params_arr['resource_id'] ? calendar_params_arr['resource_id'] : '1'; // '1' 1101 1102 // Get Data -------------------------------------------------------------------------------------------------------- 1103 var date_booking_obj = _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_class_day); // {...} 1104 1105 if (!date_booking_obj) { 1106 return false; 1107 } 1108 1109 // T o o l t i p s ------------------------------------------------------------------------------------------------- 1110 var tooltip_text = ''; 1111 if (date_booking_obj['summary']['tooltip_availability'].length > 0) { 1112 tooltip_text += date_booking_obj['summary']['tooltip_availability']; 1113 } 1114 if (date_booking_obj['summary']['tooltip_day_cost'].length > 0) { 1115 tooltip_text += date_booking_obj['summary']['tooltip_day_cost']; 1116 } 1117 if (date_booking_obj['summary']['tooltip_times'].length > 0) { 1118 tooltip_text += date_booking_obj['summary']['tooltip_times']; 1119 } 1120 if (date_booking_obj['summary']['tooltip_booking_details'].length > 0) { 1121 tooltip_text += date_booking_obj['summary']['tooltip_booking_details']; 1122 } 1123 wpbc_set_tooltip___for__calendar_date(tooltip_text, resource_id, class_day); 1124 1125 // U n h o v e r i n g in UNSELECTABLE_CALENDAR ------------------------------------------------------------ 1126 var is_unselectable_calendar = jQuery('#calendar_booking_unselectable' + resource_id).length > 0; // FixIn: 8.0.1.2. 1127 var is_booking_form_exist = jQuery('#booking_form_div' + resource_id).length > 0; 1128 if (is_unselectable_calendar && !is_booking_form_exist) { 1129 /** 1130 * Un Hover all dates in calendar (without the booking form), if only Availability Calendar here and we do not insert Booking form by mistake. 1131 */ 1132 1133 wpbc_calendars__clear_days_highlighting(resource_id); // Clear days highlighting 1134 1135 var css_of_calendar = '.wpbc_only_calendar #calendar_booking' + resource_id; 1136 jQuery(css_of_calendar + ' .datepick-days-cell, ' + css_of_calendar + ' .datepick-days-cell a').css('cursor', 'default'); // Set cursor to Default 1137 return false; 1138 } 1139 1140 // D a y s H o v e r i n g ------------------------------------------------------------------------------------ 1141 if (location.href.indexOf('page=wpbc') == -1 || location.href.indexOf('page=wpbc-new') > 0 || location.href.indexOf('page=wpbc-setup') > 0 || location.href.indexOf('page=wpbc-availability') > 0 || location.href.indexOf('page=wpbc-settings') > 0 && location.href.indexOf('&tab=form') > 0) { 1142 // The same as dates selection, but for days hovering 1143 1144 if ('function' == typeof wpbc__calendar__do_days_highlight__bs) { 1145 wpbc__calendar__do_days_highlight__bs(sql_class_day, date, resource_id); 1146 } 1147 } 1148} 1149 1150/** 1151 * Select calendar date cells 1152 * 1153 * @param date - JavaScript Date Obj: Mon Dec 11 2023 00:00:00 GMT+0200 (Eastern European Standard Time) 1154 * @param calendar_params_arr - Calendar Settings Object: { 1155 * "resource_id": 4 1156 * } 1157 * @param datepick_this - this of datepick Obj 1158 * 1159 */ 1160function wpbc__calendar__on_select_days(date, calendar_params_arr, datepick_this) { 1161 var resource_id = 'undefined' !== typeof calendar_params_arr['resource_id'] ? calendar_params_arr['resource_id'] : '1'; // '1' 1162 1163 // Set unselectable, if only Availability Calendar here (and we do not insert Booking form by mistake). 1164 var is_unselectable_calendar = jQuery('#calendar_booking_unselectable' + resource_id).length > 0; // FixIn: 8.0.1.2. 1165 var is_booking_form_exist = jQuery('#booking_form_div' + resource_id).length > 0; 1166 if (is_unselectable_calendar && !is_booking_form_exist) { 1167 wpbc_calendar__unselect_all_dates(resource_id); // Unselect Dates
1168 jQuery('.wpbc_only_calendar .popover_calendar_hover').remove(); // Hide all opened popovers 1169 return false; 1170 } 1171 jQuery('#date_booking' + resource_id).val(date); // Add selected dates to hidden textarea 1172 1173 if ('function' === typeof wpbc__calendar__do_days_select__bs) { 1174 wpbc__calendar__do_days_select__bs(date, resource_id); 1175 } 1176 wpbc_disable_time_fields_in_booking_form(resource_id); 1177 1178 // Hook -- trigger day selection ----------------------------------------------------------------------------------- 1179 var mouse_clicked_dates = date; // Can be: "05.10.2023 - 07.10.2023" | "10.10.2023 - 10.10.2023" | 1180 var all_selected_dates_arr = wpbc_get__selected_dates_sql__as_arr(resource_id); // Can be: [ "2023-10-05", "2023-10-06", "2023-10-07", ⦠] 1181 jQuery(".booking_form_div").trigger("date_selected", [resource_id, mouse_clicked_dates, all_selected_dates_arr]); 1182} 1183 1184// Mark middle selected dates with 0.5 opacity // FixIn: 10.3.0.9. 1185jQuery(document).ready(function () { 1186 jQuery(".booking_form_div").on('date_selected', function (event, resource_id, date) { 1187 if ('fixed' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode') || 'dynamic' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) { 1188 var closed_timer = setTimeout(function () { 1189 var middle_days_opacity = _wpbc.get_other_param('calendars__days_selection__middle_days_opacity'); 1190 jQuery('#calendar_booking' + resource_id + ' .datepick-current-day').not(".selected_check_in_out").css('opacity', middle_days_opacity); 1191 }, 10); 1192 } 1193 }); 1194}); 1195 1196/** 1197 * -- T i m e F i e l d s start -------------------------------------------------------------------------- 1198 */ 1199 1200/** 1201 * Disable time slots in booking form depend on selected dates and booked dates/times 1202 * 1203 * @param resource_id 1204 */ 1205function wpbc_disable_time_fields_in_booking_form(resource_id) { 1206 /** 1207 * 1. Get all time fields in the booking form as array of objects 1208 * [ 1209 * { jquery_option: jQuery_Object {} 1210 * name: 'rangetime2[]' 1211 * times_as_seconds: [ 21600, 23400 ] 1212 * value_option_24h: '06:00 - 06:30' 1213 * } 1214 * ... 1215 * { jquery_option: jQuery_Object {} 1216 * name: 'starttime2[]' 1217 * times_as_seconds: [ 21600 ] 1218 * value_option_24h: '06:00' 1219 * } 1220 * ] 1221 */ 1222 var time_fields_obj_arr = wpbc_get__time_fields__in_booking_form__as_arr(resource_id); 1223 1224 // 2. Get all selected dates in SQL format like this [ "2023-08-23", "2023-08-24", "2023-08-25", ... ] 1225 var selected_dates_arr = wpbc_get__selected_dates_sql__as_arr(resource_id); 1226 1227 // 3. Get child booking resources or single booking resource that exist in dates 1228 var child_resources_arr = wpbc_clone_obj(_wpbc.booking__get_param_value(resource_id, 'resources_id_arr__in_dates')); 1229 var sql_date; 1230 var child_resource_id; 1231 var merged_seconds; 1232 var time_fields_obj; 1233 var is_intersect; 1234 var is_check_in; 1235 var today_time__real = new Date(_wpbc.get_other_param('time_local_arr')[0], parseInt(_wpbc.get_other_param('time_local_arr')[1]) - 1, _wpbc.get_other_param('time_local_arr')[2], _wpbc.get_other_param('time_local_arr')[3], _wpbc.get_other_param('time_local_arr')[4], 0); 1236 var today_time__shift = new Date(_wpbc.get_other_param('today_arr')[0], parseInt(_wpbc.get_other_param('today_arr')[1]) - 1, _wpbc.get_other_param('today_arr')[2], _wpbc.get_other_param('today_arr')[3], _wpbc.get_other_param('today_arr')[4], 0); 1237 1238 // 4. Loop all time Fields options // FixIn: 10.3.0.2. 1239 for (var field_key = 0; field_key < time_fields_obj_arr.length; field_key++) { 1240 time_fields_obj_arr[field_key].disabled = 0; // By default, this time field is not disabled. 1241 1242 time_fields_obj = time_fields_obj_arr[field_key]; // { times_as_seconds: [ 21600, 23400 ], value_option_24h: '06:00 - 06:30', name: 'rangetime2[]', jquery_option: jQuery_Object {}} 1243 1244 // Loop all selected dates. 1245 for (var i = 0; i < selected_dates_arr.length; i++) { 1246 // Get Date: '2023-08-18'. 1247 sql_date = selected_dates_arr[i]; 1248 var is_time_in_past = wpbc_check_is_time_in_past(today_time__shift, sql_date, time_fields_obj); 1249 // Exception for 'End Time' field, when selected several dates. // FixIn: 10.14.1.5. 1250 if ('On' !== _wpbc.calendar__get_param_value(resource_id, 'booking_recurrent_time') && -1 !== time_fields_obj.name.indexOf('endtime') && selected_dates_arr.length > 1) { 1251 is_time_in_past = wpbc_check_is_time_in_past(today_time__shift, selected_dates_arr[selected_dates_arr.length - 1], time_fields_obj); 1252 } 1253 if (is_time_in_past) { 1254 // This time for selected date already in the past. 1255 time_fields_obj_arr[field_key].disabled = 1; 1256 break; // exist from Dates LOOP. 1257 } 1258 // FixIn: 9.9.0.31. 1259 if ('Off' === _wpbc.calendar__get_param_value(resource_id, 'booking_recurrent_time') && selected_dates_arr.length > 1) {
1260 //TODO: skip some fields checking if it's start / end time for mulple dates selection mode. 1261 //TODO: we need to fix situation for entimes, when user select several dates, and in start time booked 00:00 - 15:00 , but systsme block untill 15:00 the end time as well, which is wrong, because it 2 or 3 dates selection and end date can be fullu available 1262 1263 if (0 == i && time_fields_obj['name'].indexOf('endtime') >= 0) { 1264 break; 1265 } 1266 if (selected_dates_arr.length - 1 == i && time_fields_obj['name'].indexOf('starttime') >= 0) { 1267 break; 1268 } 1269 } 1270 var how_many_resources_intersected = 0; 1271 // Loop all resources ID 1272 // for ( var res_key in child_resources_arr ){ // FixIn: 10.3.0.2. 1273 for (var res_key = 0; res_key < child_resources_arr.length; res_key++) { 1274 child_resource_id = child_resources_arr[res_key]; 1275 1276 // _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[12].booked_time_slots.merged_seconds = [ "07:00:11 - 07:30:02", "10:00:11 - 00:00:00" ] 1277 // _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[2].booked_time_slots.merged_seconds = [ [ 25211, 27002 ], [ 36011, 86400 ] ] 1278 1279 if (false !== _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_date)) { 1280 merged_seconds = _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_date)[child_resource_id].booked_time_slots.merged_seconds; // [ [ 25211, 27002 ], [ 36011, 86400 ] ] 1281 } else { 1282 merged_seconds = []; 1283 } 1284 if (time_fields_obj.times_as_seconds.length > 1) { 1285 is_intersect = wpbc_is_intersect__range_time_interval([[parseInt(time_fields_obj.times_as_seconds[0]) + 20, parseInt(time_fields_obj.times_as_seconds[1]) - 20]], merged_seconds); 1286 } else { 1287 is_check_in = -1 !== time_fields_obj.name.indexOf('start'); 1288 is_intersect = wpbc_is_intersect__one_time_interval(is_check_in ? parseInt(time_fields_obj.times_as_seconds) + 20 : parseInt(time_fields_obj.times_as_seconds) - 20, merged_seconds); 1289 } 1290 if (is_intersect) { 1291 how_many_resources_intersected++; // Increase 1292 } 1293 } 1294 if (child_resources_arr.length == how_many_resources_intersected) { 1295 // All resources intersected, then it's means that this time-slot or time must be Disabled, and we can exist from selected_dates_arr LOOP 1296 1297 time_fields_obj_arr[field_key].disabled = 1; 1298 break; // exist from Dates LOOP 1299 } 1300 } 1301 } 1302 1303 // 5. Now we can disable time slot in HTML by using ( field.disabled == 1 ) property 1304 wpbc__html__time_field_options__set_disabled(time_fields_obj_arr); 1305 jQuery(".booking_form_div").trigger('wpbc_hook_timeslots_disabled', [resource_id, selected_dates_arr]); // Trigger hook on disabling timeslots. Usage: jQuery( ".booking_form_div" ).on( 'wpbc_hook_timeslots_disabled', function ( event, bk_type, all_dates ){ ... } ); // FixIn: 8.7.11.9. 1306} 1307 1308/** 1309 * Check if specific time(-slot) already in the past for selected date 1310 * 1311 * @param js_current_time_to_check - JS Date 1312 * @param sql_date - '2025-01-26' 1313 * @param time_fields_obj - Object 1314 * @returns {boolean} 1315 */ 1316function wpbc_check_is_time_in_past(js_current_time_to_check, sql_date, time_fields_obj) { 1317 // FixIn: 10.9.6.4 1318 var sql_date_arr = sql_date.split('-'); 1319 var sql_date__midnight = new Date(parseInt(sql_date_arr[0]), parseInt(sql_date_arr[1]) - 1, parseInt(sql_date_arr[2]), 0, 0, 0); 1320 var sql_date__midnight_miliseconds = sql_date__midnight.getTime(); 1321 var is_intersect = false; 1322 if (time_fields_obj.times_as_seconds.length > 1) { 1323 if (js_current_time_to_check.getTime() > sql_date__midnight_miliseconds + (parseInt(time_fields_obj.times_as_seconds[0]) + 20) * 1000) { 1324 is_intersect = true; 1325 } 1326 if (js_current_time_to_check.getTime() > sql_date__midnight_miliseconds + (parseInt(time_fields_obj.times_as_seconds[1]) - 20) * 1000) { 1327 is_intersect = true; 1328 } 1329 } else { 1330 var is_check_in = -1 !== time_fields_obj.name.indexOf('start'); 1331 var times_as_seconds_check = is_check_in ? parseInt(time_fields_obj.times_as_seconds) + 20 : parseInt(time_fields_obj.times_as_seconds) - 20; 1332 times_as_seconds_check = sql_date__midnight_miliseconds + times_as_seconds_check * 1000; 1333 if (js_current_time_to_check.getTime() > times_as_seconds_check) { 1334 is_intersect = true; 1335 } 1336 } 1337 return is_intersect; 1338} 1339
1340/** 1341 * Is number inside /intersect of array of intervals ? 1342 * 1343 * @param time_A - 25800 1344 * @param time_interval_B - [ [ 25211, 27002 ], [ 36011, 86400 ] ] 1345 * @returns {boolean} 1346 */ 1347function wpbc_is_intersect__one_time_interval(time_A, time_interval_B) { 1348 for (var j = 0; j < time_interval_B.length; j++) { 1349 if (parseInt(time_A) > parseInt(time_interval_B[j][0]) && parseInt(time_A) < parseInt(time_interval_B[j][1])) { 1350 return true; 1351 } 1352 1353 // if ( ( parseInt( time_A ) == parseInt( time_interval_B[ j ][ 0 ] ) ) || ( parseInt( time_A ) == parseInt( time_interval_B[ j ][ 1 ] ) ) ) { 1354 // // Time A just at the border of interval 1355 // } 1356 } 1357 return false; 1358} 1359 1360/** 1361 * Is these array of intervals intersected ? 1362 * 1363 * @param time_interval_A - [ [ 21600, 23400 ] ] 1364 * @param time_interval_B - [ [ 25211, 27002 ], [ 36011, 86400 ] ] 1365 * @returns {boolean} 1366 */ 1367function wpbc_is_intersect__range_time_interval(time_interval_A, time_interval_B) { 1368 var is_intersect; 1369 for (var i = 0; i < time_interval_A.length; i++) { 1370 for (var j = 0; j < time_interval_B.length; j++) { 1371 is_intersect = wpbc_intervals__is_intersected(time_interval_A[i], time_interval_B[j]); 1372 if (is_intersect) { 1373 return true; 1374 } 1375 } 1376 } 1377 return false; 1378} 1379 1380/** 1381 * Get all time fields in the booking form as array of objects 1382 * 1383 * @param resource_id 1384 * @returns [] 1385 * 1386 * Example: 1387 * [ 1388 * { 1389 * value_option_24h: '06:00 - 06:30' 1390 * times_as_seconds: [ 21600, 23400 ] 1391 * jquery_option: jQuery_Object {} 1392 * name: 'rangetime2[]' 1393 * } 1394 * ... 1395 * { 1396 * value_option_24h: '06:00' 1397 * times_as_seconds: [ 21600 ] 1398 * jquery_option: jQuery_Object {} 1399 * name: 'starttime2[]' 1400 * } 1401 * ] 1402 */ 1403function wpbc_get__time_fields__in_booking_form__as_arr(resource_id) { 1404 /** 1405 * Fields with [] like this select[name="rangetime1[]"] 1406 * it's when we have 'multiple' in shortcode: [select* rangetime multiple "06:00 - 06:30" ... ] 1407 */ 1408 var time_fields_arr = ['select[name="rangetime' + resource_id + '"]', 'select[name="rangetime' + resource_id + '[]"]', 'select[name="starttime' + resource_id + '"]', 'select[name="starttime' + resource_id + '[]"]', 'select[name="endtime' + resource_id + '"]', 'select[name="endtime' + resource_id + '[]"]']; 1409 var time_fields_obj_arr = []; 1410 1411 // Loop all Time Fields 1412 for (var ctf = 0; ctf < time_fields_arr.length; ctf++) { 1413 var time_field = time_fields_arr[ctf]; 1414 var time_option = jQuery(time_field + ' option'); 1415 1416 // Loop all options in time field 1417 for (var j = 0; j < time_option.length; j++) { 1418 var jquery_option = jQuery(time_field + ' option:eq(' + j + ')'); 1419 var value_option_seconds_arr = jquery_option.val().split('-'); 1420 var times_as_seconds = []; 1421 1422 // Get time as seconds 1423 if (value_option_seconds_arr.length) { 1424 // FixIn: 9.8.10.1. 1425 for (var i = 0; i < value_option_seconds_arr.length; i++) { 1426 // FixIn: 10.0.0.56. 1427 // value_option_seconds_arr[i] = '14:00 ' | ' 16:00' (if from 'rangetime') and '16:00' if (start/end time) 1428 1429 var start_end_times_arr = value_option_seconds_arr[i].trim().split(':'); 1430 var time_in_seconds = parseInt(start_end_times_arr[0]) * 60 * 60 + parseInt(start_end_times_arr[1]) * 60; 1431 times_as_seconds.push(time_in_seconds); 1432 } 1433 } 1434 time_fields_obj_arr.push({ 1435 'name': jQuery(time_field).attr('name'), 1436 'value_option_24h': jquery_option.val(), 1437 'jquery_option': jquery_option, 1438 'times_as_seconds': times_as_seconds 1439 }); 1440 } 1441 } 1442 return time_fields_obj_arr; 1443} 1444 1445/** 1446 * Disable HTML options and add booked CSS class 1447 * 1448 * @param time_fields_obj_arr - this value is from the func: wpbc_get__time_fields__in_booking_form__as_arr( resource_id ) 1449 * [ 1450 * { jquery_option: jQuery_Object {} 1451 * name: 'rangetime2[]' 1452 * times_as_seconds: [ 21600, 23400 ] 1453 * value_option_24h: '06:00 - 06:30' 1454 * disabled = 1 1455 * } 1456 * ... 1457 * { jquery_option: jQuery_Object {} 1458 * name: 'starttime2[]' 1459 * times_as_seconds: [ 21600 ] 1460 * value_option_24h: '06:00' 1461 * disabled = 0 1462 * } 1463 * ] 1464 * 1465 */
1466function wpbc__html__time_field_options__set_disabled(time_fields_obj_arr) { 1467 var jquery_option; 1468 for (var i = 0; i < time_fields_obj_arr.length; i++) { 1469 var jquery_option = time_fields_obj_arr[i].jquery_option; 1470 if (1 == time_fields_obj_arr[i].disabled) { 1471 jquery_option.prop('disabled', true); // Make disable some options 1472 jquery_option.addClass('booked'); // Add "booked" CSS class 1473 1474 // if this booked element selected --> then deselect it 1475 if (jquery_option.prop('selected')) { 1476 jquery_option.prop('selected', false); 1477 jquery_option.parent().find('option:not([disabled]):first').prop('selected', true).trigger("change"); 1478 } 1479 } else { 1480 jquery_option.prop('disabled', false); // Make active all times 1481 jquery_option.removeClass('booked'); // Remove class "booked" 1482 } 1483 } 1484} 1485 1486/** 1487 * Check if this time_range | Time_Slot is Full Day booked 1488 * 1489 * @param timeslot_arr_in_seconds - [ 36011, 86400 ] 1490 * @returns {boolean} 1491 */ 1492function wpbc_is_this_timeslot__full_day_booked(timeslot_arr_in_seconds) { 1493 if (timeslot_arr_in_seconds.length > 1 && parseInt(timeslot_arr_in_seconds[0]) < 30 && parseInt(timeslot_arr_in_seconds[1]) > 24 * 60 * 60 - 30) { 1494 return true; 1495 } 1496 return false; 1497} 1498 1499// ----------------------------------------------------------------------------------------------------------------- 1500/* == S e l e c t e d D a t e s / T i m e - F i e l d s == 1501// ----------------------------------------------------------------------------------------------------------------- */ 1502 1503/** 1504 * Get all selected dates in SQL format like this [ "2023-08-23", "2023-08-24" , ... ] 1505 * 1506 * @param resource_id 1507 * @returns {[]} [ "2023-08-23", "2023-08-24", "2023-08-25", "2023-08-26", "2023-08-27", "2023-08-28", "2023-08-29" ] 1508 */ 1509function wpbc_get__selected_dates_sql__as_arr(resource_id) { 1510 var selected_dates_arr = []; 1511 selected_dates_arr = jQuery('#date_booking' + resource_id).val().split(','); 1512 if (selected_dates_arr.length) { 1513 // FixIn: 9.8.10.1. 1514 for (var i = 0; i < selected_dates_arr.length; i++) { 1515 // FixIn: 10.0.0.56. 1516 selected_dates_arr[i] = selected_dates_arr[i].trim(); 1517 selected_dates_arr[i] = selected_dates_arr[i].split('.'); 1518 if (selected_dates_arr[i].length > 1) { 1519 selected_dates_arr[i] = selected_dates_arr[i][2] + '-' + selected_dates_arr[i][1] + '-' + selected_dates_arr[i][0]; 1520 } 1521 } 1522 } 1523 1524 // Remove empty elements from an array 1525 selected_dates_arr = selected_dates_arr.filter(function (n) { 1526 return parseInt(n); 1527 }); 1528 selected_dates_arr.sort(); 1529 return selected_dates_arr; 1530} 1531 1532/** 1533 * Get all time fields in the booking form as array of objects 1534 * 1535 * @param resource_id 1536 * @param is_only_selected_time 1537 * @returns [] 1538 * 1539 * Example: 1540 * [ 1541 * { 1542 * value_option_24h: '06:00 - 06:30' 1543 * times_as_seconds: [ 21600, 23400 ] 1544 * jquery_option: jQuery_Object {} 1545 * name: 'rangetime2[]' 1546 * } 1547 * ... 1548 * { 1549 * value_option_24h: '06:00' 1550 * times_as_seconds: [ 21600 ] 1551 * jquery_option: jQuery_Object {} 1552 * name: 'starttime2[]' 1553 * } 1554 * ] 1555 */ 1556function wpbc_get__selected_time_fields__in_booking_form__as_arr(resource_id) { 1557 var is_only_selected_time = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 1558 /** 1559 * Fields with [] like this select[name="rangetime1[]"] 1560 * it's when we have 'multiple' in shortcode: [select* rangetime multiple "06:00 - 06:30" ... ] 1561 */ 1562 var time_fields_arr = ['select[name="rangetime' + resource_id + '"]', 'select[name="rangetime' + resource_id + '[]"]', 'select[name="starttime' + resource_id + '"]', 'select[name="starttime' + resource_id + '[]"]', 'select[name="endtime' + resource_id + '"]', 'select[name="endtime' + resource_id + '[]"]', 'select[name="durationtime' + resource_id + '"]', 'select[name="durationtime' + resource_id + '[]"]']; 1563 var time_fields_obj_arr = []; 1564 1565 // Loop all Time Fields 1566 for (var ctf = 0; ctf < time_fields_arr.length; ctf++) { 1567 var time_field = time_fields_arr[ctf]; 1568 var time_option; 1569 if (is_only_selected_time) { 1570 time_option = jQuery('#booking_form' + resource_id + ' ' + time_field + ' option:selected'); // Exclude conditional fields, because of using '#booking_form3 ...' 1571 } else { 1572 time_option = jQuery('#booking_form' + resource_id + ' ' + time_field + ' option'); // All time fields 1573 } 1574 1575 // Loop all options in time field 1576 for (var j = 0; j < time_option.length; j++) { 1577 var jquery_option = jQuery(time_option[j]); // Get only selected options //jQuery( time_field + ' option:eq(' + j + ')' ); 1578 var value_option_seconds_arr = jquery_option.val().split('-'); 1579 var times_as_seconds = []; 1580 1581 // Get time as seconds 1582 if (value_option_seconds_arr.length) { 1583 // FixIn: 9.8.10.1. 1584 for (var i = 0; i < value_option_seconds_arr.length; i++) { 1585 // FixIn: 10.0.0.56. 1586 // value_option_seconds_arr[i] = '14:00 ' | ' 16:00' (if from 'rangetime') and '16:00' if (start/end time) 1587 1588 var start_end_times_arr = value_option_seconds_arr[i].trim().split(':'); 1589 var time_in_seconds = parseInt(start_end_times_arr[0]) * 60 * 60 + parseInt(start_end_times_arr[1]) * 60; 1590 times_as_seconds.push(time_in_seconds); 1591 } 1592 } 1593 time_fields_obj_arr.push({ 1594 'name': jQuery('#booking_form' + resource_id + ' ' + time_field).attr('name'), 1595 'value_option_24h': jquery_option.val(), 1596 'jquery_option': jquery_option, 1597 'times_as_seconds': times_as_seconds 1598 }); 1599 } 1600 } 1601 1602 // Text: [starttime] - [endtime] ----------------------------------------------------------------------------- 1603 1604 var text_time_fields_arr = ['input[name="starttime' + resource_id + '"]', 'input[name="endtime' + resource_id + '"]']; 1605 for (var tf = 0; tf < text_time_fields_arr.length; tf++) { 1606 var text_jquery = jQuery('#booking_form' + resource_id + ' ' + text_time_fields_arr[tf]); // Exclude conditional fields, because of using '#booking_form3 ...' 1607 if (text_jquery.length > 0) { 1608 var time__h_m__arr = text_jquery.val().trim().split(':'); // '14:00' 1609 if (0 == time__h_m__arr.length) { 1610 continue; // Not entered time value in a field 1611 } 1612 if (1 == time__h_m__arr.length) { 1613 if ('' === time__h_m__arr[0]) { 1614 continue; // Not entered time value in a field 1615 } 1616 time__h_m__arr[1] = 0; 1617 } 1618 var text_time_in_seconds = parseInt(time__h_m__arr[0]) * 60 * 60 + parseInt(time__h_m__arr[1]) * 60; 1619 var text_times_as_seconds = []; 1620 text_times_as_seconds.push(text_time_in_seconds); 1621 time_fields_obj_arr.push({ 1622 'name': text_jquery.attr('name'), 1623 'value_option_24h': text_jquery.val(), 1624 'jquery_option': text_jquery, 1625 'times_as_seconds': text_times_as_seconds 1626 }); 1627 } 1628 } 1629 return time_fields_obj_arr; 1630} 1631 1632// --------------------------------------------------------------------------------------------------------------------- 1633/* == S U P P O R T for C A L E N D A R == 1634// --------------------------------------------------------------------------------------------------------------------- */ 1635
1636/** 1637 * Get Calendar datepick Instance 1638 * @param resource_id of booking resource 1639 * @returns {*|null} 1640 */ 1641function wpbc_calendar__get_inst(resource_id) { 1642 if ('undefined' === typeof resource_id) { 1643 resource_id = '1'; 1644 } 1645 if (jQuery('#calendar_booking' + resource_id).length > 0) { 1646 return jQuery.datepick._getInst(jQuery('#calendar_booking' + resource_id).get(0)); 1647 } 1648 return null; 1649} 1650 1651/** 1652 * Unselect all dates in calendar and visually update this calendar 1653 * 1654 * @param resource_id ID of booking resource 1655 * @returns {boolean} true on success | false, if no such calendar 1656 */ 1657function wpbc_calendar__unselect_all_dates(resource_id) { 1658 if ('undefined' === typeof resource_id) { 1659 resource_id = '1'; 1660 } 1661 var inst = wpbc_calendar__get_inst(resource_id); 1662 if (null !== inst) { 1663 // Unselect all dates and set properties of Datepick 1664 jQuery('#date_booking' + resource_id).val(''); //FixIn: 5.4.3 1665 inst.stayOpen = false; 1666 inst.dates = []; 1667 jQuery.datepick._updateDatepick(inst); 1668 return true; 1669 } 1670 return false; 1671} 1672 1673/** 1674 * Clear days highlighting in All or specific Calendars 1675 * 1676 * @param resource_id - can be skiped to clear highlighting in all calendars 1677 */ 1678function wpbc_calendars__clear_days_highlighting(resource_id) { 1679 if ('undefined' !== typeof resource_id) { 1680 jQuery('#calendar_booking' + resource_id + ' .datepick-days-cell-over').removeClass('datepick-days-cell-over'); // Clear in specific calendar 1681 } else { 1682 jQuery('.datepick-days-cell-over').removeClass('datepick-days-cell-over'); // Clear in all calendars 1683 } 1684} 1685 1686/** 1687 * Scroll to specific month in calendar 1688 * 1689 * @param resource_id ID of resource 1690 * @param year - real year - 2023 1691 * @param month - real month - 12 1692 * @returns {boolean} 1693 */ 1694function wpbc_calendar__scroll_to(resource_id, year, month) { 1695 if ('undefined' === typeof resource_id) { 1696 resource_id = '1'; 1697 } 1698 var inst = wpbc_calendar__get_inst(resource_id); 1699 if (null !== inst) { 1700 year = parseInt(year);
1701 month = parseInt(month) - 1; // In JS date, month -1 1702 1703 inst.cursorDate = new Date(); 1704 // In some cases, the setFullYear can set only Year, and not the Month and day // FixIn: 6.2.3.5. 1705 inst.cursorDate.setFullYear(year, month, 1); 1706 inst.cursorDate.setMonth(month); 1707 inst.cursorDate.setDate(1); 1708 inst.drawMonth = inst.cursorDate.getMonth(); 1709 inst.drawYear = inst.cursorDate.getFullYear(); 1710 jQuery.datepick._notifyChange(inst); 1711 jQuery.datepick._adjustInstDate(inst); 1712 jQuery.datepick._showDate(inst); 1713 jQuery.datepick._updateDatepick(inst); 1714 return true; 1715 } 1716 return false; 1717} 1718 1719/** 1720 * Is this date selectable in calendar (mainly it's means AVAILABLE date) 1721 * 1722 * @param {int|string} resource_id 1 1723 * @param {string} sql_class_day '2023-08-11' 1724 * @returns {boolean} true | false 1725 */ 1726function wpbc_is_this_day_selectable(resource_id, sql_class_day) { 1727 // Get Data -------------------------------------------------------------------------------------------------------- 1728 var date_bookings_obj = _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_class_day); 1729 var is_day_selectable = parseInt(date_bookings_obj['day_availability']) > 0; 1730 if (typeof date_bookings_obj['summary'] === 'undefined') { 1731 return is_day_selectable; 1732 } 1733 if ('available' != date_bookings_obj['summary']['status_for_day']) { 1734 var is_set_pending_days_selectable = _wpbc.calendar__get_param_value(resource_id, 'pending_days_selectable'); // set pending days selectable // FixIn: 8.6.1.18. 1735 1736 switch (date_bookings_obj['summary']['status_for_bookings']) { 1737 case 'pending': 1738 // Situations for "change-over" days: 1739 case 'pending_pending': 1740 case 'pending_approved': 1741 case 'approved_pending': 1742 is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable; 1743 break; 1744 default: 1745 } 1746 } 1747 return is_day_selectable; 1748} 1749 1750/** 1751 * Is date to check IN array of selected dates 1752 * 1753 * @param {date}js_date_to_check - JS Date - simple JavaScript Date object 1754 * @param {[]} js_dates_arr - [ JSDate, ... ] - array of JS dates 1755 * @returns {boolean} 1756 */ 1757function wpbc_is_this_day_among_selected_days(js_date_to_check, js_dates_arr) { 1758 for (var date_index = 0; date_index < js_dates_arr.length; date_index++) { 1759 // FixIn: 8.4.5.16. 1760 if (js_dates_arr[date_index].getFullYear() === js_date_to_check.getFullYear() && js_dates_arr[date_index].getMonth() === js_date_to_check.getMonth() && js_dates_arr[date_index].getDate() === js_date_to_check.getDate()) { 1761 return true; 1762 } 1763 } 1764 return false; 1765} 1766 1767/** 1768 * Get SQL Class Date '2023-08-01' from JS Date 1769 * 1770 * @param date JS Date 1771 * @returns {string} '2023-08-12' 1772 */ 1773function wpbc__get__sql_class_date(date) { 1774 var sql_class_day = date.getFullYear() + '-'; 1775 sql_class_day += date.getMonth() + 1 < 10 ? '0' : ''; 1776 sql_class_day += date.getMonth() + 1 + '-'; 1777 sql_class_day += date.getDate() < 10 ? '0' : ''; 1778 sql_class_day += date.getDate(); 1779 return sql_class_day; 1780} 1781 1782/** 1783 * Get JS Date from the SQL date format '2024-05-14' 1784 * @param sql_class_date 1785 * @returns {Date} 1786 */ 1787function wpbc__get__js_date(sql_class_date) { 1788 var sql_class_date_arr = sql_class_date.split('-'); 1789 var date_js = new Date(); 1790 date_js.setFullYear(parseInt(sql_class_date_arr[0]), parseInt(sql_class_date_arr[1]) - 1, parseInt(sql_class_date_arr[2])); // year, month, date 1791 1792 // Without this time adjust Dates selection in Datepicker can not work!!! 1793 date_js.setHours(0); 1794 date_js.setMinutes(0); 1795 date_js.setSeconds(0); 1796 date_js.setMilliseconds(0); 1797 return date_js; 1798} 1799 1800/** 1801 * Get TD Class Date '1-31-2023' from JS Date 1802 * 1803 * @param date JS Date 1804 * @returns {string} '1-31-2023' 1805 */ 1806function wpbc__get__td_class_date(date) { 1807 var td_class_day = date.getMonth() + 1 + '-' + date.getDate() + '-' + date.getFullYear(); // '1-9-2023' 1808 1809 return td_class_day; 1810} 1811 1812/** 1813 * Get date params from string date 1814 * 1815 * @param date string date like '31.5.2023' 1816 * @param separator default '.' can be skipped. 1817 * @returns { {date: number, month: number, year: number} } 1818 */
1819function wpbc__get__date_params__from_string_date(date, separator) { 1820 separator = 'undefined' !== typeof separator ? separator : '.'; 1821 var date_arr = date.split(separator); 1822 var date_obj = { 1823 'year': parseInt(date_arr[2]), 1824 'month': parseInt(date_arr[1]) - 1, 1825 'date': parseInt(date_arr[0]) 1826 }; 1827 return date_obj; // for = new Date( date_obj.year , date_obj.month , date_obj.date ); 1828} 1829 1830/** 1831 * Add Spin Loader to calendar 1832 * @param resource_id 1833 */ 1834function wpbc_calendar__loading__start(resource_id) { 1835 if (!jQuery('#calendar_booking' + resource_id).next().hasClass('wpbc_spins_loader_wrapper')) { 1836 jQuery('#calendar_booking' + resource_id).after('<div class="wpbc_spins_loader_wrapper"><div class="wpbc_spins_loader"></div></div>'); 1837 } 1838 if (!jQuery('#calendar_booking' + resource_id).hasClass('wpbc_calendar_blur_small')) { 1839 jQuery('#calendar_booking' + resource_id).addClass('wpbc_calendar_blur_small'); 1840 } 1841 wpbc_calendar__blur__start(resource_id); 1842} 1843 1844/** 1845 * Remove Spin Loader to calendar 1846 * @param resource_id 1847 */ 1848function wpbc_calendar__loading__stop(resource_id) { 1849 jQuery('#calendar_booking' + resource_id + ' + .wpbc_spins_loader_wrapper').remove(); 1850 jQuery('#calendar_booking' + resource_id).removeClass('wpbc_calendar_blur_small'); 1851 wpbc_calendar__blur__stop(resource_id); 1852} 1853 1854/** 1855 * Add Blur to calendar 1856 * @param resource_id 1857 */ 1858function wpbc_calendar__blur__start(resource_id) { 1859 if (!jQuery('#calendar_booking' + resource_id).hasClass('wpbc_calendar_blur')) { 1860 jQuery('#calendar_booking' + resource_id).addClass('wpbc_calendar_blur'); 1861 } 1862} 1863 1864/** 1865 * Remove Blur in calendar 1866 * @param resource_id 1867 */ 1868function wpbc_calendar__blur__stop(resource_id) { 1869 jQuery('#calendar_booking' + resource_id).removeClass('wpbc_calendar_blur'); 1870} 1871 1872// ................................................................................................................. 1873/* == Calendar Update - View == 1874// ................................................................................................................. */ 1875 1876/** 1877 * Update Look of calendar 1878 * 1879 * @param resource_id 1880 */ 1881function wpbc_calendar__update_look(resource_id) { 1882 var inst = wpbc_calendar__get_inst(resource_id); 1883 jQuery.datepick._updateDatepick(inst); 1884} 1885 1886/** 1887 * Update dynamically Number of Months in calendar 1888 * 1889 * @param resource_id int 1890 * @param months_number int 1891 */ 1892function wpbc_calendar__update_months_number(resource_id, months_number) { 1893 var inst = wpbc_calendar__get_inst(resource_id); 1894 if (null !== inst) { 1895 inst.settings['numberOfMonths'] = months_number; 1896 //_wpbc.calendar__set_param_value( resource_id, 'calendar_number_of_months', months_number ); 1897 wpbc_calendar__update_look(resource_id); 1898 } 1899} 1900 1901/** 1902 * Show calendar in different Skin 1903 * 1904 * @param selected_skin_url 1905 */ 1906function wpbc__calendar__change_skin(selected_skin_url) { 1907 //console.log( 'SKIN SELECTION ::', selected_skin_url ); 1908 1909 // Remove CSS skin 1910 var stylesheet = document.getElementById('wpbc-calendar-skin-css'); 1911 stylesheet.parentNode.removeChild(stylesheet); 1912 1913 // Add new CSS skin 1914 var headID = document.getElementsByTagName("head")[0]; 1915 var cssNode = document.createElement('link'); 1916 cssNode.type = 'text/css'; 1917 cssNode.setAttribute("id", "wpbc-calendar-skin-css"); 1918 cssNode.rel = 'stylesheet';
1919 cssNode.media = 'screen'; 1920 cssNode.href = selected_skin_url; //"http://beta/wp-content/plugins/booking/css/skins/green-01.css"; 1921 headID.appendChild(cssNode); 1922} 1923function wpbc__css__change_skin(selected_skin_url) { 1924 var stylesheet_id = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'wpbc-time_picker-skin-css'; 1925 // Remove CSS skin 1926 var stylesheet = document.getElementById(stylesheet_id); 1927 stylesheet.parentNode.removeChild(stylesheet); 1928 1929 // Add new CSS skin 1930 var headID = document.getElementsByTagName("head")[0]; 1931 var cssNode = document.createElement('link'); 1932 cssNode.type = 'text/css'; 1933 cssNode.setAttribute("id", stylesheet_id); 1934 cssNode.rel = 'stylesheet'; 1935 cssNode.media = 'screen'; 1936 cssNode.href = selected_skin_url; //"http://beta/wp-content/plugins/booking/css/skins/green-01.css"; 1937 headID.appendChild(cssNode); 1938} 1939 1940// --------------------------------------------------------------------------------------------------------------------- 1941/* == S U P P O R T M A T H == 1942// --------------------------------------------------------------------------------------------------------------------- */ 1943 1944/** 1945 * Merge several intersected intervals or return not intersected: [[1,3],[2,6],[8,10],[15,18]] -> [[1,6],[8,10],[15,18]] 1946 * 1947 * @param [] intervals [ [1,3],[2,4],[6,8],[9,10],[3,7] ] 1948 * @returns [] [ [1,8],[9,10] ] 1949 * 1950 * Exmample: wpbc_intervals__merge_inersected( [ [1,3],[2,4],[6,8],[9,10],[3,7] ] ); 1951 */ 1952function wpbc_intervals__merge_inersected(intervals) { 1953 if (!intervals || intervals.length === 0) { 1954 return []; 1955 } 1956 var merged = []; 1957 intervals.sort(function (a, b) { 1958 return a[0] - b[0]; 1959 }); 1960 var mergedInterval = intervals[0]; 1961 for (var i = 1; i < intervals.length; i++) { 1962 var interval = intervals[i]; 1963 if (interval[0] <= mergedInterval[1]) { 1964 mergedInterval[1] = Math.max(mergedInterval[1], interval[1]); 1965 } else { 1966 merged.push(mergedInterval); 1967 mergedInterval = interval; 1968 } 1969 } 1970 merged.push(mergedInterval); 1971 return merged; 1972} 1973 1974/** 1975 * Is 2 intervals intersected: [36011, 86392] <=> [1, 43192] => true ( intersected ) 1976 * 1977 * Good explanation here https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap 1978 * 1979 * @param interval_A - [ 36011, 86392 ] 1980 * @param interval_B - [ 1, 43192 ] 1981 * 1982 * @return bool 1983 */ 1984function wpbc_intervals__is_intersected(interval_A, interval_B) { 1985 if (0 == interval_A.length || 0 == interval_B.length) { 1986 return false; 1987 } 1988 interval_A[0] = parseInt(interval_A[0]); 1989 interval_A[1] = parseInt(interval_A[1]); 1990 interval_B[0] = parseInt(interval_B[0]); 1991 interval_B[1] = parseInt(interval_B[1]); 1992 var is_intersected = Math.max(interval_A[0], interval_B[0]) - Math.min(interval_A[1], interval_B[1]); 1993 1994 // if ( 0 == is_intersected ) { 1995 // // Such ranges going one after other, e.g.: [ 12, 15 ] and [ 15, 21 ] 1996 // } 1997 1998 if (is_intersected < 0) { 1999 return true; // INTERSECTED 2000 } 2001 return false; // Not intersected 2002} 2003 2004/** 2005 * Get the closets ABS value of element in array to the current myValue 2006 * 2007 * @param myValue - int element to search closet 4 2008 * @param myArray - array of elements where to search [5,8,1,7] 2009 * @returns int 5 2010 */ 2011function wpbc_get_abs_closest_value_in_arr(myValue, myArray) { 2012 if (myArray.length == 0) { 2013 // If the array is empty -> return the myValue 2014 return myValue; 2015 } 2016 var obj = myArray[0]; 2017 var diff = Math.abs(myValue - obj); // Get distance between 1st element 2018 var closetValue = myArray[0]; // Save 1st element 2019 2020 for (var i = 1; i < myArray.length; i++) { 2021 obj = myArray[i]; 2022 if (Math.abs(myValue - obj) < diff) { 2023 // we found closer value -> save it 2024 diff = Math.abs(myValue - obj); 2025 closetValue = obj; 2026 } 2027 } 2028 return closetValue; 2029} 2030 2031// --------------------------------------------------------------------------------------------------------------------- 2032/* == T O O L T I P S == 2033// --------------------------------------------------------------------------------------------------------------------- */ 2034
2035/** 2036 * Define tooltip to show, when mouse over Date in Calendar 2037 * 2038 * @param tooltip_text - Text to show 'Booked time: 12:00 - 13:00<br>Cost: $20.00' 2039 * @param resource_id - ID of booking resource '1' 2040 * @param td_class - SQL class '1-9-2023' 2041 * @returns {boolean} - defined to show or not 2042 */ 2043function wpbc_set_tooltip___for__calendar_date(tooltip_text, resource_id, td_class) { 2044 //TODO: make escaping of text for quot symbols, and JS/HTML... 2045 2046 jQuery('#calendar_booking' + resource_id + ' td.cal4date-' + td_class).attr('data-content', tooltip_text); 2047 var td_el = jQuery('#calendar_booking' + resource_id + ' td.cal4date-' + td_class).get(0); // FixIn: 9.0.1.1. 2048 2049 if ('undefined' !== typeof td_el && undefined == td_el._tippy && '' !== tooltip_text) { 2050 wpbc_tippy(td_el, { 2051 content: function content(reference) { 2052 var popover_content = reference.getAttribute('data-content'); 2053 return '<div class="popover popover_tippy">' + '<div class="popover-content">' + popover_content + '</div>' + '</div>'; 2054 }, 2055 allowHTML: true, 2056 trigger: 'mouseenter focus', 2057 interactive: false, 2058 hideOnClick: true, 2059 interactiveBorder: 10, 2060 maxWidth: 550, 2061 theme: 'wpbc-tippy-times', 2062 placement: 'top', 2063 delay: [400, 0], 2064 // FixIn: 9.4.2.2. 2065 //delay : [0, 9999999999], // Debuge tooltip 2066 ignoreAttributes: true, 2067 touch: true, 2068 //['hold', 500], // 500ms delay // FixIn: 9.2.1.5. 2069 appendTo: function appendTo() { 2070 return document.body; 2071 } 2072 }); 2073 return true; 2074 } 2075 return false; 2076} 2077 2078// --------------------------------------------------------------------------------------------------------------------- 2079/* == Dates Functions == 2080// --------------------------------------------------------------------------------------------------------------------- */ 2081 2082/** 2083 * Get number of dates between 2 JS Dates 2084 * 2085 * @param date1 JS Date 2086 * @param date2 JS Date 2087 * @returns {number} 2088 */ 2089function wpbc_dates__days_between(date1, date2) { 2090 // The number of milliseconds in one day 2091 var ONE_DAY = 1000 * 60 * 60 * 24; 2092 2093 // Convert both dates to milliseconds 2094 var date1_ms = date1.getTime(); 2095 var date2_ms = date2.getTime(); 2096 2097 // Calculate the difference in milliseconds 2098 var difference_ms = date1_ms - date2_ms; 2099 2100 // Convert back to days and return 2101 return Math.round(difference_ms / ONE_DAY); 2102} 2103 2104/** 2105 * Check if this array of dates is consecutive array of dates or not. 2106 * e.g. ['2024-05-09','2024-05-19','2024-05-30'] -> false 2107 * e.g. ['2024-05-09','2024-05-10','2024-05-11'] -> true 2108 * @param sql_dates_arr array e.g.: ['2024-05-09','2024-05-19','2024-05-30'] 2109 * @returns {boolean} 2110 */ 2111function wpbc_dates__is_consecutive_dates_arr_range(sql_dates_arr) { 2112 // FixIn: 10.0.0.50. 2113 2114 if (sql_dates_arr.length > 1) { 2115 var previos_date = wpbc__get__js_date(sql_dates_arr[0]); 2116 var current_date; 2117 for (var i = 1; i < sql_dates_arr.length; i++) { 2118 current_date = wpbc__get__js_date(sql_dates_arr[i]); 2119 if (wpbc_dates__days_between(current_date, previos_date) != 1) { 2120 return false; 2121 } 2122 previos_date = current_date; 2123 } 2124 } 2125 return true; 2126} 2127 2128// --------------------------------------------------------------------------------------------------------------------- 2129/* == Auto Dates Selection == 2130// --------------------------------------------------------------------------------------------------------------------- */ 2131 2132/** 2133 * == How to use ? == 2134 * 2135 * For Dates selection, we need to use this logic! We need select the dates only after booking data loaded! 2136 * 2137 * Check example bellow. 2138 * 2139 * // Fire on all booking dates loaded 2140 * jQuery( 'body' ).on( 'wpbc_calendar_ajx__loaded_data', function ( event, loaded_resource_id ){ 2141 * 2142 * if ( loaded_resource_id == select_dates_in_calendar_id ){ 2143 * wpbc_auto_select_dates_in_calendar( select_dates_in_calendar_id, '2024-05-15', '2024-05-25' ); 2144 * } 2145 * } ); 2146 * 2147 */ 2148 2149/** 2150 * Try to Auto select dates in specific calendar by simulated clicks in datepicker 2151 * 2152 * @param resource_id 1 2153 * @param check_in_ymd '2024-05-09' OR ['2024-05-09','2024-05-19','2024-05-20'] 2154 * @param check_out_ymd '2024-05-15' Optional 2155 * 2156 * @returns {number} number of selected dates 2157 * 2158 * Example 1: var num_selected_days = wpbc_auto_select_dates_in_calendar( 1, '2024-05-15', '2024-05-25' ); 2159 * Example 2: var num_selected_days = wpbc_auto_select_dates_in_calendar( 1, ['2024-05-09','2024-05-19','2024-05-20'] ); 2160 */
2161function wpbc_auto_select_dates_in_calendar(resource_id, check_in_ymd) { 2162 var check_out_ymd = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; 2163 // FixIn: 10.0.0.47. 2164 2165 console.log('WPBC_AUTO_SELECT_DATES_IN_CALENDAR( RESOURCE_ID, CHECK_IN_YMD, CHECK_OUT_YMD )', resource_id, check_in_ymd, check_out_ymd); 2166 if ('2100-01-01' == check_in_ymd || '2100-01-01' == check_out_ymd || '' == check_in_ymd && '' == check_out_ymd) { 2167 return 0; 2168 } 2169 2170 // ----------------------------------------------------------------------------------------------------------------- 2171 // If check_in_ymd = [ '2024-05-09','2024-05-19','2024-05-30' ] ARRAY of DATES // FixIn: 10.0.0.50. 2172 // ----------------------------------------------------------------------------------------------------------------- 2173 var dates_to_select_arr = []; 2174 if (Array.isArray(check_in_ymd)) { 2175 dates_to_select_arr = wpbc_clone_obj(check_in_ymd); 2176 2177 // ------------------------------------------------------------------------------------------------------------- 2178 // Exceptions to set MULTIPLE DAYS mode 2179 // ------------------------------------------------------------------------------------------------------------- 2180 // if dates as NOT CONSECUTIVE: ['2024-05-09','2024-05-19','2024-05-30'], -> set MULTIPLE DAYS mode 2181 if (dates_to_select_arr.length > 0 && '' == check_out_ymd && !wpbc_dates__is_consecutive_dates_arr_range(dates_to_select_arr)) { 2182 wpbc_cal_days_select__multiple(resource_id); 2183 } 2184 // if multiple days to select, but enabled SINGLE day mode, -> set MULTIPLE DAYS mode 2185 if (dates_to_select_arr.length > 1 && '' == check_out_ymd && 'single' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) { 2186 wpbc_cal_days_select__multiple(resource_id); 2187 } 2188 // ------------------------------------------------------------------------------------------------------------- 2189 check_in_ymd = dates_to_select_arr[0]; 2190 if ('' == check_out_ymd) { 2191 check_out_ymd = dates_to_select_arr[dates_to_select_arr.length - 1]; 2192 } 2193 } 2194 // ----------------------------------------------------------------------------------------------------------------- 2195 2196 if ('' == check_in_ymd) { 2197 check_in_ymd = check_out_ymd; 2198 } 2199 if ('' == check_out_ymd) { 2200 check_out_ymd = check_in_ymd; 2201 } 2202 if ('undefined' === typeof resource_id) { 2203 resource_id = '1'; 2204 } 2205 var inst = wpbc_calendar__get_inst(resource_id); 2206 if (null !== inst) { 2207 // Unselect all dates and set properties of Datepick 2208 jQuery('#date_booking' + resource_id).val(''); //FixIn: 5.4.3 2209 inst.stayOpen = false; 2210 inst.dates = []; 2211 var check_in_js = wpbc__get__js_date(check_in_ymd); 2212 var td_cell = wpbc_get_clicked_td(inst.id, check_in_js); 2213 2214 // Is ome type of error, then select multiple days selection mode. 2215 if ('' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) { 2216 _wpbc.calendar__set_param_value(resource_id, 'days_select_mode', 'multiple'); 2217 } 2218 2219 // --------------------------------------------------------------------------------------------------------- 2220 // == DYNAMIC == 2221 if ('dynamic' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) { 2222 // 1-st click 2223 inst.stayOpen = false; 2224 jQuery.datepick._selectDay(td_cell, '#' + inst.id, check_in_js.getTime()); 2225 if (0 === inst.dates.length) { 2226 return 0; // First click was unsuccessful, so we must not make other click 2227 } 2228 2229 // 2-nd click 2230 var check_out_js = wpbc__get__js_date(check_out_ymd); 2231 var td_cell_out = wpbc_get_clicked_td(inst.id, check_out_js); 2232 inst.stayOpen = true; 2233 jQuery.datepick._selectDay(td_cell_out, '#' + inst.id, check_out_js.getTime()); 2234 } 2235 2236 // --------------------------------------------------------------------------------------------------------- 2237 // == FIXED == 2238 if ('fixed' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) { 2239 jQuery.datepick._selectDay(td_cell, '#' + inst.id, check_in_js.getTime()); 2240 } 2241 2242 // --------------------------------------------------------------------------------------------------------- 2243 // == SINGLE == 2244 if ('single' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) { 2245 //jQuery.datepick._restrictMinMax( inst, jQuery.datepick._determineDate( inst, check_in_js, null ) ); // Do we need to run this ? Please note, check_in_js must have time, min, sec defined to 0! 2246 jQuery.datepick._selectDay(td_cell, '#' + inst.id, check_in_js.getTime()); 2247 } 2248 2249 // --------------------------------------------------------------------------------------------------------- 2250 // == MULTIPLE == 2251 if ('multiple' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) { 2252 var dates_arr; 2253 if (dates_to_select_arr.length > 0) { 2254 // Situation, when we have dates array: ['2024-05-09','2024-05-19','2024-05-30']. and not the Check In / Check out dates as parameter in this function 2255 dates_arr = wpbc_get_selection_dates_js_str_arr__from_arr(dates_to_select_arr); 2256 } else { 2257 dates_arr = wpbc_get_selection_dates_js_str_arr__from_check_in_out(check_in_ymd, check_out_ymd, inst); 2258 } 2259 if (0 === dates_arr.dates_js.length) { 2260 return 0; 2261 } 2262 2263 // For Calendar Days selection 2264 for (var j = 0; j < dates_arr.dates_js.length; j++) { 2265 // Loop array of dates 2266 2267 var str_date = wpbc__get__sql_class_date(dates_arr.dates_js[j]); 2268 2269 // Date unavailable ! 2270 if (0 == _wpbc.bookings_in_calendar__get_for_date(resource_id, str_date).day_availability) { 2271 return 0; 2272 } 2273 if (dates_arr.dates_js[j] != -1) { 2274 inst.dates.push(dates_arr.dates_js[j]); 2275 } 2276 } 2277 var check_out_date = dates_arr.dates_js[dates_arr.dates_js.length - 1]; 2278 inst.dates.push(check_out_date); // Need add one additional SAME date for correct works of dates selection !!!!! 2279 2280 var checkout_timestamp = check_out_date.getTime(); 2281 var td_cell = wpbc_get_clicked_td(inst.id, check_out_date); 2282 jQuery.datepick._selectDay(td_cell, '#' + inst.id, checkout_timestamp); 2283 } 2284 if (0 !== inst.dates.length) { 2285 // Scroll to specific month, if we set dates in some future months 2286 wpbc_calendar__scroll_to(resource_id, inst.dates[0].getFullYear(), inst.dates[0].getMonth() + 1); 2287 } 2288 return inst.dates.length; 2289 } 2290 return 0; 2291} 2292 2293/** 2294 * Get HTML td element (where was click in calendar day cell) 2295 * 2296 * @param calendar_html_id 'calendar_booking1' 2297 * @param date_js JS Date 2298 * @returns {*|jQuery} Dom HTML td element 2299 */
2300function wpbc_get_clicked_td(calendar_html_id, date_js) { 2301 var td_cell = jQuery('#' + calendar_html_id + ' .sql_date_' + wpbc__get__sql_class_date(date_js)).get(0); 2302 return td_cell; 2303} 2304 2305/** 2306 * Get arrays of JS and SQL dates as dates array 2307 * 2308 * @param check_in_ymd '2024-05-15' 2309 * @param check_out_ymd '2024-05-25' 2310 * @param inst Datepick Inst. Use wpbc_calendar__get_inst( resource_id ); 2311 * @returns {{dates_js: *[], dates_str: *[]}} 2312 */ 2313function wpbc_get_selection_dates_js_str_arr__from_check_in_out(check_in_ymd, check_out_ymd, inst) { 2314 var original_array = []; 2315 var date; 2316 var bk_distinct_dates = []; 2317 var check_in_date = check_in_ymd.split('-'); 2318 var check_out_date = check_out_ymd.split('-'); 2319 date = new Date(); 2320 date.setFullYear(check_in_date[0], check_in_date[1] - 1, check_in_date[2]); // year, month, date 2321 var original_check_in_date = date; 2322 original_array.push(jQuery.datepick._restrictMinMax(inst, jQuery.datepick._determineDate(inst, date, null))); //add date 2323 if (!wpbc_in_array(bk_distinct_dates, check_in_date[2] + '.' + check_in_date[1] + '.' + check_in_date[0])) { 2324 bk_distinct_dates.push(parseInt(check_in_date[2]) + '.' + parseInt(check_in_date[1]) + '.' + check_in_date[0]); 2325 } 2326 var date_out = new Date(); 2327 date_out.setFullYear(check_out_date[0], check_out_date[1] - 1, check_out_date[2]); // year, month, date 2328 var original_check_out_date = date_out; 2329 var mewDate = new Date(original_check_in_date.getFullYear(), original_check_in_date.getMonth(), original_check_in_date.getDate()); 2330 mewDate.setDate(original_check_in_date.getDate() + 1); 2331 while (original_check_out_date > date && original_check_in_date != original_check_out_date) { 2332 date = new Date(mewDate.getFullYear(), mewDate.getMonth(), mewDate.getDate()); 2333 original_array.push(jQuery.datepick._restrictMinMax(inst, jQuery.datepick._determineDate(inst, date, null))); //add date 2334 if (!wpbc_in_array(bk_distinct_dates, date.getDate() + '.' + parseInt(date.getMonth() + 1) + '.' + date.getFullYear())) { 2335 bk_distinct_dates.push(parseInt(date.getDate()) + '.' + parseInt(date.getMonth() + 1) + '.' + date.getFullYear()); 2336 } 2337 mewDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()); 2338 mewDate.setDate(mewDate.getDate() + 1); 2339 } 2340 original_array.pop(); 2341 bk_distinct_dates.pop(); 2342 return { 2343 'dates_js': original_array, 2344 'dates_str': bk_distinct_dates 2345 }; 2346} 2347 2348/** 2349 * Get arrays of JS and SQL dates as dates array 2350 * 2351 * @param dates_to_select_arr = ['2024-05-09','2024-05-19','2024-05-30'] 2352 * 2353 * @returns {{dates_js: *[], dates_str: *[]}} 2354 */ 2355function wpbc_get_selection_dates_js_str_arr__from_arr(dates_to_select_arr) { 2356 // FixIn: 10.0.0.50. 2357 2358 var original_array = []; 2359 var bk_distinct_dates = []; 2360 var one_date_str; 2361 for (var d = 0; d < dates_to_select_arr.length; d++) { 2362 original_array.push(wpbc__get__js_date(dates_to_select_arr[d])); 2363 one_date_str = dates_to_select_arr[d].split('-'); 2364 if (!wpbc_in_array(bk_distinct_dates, one_date_str[2] + '.' + one_date_str[1] + '.' + one_date_str[0])) { 2365 bk_distinct_dates.push(parseInt(one_date_str[2]) + '.' + parseInt(one_date_str[1]) + '.' + one_date_str[0]); 2366 } 2367 } 2368 return { 2369 'dates_js': original_array, 2370 'dates_str': original_array 2371 }; 2372} 2373 2374// ===================================================================================================================== 2375/* == Auto Fill Fields / Auto Select Dates == 2376// ===================================================================================================================== */ 2377 2378jQuery(document).ready(function () { 2379 var url_params = new URLSearchParams(window.location.search); 2380 2381 // Disable days selection in calendar, after redirection from the "Search results page, after search availability" // FixIn: 8.8.2.3. 2382 if ('On' != _wpbc.get_other_param('is_enabled_booking_search_results_days_select')) { 2383 if (url_params.has('wpbc_select_check_in') && url_params.has('wpbc_select_check_out') && url_params.has('wpbc_select_calendar_id')) { 2384 var select_dates_in_calendar_id = parseInt(url_params.get('wpbc_select_calendar_id')); 2385 2386 // Fire on all booking dates loaded 2387 jQuery('body').on('wpbc_calendar_ajx__loaded_data', function (event, loaded_resource_id) { 2388 if (loaded_resource_id == select_dates_in_calendar_id) { 2389 wpbc_auto_select_dates_in_calendar(select_dates_in_calendar_id, url_params.get('wpbc_select_check_in'), url_params.get('wpbc_select_check_out')); 2390 } 2391 }); 2392 } 2393 } 2394 if (url_params.has('wpbc_auto_fill')) { 2395 var wpbc_auto_fill_value = url_params.get('wpbc_auto_fill'); 2396 2397 // Convert back. Some systems do not like symbol '~' in URL, so we need to replace to some other symbols 2398 wpbc_auto_fill_value = wpbc_auto_fill_value.replaceAll('_^_', '~'); 2399 wpbc_auto_fill_booking_fields(wpbc_auto_fill_value); 2400 } 2401}); 2402 2403/** 2404 * Autofill / select booking form fields by values from the GET request parameter: ?wpbc_auto_fill= 2405 * 2406 * @param auto_fill_str 2407 */
2408function wpbc_auto_fill_booking_fields(auto_fill_str) { 2409 // FixIn: 10.0.0.48. 2410 2411 if ('' == auto_fill_str) { 2412 return; 2413 } 2414 2415 // console.log( 'WPBC_AUTO_FILL_BOOKING_FIELDS( AUTO_FILL_STR )', auto_fill_str); 2416 2417 var fields_arr = wpbc_auto_fill_booking_fields__parse(auto_fill_str); 2418 for (var i = 0; i < fields_arr.length; i++) { 2419 jQuery('[name="' + fields_arr[i]['name'] + '"]').val(fields_arr[i]['value']); 2420 } 2421} 2422 2423/** 2424 * Parse data from get parameter: ?wpbc_auto_fill=visitors231^2~max_capacity231^2 2425 * 2426 * @param data_str = 'visitors231^2~max_capacity231^2'; 2427 * @returns {*} 2428 */ 2429function wpbc_auto_fill_booking_fields__parse(data_str) { 2430 var filter_options_arr = []; 2431 var data_arr = data_str.split('~'); 2432 for (var j = 0; j < data_arr.length; j++) { 2433 var my_form_field = data_arr[j].split('^'); 2434 var filter_name = 'undefined' !== typeof my_form_field[0] ? my_form_field[0] : ''; 2435 var filter_value = 'undefined' !== typeof my_form_field[1] ? my_form_field[1] : ''; 2436 filter_options_arr.push({ 2437 'name': filter_name, 2438 'value': filter_value 2439 }); 2440 } 2441 return filter_options_arr; 2442} 2443 2444/** 2445 * Parse data from get parameter: ?search_get__custom_params=... 2446 * 2447 * @param data_str = 'text^search_field__display_check_in^23.05.2024~text^search_field__display_check_out^26.05.2024~selectbox-one^search_quantity^2~selectbox-one^location^Spain~selectbox-one^max_capacity^2~selectbox-one^amenity^parking~checkbox^search_field__extend_search_days^5~submit^^Search~hidden^search_get__check_in_ymd^2024-05-23~hidden^search_get__check_out_ymd^2024-05-26~hidden^search_get__time^~hidden^search_get__quantity^2~hidden^search_get__extend^5~hidden^search_get__users_id^~hidden^search_get__custom_params^~'; 2448 * @returns {*} 2449 */ 2450function wpbc_auto_fill_search_fields__parse(data_str) { 2451 var filter_options_arr = []; 2452 var data_arr = data_str.split('~'); 2453 for (var j = 0; j < data_arr.length; j++) { 2454 var my_form_field = data_arr[j].split('^'); 2455 var filter_type = 'undefined' !== typeof my_form_field[0] ? my_form_field[0] : ''; 2456 var filter_name = 'undefined' !== typeof my_form_field[1] ? my_form_field[1] : ''; 2457 var filter_value = 'undefined' !== typeof my_form_field[2] ? my_form_field[2] : ''; 2458 filter_options_arr.push({ 2459 'type': filter_type, 2460 'name': filter_name, 2461 'value': filter_value 2462 }); 2463 } 2464 return filter_options_arr; 2465} 2466 2467// --------------------------------------------------------------------------------------------------------------------- 2468/* == Auto Update number of months in calendars ON screen size changed == 2469// --------------------------------------------------------------------------------------------------------------------- */ 2470 2471/** 2472 * Auto Update Number of Months in Calendar, e.g.: if ( WINDOW_WIDTH <= 782px ) >>> MONTHS_NUMBER = 1 2473 * ELSE: number of months defined in shortcode. 2474 * @param resource_id int 2475 * 2476 */ 2477function wpbc_calendar__auto_update_months_number__on_resize(resource_id) { 2478 if (true === _wpbc.get_other_param('is_allow_several_months_on_mobile')) { 2479 return false; 2480 } 2481 var local__number_of_months = parseInt(_wpbc.calendar__get_param_value(resource_id, 'calendar_number_of_months')); 2482 if (local__number_of_months > 1) { 2483 if (jQuery(window).width() <= 782) { 2484 wpbc_calendar__update_months_number(resource_id, 1); 2485 } else { 2486 wpbc_calendar__update_months_number(resource_id, local__number_of_months); 2487 } 2488 } 2489} 2490 2491/** 2492 * Auto Update Number of Months in ALL Calendars 2493 * 2494 */ 2495function wpbc_calendars__auto_update_months_number() { 2496 var all_calendars_arr = _wpbc.calendars_all__get(); 2497 2498 // This LOOP "for in" is GOOD, because we check here keys 'calendar_' === calendar_id.slice( 0, 9 ) 2499 for (var calendar_id in all_calendars_arr) {
2500 if ('calendar_' === calendar_id.slice(0, 9)) { 2501 var resource_id = parseInt(calendar_id.slice(9)); // 'calendar_3' -> 3 2502 if (resource_id > 0) { 2503 wpbc_calendar__auto_update_months_number__on_resize(resource_id); 2504 } 2505 } 2506 } 2507} 2508 2509/** 2510 * If browser window changed, then update number of months. 2511 */ 2512jQuery(window).on('resize', function () { 2513 wpbc_calendars__auto_update_months_number(); 2514}); 2515 2516/** 2517 * Auto update calendar number of months on initial page load 2518 */ 2519jQuery(document).ready(function () { 2520 var closed_timer = setTimeout(function () { 2521 wpbc_calendars__auto_update_months_number(); 2522 }, 100); 2523}); 2524 2525// --------------------------------------------------------------------------------------------------------------------- 2526/* == Check: calendar_dates_start: "2026-01-01", calendar_dates_end: "2026-12-31" == // FixIn: 10.13.1.4. 2527// --------------------------------------------------------------------------------------------------------------------- */ 2528/** 2529 * Get Start JS Date of starting dates in calendar, from the _wpbc object. 2530 * 2531 * @param integer resource_id - resource ID, e.g.: 1. 2532 */ 2533function wpbc_calendar__get_dates_start(resource_id) { 2534 return wpbc_calendar__get_date_parameter(resource_id, 'calendar_dates_start'); 2535} 2536 2537/** 2538 * Get End JS Date of ending dates in calendar, from the _wpbc object. 2539 * 2540 * @param integer resource_id - resource ID, e.g.: 1. 2541 */ 2542function wpbc_calendar__get_dates_end(resource_id) { 2543 return wpbc_calendar__get_date_parameter(resource_id, 'calendar_dates_end'); 2544} 2545 2546/** 2547 * Get validates date parameter. 2548 * 2549 * @param resource_id - 1 2550 * @param parameter_str - 'calendar_dates_start' | 'calendar_dates_end' | ... 2551 */ 2552function wpbc_calendar__get_date_parameter(resource_id, parameter_str) { 2553 var date_expected_ymd = _wpbc.calendar__get_param_value(resource_id, parameter_str); 2554 if (!date_expected_ymd) { 2555 return false; // '' | 0 | null | undefined -> false. 2556 } 2557 if (-1 !== date_expected_ymd.indexOf('-')) { 2558 var date_expected_ymd_arr = date_expected_ymd.split('-'); // '2025-07-26' -> ['2025', '07', '26'] 2559 2560 if (date_expected_ymd_arr.length > 0) { 2561 var year = date_expected_ymd_arr.length > 0 ? parseInt(date_expected_ymd_arr[0]) : new Date().getFullYear(); // Year. 2562 var month = date_expected_ymd_arr.length > 1 ? parseInt(date_expected_ymd_arr[1]) - 1 : 0; // (month - 1) or 0 - Jan. 2563 var day = date_expected_ymd_arr.length > 2 ? parseInt(date_expected_ymd_arr[2]) : 1; // date or Otherwise 1st of month 2564 2565 var date_js = new Date(year, month, day, 0, 0, 0, 0); 2566 return date_js; 2567 } 2568 } 2569 return false; // Fallback, if we not parsed this parameter 'calendar_dates_start' = '2025-07-26', for example because of 'calendar_dates_start' = 'sfsdf'. 2570} 2571/** 2572 * ==================================================================================================================== 2573 * includes/__js/cal/days_select_custom.js 2574 * ==================================================================================================================== 2575 */ 2576 2577// FixIn: 9.8.9.2. 2578 2579/** 2580 * Re-Init Calendar and Re-Render it. 2581 * 2582 * @param resource_id 2583 */ 2584function wpbc_cal__re_init(resource_id) { 2585 // Remove CLASS for ability to re-render and reinit calendar. 2586 jQuery('#calendar_booking' + resource_id).removeClass('hasDatepick'); 2587 wpbc_calendar_show(resource_id); 2588} 2589 2590/** 2591 * Re-Init previously saved days selection variables. 2592 * 2593 * @param resource_id 2594 */ 2595function wpbc_cal_days_select__re_init(resource_id) { 2596 _wpbc.calendar__set_param_value(resource_id, 'saved_variable___days_select_initial', { 2597 'dynamic__days_min': _wpbc.calendar__get_param_value(resource_id, 'dynamic__days_min'), 2598 'dynamic__days_max': _wpbc.calendar__get_param_value(resource_id, 'dynamic__days_max'), 2599 'dynamic__days_specific': _wpbc.calendar__get_param_value(resource_id, 'dynamic__days_specific'), 2600 'dynamic__week_days__start': _wpbc.calendar__get_param_value(resource_id, 'dynamic__week_days__start'), 2601 'fixed__days_num': _wpbc.calendar__get_param_value(resource_id, 'fixed__days_num'), 2602 'fixed__week_days__start': _wpbc.calendar__get_param_value(resource_id, 'fixed__week_days__start') 2603 }); 2604} 2605 2606// --------------------------------------------------------------------------------------------------------------------- 2607 2608/** 2609 * Set Single Day selection - after page load 2610 * 2611 * @param resource_id ID of booking resource 2612 */
2613function wpbc_cal_ready_days_select__single(resource_id) { 2614 // Re-define selection, only after page loaded with all init vars 2615 jQuery(document).ready(function () { 2616 // Wait 1 second, just to be sure, that all init vars defined 2617 setTimeout(function () { 2618 wpbc_cal_days_select__single(resource_id); 2619 }, 1000); 2620 }); 2621} 2622 2623/** 2624 * Set Single Day selection 2625 * Can be run at any time, when calendar defined - useful for console run. 2626 * 2627 * @param resource_id ID of booking resource 2628 */ 2629function wpbc_cal_days_select__single(resource_id) { 2630 _wpbc.calendar__set_parameters(resource_id, { 2631 'days_select_mode': 'single' 2632 }); 2633 wpbc_cal_days_select__re_init(resource_id); 2634 wpbc_cal__re_init(resource_id); 2635} 2636 2637// --------------------------------------------------------------------------------------------------------------------- 2638 2639/** 2640 * Set Multiple Days selection - after page load 2641 * 2642 * @param resource_id ID of booking resource 2643 */ 2644function wpbc_cal_ready_days_select__multiple(resource_id) { 2645 // Re-define selection, only after page loaded with all init vars 2646 jQuery(document).ready(function () { 2647 // Wait 1 second, just to be sure, that all init vars defined 2648 setTimeout(function () { 2649 wpbc_cal_days_select__multiple(resource_id); 2650 }, 1000); 2651 }); 2652} 2653 2654/** 2655 * Set Multiple Days selection 2656 * Can be run at any time, when calendar defined - useful for console run. 2657 * 2658 * @param resource_id ID of booking resource 2659 */ 2660function wpbc_cal_days_select__multiple(resource_id) { 2661 _wpbc.calendar__set_parameters(resource_id, { 2662 'days_select_mode': 'multiple' 2663 }); 2664 wpbc_cal_days_select__re_init(resource_id); 2665 wpbc_cal__re_init(resource_id); 2666} 2667 2668// --------------------------------------------------------------------------------------------------------------------- 2669 2670/** 2671 * Set Fixed Days selection with 1 mouse click - after page load 2672 * 2673 * @integer resource_id - 1 -- ID of booking resource (calendar) - 2674 * @integer days_number - 3 -- number of days to select - 2675 * @array week_days__start - [-1] | [ 1, 5] -- { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat } 2676 */ 2677function wpbc_cal_ready_days_select__fixed(resource_id, days_number) { 2678 var week_days__start = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [-1]; 2679 // Re-define selection, only after page loaded with all init vars 2680 jQuery(document).ready(function () { 2681 // Wait 1 second, just to be sure, that all init vars defined 2682 setTimeout(function () { 2683 wpbc_cal_days_select__fixed(resource_id, days_number, week_days__start); 2684 }, 1000); 2685 }); 2686} 2687 2688/** 2689 * Set Fixed Days selection with 1 mouse click 2690 * Can be run at any time, when calendar defined - useful for console run. 2691 * 2692 * @integer resource_id - 1 -- ID of booking resource (calendar) - 2693 * @integer days_number - 3 -- number of days to select - 2694 * @array week_days__start - [-1] | [ 1, 5] -- { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat } 2695 */ 2696function wpbc_cal_days_select__fixed(resource_id, days_number) { 2697 var week_days__start = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [-1]; 2698 _wpbc.calendar__set_parameters(resource_id, { 2699 'days_select_mode': 'fixed' 2700 }); 2701 _wpbc.calendar__set_parameters(resource_id, { 2702 'fixed__days_num': parseInt(days_number) 2703 }); // Number of days selection with 1 mouse click 2704 _wpbc.calendar__set_parameters(resource_id, { 2705 'fixed__week_days__start': week_days__start 2706 }); // { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat } 2707 2708 wpbc_cal_days_select__re_init(resource_id); 2709 wpbc_cal__re_init(resource_id); 2710} 2711 2712// --------------------------------------------------------------------------------------------------------------------- 2713 2714/** 2715 * Set Range Days selection with 2 mouse clicks - after page load 2716 * 2717 * @integer resource_id - 1 -- ID of booking resource (calendar) 2718 * @integer days_min - 7 -- Min number of days to select 2719 * @integer days_max - 30 -- Max number of days to select 2720 * @array days_specific - [] | [7,14,21,28] -- Restriction for Specific number of days selection 2721 * @array week_days__start - [-1] | [ 1, 5] -- { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat } 2722 */
2723function wpbc_cal_ready_days_select__range(resource_id, days_min, days_max) { 2724 var days_specific = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; 2725 var week_days__start = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [-1]; 2726 // Re-define selection, only after page loaded with all init vars 2727 jQuery(document).ready(function () { 2728 // Wait 1 second, just to be sure, that all init vars defined 2729 setTimeout(function () { 2730 wpbc_cal_days_select__range(resource_id, days_min, days_max, days_specific, week_days__start); 2731 }, 1000); 2732 }); 2733} 2734 2735/** 2736 * Set Range Days selection with 2 mouse clicks 2737 * Can be run at any time, when calendar defined - useful for console run. 2738 * 2739 * @integer resource_id - 1 -- ID of booking resource (calendar) 2740 * @integer days_min - 7 -- Min number of days to select 2741 * @integer days_max - 30 -- Max number of days to select 2742 * @array days_specific - [] | [7,14,21,28] -- Restriction for Specific number of days selection 2743 * @array week_days__start - [-1] | [ 1, 5] -- { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat } 2744 */ 2745function wpbc_cal_days_select__range(resource_id, days_min, days_max) { 2746 var days_specific = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; 2747 var week_days__start = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [-1]; 2748 _wpbc.calendar__set_parameters(resource_id, { 2749 'days_select_mode': 'dynamic' 2750 }); 2751 _wpbc.calendar__set_param_value(resource_id, 'dynamic__days_min', parseInt(days_min)); // Min. Number of days selection with 2 mouse clicks 2752 _wpbc.calendar__set_param_value(resource_id, 'dynamic__days_max', parseInt(days_max)); // Max. Number of days selection with 2 mouse clicks 2753 _wpbc.calendar__set_param_value(resource_id, 'dynamic__days_specific', days_specific); // Example [5,7] 2754 _wpbc.calendar__set_param_value(resource_id, 'dynamic__week_days__start', week_days__start); // { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat } 2755 2756 wpbc_cal_days_select__re_init(resource_id); 2757 wpbc_cal__re_init(resource_id); 2758} 2759 2760/** 2761 * ==================================================================================================================== 2762 * includes/__js/cal_ajx_load/wpbc_cal_ajx.js 2763 * ==================================================================================================================== 2764 */ 2765 2766// --------------------------------------------------------------------------------------------------------------------- 2767// A j a x L o a d C a l e n d a r D a t a 2768// --------------------------------------------------------------------------------------------------------------------- 2769 2770function wpbc_calendar__load_data__ajx(params) { 2771 // FixIn: 9.8.6.2. 2772 wpbc_calendar__loading__start(params['resource_id']); 2773 2774 // Trigger event for calendar before loading Booking data, but after showing Calendar. 2775 if (jQuery('#calendar_booking' + params['resource_id']).length > 0) { 2776 var target_elm = jQuery('body').trigger("wpbc_calendar_ajx__before_loaded_data", [params['resource_id']]); 2777 //jQuery( 'body' ).on( 'wpbc_calendar_ajx__before_loaded_data', function( event, resource_id ) { ... } ); 2778 } 2779 if (wpbc_balancer__is_wait(params, 'wpbc_calendar__load_data__ajx')) { 2780 return false; 2781 } 2782 2783 // FixIn: 9.8.6.2. 2784 wpbc_calendar__blur__stop(params['resource_id']); 2785 2786 // ----------------------------------------------------------------------------------------------------------------- 2787 // == Get start / end dates from the Booking Calendar shortcode. == 2788 // Example: [booking calendar_dates_start='2026-01-01' calendar_dates_end='2026-12-31' resource_id=1] // FixIn: 10.13.1.4. 2789 // ----------------------------------------------------------------------------------------------------------------- 2790 if (false !== wpbc_calendar__get_dates_start(params['resource_id'])) { 2791 if (!params['dates_to_check']) { 2792 params['dates_to_check'] = []; 2793 } 2794 var dates_start = wpbc_calendar__get_dates_start(params['resource_id']); // E.g. - local__min_date = new Date( 2025, 0, 1 ); 2795 if (false !== dates_start) { 2796 params['dates_to_check'][0] = wpbc__get__sql_class_date(dates_start); 2797 } 2798 } 2799 if (false !== wpbc_calendar__get_dates_end(params['resource_id'])) { 2800 if (!params['dates_to_check']) { 2801 params['dates_to_check'] = []; 2802 } 2803 var dates_end = wpbc_calendar__get_dates_end(params['resource_id']); // E.g. - local__min_date = new Date( 2025, 0, 1 ); 2804 if (false !== dates_end) { 2805 params['dates_to_check'][1] = wpbc__get__sql_class_date(dates_end); 2806 if (!params['dates_to_check'][0]) { 2807 params['dates_to_check'][0] = wpbc__get__sql_class_date(new Date()); 2808 } 2809 } 2810 } 2811 // ----------------------------------------------------------------------------------------------------------------- 2812 2813 // console.groupEnd(); console.time('resource_id_' + params['resource_id']); 2814 console.groupCollapsed('WPBC_AJX_CALENDAR_LOAD'); 2815 console.log(' == Before Ajax Send - calendars_all__get() == ', _wpbc.calendars_all__get()); 2816 if ('function' === typeof wpbc_hook__init_timeselector) { 2817 wpbc_hook__init_timeselector(); 2818 } 2819 2820 // Start Ajax 2821 jQuery.post(wpbc_url_ajax, { 2822 action: 'WPBC_AJX_CALENDAR_LOAD', 2823 wpbc_ajx_user_id: _wpbc.get_secure_param('user_id'), 2824 nonce: _wpbc.get_secure_param('nonce'), 2825 wpbc_ajx_locale: _wpbc.get_secure_param('locale'), 2826 calendar_request_params: params // Usually like: { 'resource_id': 1, 'max_days_count': 365 } 2827 }, 2828 /** 2829 * S u c c e s s 2830 * 2831 * @param response_data - its object returned from Ajax - class-live-search.php 2832 * @param textStatus - 'success' 2833 * @param jqXHR - Object 2834 */ 2835 function (response_data, textStatus, jqXHR) { 2836 // console.timeEnd('resource_id_' + response_data['resource_id']); 2837 console.log(' == Response WPBC_AJX_CALENDAR_LOAD == ', response_data); 2838 console.groupEnd(); 2839 2840 // FixIn: 9.8.6.2. 2841 var ajx_post_data__resource_id = wpbc_get_resource_id__from_ajx_post_data_url(this.data); 2842 wpbc_balancer__completed(ajx_post_data__resource_id, 'wpbc_calendar__load_data__ajx'); 2843 2844 // Probably Error 2845 if (_typeof(response_data) !== 'object' || response_data === null) { 2846 var jq_node = wpbc_get_calendar__jq_node__for_messages(this.data); 2847 var message_type = 'info'; 2848 if ('' === response_data) { 2849 response_data = 'The server responds with an empty string. The server probably stopped working unexpectedly. <br>Please check your <strong>error.log</strong> in your server configuration for relative errors.'; 2850 message_type = 'warning'; 2851 } 2852 2853 // Show Message 2854 wpbc_front_end__show_message(response_data, { 2855 'type': message_type, 2856 'show_here': { 2857 'jq_node': jq_node, 2858 'where': 'after' 2859 }, 2860 'is_append': true, 2861 'style': 'text-align:left;', 2862 'delay': 0 2863 }); 2864 return; 2865 } 2866 2867 // Show Calendar 2868 wpbc_calendar__loading__stop(response_data['resource_id']); 2869 2870 // ------------------------------------------------------------------------------------------------- 2871 // Bookings - Dates 2872 _wpbc.bookings_in_calendar__set_dates(response_data['resource_id'], response_data['ajx_data']['dates']); 2873 2874 // Bookings - Child or only single booking resource in dates 2875 _wpbc.booking__set_param_value(response_data['resource_id'], 'resources_id_arr__in_dates', response_data['ajx_data']['resources_id_arr__in_dates']); 2876 2877 // Aggregate booking resources, if any ? 2878 _wpbc.booking__set_param_value(response_data['resource_id'], 'aggregate_resource_id_arr', response_data['ajx_data']['aggregate_resource_id_arr']); 2879 // ------------------------------------------------------------------------------------------------- 2880 2881 // Update calendar 2882 wpbc_calendar__update_look(response_data['resource_id']); 2883 if ('function' === typeof wpbc_hook__init_timeselector) { 2884 wpbc_hook__init_timeselector(); 2885 } 2886 if ('undefined' !== typeof response_data['ajx_data']['ajx_after_action_message'] && '' != response_data['ajx_data']['ajx_after_action_message'].replace(/\n/g, "<br />")) { 2887 var jq_node = wpbc_get_calendar__jq_node__for_messages(this.data); 2888 2889 // Show Message 2890 wpbc_front_end__show_message(response_data['ajx_data']['ajx_after_action_message'].replace(/\n/g, "<br />"), { 2891 'type': 'undefined' !== typeof response_data['ajx_data']['ajx_after_action_message_status'] ? response_data['ajx_data']['ajx_after_action_message_status'] : 'info', 2892 'show_here': { 2893 'jq_node': jq_node, 2894 'where': 'after' 2895 }, 2896 'is_append': true, 2897 'style': 'text-align:left;', 2898 'delay': 10000 2899 }); 2900 } 2901 2902 // Trigger event that calendar has been // FixIn: 10.0.0.44. 2903 if (jQuery('#calendar_booking' + response_data['resource_id']).length > 0) { 2904 var target_elm = jQuery('body').trigger("wpbc_calendar_ajx__loaded_data", [response_data['resource_id']]);
2905 //jQuery( 'body' ).on( 'wpbc_calendar_ajx__loaded_data', function( event, resource_id ) { ... } ); 2906 } 2907 2908 //jQuery( '#ajax_respond' ).html( response_data ); // For ability to show response, add such DIV element to page 2909 }).fail(function (jqXHR, textStatus, errorThrown) { 2910 if (window.console && window.console.log) { 2911 console.log('Ajax_Error', jqXHR, textStatus, errorThrown); 2912 } 2913 var ajx_post_data__resource_id = wpbc_get_resource_id__from_ajx_post_data_url(this.data); 2914 wpbc_balancer__completed(ajx_post_data__resource_id, 'wpbc_calendar__load_data__ajx'); 2915 2916 // Get Content of Error Message 2917 var error_message = '<strong>' + 'Error!' + '</strong> ' + errorThrown; 2918 if (jqXHR.status) { 2919 error_message += ' (<b>' + jqXHR.status + '</b>)'; 2920 if (403 == jqXHR.status) { 2921 error_message += '<br> Probably nonce for this page has been expired. Please <a href="javascript:void(0)" onclick="javascript:location.reload();">reload the page</a>.'; 2922 error_message += '<br> Otherwise, please check this <a style="font-weight: 600;" href="https://wpbookingcalendar.com/faq/request-do-not-pass-security-check/?after_update=10.1.1">troubleshooting instruction</a>.<br>'; 2923 } 2924 } 2925 var message_show_delay = 3000; 2926 if (jqXHR.responseText) { 2927 error_message += ' ' + jqXHR.responseText; 2928 message_show_delay = 10; 2929 } 2930 error_message = error_message.replace(/\n/g, "<br />"); 2931 var jq_node = wpbc_get_calendar__jq_node__for_messages(this.data); 2932 2933 /** 2934 * If we make fast clicking on different pages, 2935 * then under calendar will show error message with empty text, because ajax was not received. 2936 * To not show such warnings we are set delay in 3 seconds. var message_show_delay = 3000; 2937 */ 2938 var closed_timer = setTimeout(function () { 2939 // Show Message 2940 wpbc_front_end__show_message(error_message, { 2941 'type': 'error', 2942 'show_here': { 2943 'jq_node': jq_node, 2944 'where': 'after' 2945 }, 2946 'is_append': true, 2947 'style': 'text-align:left;', 2948 'css_class': 'wpbc_fe_message_alt', 2949 'delay': 0 2950 }); 2951 }, parseInt(message_show_delay)); 2952 }) 2953 // .done( function ( data, textStatus, jqXHR ) { if ( window.console && window.console.log ){ console.log( 'second success', data, textStatus, jqXHR ); } }) 2954 // .always( function ( data_jqXHR, textStatus, jqXHR_errorThrown ) { if ( window.console && window.console.log ){ console.log( 'always finished', data_jqXHR, textStatus, jqXHR_errorThrown ); } }) 2955 ; // End Ajax 2956} 2957 2958// --------------------------------------------------------------------------------------------------------------------- 2959// Support 2960// --------------------------------------------------------------------------------------------------------------------- 2961 2962/** 2963 * Get Calendar jQuery node for showing messages during Ajax 2964 * This parameter: calendar_request_params[resource_id] parsed from this.data Ajax post data 2965 * 2966 * @param ajx_post_data_url_params 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params' 2967 * @returns {string} ''#calendar_booking1' | '.booking_form_div' ... 2968 * 2969 * Example var jq_node = wpbc_get_calendar__jq_node__for_messages( this.data ); 2970 */ 2971function wpbc_get_calendar__jq_node__for_messages(ajx_post_data_url_params) { 2972 var jq_node = '.booking_form_div'; 2973 var calendar_resource_id = wpbc_get_resource_id__from_ajx_post_data_url(ajx_post_data_url_params); 2974 if (calendar_resource_id > 0) { 2975 jq_node = '#calendar_booking' + calendar_resource_id; 2976 } 2977 return jq_node; 2978} 2979 2980/** 2981 * Get resource ID from ajx post data url usually from this.data = 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params' 2982 * 2983 * @param ajx_post_data_url_params 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params' 2984 * @returns {int} 1 | 0 (if errror then 0) 2985 * 2986 * Example var jq_node = wpbc_get_calendar__jq_node__for_messages( this.data ); 2987 */
2988function wpbc_get_resource_id__from_ajx_post_data_url(ajx_post_data_url_params) { 2989 // Get booking resource ID from Ajax Post Request -> this.data = 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params' 2990 var calendar_resource_id = wpbc_get_uri_param_by_name('calendar_request_params[resource_id]', ajx_post_data_url_params); 2991 if (null !== calendar_resource_id && '' !== calendar_resource_id) { 2992 calendar_resource_id = parseInt(calendar_resource_id); 2993 if (calendar_resource_id > 0) { 2994 return calendar_resource_id; 2995 } 2996 } 2997 return 0; 2998} 2999 3000/** 3001 * Get parameter from URL - parse URL parameters, like this: action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params 3002 * @param name parameter name, like 'calendar_request_params[resource_id]' 3003 * @param url 'parameter string URL' 3004 * @returns {string|null} parameter value 3005 * 3006 * Example: wpbc_get_uri_param_by_name( 'calendar_request_params[resource_id]', this.data ); -> '2' 3007 */ 3008function wpbc_get_uri_param_by_name(name, url) { 3009 url = decodeURIComponent(url); 3010 name = name.replace(/[\[\]]/g, '\\$&'); 3011 var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), 3012 results = regex.exec(url); 3013 if (!results) return null; 3014 if (!results[2]) return ''; 3015 return decodeURIComponent(results[2].replace(/\+/g, ' ')); 3016} 3017 3018/** 3019 * ===================================================================================================================== 3020 * includes/__js/front_end_messages/wpbc_fe_messages.js 3021 * ===================================================================================================================== 3022 */ 3023 3024// --------------------------------------------------------------------------------------------------------------------- 3025// Show Messages at Front-Edn side 3026// --------------------------------------------------------------------------------------------------------------------- 3027 3028/** 3029 * Show message in content 3030 * 3031 * @param message Message HTML 3032 * @param params = { 3033 * 'type' : 'warning', // 'error' | 'warning' | 'info' | 'success' 3034 * 'show_here' : { 3035 * 'jq_node' : '', // any jQuery node definition 3036 * 'where' : 'inside' // 'inside' | 'before' | 'after' | 'right' | 'left' 3037 * }, 3038 * 'is_append': true, // Apply only if 'where' : 'inside' 3039 * 'style' : 'text-align:left;', // styles, if needed 3040 * 'css_class': '', // For example can be: 'wpbc_fe_message_alt' 3041 * 'delay' : 0, // how many microsecond to show, if 0 then show forever 3042 * 'if_visible_not_show': false // if true, then do not show message, if previos message was not hided (not apply if 'where' : 'inside' ) 3043 * }; 3044 * Examples: 3045 * var html_id = wpbc_front_end__show_message( 'You can test days selection in calendar', {} ); 3046 * 3047 * var notice_message_id = wpbc_front_end__show_message( _wpbc.get_message( 'message_check_required' ), { 'type': 'warning', 'delay': 10000, 'if_visible_not_show': true, 3048 * 'show_here': {'where': 'right', 'jq_node': el,} } ); 3049 * 3050 * wpbc_front_end__show_message( response_data[ 'ajx_data' ][ 'ajx_after_action_message' ].replace( /\n/g, "<br />" ), 3051 * { 'type' : ( 'undefined' !== typeof( response_data[ 'ajx_data' ][ 'ajx_after_action_message_status' ] ) ) 3052 * ? response_data[ 'ajx_data' ][ 'ajx_after_action_message_status' ] : 'info', 3053 * 'show_here': {'jq_node': jq_node, 'where': 'after'}, 3054 * 'css_class':'wpbc_fe_message_alt', 3055 * 'delay' : 10000 3056 * } ); 3057 * 3058 * 3059 * @returns string - HTML ID or 0 if not showing during this time. 3060 */ 3061function wpbc_front_end__show_message(message) { 3062 var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 3063 var params_default = { 3064 'type': 'warning', 3065 // 'error' | 'warning' | 'info' | 'success' 3066 'show_here': { 3067 'jq_node': '', 3068 // any jQuery node definition 3069 'where': 'inside' // 'inside' | 'before' | 'after' | 'right' | 'left' 3070 }, 3071 'is_append': true, 3072 // Apply only if 'where' : 'inside' 3073 'style': 'text-align:left;', 3074 // styles, if needed 3075 'css_class': '', 3076 // For example can be: 'wpbc_fe_message_alt' 3077 'delay': 0, 3078 // how many microsecond to show, if 0 then show forever 3079 'if_visible_not_show': false, 3080 // if true, then do not show message, if previos message was not hided (not apply if 'where' : 'inside' ) 3081 'is_scroll': true // is scroll to this element 3082 }; 3083 for (var p_key in params) { 3084 params_default[p_key] = params[p_key]; 3085 } 3086 params = params_default; 3087 var unique_div_id = new Date(); 3088 unique_div_id = 'wpbc_notice_' + unique_div_id.getTime(); 3089 params['css_class'] += ' wpbc_fe_message';
3090 if (params['type'] == 'error') { 3091 params['css_class'] += ' wpbc_fe_message_error'; 3092 message = '<i class="menu_icon icon-1x wpbc_icn_report_gmailerrorred"></i>' + message; 3093 } 3094 if (params['type'] == 'warning') { 3095 params['css_class'] += ' wpbc_fe_message_warning'; 3096 message = '<i class="menu_icon icon-1x wpbc_icn_warning"></i>' + message; 3097 } 3098 if (params['type'] == 'info') { 3099 params['css_class'] += ' wpbc_fe_message_info'; 3100 } 3101 if (params['type'] == 'success') { 3102 params['css_class'] += ' wpbc_fe_message_success'; 3103 message = '<i class="menu_icon icon-1x wpbc_icn_done_outline"></i>' + message; 3104 } 3105 var scroll_to_element = '<div id="' + unique_div_id + '_scroll" style="display:none;"></div>'; 3106 message = '<div id="' + unique_div_id + '" class="wpbc_front_end__message ' + params['css_class'] + '" style="' + params['style'] + '">' + message + '</div>'; 3107 var jq_el_message = false; 3108 var is_show_message = true; 3109 if ('inside' === params['show_here']['where']) { 3110 if (params['is_append']) { 3111 jQuery(params['show_here']['jq_node']).append(scroll_to_element); 3112 jQuery(params['show_here']['jq_node']).append(message); 3113 } else { 3114 jQuery(params['show_here']['jq_node']).html(scroll_to_element + message); 3115 } 3116 } else if ('before' === params['show_here']['where']) { 3117 jq_el_message = jQuery(params['show_here']['jq_node']).siblings('[id^="wpbc_notice_"]'); 3118 if (params['if_visible_not_show'] && jq_el_message.is(':visible')) { 3119 is_show_message = false; 3120 unique_div_id = jQuery(jq_el_message.get(0)).attr('id'); 3121 } 3122 if (is_show_message) { 3123 jQuery(params['show_here']['jq_node']).before(scroll_to_element); 3124 jQuery(params['show_here']['jq_node']).before(message); 3125 } 3126 } else if ('after' === params['show_here']['where']) { 3127 jq_el_message = jQuery(params['show_here']['jq_node']).nextAll('[id^="wpbc_notice_"]'); 3128 if (params['if_visible_not_show'] && jq_el_message.is(':visible')) { 3129 is_show_message = false; 3130 unique_div_id = jQuery(jq_el_message.get(0)).attr('id'); 3131 } 3132 if (is_show_message) { 3133 jQuery(params['show_here']['jq_node']).before(scroll_to_element); // We need to set here before(for handy scroll) 3134 jQuery(params['show_here']['jq_node']).after(message); 3135 } 3136 } else if ('right' === params['show_here']['where']) { 3137 jq_el_message = jQuery(params['show_here']['jq_node']).nextAll('.wpbc_front_end__message_container_right').find('[id^="wpbc_notice_"]'); 3138 if (params['if_visible_not_show'] && jq_el_message.is(':visible')) { 3139 is_show_message = false; 3140 unique_div_id = jQuery(jq_el_message.get(0)).attr('id'); 3141 } 3142 if (is_show_message) { 3143 jQuery(params['show_here']['jq_node']).before(scroll_to_element); // We need to set here before(for handy scroll) 3144 jQuery(params['show_here']['jq_node']).after('<div class="wpbc_front_end__message_container_right">' + message + '</div>'); 3145 } 3146 } else if ('left' === params['show_here']['where']) { 3147 jq_el_message = jQuery(params['show_here']['jq_node']).siblings('.wpbc_front_end__message_container_left').find('[id^="wpbc_notice_"]'); 3148 if (params['if_visible_not_show'] && jq_el_message.is(':visible')) { 3149 is_show_message = false; 3150 unique_div_id = jQuery(jq_el_message.get(0)).attr('id'); 3151 } 3152 if (is_show_message) { 3153 jQuery(params['show_here']['jq_node']).before(scroll_to_element); // We need to set here before(for handy scroll) 3154 jQuery(params['show_here']['jq_node']).before('<div class="wpbc_front_end__message_container_left">' + message + '</div>'); 3155 } 3156 } 3157 if (is_show_message && parseInt(params['delay']) > 0) { 3158 var closed_timer = setTimeout(function () { 3159 jQuery('#' + unique_div_id).fadeOut(1500); 3160 }, parseInt(params['delay'])); 3161 var closed_timer2 = setTimeout(function () { 3162 jQuery('#' + unique_div_id).trigger('hide'); 3163 }, parseInt(params['delay']) + 1501); 3164 } 3165 3166 // Check if showed message in some hidden parent section and show it. But it must be lower than '.wpbc_container' 3167 var parent_els = jQuery('#' + unique_div_id).parents().map(function () {
3168 if (!jQuery(this).is('visible') && jQuery('.wpbc_container').has(this)) { 3169 jQuery(this).show(); 3170 } 3171 }); 3172 if (params['is_scroll']) { 3173 wpbc_do_scroll('#' + unique_div_id + '_scroll'); 3174 } 3175 return unique_div_id; 3176} 3177 3178/** 3179 * Error message. Preset of parameters for real message function. 3180 * 3181 * @param el - any jQuery node definition 3182 * @param message - Message HTML 3183 * @returns string - HTML ID or 0 if not showing during this time. 3184 */ 3185function wpbc_front_end__show_message__error(jq_node, message) { 3186 var notice_message_id = wpbc_front_end__show_message(message, { 3187 'type': 'error', 3188 'delay': 10000, 3189 'if_visible_not_show': true, 3190 'show_here': { 3191 'where': 'right', 3192 'jq_node': jq_node 3193 } 3194 }); 3195 return notice_message_id; 3196} 3197 3198/** 3199 * Error message UNDER element. Preset of parameters for real message function. 3200 * 3201 * @param el - any jQuery node definition 3202 * @param message - Message HTML 3203 * @returns string - HTML ID or 0 if not showing during this time. 3204 */ 3205function wpbc_front_end__show_message__error_under_element(jq_node, message, message_delay) { 3206 if ('undefined' === typeof message_delay) { 3207 message_delay = 0; 3208 } 3209 var notice_message_id = wpbc_front_end__show_message(message, { 3210 'type': 'error', 3211 'delay': message_delay, 3212 'if_visible_not_show': true, 3213 'show_here': { 3214 'where': 'after', 3215 'jq_node': jq_node 3216 } 3217 }); 3218 return notice_message_id; 3219} 3220 3221/** 3222 * Error message UNDER element. Preset of parameters for real message function. 3223 * 3224 * @param el - any jQuery node definition 3225 * @param message - Message HTML 3226 * @returns string - HTML ID or 0 if not showing during this time. 3227 */ 3228function wpbc_front_end__show_message__error_above_element(jq_node, message, message_delay) { 3229 if ('undefined' === typeof message_delay) { 3230 message_delay = 10000; 3231 } 3232 var notice_message_id = wpbc_front_end__show_message(message, { 3233 'type': 'error', 3234 'delay': message_delay, 3235 'if_visible_not_show': true, 3236 'show_here': { 3237 'where': 'before', 3238 'jq_node': jq_node 3239 } 3240 }); 3241 return notice_message_id; 3242} 3243 3244/** 3245 * Warning message. Preset of parameters for real message function. 3246 * 3247 * @param el - any jQuery node definition 3248 * @param message - Message HTML 3249 * @returns string - HTML ID or 0 if not showing during this time. 3250 */ 3251function wpbc_front_end__show_message__warning(jq_node, message) { 3252 var notice_message_id = wpbc_front_end__show_message(message, { 3253 'type': 'warning', 3254 'delay': 10000, 3255 'if_visible_not_show': true, 3256 'show_here': { 3257 'where': 'right', 3258 'jq_node': jq_node 3259 } 3260 }); 3261 wpbc_highlight_error_on_form_field(jq_node); 3262 return notice_message_id; 3263} 3264 3265/** 3266 * Warning message UNDER element. Preset of parameters for real message function. 3267 * 3268 * @param el - any jQuery node definition 3269 * @param message - Message HTML 3270 * @returns string - HTML ID or 0 if not showing during this time. 3271 */ 3272function wpbc_front_end__show_message__warning_under_element(jq_node, message) { 3273 var notice_message_id = wpbc_front_end__show_message(message, { 3274 'type': 'warning', 3275 'delay': 10000, 3276 'if_visible_not_show': true, 3277 'show_here': { 3278 'where': 'after', 3279 'jq_node': jq_node 3280 } 3281 }); 3282 return notice_message_id; 3283} 3284 3285/** 3286 * Warning message ABOVE element. Preset of parameters for real message function. 3287 * 3288 * @param el - any jQuery node definition 3289 * @param message - Message HTML 3290 * @returns string - HTML ID or 0 if not showing during this time. 3291 */ 3292function wpbc_front_end__show_message__warning_above_element(jq_node, message) { 3293 var notice_message_id = wpbc_front_end__show_message(message, { 3294 'type': 'warning', 3295 'delay': 10000, 3296 'if_visible_not_show': true, 3297 'show_here': { 3298 'where': 'before', 3299 'jq_node': jq_node 3300 } 3301 }); 3302 return notice_message_id; 3303} 3304 3305/** 3306 * Highlight Error in specific field 3307 * 3308 * @param jq_node string or jQuery element, where scroll to 3309 */ 3310function wpbc_highlight_error_on_form_field(jq_node) { 3311 if (!jQuery(jq_node).length) { 3312 return; 3313 } 3314 if (!jQuery(jq_node).is(':input')) { 3315 // Situation with checkboxes or radio buttons 3316 var jq_node_arr = jQuery(jq_node).find(':input'); 3317 if (!jq_node_arr.length) { 3318 return; 3319 } 3320 jq_node = jq_node_arr.get(0); 3321 } 3322 var params = {}; 3323 params['delay'] = 10000; 3324 if (!jQuery(jq_node).hasClass('wpbc_form_field_error')) { 3325 jQuery(jq_node).addClass('wpbc_form_field_error'); 3326 if (parseInt(params['delay']) > 0) { 3327 var closed_timer = setTimeout(function () { 3328 jQuery(jq_node).removeClass('wpbc_form_field_error'); 3329 }, parseInt(params['delay'])); 3330 } 3331 } 3332} 3333 3334/** 3335 * Scroll to specific element 3336 * 3337 * @param jq_node string or jQuery element, where scroll to 3338 * @param extra_shift_offset int shift offset from jq_node 3339 */
3340function wpbc_do_scroll(jq_node) { 3341 var extra_shift_offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; 3342 if (!jQuery(jq_node).length) { 3343 return; 3344 } 3345 var targetOffset = jQuery(jq_node).offset().top; 3346 if (targetOffset <= 0) { 3347 if (0 != jQuery(jq_node).nextAll(':visible').length) { 3348 targetOffset = jQuery(jq_node).nextAll(':visible').first().offset().top; 3349 } else if (0 != jQuery(jq_node).parent().nextAll(':visible').length) { 3350 targetOffset = jQuery(jq_node).parent().nextAll(':visible').first().offset().top; 3351 } 3352 } 3353 if (jQuery('#wpadminbar').length > 0) { 3354 targetOffset = targetOffset - 50 - 50; 3355 } else { 3356 targetOffset = targetOffset - 20 - 50; 3357 } 3358 targetOffset += extra_shift_offset; 3359 3360 // Scroll only if we did not scroll before 3361 if (!jQuery('html,body').is(':animated')) { 3362 jQuery('html,body').animate({ 3363 scrollTop: targetOffset 3364 }, 500); 3365 } 3366} 3367 3368// FixIn: 10.2.0.4. 3369/** 3370 * Define Popovers for Timelines in WP Booking Calendar 3371 * 3372 * @returns {string|boolean} 3373 */ 3374function wpbc_define_tippy_popover() { 3375 if ('function' !== typeof wpbc_tippy) { 3376 console.log('WPBC Error. wpbc_tippy was not defined.'); 3377 return false; 3378 } 3379 wpbc_tippy('.popover_bottom.popover_click', { 3380 content: function content(reference) { 3381 var popover_title = reference.getAttribute('data-original-title'); 3382 var popover_content = reference.getAttribute('data-content'); 3383 return '<div class="popover popover_tippy">' + '<div class="popover-close"><a href="javascript:void(0)" onclick="javascript:this.parentElement.parentElement.parentElement.parentElement.parentElement._tippy.hide();" >×</a></div>' + popover_content + '</div>'; 3384 }, 3385 allowHTML: true, 3386 trigger: 'manual', 3387 interactive: true, 3388 hideOnClick: false, 3389 interactiveBorder: 10, 3390 maxWidth: 550, 3391 theme: 'wpbc-tippy-popover', 3392 placement: 'bottom-start', 3393 touch: ['hold', 500] 3394 }); 3395 jQuery('.popover_bottom.popover_click').on('click', function () { 3396 if (this._tippy.state.isVisible) { 3397 this._tippy.hide(); 3398 } else { 3399 this._tippy.show(); 3400 } 3401 }); 3402 wpbc_define_hide_tippy_on_scroll(); 3403} 3404function wpbc_define_hide_tippy_on_scroll() { 3405 jQuery('.flex_tl__scrolling_section2,.flex_tl__scrolling_sections').on('scroll', function (event) { 3406 if ('function' === typeof wpbc_tippy) { 3407 wpbc_tippy.hideAll(); 3408 } 3409 }); 3410} 3411//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2Rpc3QvYWxsL19vdXQvd3BiY19hbGwuanMiLCJuYW1lcyI6WyJ3cGJjX3RyaW0iLCJzdHJpbmdfdG9fdHJpbSIsIkFycmF5IiwiaXNBcnJheSIsImpvaW4iLCJ0cmltIiwid3BiY19pbl9hcnJheSIsImFycmF5X2hlcmUiLCJwX3ZhbCIsImkiLCJsIiwibGVuZ3RoIiwid3BiY19jbG9uZV9vYmoiLCJvYmoiLCJKU09OIiwicGFyc2UiLCJzdHJpbmdpZnkiLCJfd3BiYyIsIiQiLCJwX3NlY3VyZSIsInNlY3VyaXR5X29iaiIsInVzZXJfaWQiLCJub25jZSIsImxvY2FsZSIsInNldF9zZWN1cmVfcGFyYW0iLCJwYXJhbV9rZXkiLCJwYXJhbV92YWwiLCJ
3411nZXRfc2VjdXJlX3BhcmFtIiwicF9jYWxlbmRhcnMiLCJjYWxlbmRhcnNfb2JqIiwiY2FsZW5kYXJfX2lzX2RlZmluZWQiLCJyZXNvdXJjZV9pZCIsImNhbGVuZGFyX19pbml0IiwiY2FsZW5kYXJfX2lzX3Byb3BfaW50IiwicHJvcGVydHlfbmFtZSIsInBfY2FsZW5kYXJfaW50X3Byb3BlcnRpZXMiLCJpc19pbmNsdWRlIiwiaW5jbHVkZXMiLCJjYWxlbmRhcnNfYWxsX19zZXQiLCJjYWxlbmRhcnNfYWxsX19nZXQiLCJjYWxlbmRhcl9fZ2V0X3BhcmFtZXRlcnMiLCJjYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMiLCJjYWxlbmRhcl9wcm9wZXJ0eV9vYmoiLCJpc19jb21wbGV0ZV9vdmVyd3JpdGUiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJwcm9wX25hbWUiLCJjYWxlbmRhcl9fc2V0X3BhcmFtX3ZhbHVlIiwicHJvcF92YWx1ZSIsImNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUiLCJwYXJzZUludCIsInBfYm9va2luZ3MiLCJib29raW5nc19vYmoiLCJib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCIsImJvb2tpbmdzX2luX2NhbGVuZGFyX19nZXQiLCJib29raW5nc19pbl9jYWxlbmRhcl9fc2V0IiwiY2FsZW5kYXJfb2JqIiwiYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9kYXRlcyIsImJvb2tpbmdzX2luX2NhbGVuZGFyX19zZXRfZGF0ZXMiLCJkYXRlc19vYmoiLCJib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlIiwic3FsX2NsYXNzX2RheSIsImJvb2tpbmdfX3NldF9wYXJhbV92YWx1ZSIsImJvb2tpbmdfX2dldF9wYXJhbV92YWx1ZSIsImJvb2tpbmdzX2luX2NhbGVuZGFyc19fc2V0X2FsbCIsImJvb2tpbmdzX2luX2NhbGVuZGFyc19fZ2V0X2FsbCIsInBfc2Vhc29ucyIsInNlYXNvbnNfb2JqIiwic2Vhc29uc19fc2V0Iiwic2Vhc29uX25hbWVfa2V5IiwicHVzaCIsInNlYXNvbnNfX2dldF9mb3JfZGF0ZSIsInBfb3RoZXIiLCJvdGhlcl9vYmoiLCJzZXRfb3RoZXJfcGFyYW0iLCJnZXRfb3RoZXJfcGFyYW0iLCJnZXRfb3RoZXJfcGFyYW1fX2FsbCIsInBfbWVzc2FnZXMiLCJtZXNzYWdlc19vYmoiLCJzZXRfbWVzc2FnZSIsImdldF9tZXNzYWdlIiwiZ2V0X21lc3NhZ2VzX19hbGwiLCJqUXVlcnkiLCJwX2JhbGFuY2VyIiwiYmFsYW5jZXJfb2JqIiwiYmFsYW5jZXJfX3NldF9tYXhfdGhyZWFkcyIsIm1heF90aHJlYWRzIiwiYmFsYW5jZXJfX2lzX2RlZmluZWQiLCJiYWxhbmNlcl9faW5pdCIsImZ1bmN0aW9uX25
3411hbWUiLCJwYXJhbXMiLCJiYWxhbmNlX29iaiIsImJhbGFuY2VyX19pc19hbHJlYWR5X3J1biIsImJhbGFuY2VyX19pc19hbHJlYWR5X3dhaXQiLCJiYWxhbmNlcl9fY2FuX2lfcnVuIiwiYmFsYW5jZXJfX2FkZF90b19fcnVuIiwiYmFsYW5jZXJfX2FkZF90b19fd2FpdCIsImJhbGFuY2VyX19yZW1vdmVfZnJvbV9fd2FpdF9saXN0IiwicmVtb3ZlZF9lbCIsInNwbGljZSIsInBvcCIsImZpbHRlciIsInYiLCJiYWxhbmNlcl9fcmVtb3ZlX2Zyb21fX3J1bl9saXN0IiwiYmFsYW5jZXJfX3J1bl9uZXh0IiwiYmFsYW5jZXJfX3J1biIsIndwYmNfY2FsZW5kYXJfX2xvYWRfZGF0YV9fYWp4Iiwid3BiY19iYWxhbmNlcl9faXNfd2FpdCIsImJhbGFuY2VyX3N0YXR1cyIsIndwYmNfYmFsYW5jZXJfX2NvbXBsZXRlZCIsIndwYmNfY2FsZW5kYXJfc2hvdyIsImhhc0NsYXNzIiwibG9jYWxfX2lzX3JhbmdlX3NlbGVjdCIsImxvY2FsX19tdWx0aV9kYXlzX3NlbGVjdF9udW0iLCJsb2NhbF9fbWluX2RhdGUiLCJEYXRlIiwibG9jYWxfX21heF9kYXRlIiwid3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX3N0YXJ0Iiwid3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX2VuZCIsImxvY2F0aW9uIiwiaHJlZiIsImluZGV4T2YiLCJsb2NhbF9fc3RhcnRfd2Vla2RheSIsImxvY2FsX19udW1iZXJfb2ZfbW9udGhzIiwidGV4dCIsImRhdGVwaWNrIiwiYmVmb3JlU2hvd0RheSIsImpzX2RhdGUiLCJ3cGJjX19jYWxlbmRhcl9fYXBwbHlfY3NzX3RvX2RheXMiLCJvblNlbGVjdCIsInN0cmluZ19kYXRlcyIsImpzX2RhdGVzX2FyciIsIndwYmNfX2NhbGVuZGFyX19vbl9zZWxlY3RfZGF5cyIsIm9uSG92ZXIiLCJzdHJpbmdfZGF0ZSIsIndwYmNfX2NhbGVuZGFyX19vbl9ob3Zlcl9kYXlzIiwib25DaGFuZ2VNb250aFllYXIiLCJ5ZWFyIiwicmVhbF9tb250aCIsImpzX2RhdGVfXzFzdF9kYXlfaW5fbW9udGgiLCJzaG93T24iLCJudW1iZXJPZk1vbnRocyIsInN0ZXBNb250aHMiLCJwcmV2VGV4dCIsIm5leHRUZXh0IiwiZGF0ZUZvcm1hdCIsImNoYW5nZU1vbnRoIiwiY2hhbmdlWWVhciIsIm1pbkRhdGUiLCJtYXhEYXRlIiwic2hvd1N0YXR1cyIsIm11bHRpU2VwYXJhdG9yIiwiY2xvc2VBdFRvcCIsImZpcnN0RGF5IiwiZ290b0N1cnJlbnQiLCJoaWRlSWZOb1ByZXZOZXh0IiwibXVsdGlTZWxlY3QiLCJyYW5nZVNlbGVjdCIsInVzZVRoZW1lUm9sbGVyIiwic2V0VGltZW91dCIsIndwYmNfY2FsZW5kYXJzX19jbGVhcl9kYXlzX2hpZ2hsaWdodGluZyIsInN0YXJ0X2JrX21vbnRoIiwid3BiY19jYWxlbmRhcl9fc2Nyb2xsX3RvIiwiZGF0ZSIsImNhbGVuZGFyX3BhcmFtc19hcnIiLCJkYXRlcGlja190aGlzIiwidG9kYXlfZGF0ZSIsImNsYXNzX2RheSIsIndwYmNfX2dldF9fdGRfY2xhc3NfZGF0ZSIsIndwYmNfX2dldF9fc3FsX2NsYXNzX2RhdGUiLCJzZWxlY3RlZF9kYXRlc19zcWwiLCJ3cGJjX2dldF9fc2VsZWN0ZWRfZGF0ZXNfc3FsX19hc19hcnIiLCJkYXRlX2Jvb2tpbmdzX29iaiIsImNzc19jbGFzc2VzX19mb3JfZGF0ZSIsImdldERheSIsImlzX2RheV9zZWxlY3RhYmxlIiwic2Vhc29uX25hbWVzX2FyciIsInNlYXNvbl9rZXkiLCJ0b1N0cmluZyIsInJlcGxhY2UiLCJpc19zZXRfcGVuZGluZ19kYXlzX3NlbGVjdGFibGUiLCJkYXRlX2Jvb2tpbmdfb2JqIiwidG9vbHRpcF90ZXh0Iiwid3BiY19zZXRfdG9vbHRpcF9fX2Zvcl9fY2FsZW5kYXJfZGF0ZSIsImlzX3Vuc2VsZWN0YWJsZV9jYWxlbmRhciIsImlzX2Jvb2tpbmdfZm9ybV9leGlzdCIsImNzc19vZl9jYWxlbmRhciIsImNzcyIsIndwYmNfX2NhbGVuZGFyX19kb19kYXlzX2hpZ2hsaWdodF9fYnMiLCJ3cGJjX2NhbGVuZGFyX191bnNlbGVjdF9hbGxfZGF0ZXMiLCJyZW1vdmUiLCJ2YWwiLCJ3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19zZWxlY3RfX2JzIiwid3BiY19kaXNhYmxlX3RpbWVfZmllbGRzX2luX2Jvb2tpbmdfZm9ybSIsIm1vdXNlX2NsaWNrZWRfZGF0ZXMiLCJhbGxfc2VsZWN0ZWRfZGF0ZXNfYXJyIiwidHJpZ2dlciIsImRvY3VtZW50IiwicmVhZHkiLCJvbiIsImV2ZW50IiwiY2xvc2VkX3RpbWVyIiwibWlkZGxlX2RheXNfb3BhY2l0eSIsIm5vdCIsInRpbWVfZmllbGRzX29ial9hcnIiLCJ3cGJjX2dldF9fdGltZV9maWVsZHNfX2luX2Jvb2tpbmdfZm9ybV9fYXNfYXJyIiwic2VsZWN0ZWRfZGF0ZXNfYXJyIiwiY2hpbGRfcmVzb3VyY2VzX2FyciIsInNxbF9kYXRlIiwiY2hpbGRfcmVzb3VyY2VfaWQiLCJtZXJnZWRfc2Vjb25kcyIsInRpbWVfZmllbGRzX29iaiIsImlzX2ludGVyc2VjdCIsImlzX2NoZWNrX2luIiwidG9kYXlfdGltZV9fcmVhbCIsInRvZGF5X3RpbWVfX3NoaWZ0IiwiZmllbGRfa2V5IiwiZGlzYWJsZWQiLCJpc190aW1lX2luX3Bhc3QiLCJ3cGJjX2NoZWNrX2lzX3RpbWVfaW5fcGFzdCIsIm5hbWUiLCJob3dfbWFueV9yZXNvdXJjZXNfaW50ZXJzZWN0ZWQiLCJyZXNfa2V5IiwiYm9va2VkX3RpbWVfc2xvdHMiLCJ0aW1lc19hc19zZWNvbmRzIiwid3BiY19pc19pbnRlcnNlY3RfX3JhbmdlX3RpbWVfaW50ZXJ2YWwiLCJ3cGJjX2lzX2ludGVyc2VjdF9fb25lX3RpbWVfaW50ZXJ2YWwiLCJ3cGJjX19odG1sX190aW1lX2ZpZWxkX29wdGlvbnNfX3NldF9kaXNhYmxlZCIsImpzX2N1cnJlbnRfdGltZV90b19jaGVjayIsInNxbF9kYXRlX2FyciIsInNwbGl0Iiwic3FsX2RhdGVfX21pZG5pZ2h0Iiwic3FsX2RhdGVfX21pZG5pZ2h0X21pbGlzZWNvbmRzIiwiZ2V0VGltZSIsInRpbWVzX2FzX3NlY29uZHNfY2hlY2siLCJ0aW1lX0EiLCJ0aW1lX2ludGVydmFsX0IiLCJqIiwidGltZV9pbnRlcnZhbF9BIiwid3BiY19pbnRlcnZhbHNfX2lzX2ludGVyc2VjdGVkIiwidGltZV9maWVsZHNfYXJyIiwiY3RmIiwidGltZV9maWVsZCIsInRpbWVfb3B0aW9uIiwianF1ZXJ5X29wdGlvbiIsInZhbHVlX29wdGlvbl9zZWNvbmRzX2FyciIsInN0YXJ0X2VuZF90aW1lc19hcnIiLCJ0aW1lX2luX3NlY29uZHMiLCJhdHRyIiwicHJvcCIsImFkZENsYXNzIiwicGFyZW50IiwiZmluZCIsInJlbW92ZUNsYXNzIiwid3BiY19pc190aGlzX3RpbWVzbG90X19mdWxsX2RheV9ib29rZWQiLCJ0aW1lc2xvdF9hcnJfaW5fc2Vjb25kcyIsIm4iLCJzb3J0Iiwid3BiY19nZXRfX3NlbGVjdGVkX3RpbWVfZmllbGRzX19pbl9ib29raW5nX2Zvcm1fX2FzX2FyciIsImlzX29ubHlfc2VsZWN0ZWRfdGltZSIsInRleHRfdGltZV9maWVsZHNfYXJyIiwidGYiLCJ0ZXh0X2pxdWVyeSIsInRpbWVfX2hfbV9fYXJyIiwidGV4dF90aW1lX2luX3NlY29uZHMiLCJ0ZXh0X3RpbWVzX2FzX3
3411NlY29uZHMiLCJ3cGJjX2NhbGVuZGFyX19nZXRfaW5zdCIsIl9nZXRJbnN0IiwiZ2V0IiwiaW5zdCIsInN0YXlPcGVuIiwiZGF0ZXMiLCJfdXBkYXRlRGF0ZXBpY2siLCJtb250aCIsImN1cnNvckRhdGUiLCJzZXRGdWxsWWVhciIsInNldE1vbnRoIiwic2V0RGF0ZSIsImRyYXdNb250aCIsImdldE1vbnRoIiwiZHJhd1llYXIiLCJnZXRGdWxsWWVhciIsIl9ub3RpZnlDaGFuZ2UiLCJfYWRqdXN0SW5zdERhdGUiLCJfc2hvd0RhdGUiLCJ3cGJjX2lzX3RoaXNfZGF5X3NlbGVjdGFibGUiLCJ3cGJjX2lzX3RoaXNfZGF5X2Ftb25nX3NlbGVjdGVkX2RheXMiLCJqc19kYXRlX3RvX2NoZWNrIiwiZGF0ZV9pbmRleCIsImdldERhdGUiLCJ3cGJjX19nZXRfX2pzX2RhdGUiLCJzcWxfY2xhc3NfZGF0ZSIsInNxbF9jbGFzc19kYXRlX2FyciIsImRhdGVfanMiLCJzZXRIb3VycyIsInNldE1pbnV0ZXMiLCJzZXRTZWNvbmRzIiwic2V0TWlsbGlzZWNvbmRzIiwidGRfY2xhc3NfZGF5Iiwid3BiY19fZ2V0X19kYXRlX3BhcmFtc19fZnJvbV9zdHJpbmdfZGF0ZSIsInNlcGFyYXRvciIsImRhdGVfYXJyIiwiZGF0ZV9vYmoiLCJ3cGJjX2NhbGVuZGFyX19sb2FkaW5nX19zdGFydCIsIm5leHQiLCJhZnRlciIsIndwYmNfY2FsZW5kYXJfX2JsdXJfX3N0YXJ0Iiwid3BiY19jYWxlbmRhcl9fbG9hZGluZ19fc3RvcCIsIndwYmNfY2FsZW5kYXJfX2JsdXJfX3N0b3AiLCJ3cGJjX2NhbGVuZGFyX191cGRhdGVfbG9vayIsIndwYmNfY2FsZW5kYXJfX3VwZGF0ZV9tb250aHNfbnVtYmVyIiwibW9udGhzX251bWJlciIsInNldHRpbmdzIiwid3BiY19fY2FsZW5kYXJfX2NoYW5nZV9za2luIiwic2VsZWN0ZWRfc2tpbl91cmwiLCJzdHlsZXNoZWV0IiwiZ2V0RWxlbWVudEJ5SWQiLCJwYXJlbnROb2RlIiwicmVtb3ZlQ2hpbGQiLCJoZWFkSUQiLCJnZXRFbGVtZW50c0J5VGFnTmFtZSIsImNzc05vZGUiLCJjcmVhdGVFbGVtZW50IiwidHlwZSIsInNldEF0dHJpYnV0ZSIsInJlbCIsIm1lZGlhIiwiYXBwZW5kQ2hpbGQiLCJ3cGJjX19jc3NfX2NoYW5nZV9za2luIiwic3R5bGVzaGVldF9pZCIsIndwYmNfaW50ZXJ2YWxzX19tZXJnZV9pbmVyc2VjdGVkIiwiaW50ZXJ2YWxzIiwibWVyZ2VkIiwiYSIsImIiLCJtZXJnZWRJbnRlcnZhbCIsImludGVydmFsIiwiTWF0aCIsIm1heCIsImludGVydmFsX0EiLCJpbnRlcnZhbF9CIiwiaXNfaW50ZXJzZWN0ZWQiLCJtaW4iLCJ3cGJjX2dldF9hYnNfY2xvc2VzdF92YWx1ZV9pbl9hcnIiLCJteVZhbHVlIiwibXlBcnJheSIsImRpZmYiLCJhYnMiLCJjbG9zZXRWYWx1ZSIsInRkX2NsYXNzIiwidGRfZWwiLCJfdGlwcHkiLCJ3cGJjX3RpcHB5IiwiY29udGVudCIsInJlZmVyZW5jZSIsInBvcG92ZXJfY29udGVudCIsImdldEF0dHJpYnV0ZSIsImFsbG93SFRNTCIsImludGVyYWN0aXZlIiwiaGlkZU9uQ2xpY2siLCJpbnRlcmFjdGl2ZUJvcmRlciIsIm1heFdpZHRoIiwidGhlbWUiLCJwbGFjZW1lbnQiLCJkZWxheSIsImlnbm9yZUF0dHJpYnV0ZXMiLCJ0b3VjaCIsImFwcGVuZFRvIiwiYm9keSIsIndwYmNfZGF0ZXNfX2RheXNfYmV0d2VlbiIsImRhdGUxIiwiZGF0ZTIiLCJPTkVfREFZIiwiZGF0ZTFfbXMiLCJkYXRlMl9tcyIsImRpZmZlcmVuY2VfbXMiLCJyb3VuZCIsIndwYmNfZGF0ZXNfX2lzX2NvbnNlY3V0aXZlX2RhdGVzX2Fycl9yYW5nZSIsInNxbF9kYXRlc19hcnIiLCJwcmV2aW9zX2RhdGUiLCJjdXJyZW50X2RhdGUiLCJ3cGJjX2F1dG9fc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyIiwiY2hlY2tfaW5feW1kIiwiY2hlY2tfb3V0X3ltZCIsImNvbnNvbGUiLCJsb2ciLCJkYXRlc190b19zZWxlY3RfYXJyIiwid3BiY19jYWxfZGF5c19zZWxlY3RfX211bHRpcGxlIiwiY2hlY2tfaW5fanMiLCJ0ZF9jZWxsIiwid3BiY19nZXRfY2xpY2tlZF90ZCIsImlkIiwiX3NlbGVjdERheSIsImNoZWNrX291dF9qcyIsInRkX2NlbGxfb3V0IiwiZGF0ZXNfYXJyIiwid3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fYXJyIiwid3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fY2hlY2tfaW5fb3V0IiwiZGF0ZXNfanMiLCJzdHJfZGF0ZSIsImRheV9hdmFpbGFiaWxpdHkiLCJjaGVja19vdXRfZGF0ZSIsImNoZWNrb3V0X3RpbWVzdGFtcCIsImNhbGVuZGFyX2h0bWxfaWQiLCJvcmlnaW5hbF9hcnJheSIsImJrX2Rpc3RpbmN0X2RhdGVzIiwiY2hlY2tfaW5fZGF0ZSIsIm9yaWdpbmFsX2NoZWNrX2luX2RhdGUiLCJfcmVzdHJpY3RNaW5NYXgiLCJfZGV0ZXJtaW5lRGF0ZSIsImRhdGVfb3V0Iiwib3JpZ2luYWxfY2hlY2tfb3V0X2RhdGUiLCJtZXdEYXRlIiwib25lX2RhdGVfc3RyIiwiZCIsInVybF9wYXJhbXMiLCJVUkxTZWFyY2hQYXJhbXMiLCJ3aW5kb3ciLCJzZWFyY2giLCJoYXMiLCJzZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXJfaWQiLCJsb2FkZWRfcmVzb3VyY2VfaWQiLCJ3cGJjX2F1dG9fZmlsbF92YWx1ZSIsInJlcGxhY2VBbGwiLCJ3cGJjX2F1dG9fZmlsbF9ib29raW5nX2ZpZWxkcyIsImF1dG9fZmlsbF9zdHIiLCJmaWVsZHNfYXJyIiwid3BiY19hdXRvX2ZpbGxfYm9va2luZ19maWVsZHNfX3BhcnNlIiwiZGF0YV9zdHIiLCJmaWx0ZXJfb3B0aW9uc19hcnIiLCJkYXRhX2FyciIsIm15X2Zvcm1fZmllbGQiLCJmaWx0ZXJfbmFtZSIsImZpbHRlcl92YWx1ZSIsIndwYmNfYXV0b19maWxsX3NlYXJjaF9maWVsZHNfX3BhcnNlIiwiZmlsdGVyX3R5cGUiLCJ3cGJjX2NhbGVuZGFyX19hdXRvX3VwZGF0ZV9tb250aHNfbnVtYmVyX19vbl9yZXNpemUiLCJ3aWR0aCIsIndwYmNfY2FsZW5kYXJzX19hdXRvX3VwZGF0ZV9tb250aHNfbnVtYmVyIiwiYWxsX2NhbGVuZGFyc19hcnIiLCJjYWxlbmRhcl9pZCIsInNsaWNlIiwid3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVfcGFyYW1ldGVyIiwicGFyYW1ldGVyX3N0ciIsImRhdGVfZXhwZWN0ZWRfeW1kIiwiZGF0ZV9leHBlY3RlZF95bWRfYXJyIiwiZGF5Iiwid3BiY19jYWxfX3JlX2luaXQiLCJ3cGJjX2NhbF9kYXlzX3NlbGVjdF9fcmVfaW5pdCIsIndwYmNfY2FsX3JlYWR5X2RheXNfc2VsZWN0X19zaW5nbGUiLCJ3cGJjX2NhbF9kYXlzX3NlbGVjdF9fc2luZ2xlIiwid3BiY19jYWxfcmVhZHlfZGF5c19zZWxlY3RfX211bHRpcGxlIiwid3BiY19jYWxfcmVhZHlfZGF5c19zZWxlY3RfX2ZpeGVkIiwiZGF5c19udW1iZXIiLCJ3ZWVrX2RheXNfX3N0YXJ0Iiwid3BiY19jYWxfZGF5c19zZWxlY3RfX2ZpeGVkIiwid3BiY19jYWxfcmVhZHlfZGF5c19zZWxlY3RfX3JhbmdlIiwiZGF5c19taW4iLCJkYXlzX21heCIsImRheXNfc3BlY2lmaWMiLCJ3cGJjX2NhbF9kYXlzX3NlbGVjdF9fcmFuZ2UiLCJ0YXJnZXRfZWxtIiwiZGF0ZXNfc3RhcnQiLCJkYXRlc19lbmQiLCJncm91cENvbGxhcHNlZCIsIndwYmNfaG9va19faW5pdF90aW1lc2VsZWN0b3IiLCJwb3N0Iiwid3BiY191cmxfYWpheCIsImFjdGlvbiIsIndwYmNfYWp4X3VzZXJfaWQiLCJ3cGJjX2FqeF9sb2NhbGUiLCJjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyIsInJlc3BvbnNlX2RhdGEiLCJ0ZXh0U3RhdHVzIiwianFYSFIiLCJncm91cEVuZCIsImFqeF9wb3N0X2RhdGFfX3Jlc291cmNlX2lkIiwid3BiY19nZXRfcmVzb3VyY2VfaWRfX2Zyb21fYWp4X3Bvc3RfZGF0YV91cmwiLCJkYXRhIiwiX3R5cGVvZiIsImpxX25vZGUiLCJ3cGJjX2dldF9jYWxlbmRhcl9fanFfbm9kZV9fZm9yX21lc3NhZ2VzIiwibWVzc2FnZV90eXBlIiwid3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZSIsImZhaWwiLCJlcnJvclRocm93biIsImVycm9yX21lc3NhZ2UiLCJzdGF0dXMiLCJtZXNzYWdlX3Nob3dfZGVsYXkiLCJyZXNwb25zZVRleHQiLCJhanhfcG9zdF9kYXRhX3VybF9wYXJhbXMiLCJjYWxlbmRhcl9yZXNvdXJjZV9pZCIsIndwYmNfZ2V0X3VyaV9wYXJhbV9ieV9uYW1lIiwidXJsIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwicmVnZXgiLCJSZWdFeHAiLCJyZXN1bHRzIiwiZXhlYyIsIm1lc3NhZ2UiLCJwYXJhbXNfZGVmYXVsdCIsInBfa2V5IiwidW5
3411pcXVlX2Rpdl9pZCIsInNjcm9sbF90b19lbGVtZW50IiwianFfZWxfbWVzc2FnZSIsImlzX3Nob3dfbWVzc2FnZSIsImFwcGVuZCIsImh0bWwiLCJzaWJsaW5ncyIsImlzIiwiYmVmb3JlIiwibmV4dEFsbCIsImZhZGVPdXQiLCJjbG9zZWRfdGltZXIyIiwicGFyZW50X2VscyIsInBhcmVudHMiLCJtYXAiLCJzaG93Iiwid3BiY19kb19zY3JvbGwiLCJ3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlX19lcnJvciIsIm5vdGljZV9tZXNzYWdlX2lkIiwid3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZV9fZXJyb3JfdW5kZXJfZWxlbWVudCIsIm1lc3NhZ2VfZGVsYXkiLCJ3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlX19lcnJvcl9hYm92ZV9lbGVtZW50Iiwid3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZV9fd2FybmluZyIsIndwYmNfaGlnaGxpZ2h0X2Vycm9yX29uX2Zvcm1fZmllbGQiLCJ3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlX193YXJuaW5nX3VuZGVyX2VsZW1lbnQiLCJ3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlX193YXJuaW5nX2Fib3ZlX2VsZW1lbnQiLCJqcV9ub2RlX2FyciIsImV4dHJhX3NoaWZ0X29mZnNldCIsInRhcmdldE9mZnNldCIsIm9mZnNldCIsInRvcCIsImZpcnN0IiwiYW5pbWF0ZSIsInNjcm9sbFRvcCIsIndwYmNfZGVmaW5lX3RpcHB5X3BvcG92ZXIiLCJwb3BvdmVyX3RpdGxlIiwic3RhdGUiLCJpc1Zpc2libGUiLCJoaWRlIiwid3BiY19kZWZpbmVfaGlkZV90aXBweV9vbl9zY3JvbGwiLCJoaWRlQWxsIl0sInNvdXJjZXMiOlsid3BiY191dGlscy5qcyIsIndwYmMuanMiLCJhanhfbG9hZF9iYWxhbmNlci5qcyIsIndwYmNfY2FsLmpzIiwiZGF5c19zZWxlY3RfY3VzdG9tLmpzIiwid3BiY19jYWxfYWp4LmpzIiwid3BiY19mZV9tZXNzYWdlcy5qcyIsInRpbWVsaW5lX3BvcG92ZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKiBKYXZhU2NyaXB0IFV0aWwgRnVuY3Rpb25zXHRcdC4uL2luY2x1ZGVzL19fanMvdXRpbHMvd3BiY191dGlscy5qc1xyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICovXHJcblxyXG4vKipcclxuICogVHJpbSAgc3RyaW5ncyBhbmQgYXJyYXkgam9pbmVkIHdpdGggICgsKVxyXG4gKlxyXG4gKiBAcGFyYW0gc3RyaW5nX3RvX3RyaW0gICBzdHJpbmcgLyBhcnJheVxyXG4gKiBAcmV0dXJucyBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfdHJpbSggc3RyaW5nX3RvX3RyaW0gKXtcclxuXHJcbiAgICBpZiAoIEFycmF5LmlzQXJyYXkoIHN0cmluZ190b190cmltICkgKXtcclxuICAgICAgICBzdHJpbmdfdG9fdHJpbSA9IHN0cmluZ190b190cmltLmpvaW4oICcsJyApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICggJ3N0cmluZycgPT0gdHlwZW9mIChzdHJpbmdfdG9fdHJpbSkgKXtcclxuICAgICAgICBzdHJpbmdfdG9fdHJpbSA9IHN0cmluZ190b190cmltLnRyaW0oKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc3RyaW5nX3RvX3RyaW07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiBlbGVtZW50IGluIGFycmF5XHJcbiAqXHJcbiAqIEBwYXJhbSBhcnJheV9oZXJlXHRcdGFycmF5XHJcbiAqIEBwYXJhbSBwX3ZhbFx0XHRcdFx0ZWxlbWVudCB0byAgY2hlY2tcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2luX2FycmF5KCBhcnJheV9oZXJlLCBwX3ZhbCApe1xyXG5cdGZvciAoIHZhciBpID0gMCwgbCA9IGFycmF5X2hlcmUubGVuZ3RoOyBpIDwgbDsgaSsrICl7XHJcblx0XHRpZiAoIGFycmF5X2hlcmVbIGkgXSA9PSBwX3ZhbCApe1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIGZhbHNlO1xyXG59XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG4vKipcclxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqXHRpbmNsdWRlcy9fX2pzL3dwYmMvd3BiYy5qc1xyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICovXHJcblxyXG4vKipcclxuICogRGVlcCBDbG9uZSBvZiBvYmplY3Qgb3IgYXJyYXlcclxuICpcclxuICogQHBhcmFtIG9ialxyXG4gKiBAcmV0dXJucyB7YW55fVxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jbG9uZV9vYmooIG9iaiApe1xyXG5cclxuXHRyZXR1cm4gSlNPTi5wYXJzZSggSlNPTi5zdHJpbmdpZnkoIG9iaiApICk7XHJcbn1cclxuXHJcblxyXG5cclxuLyoqXHJcbiAqIE1haW4gX3dwYmMgSlMgb2JqZWN0XHJcbiAqL1xyXG5cclxudmFyIF93cGJjID0gKGZ1bmN0aW9uICggb2JqLCAkKSB7XHJcblxyXG5cdC8vIFNlY3VyZSBwYXJhbWV0ZXJzIGZvciBBamF4XHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHR2YXIgcF9zZWN1cmUgPSBvYmouc2VjdXJpdHlfb2JqID0gb2JqLnNlY3VyaXR5X29iaiB8fCB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHVzZXJfaWQ6IDAsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdG5vbmNlICA6ICcnLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRsb2NhbGUgOiAnJ1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICB9O1xyXG5cdG9iai5zZXRfc2VjdXJlX3BhcmFtID0gZnVuY3Rpb24gKCBwYXJhbV9rZXksIHBhcmFtX3ZhbCApIHtcclxuXHRcdH
3411Bfc2VjdXJlWyBwYXJhbV9rZXkgXSA9IHBhcmFtX3ZhbDtcclxuXHR9O1xyXG5cclxuXHRvYmouZ2V0X3NlY3VyZV9wYXJhbSA9IGZ1bmN0aW9uICggcGFyYW1fa2V5ICkge1xyXG5cdFx0cmV0dXJuIHBfc2VjdXJlWyBwYXJhbV9rZXkgXTtcclxuXHR9O1xyXG5cclxuXHJcblx0Ly8gQ2FsZW5kYXJzIFx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdHZhciBwX2NhbGVuZGFycyA9IG9iai5jYWxlbmRhcnNfb2JqID0gb2JqLmNhbGVuZGFyc19vYmogfHwge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBzb3J0ICAgICAgICAgICAgOiBcImJvb2tpbmdfaWRcIixcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gc29ydF90eXBlICAgICAgIDogXCJERVNDXCIsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIHBhZ2VfbnVtICAgICAgICA6IDEsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIHBhZ2VfaXRlbXNfY291bnQ6IDEwLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBjcmVhdGVfZGF0ZSAgICAgOiBcIlwiLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBrZXl3b3JkICAgICAgICAgOiBcIlwiLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBzb3VyY2UgICAgICAgICAgOiBcIlwiXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogIENoZWNrIGlmIGNhbGVuZGFyIGZvciBzcGVjaWZpYyBib29raW5nIHJlc291cmNlIGRlZmluZWQgICA6OiAgIHRydWUgfCBmYWxzZVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdG9iai5jYWxlbmRhcl9faXNfZGVmaW5lZCA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQgKSB7XHJcblxyXG5cdFx0cmV0dXJuICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mKCBwX2NhbGVuZGFyc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdICkgKTtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiAgQ3JlYXRlIENhbGVuZGFyIGluaXRpYWxpemluZ1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFxyXG5cdCAqL1xyXG5cdG9iai5jYWxlbmRhcl9faW5pdCA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQgKSB7XHJcblxyXG5cdFx0cF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXSA9IHt9O1xyXG5cdFx0cF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2lkJyBdID0gcmVzb3VyY2VfaWQ7XHJcblx0XHRwX2NhbGVuZGFyc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyAncGVuZGluZ19kYXlzX3NlbGVjdGFibGUnIF0gPSBmYWxzZTtcclxuXHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogQ2hlY2sgIGlmIHRoZSB0eXBlIG9mIHRoaXMgcHJvcGVydHkgIGlzIElOVFxyXG5cdCAqIEBwYXJhbSBwcm9wZXJ0eV9uYW1lXHJcblx0ICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0ICovXHJcblx0b2JqLmNhbGVuZGFyX19pc19wcm9wX2ludCA9IGZ1bmN0aW9uICggcHJvcGVydHlfbmFtZSApIHtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiA5LjkuMC4yOS5cclxuXHJcblx0XHR2YXIgcF9jYWxlbmRhcl9pbnRfcHJvcGVydGllcyA9IFsnZHluYW1pY19fZGF5c19taW4nLCAnZHluYW1pY19fZGF5c19tYXgnLCAnZml4ZWRfX2RheXNfbnVtJ107XHJcblxyXG5cdFx0dmFyIGlzX2luY2x1ZGUgPSBwX2NhbGVuZGFyX2ludF9wcm9wZXJ0aWVzLmluY2x1ZGVzKCBwcm9wZXJ0eV9uYW1lICk7XHJcblxyXG5cdFx0cmV0dXJuIGlzX2luY2x1ZGU7XHJcblx0fTtcclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCBwYXJhbXMgZm9yIGFsbCAgY2FsZW5kYXJzXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gY2FsZW5kYXJzX29ialx0XHRPYmplY3QgeyBjYWxlbmRhcl8xOiB7fSB9XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IGNhbGVuZGFyXzM6IHt9LCAuLi4gfVxyXG5cdCAqL1xyXG5cdG9iai5jYWxlbmRhcnNfYWxsX19zZXQgPSBmdW5jdGlvbiAoIGNhbGVuZGFyc19vYmogKSB7XHJcblx0XHRwX2NhbGVuZGFycyA9IGNhbGVuZGFyc19vYmo7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogR2V0IGJvb2tpbmdzIGluIGFsbCBjYWxlbmRhcnNcclxuXHQgKlxyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R8e319XHJcblx0ICovXHJcblx0b2JqLmNhbGVuZGFyc19hbGxfX2dldCA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdHJldHVybiBwX2NhbGVuZGFycztcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgY2FsZW5kYXIgb2JqZWN0ICAgOjogICB7IGlkOiAxLCDigKYgfVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdFx0ICAnMidcclxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fGJvb2xlYW59XHRcdFx0XHRcdHsgaWQ6IDIgLOKApiB9XHJcblx0ICovXHJcblx0b2JqLmNhbGVuZGFyX19nZXRfcGFyYW1ldGVycyA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQgKSB7XHJcblxyXG5cdFx0aWYgKCBvYmouY2FsZW5kYXJfX2lzX2RlZmluZWQoIHJlc291cmNlX2lkICkgKXtcclxuXHJcblx0XHRcdHJldHVybiBwX2NhbGVuZGFyc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCBjYWxlbmRhciBvYmplY3QgICA6OiAgIHsgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfVxyXG5cdCAqXHJcblx0ICogaWYgY2FsZW5kYXIgb2JqZWN0ICBub3QgZGVmaW5lZCwgdGhlbiAgaXQncyB3aWxsIGJlIGRlZmluZWQgYW5kIElEIHNldFxyXG5cdCAqIGlmIGNhbGVuZGFyIGV4aXN0LCB0aGVuICBzeXN0ZW0gc2V0ICBhcyBuZXcgb3Igb3ZlcndyaXRlIG9ubHkgcHJvcGVydGllcyBmcm9tIGNhbGVuZGFyX3Byb3BlcnR5X29iaiBwYXJhbWV0ZXIsICBidXQgb3RoZXIgcHJvcGVydGllcyB3aWxsIGJlIGV4aXN0ZWQgYW5kIG5vdCBvdmVyd3JpdGUsIGxpa2UgJ2lkJ1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdFx0ICAnMidcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gY2FsZW5kYXJfcHJvcGVydHlfb2JqXHRcdFx0XHRcdCAgeyAgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfSAgfVxyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNfY29tcGxldGVfb3ZlcndyaXRlXHRcdCAgaWYgJ3RydWUnIChkZWZhdWx0OiAnZmFsc2UnKSwgIHRoZW4gIG9ubHkgb3ZlcndyaXRlIG9yIGFkZCAgbmV3IHByb3BlcnRpZXMgaW4gIGNhbGVuZGFyX3Byb3BlcnR5X29ialxyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqXHJcblx0ICogRXhhbXBsZXM6XHJcblx0ICpcclxuXHQgKiBDb21tb24gdXNhZ2UgaW4gUEhQOlxyXG5cdCAqICAgXHRcdFx0ZWNobyBcIiAgX3dwYmMuY2FsZW5kYXJfX3NldCggIFwiIC5pbnR2YWw
3411oICRyZXNvdXJjZV9pZCApIC4gXCIsIHsgJ2RhdGVzJzogXCIgLiB3cF9qc29uX2VuY29kZSggJGF2YWlsYWJpbGl0eV9wZXJfZGF5c19hcnIgKSAuIFwiIH0gKTtcIjtcclxuXHQgKi9cclxuXHRvYmouY2FsZW5kYXJfX3NldF9wYXJhbWV0ZXJzID0gZnVuY3Rpb24gKCByZXNvdXJjZV9pZCwgY2FsZW5kYXJfcHJvcGVydHlfb2JqLCBpc19jb21wbGV0ZV9vdmVyd3JpdGUgPSBmYWxzZSAgKSB7XHJcblxyXG5cdFx0aWYgKCAoIW9iai5jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSkgfHwgKHRydWUgPT09IGlzX2NvbXBsZXRlX292ZXJ3cml0ZSkgKXtcclxuXHRcdFx0b2JqLmNhbGVuZGFyX19pbml0KCByZXNvdXJjZV9pZCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZvciAoIHZhciBwcm9wX25hbWUgaW4gY2FsZW5kYXJfcHJvcGVydHlfb2JqICl7XHJcblxyXG5cdFx0XHRwX2NhbGVuZGFyc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyBwcm9wX25hbWUgXSA9IGNhbGVuZGFyX3Byb3BlcnR5X29ialsgcHJvcF9uYW1lIF07XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHBfY2FsZW5kYXJzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF07XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogU2V0IHByb3BlcnR5ICB0byAgY2FsZW5kYXJcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcdFwiMVwiXHJcblx0ICogQHBhcmFtIHByb3BfbmFtZVx0XHRuYW1lIG9mIHByb3BlcnR5XHJcblx0ICogQHBhcmFtIHByb3BfdmFsdWVcdHZhbHVlIG9mIHByb3BlcnR5XHJcblx0ICogQHJldHVybnMgeyp9XHRcdFx0Y2FsZW5kYXIgb2JqZWN0XHJcblx0ICovXHJcblx0b2JqLmNhbGVuZGFyX19zZXRfcGFyYW1fdmFsdWUgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBwcm9wX25hbWUsIHByb3BfdmFsdWUgKSB7XHJcblxyXG5cdFx0aWYgKCAoIW9iai5jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSkgKXtcclxuXHRcdFx0b2JqLmNhbGVuZGFyX19pbml0KCByZXNvdXJjZV9pZCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHBfY2FsZW5kYXJzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdID0gcHJvcF92YWx1ZTtcclxuXHJcblx0XHRyZXR1cm4gcF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXTtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGNhbGVuZGFyIHByb3BlcnR5IHZhbHVlICAgXHQ6OiAgIG1peGVkIHwgbnVsbFxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSAgcmVzb3VyY2VfaWRcdFx0JzEnXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHByb3BfbmFtZVx0XHRcdCdzZWxlY3Rpb25fbW9kZSdcclxuXHQgKiBAcmV0dXJucyB7KnxudWxsfVx0XHRcdFx0XHRtaXhlZCB8IG51bGxcclxuXHQgKi9cclxuXHRvYmouY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSA9IGZ1bmN0aW9uKCByZXNvdXJjZV9pZCwgcHJvcF9uYW1lICl7XHJcblxyXG5cdFx0aWYgKFxyXG5cdFx0XHQgICAoIG9iai5jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSApXHJcblx0XHRcdCYmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHBfY2FsZW5kYXJzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdICkgKVxyXG5cdFx0KXtcclxuXHRcdFx0Ly8gRml4SW46IDkuOS4wLjI5LlxyXG5cdFx0XHRpZiAoIG9iai5jYWxlbmRhcl9faXNfcHJvcF9pbnQoIHByb3BfbmFtZSApICl7XHJcblx0XHRcdFx0cF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgcHJvcF9uYW1lIF0gPSBwYXJzZUludCggcF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgcHJvcF9uYW1lIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gIHBfY2FsZW5kYXJzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBudWxsO1x0XHQvLyBJZiBzb21lIHByb3BlcnR5IG5vdCBkZWZpbmVkLCB0aGVuIG51bGw7XHJcblx0fTtcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHJcblx0Ly8gQm9va2luZ3MgXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0dmFyIHBfYm9va2luZ3MgPSBvYmouYm9va2luZ3Nfb2JqID0gb2JqLmJvb2tpbmdzX29iaiB8fCB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gY2FsZW5kYXJfMTogT2JqZWN0IHtcclxuIFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly9cdFx0XHRcdFx0XHQgICBpZDogICAgIDFcclxuIFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly9cdFx0XHRcdFx0XHQgLCBkYXRlczogIE9iamVjdCB7IFwiMjAyMy0wNy0yMVwiOiB74oCmfSwgXCIyMDIzLTA3LTIyXCI6IHvigKZ9LCBcIjIwMjMtMDctMjNcIjoge+KApn0sIOKAplxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogIENoZWNrIGlmIGJvb2tpbmdzIGZvciBzcGVjaWZpYyBib29raW5nIHJlc291cmNlIGRlZmluZWQgICA6OiAgIHRydWUgfCBmYWxzZVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQgKSB7XHJcblxyXG5cdFx0cmV0dXJuICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mKCBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF0gKSApO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBib29raW5ncyBjYWxlbmRhciBvYmplY3QgICA6OiAgIHsgaWQ6IDEgLCBkYXRlczogIE9iamVjdCB7IFwiMjAyMy0wNy0yMVwiOiB74oCmfSwgXCIyMDIzLTA3LTIyXCI6IHvigKZ9LCBcIjIwMjMtMDctMjNcIjoge+KApn0sIOKApiB9XHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge3N0cmluZ3xpbnR9IHJlc291cmNlX2lkXHRcdFx0XHQgICcyJ1xyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R8Ym9vbGVhbn1cdFx0XHRcdFx0eyBpZDogMiAsIGRhdGVzOiAgT2JqZWN0IHsgXCIyMDIzLTA3LTIxXCI6IHvigKZ9LCBcIjIwMjMtMDctMjJcIjoge+KApn0sIFwiMjAyMy0wNy0yM1wiOiB74oCmfSwg4oCmIH1cclxuXHQgKi9cclxuXHRvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldCA9IGZ1bmN0aW9uKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRcdGlmICggb2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19pc19kZWZpbmVkKCByZXNvdXJjZV9pZCApICl7XHJcblxyXG5cdFx0XHRyZXR1cm4gcF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCBib29raW5ncyBjYWxlbmRhciBvYmplY3QgICA6OiAgIHsgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfVxyXG5cdCAqXHJcblx0ICogaWYgY2FsZW5kYXIgb2JqZWN0ICBub3QgZGVmaW5lZCwgdGhlbiAgaXQncyB3aWxsIGJlIGRlZmluZWQgYW5kIElEIHNldFxyXG5cdCAqIGlmIGNhbGVuZGFyIGV4aXN0LCB0aGVuICBzeXN0ZW0gc2V0ICBhcyBuZXcgb3Igb3ZlcndyaXRlIG9ubHkgcHJvcGVydGllcyBmcm9tIGNhbGVuZGFyX29iaiBwYXJhbWV0ZXIsICBidXQgb3RoZXIgcHJvcGVydGllcyB3aWxsIGJlIGV4aXN0ZWQgYW5kIG5vdCBvdmVyd3JpdGUsIGxpa2UgJ2lkJ1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdFx0ICAnMidcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gY2FsZW5kYXJfb2JqXHRcdFx0XHRcdCAgeyAgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfSAgfVxyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqXHJcblx0ICogRXhhbXBsZXM6XHJcblx0ICpcclxuXHQgKiBDb21tb24gdXNhZ2UgaW4gUEhQOlxyXG5cdCAqICAgXHRcdFx0ZWNobyBcIiAgX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX3NldCggIFwiIC5pbnR2YWw
3411oICRyZXNvdXJjZV9pZCApIC4gXCIsIHsgJ2RhdGVzJzogXCIgLiB3cF9qc29uX2VuY29kZSggJGF2YWlsYWJpbGl0eV9wZXJfZGF5c19hcnIgKSAuIFwiIH0gKTtcIjtcclxuXHQgKi9cclxuXHRvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJfX3NldCA9IGZ1bmN0aW9uKCByZXNvdXJjZV9pZCwgY2FsZW5kYXJfb2JqICl7XHJcblxyXG5cdFx0aWYgKCAhIG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSApe1xyXG5cdFx0XHRwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF0gPSB7fTtcclxuXHRcdFx0cF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyAnaWQnIF0gPSByZXNvdXJjZV9pZDtcclxuXHRcdH1cclxuXHJcblx0XHRmb3IgKCB2YXIgcHJvcF9uYW1lIGluIGNhbGVuZGFyX29iaiApe1xyXG5cclxuXHRcdFx0cF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyBwcm9wX25hbWUgXSA9IGNhbGVuZGFyX29ialsgcHJvcF9uYW1lIF07XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXTtcclxuXHR9O1xyXG5cclxuXHQvLyBEYXRlc1xyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGJvb2tpbmdzIGRhdGEgZm9yIEFMTCBEYXRlcyBpbiBjYWxlbmRhciAgIDo6ICAgZmFsc2UgfCB7IFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdCcxJ1xyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R8Ym9vbGVhbn1cdFx0XHRcdGZhbHNlIHwgT2JqZWN0IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIjIwMjMtMDctMjRcIjogT2JqZWN0IHsgWydzdW1tYXJ5J11bJ3N0YXR1c19mb3JfZGF5J106IFwiYXZhaWxhYmxlXCIsIGRheV9hdmFpbGFiaWxpdHk6IDEsIG1heF9jYXBhY2l0eTogMSwg4oCmIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIjIwMjMtMDctMjZcIjogT2JqZWN0IHsgWydzdW1tYXJ5J11bJ3N0YXR1c19mb3JfZGF5J106IFwiZnVsbF9kYXlfYm9va2luZ1wiLCBbJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncyddOiBcInBlbmRpbmdcIiwgZGF5X2F2YWlsYWJpbGl0eTogMCwg4oCmIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIjIwMjMtMDctMjlcIjogT2JqZWN0IHsgWydzdW1tYXJ5J11bJ3N0YXR1c19mb3JfZGF5J106IFwicmVzb3VyY2VfYXZhaWxhYmlsaXR5XCIsIGRheV9hdmFpbGFiaWxpdHk6IDAsIG1heF9jYXBhY2l0eTogMSwg4oCmIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIjIwMjMtMDctMzBcIjoge+KApn0sIFwiMjAyMy0wNy0zMVwiOiB74oCmfSwg4oCmXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cclxuXHQgKi9cclxuXHRvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9kYXRlcyA9IGZ1bmN0aW9uKCByZXNvdXJjZV9pZCl7XHJcblxyXG5cdFx0aWYgKFxyXG5cdFx0XHQgICAoIG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSApXHJcblx0XHRcdCYmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2RhdGVzJyBdICkgKVxyXG5cdFx0KXtcclxuXHRcdFx0cmV0dXJuICBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdkYXRlcycgXTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZmFsc2U7XHRcdC8vIElmIHNvbWUgcHJvcGVydHkgbm90IGRlZmluZWQsIHRoZW4gZmFsc2U7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogU2V0IGJvb2tpbmdzIGRhdGVzIGluIGNhbGVuZGFyIG9iamVjdCAgIDo6ICAgIHsgXCIyMDIzLTA3LTIxXCI6IHvigKZ9LCBcIjIwMjMtMDctMjJcIjoge+KApn0sIFwiMjAyMy0wNy0yM1wiOiB74oCmfSwg4oCmIH1cclxuXHQgKlxyXG5cdCAqIGlmIGNhbGVuZGFyIG9iamVjdCAgbm90IGRlZmluZWQsIHRoZW4gIGl0J3Mgd2lsbCBiZSBkZWZpbmVkIGFuZCAnaWQnLCAnZGF0ZXMnIHNldFxyXG5cdCAqIGlmIGNhbGVuZGFyIGV4aXN0LCB0aGVuIHN5c3RlbSBhZGQgYSAgbmV3IG9yIG92ZXJ3cml0ZSBvbmx5IGRhdGVzIGZyb20gZGF0ZXNfb2JqIHBhcmFtZXRlcixcclxuXHQgKiBidXQgb3RoZXIgZGF0ZXMgbm90IGZyb20gcGFyYW1ldGVyIGRhdGVzX29iaiB3aWxsIGJlIGV4aXN0ZWQgYW5kIG5vdCBvdmVyd3JpdGUuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge3N0cmluZ3xpbnR9IHJlc291cmNlX2lkXHRcdFx0XHQgICcyJ1xyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBkYXRlc19vYmpcdFx0XHRcdFx0ICB7IFwiMjAyMy0wNy0yMVwiOiB74oCmfSwgXCIyMDIzLTA3LTIyXCI6IHvigKZ9LCBcIjIwMjMtMDctMjNcIjoge+KApn0sIOKApiB9XHJcblx0ICogQHBhcmFtIHtib29sZWFufSBpc19jb21wbGV0ZV9vdmVyd3JpdGVcdFx0ICBpZiBmYWxzZSwgIHRoZW4gIG9ubHkgb3ZlcndyaXRlIG9yIGFkZCAgZGF0ZXMgZnJvbSBcdGRhdGVzX29ialxyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqXHJcblx0ICogRXhhbXBsZXM6XHJcblx0ICogICBcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fc2V0X2RhdGVzKCByZXNvdXJjZV9pZCwgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwg4oCmIH0gICk7XHRcdDwtICAgb3ZlcndyaXRlIEFMTCBkYXRlc1xyXG5cdCAqICAgXHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX3NldF9kYXRlcyggcmVzb3VyY2VfaWQsIHsgXCIyMDIzLTA3LTIyXCI6IHvigKZ9IH0sICBmYWxzZSAgKTtcdFx0XHRcdFx0PC0gICBhZGQgb3Igb3ZlcndyaXRlIG9ubHkgIFx0XCIyMDIzLTA3LTIyXCI6IHt9XHJcblx0ICpcclxuXHQgKiBDb21tb24gdXNhZ2UgaW4gUEhQOlxyXG5cdCAqICAgXHRcdFx0ZWNobyBcIiAgX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX3NldF9kYXRlcyggIFwiIC4gaW50dmFsKCAkcmVzb3VyY2VfaWQgKSAuIFwiLCAgXCIgLiB3cF9qc29uX2VuY29kZSggJGF2YWlsYWJpbGl0eV9wZXJfZGF5c19hcnIgKSAuIFwiICApOyAgXCI7XHJcblx0ICovXHJcblx0b2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19zZXRfZGF0ZXMgPSBmdW5jdGlvbiggcmVzb3VyY2VfaWQsIGRhdGVzX29iaiAsIGlzX2NvbXBsZXRlX292ZXJ3cml0ZSA9IHRydWUgKXtcclxuXHJcblx0XHRpZiAoICFvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJfX2lzX2RlZmluZWQoIHJlc291cmNlX2lkICkgKXtcclxuXHRcdFx0b2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19zZXQoIHJlc291cmNlX2lkLCB7ICdkYXRlcyc6IHt9IH0gKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoICd1bmRlZmluZWQnID09PSB0eXBlb2YgKHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2RhdGVzJyBdKSApe1xyXG5cdFx0XHRwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdkYXRlcycgXSA9IHt9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGlzX2NvbXBsZXRlX292ZXJ3cml0ZSl7XHJcblxyXG5cdFx0XHQvLyBDb21wbGV0ZSBvdmVyd3JpdGUgYWxsICBib29raW5nIGRhdGVzXHJcblx0XHRcdHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2RhdGVzJyBdID0gZGF0ZXNfb2JqO1xyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIEFkZCBvbmx5ICBuZXcgb3Igb3ZlcndyaXRlIGV4aXN0IGJvb2tpbmcgZGF0ZXMgZnJvbSAgcGFyYW1ldGVyLiBCb29raW5nIGRhdGVzIG5vdCBmcm9tICBwYXJhbWV0ZXIgIHdpbGwgIGJlIHdpdGhvdXQgY2huYW5nZXNcclxuXHRcdFx0Zm9yICggdmFyIHByb3BfbmFtZSBpbiBkYXRlc19vYmogKXtcclxuXHJcblx0XHRcdFx0cF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWydkYXRlcyddWy
3411Bwcm9wX25hbWUgXSA9IGRhdGVzX29ialsgcHJvcF9uYW1lIF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gcF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdO1xyXG5cdH07XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGJvb2tpbmdzIGRhdGEgZm9yIHNwZWNpZmljIGRhdGUgaW4gY2FsZW5kYXIgICA6OiAgIGZhbHNlIHwgeyBkYXlfYXZhaWxhYmlsaXR5OiAxLCAuLi4gfVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdCcxJ1xyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzcWxfY2xhc3NfZGF5XHRcdFx0JzIwMjMtMDctMjEnXHJcblx0ICogQHJldHVybnMge29iamVjdHxib29sZWFufVx0XHRcdFx0ZmFsc2UgfCB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGRheV9hdmFpbGFiaWxpdHk6IDRcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWF4X2NhcGFjaXR5OiA0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gID49IEJ1c2luZXNzIExhcmdlXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdDI6IE9iamVjdCB7IGlzX2RheV91bmF2YWlsYWJsZTogZmFsc2UsIF9kYXlfc3RhdHVzOiBcImF2YWlsYWJsZVwiIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0MTA6IE9iamVjdCB7IGlzX2RheV91bmF2YWlsYWJsZTogZmFsc2UsIF9kYXlfc3RhdHVzOiBcImF2YWlsYWJsZVwiIH1cdFx0Ly8gID49IEJ1c2luZXNzIExhcmdlIC4uLlxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQxMTogT2JqZWN0IHsgaXNfZGF5X3VuYXZhaWxhYmxlOiBmYWxzZSwgX2RheV9zdGF0dXM6IFwiYXZhaWxhYmxlXCIgfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQxMjogT2JqZWN0IHsgaXNfZGF5X3VuYXZhaWxhYmxlOiBmYWxzZSwgX2RheV9zdGF0dXM6IFwiYXZhaWxhYmxlXCIgfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdCAqL1xyXG5cdG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlID0gZnVuY3Rpb24oIHJlc291cmNlX2lkLCBzcWxfY2xhc3NfZGF5ICl7XHJcblxyXG5cdFx0aWYgKFxyXG5cdFx0XHQgICAoIG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSApXHJcblx0XHRcdCYmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2RhdGVzJyBdICkgKVxyXG5cdFx0XHQmJiAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YgKCBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdkYXRlcycgXVsgc3FsX2NsYXNzX2RheSBdICkgKVxyXG5cdFx0KXtcclxuXHRcdFx0cmV0dXJuICBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdkYXRlcycgXVsgc3FsX2NsYXNzX2RheSBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBmYWxzZTtcdFx0Ly8gSWYgc29tZSBwcm9wZXJ0eSBub3QgZGVmaW5lZCwgdGhlbiBmYWxzZTtcclxuXHR9O1xyXG5cclxuXHJcblx0Ly8gQW55ICBQQVJBTVMgICBpbiBib29raW5nc1xyXG5cclxuXHQvKipcclxuXHQgKiBTZXQgcHJvcGVydHkgIHRvICBib29raW5nXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHRcIjFcIlxyXG5cdCAqIEBwYXJhbSBwcm9wX25hbWVcdFx0bmFtZSBvZiBwcm9wZXJ0eVxyXG5cdCAqIEBwYXJhbSBwcm9wX3ZhbHVlXHR2YWx1ZSBvZiBwcm9wZXJ0eVxyXG5cdCAqIEByZXR1cm5zIHsqfVx0XHRcdGJvb2tpbmcgb2JqZWN0XHJcblx0ICovXHJcblx0b2JqLmJvb2tpbmdfX3NldF9wYXJhbV92YWx1ZSA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQsIHByb3BfbmFtZSwgcHJvcF92YWx1ZSApIHtcclxuXHJcblx0XHRpZiAoICEgb2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19pc19kZWZpbmVkKCByZXNvdXJjZV9pZCApICl7XHJcblx0XHRcdHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXSA9IHt9O1xyXG5cdFx0XHRwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdpZCcgXSA9IHJlc291cmNlX2lkO1xyXG5cdFx0fVxyXG5cclxuXHRcdHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgcHJvcF9uYW1lIF0gPSBwcm9wX3ZhbHVlO1xyXG5cclxuXHRcdHJldHVybiBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF07XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogIEdldCBib29raW5nIHByb3BlcnR5IHZhbHVlICAgXHQ6OiAgIG1peGVkIHwgbnVsbFxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSAgcmVzb3VyY2VfaWRcdFx0JzEnXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHByb3BfbmFtZVx0XHRcdCdzZWxlY3Rpb25fbW9kZSdcclxuXHQgKiBAcmV0dXJucyB7KnxudWxsfVx0XHRcdFx0XHRtaXhlZCB8IG51bGxcclxuXHQgKi9cclxuXHRvYmouYm9va2luZ19fZ2V0X3BhcmFtX3ZhbHVlID0gZnVuY3Rpb24oIHJlc291cmNlX2lkLCBwcm9wX25hbWUgKXtcclxuXHJcblx0XHRpZiAoXHJcblx0XHRcdCAgICggb2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19pc19kZWZpbmVkKCByZXNvdXJjZV9pZCApIClcclxuXHRcdFx0JiYgKCAndW5kZWZpbmVkJyAhPT0gdHlwZW9mICggcF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyBwcm9wX25hbWUgXSApIClcclxuXHRcdCl7XHJcblx0XHRcdHJldHVybiAgcF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyBwcm9wX25hbWUgXTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbnVsbDtcdFx0Ly8gSWYgc29tZSBwcm9wZXJ0eSBub3QgZGVmaW5lZCwgdGhlbiBudWxsO1xyXG5cdH07XHJcblxyXG5cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCBib29raW5ncyBmb3IgYWxsICBjYWxlbmRhcnNcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBjYWxlbmRhcnNfb2JqXHRcdE9iamVjdCB7IGNhbGVuZGFyXzE6IHsgaWQ6IDEsIGRhdGVzOiBPYmplY3QgeyBcIjIwMjMtMDctMjJcIjoge+KApn0sIFwiMjAyMy0wNy0yM1wiOiB74oCmfSwgXCIyMDIzLTA3LTI0XCI6IHvigKZ9LCDigKYgfSB9XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IGNhbGVuZGFyXzM6IHt9LCAuLi4gfVxyXG5cdCAqL1xyXG5cdG9iai5ib29raW5nc19pbl9jYWxlbmRhcnNfX3NldF9hbGwgPSBmdW5jdGlvbiAoIGNhbGVuZGFyc19vYmogKSB7XHJcblx0XHRwX2Jvb2tpbmdzID0gY2FsZW5kYXJzX29iajtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgYm9va2luZ3MgaW4gYWxsIGNhbGVuZGFyc1xyXG5cdCAqXHJcblx0ICogQHJldHVybnMge29iamVjdHx7fX1cclxuXHQgKi9cclxuXHRvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJzX19nZXRfYWxsID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0cmV0dXJuIHBfYm9va2luZ3M7XHJcblx0fTtcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHJcblxyXG5cclxuXHQvLyBTZWFzb25zIFx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdHZhciBwX3NlYXNvbnMgPSBvYmouc2Vhc29uc19vYmogPSBvYmouc2Vhc29uc19vYmogfHwge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGNhbGVuZGFyXzE6IE9iamVjdCB7X
3411HJcbiBcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vXHRcdFx0XHRcdFx0ICAgaWQ6ICAgICAxXHJcbiBcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vXHRcdFx0XHRcdFx0ICwgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKZcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEFkZCBzZWFzb24gbmFtZXMgZm9yIGRhdGVzIGluIGNhbGVuZGFyIG9iamVjdCAgIDo6ICAgIHsgXCIyMDIzLTA3LTIxXCI6IFsgJ3dwYmNfc2Vhc29uX3NlcHRlbWJlcl8yMDIzJywgJ3dwYmNfc2Vhc29uX3NlcHRlbWJlcl8yMDI0JyBdLCBcIjIwMjMtMDctMjJcIjogWy4uLl0sIC4uLiB9XHJcblx0ICpcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfGludH0gcmVzb3VyY2VfaWRcdFx0XHRcdCAgJzInXHJcblx0ICogQHBhcmFtIHtvYmplY3R9IGRhdGVzX29ialx0XHRcdFx0XHQgIHsgXCIyMDIzLTA3LTIxXCI6IHvigKZ9LCBcIjIwMjMtMDctMjJcIjoge+KApn0sIFwiMjAyMy0wNy0yM1wiOiB74oCmfSwg4oCmIH1cclxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGlzX2NvbXBsZXRlX292ZXJ3cml0ZVx0XHQgIGlmIGZhbHNlLCAgdGhlbiAgb25seSAgYWRkICBkYXRlcyBmcm9tIFx0ZGF0ZXNfb2JqXHJcblx0ICogQHJldHVybnMgeyp9XHJcblx0ICpcclxuXHQgKiBFeGFtcGxlczpcclxuXHQgKiAgIFx0XHRcdF93cGJjLnNlYXNvbnNfX3NldCggcmVzb3VyY2VfaWQsIHsgXCIyMDIzLTA3LTIxXCI6IFsgJ3dwYmNfc2Vhc29uX3NlcHRlbWJlcl8yMDIzJywgJ3dwYmNfc2Vhc29uX3NlcHRlbWJlcl8yMDI0JyBdLCBcIjIwMjMtMDctMjJcIjogWy4uLl0sIC4uLiB9ICApO1xyXG5cdCAqL1xyXG5cdG9iai5zZWFzb25zX19zZXQgPSBmdW5jdGlvbiggcmVzb3VyY2VfaWQsIGRhdGVzX29iaiAsIGlzX2NvbXBsZXRlX292ZXJ3cml0ZSA9IGZhbHNlICl7XHJcblxyXG5cdFx0aWYgKCAndW5kZWZpbmVkJyA9PT0gdHlwZW9mIChwX3NlYXNvbnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXSkgKXtcclxuXHRcdFx0cF9zZWFzb25zWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF0gPSB7fTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGlzX2NvbXBsZXRlX292ZXJ3cml0ZSApe1xyXG5cclxuXHRcdFx0Ly8gQ29tcGxldGUgb3ZlcndyaXRlIGFsbCAgc2Vhc29uIGRhdGVzXHJcblx0XHRcdHBfc2Vhc29uc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdID0gZGF0ZXNfb2JqO1xyXG5cclxuXHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHQvLyBBZGQgb25seSAgbmV3IG9yIG92ZXJ3cml0ZSBleGlzdCBib29raW5nIGRhdGVzIGZyb20gIHBhcmFtZXRlci4gQm9va2luZyBkYXRlcyBub3QgZnJvbSAgcGFyYW1ldGVyICB3aWxsICBiZSB3aXRob3V0IGNobmFuZ2VzXHJcblx0XHRcdGZvciAoIHZhciBwcm9wX25hbWUgaW4gZGF0ZXNfb2JqICl7XHJcblxyXG5cdFx0XHRcdGlmICggJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiAocF9zZWFzb25zWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdKSApe1xyXG5cdFx0XHRcdFx0cF9zZWFzb25zWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdID0gW107XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGZvciAoIHZhciBzZWFzb25fbmFtZV9rZXkgaW4gZGF0ZXNfb2JqWyBwcm9wX25hbWUgXSApe1xyXG5cdFx0XHRcdFx0cF9zZWFzb25zWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdLnB1c2goIGRhdGVzX29ialsgcHJvcF9uYW1lIF1bIHNlYXNvbl9uYW1lX2tleSBdICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHBfc2Vhc29uc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdO1xyXG5cdH07XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGJvb2tpbmdzIGRhdGEgZm9yIHNwZWNpZmljIGRhdGUgaW4gY2FsZW5kYXIgICA6OiAgIFtdIHwgWyAnd3BiY19zZWFzb25fc2VwdGVtYmVyXzIwMjMnLCAnd3BiY19zZWFzb25fc2VwdGVtYmVyXzIwMjQnIF1cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfGludH0gcmVzb3VyY2VfaWRcdFx0XHQnMSdcclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3FsX2NsYXNzX2RheVx0XHRcdCcyMDIzLTA3LTIxJ1xyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R8Ym9vbGVhbn1cdFx0XHRcdFtdICB8ICBbICd3cGJjX3NlYXNvbl9zZXB0ZW1iZXJfMjAyMycsICd3cGJjX3NlYXNvbl9zZXB0ZW1iZXJfMjAyNCcgXVxyXG5cdCAqL1xyXG5cdG9iai5zZWFzb25zX19nZXRfZm9yX2RhdGUgPSBmdW5jdGlvbiggcmVzb3VyY2VfaWQsIHNxbF9jbGFzc19kYXkgKXtcclxuXHJcblx0XHRpZiAoXHJcblx0XHRcdCAgICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHBfc2Vhc29uc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdICkgKVxyXG5cdFx0XHQmJiAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YgKCBwX3NlYXNvbnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgc3FsX2NsYXNzX2RheSBdICkgKVxyXG5cdFx0KXtcclxuXHRcdFx0cmV0dXJuICBwX3NlYXNvbnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgc3FsX2NsYXNzX2RheSBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBbXTtcdFx0Ly8gSWYgbm90IGRlZmluZWQsIHRoZW4gW107XHJcblx0fTtcclxuXHJcblxyXG5cdC8vIE90aGVyIHBhcmFtZXRlcnMgXHRcdFx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0dmFyIHBfb3RoZXIgPSBvYmoub3RoZXJfb2JqID0gb2JqLm90aGVyX29iaiB8fCB7IH07XHJcblxyXG5cdG9iai5zZXRfb3RoZXJfcGFyYW0gPSBmdW5jdGlvbiAoIHBhcmFtX2tleSwgcGFyYW1fdmFsICkge1xyXG5cdFx0cF9vdGhlclsgcGFyYW1fa2V5IF0gPSBwYXJhbV92YWw7XHJcblx0fTtcclxuXHJcblx0b2JqLmdldF9vdGhlcl9wYXJhbSA9IGZ1bmN0aW9uICggcGFyYW1fa2V5ICkge1xyXG5cdFx0cmV0dXJuIHBfb3RoZXJbIHBhcmFtX2tleSBdO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBhbGwgb3RoZXIgcGFyYW1zXHJcblx0ICpcclxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fHt9fVxyXG5cdCAqL1xyXG5cdG9iai5nZXRfb3RoZXJfcGFyYW1fX2FsbCA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdHJldHVybi
3411BwX290aGVyO1xyXG5cdH07XHJcblxyXG5cdC8vIE1lc3NhZ2VzIFx0XHRcdCAgICAgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0dmFyIHBfbWVzc2FnZXMgPSBvYmoubWVzc2FnZXNfb2JqID0gb2JqLm1lc3NhZ2VzX29iaiB8fCB7IH07XHJcblxyXG5cdG9iai5zZXRfbWVzc2FnZSA9IGZ1bmN0aW9uICggcGFyYW1fa2V5LCBwYXJhbV92YWwgKSB7XHJcblx0XHRwX21lc3NhZ2VzWyBwYXJhbV9rZXkgXSA9IHBhcmFtX3ZhbDtcclxuXHR9O1xyXG5cclxuXHRvYmouZ2V0X21lc3NhZ2UgPSBmdW5jdGlvbiAoIHBhcmFtX2tleSApIHtcclxuXHRcdHJldHVybiBwX21lc3NhZ2VzWyBwYXJhbV9rZXkgXTtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgYWxsIG90aGVyIHBhcmFtc1xyXG5cdCAqXHJcblx0ICogQHJldHVybnMge29iamVjdHx7fX1cclxuXHQgKi9cclxuXHRvYmouZ2V0X21lc3NhZ2VzX19hbGwgPSBmdW5jdGlvbiAoKSB7XHJcblx0XHRyZXR1cm4gcF9tZXNzYWdlcztcclxuXHR9O1xyXG5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHRyZXR1cm4gb2JqO1xyXG5cclxufSggX3dwYmMgfHwge30sIGpRdWVyeSApKTtcclxuIiwiLyoqXHJcbiAqIEV4dGVuZCBfd3BiYyB3aXRoICBuZXcgbWV0aG9kcyAgICAgICAgLy8gRml4SW46IDkuOC42LjIuXHJcbiAqXHJcbiAqIEB0eXBlIHsqfHt9fVxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuIF93cGJjID0gKGZ1bmN0aW9uICggb2JqLCAkKSB7XHJcblxyXG5cdC8vIExvYWQgQmFsYW5jZXIgXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHR2YXIgcF9iYWxhbmNlciA9IG9iai5iYWxhbmNlcl9vYmogPSBvYmouYmFsYW5jZXJfb2JqIHx8IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnbWF4X3RocmVhZHMnOiAyLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdpbl9wcm9jZXNzJyA6IFtdLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd3YWl0JyAgICAgICA6IFtdXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH07XHJcblxyXG5cdCAvKipcclxuXHQgICogU2V0ICBtYXggcGFyYWxsZWwgcmVxdWVzdCAgdG8gIGxvYWRcclxuXHQgICpcclxuXHQgICogQHBhcmFtIG1heF90aHJlYWRzXHJcblx0ICAqL1xyXG5cdG9iai5iYWxhbmNlcl9fc2V0X21heF90aHJlYWRzID0gZnVuY3Rpb24gKCBtYXhfdGhyZWFkcyApe1xyXG5cclxuXHRcdHBfYmFsYW5jZXJbICdtYXhfdGhyZWFkcycgXSA9IG1heF90aHJlYWRzO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqICBDaGVjayBpZiBiYWxhbmNlciBmb3Igc3BlY2lmaWMgYm9va2luZyByZXNvdXJjZSBkZWZpbmVkICAgOjogICB0cnVlIHwgZmFsc2VcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfGludH0gcmVzb3VyY2VfaWRcclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuXHQgKi9cclxuXHRvYmouYmFsYW5jZXJfX2lzX2RlZmluZWQgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkICkge1xyXG5cclxuXHRcdHJldHVybiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiggcF9iYWxhbmNlclsgJ2JhbGFuY2VyXycgKyByZXNvdXJjZV9pZCBdICkgKTtcclxuXHR9O1xyXG5cclxuXHJcblx0LyoqXHJcblx0ICogIENyZWF0ZSBiYWxhbmNlciBpbml0aWFsaXppbmdcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfGludH0gcmVzb3VyY2VfaWRcclxuXHQgKi9cclxuXHRvYmouYmFsYW5jZXJfX2luaXQgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICwgcGFyYW1zID17fSkge1xyXG5cclxuXHRcdHZhciBiYWxhbmNlX29iaiA9IHt9O1xyXG5cdFx0YmFsYW5jZV9vYmpbICdyZXNvdXJjZV9pZCcgXSAgID0gcmVzb3VyY2VfaWQ7XHJcblx0XHRiYWxhbmNlX29ialsgJ3ByaW9yaXR5JyBdICAgICAgPSAxO1xyXG5cdFx0YmFsYW5jZV9vYmpbICdmdW5jdGlvbl9uYW1lJyBdID0gZnVuY3Rpb25fbmFtZTtcclxuXHRcdGJhbGFuY2Vfb2JqWyAncGFyYW1zJyBdICAgICAgICA9IHdwYmNfY2xvbmVfb2JqKCBwYXJhbXMgKTtcclxuXHJcblxyXG5cdFx0aWYgKCBvYmouYmFsYW5jZXJfX2lzX2FscmVhZHlfcnVuKCByZXNvdXJjZV9pZCwgZnVuY3Rpb25fbmFtZSApICl7XHJcblx0XHRcdHJldHVybiAncnVuJztcclxuXHRcdH1cclxuXHRcdGlmICggb2JqLmJhbGFuY2VyX19pc19hbHJlYWR5X3dhaXQoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICkgKXtcclxuXHRcdFx0cmV0dXJuICd3YWl0JztcclxuXHRcdH1cclxuXHJcblxyXG5cdFx0aWYgKCBvYmouYmFsYW5jZXJfX2Nhbl9pX3J1bigpICl7XHJcblx0XHRcdG9iai5iYWxhbmNlcl9fYWRkX3RvX19ydW4oIGJhbGFuY2Vfb2JqICk7XHJcblx0XHRcdHJldHVybiAncnVuJztcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG9iai5iYWxhbmNlcl9fYWRkX3RvX193YWl0KCBiYWxhbmNlX29iaiApO1xyXG5cdFx0XHRyZXR1cm4gJ3dhaXQnO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdCAvKipcclxuXHQgICogQ2FuIEkgUnVuID9cclxuXHQgICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0ICAqL1xyXG5cdG9iai5iYWxhbmNlcl9fY2FuX2lfcnVuID0gZnVuY3Rpb24gKCl7XHJcblx0XHRyZXR1cm4gKCBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXS5sZW5ndGggPCBwX2JhbGFuY2VyWyAnbWF4X3RocmVhZHMnIF0gKTtcclxuXHR9XHJcblxyXG5cdFx0IC8qKlxyXG5cdFx0ICAqIEFkZCB0byBXQUlUXHJcblx0XHQgICogQHBhcmFtIGJhbGFuY2Vfb2JqXHJcblx0XHQgICovXHJcblx0XHRvYmouYmFsYW5jZXJfX2FkZF90b19fd2FpdCA9IGZ1bmN0aW9uICggYmFsYW5jZV9vYmogKSB7XHJcblx0XHRcdHBfYmFsYW5jZXJbJ3dhaXQnXS5wdXNoKCBiYWxhbmNlX29iaiApO
34111xyXG5cdFx0fVxyXG5cclxuXHRcdCAvKipcclxuXHRcdCAgKiBSZW1vdmUgZnJvbSBXYWl0XHJcblx0XHQgICpcclxuXHRcdCAgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHRcdCAgKiBAcGFyYW0gZnVuY3Rpb25fbmFtZVxyXG5cdFx0ICAqIEByZXR1cm5zIHsqfGJvb2xlYW59XHJcblx0XHQgICovXHJcblx0XHRvYmouYmFsYW5jZXJfX3JlbW92ZV9mcm9tX193YWl0X2xpc3QgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICl7XHJcblxyXG5cdFx0XHR2YXIgcmVtb3ZlZF9lbCA9IGZhbHNlO1xyXG5cclxuXHRcdFx0aWYgKCBwX2JhbGFuY2VyWyAnd2FpdCcgXS5sZW5ndGggKXtcdFx0XHRcdFx0Ly8gRml4SW46IDkuOC4xMC4xLlxyXG5cdFx0XHRcdGZvciAoIHZhciBpIGluIHBfYmFsYW5jZXJbICd3YWl0JyBdICl7XHJcblx0XHRcdFx0XHRpZiAoXHJcblx0XHRcdFx0XHRcdChyZXNvdXJjZV9pZCA9PT0gcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ3Jlc291cmNlX2lkJyBdKVxyXG5cdFx0XHRcdFx0XHQmJiAoZnVuY3Rpb25fbmFtZSA9PT0gcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ2Z1bmN0aW9uX25hbWUnIF0pXHJcblx0XHRcdFx0XHQpe1xyXG5cdFx0XHRcdFx0XHRyZW1vdmVkX2VsID0gcF9iYWxhbmNlclsgJ3dhaXQnIF0uc3BsaWNlKCBpLCAxICk7XHJcblx0XHRcdFx0XHRcdHJlbW92ZWRfZWwgPSByZW1vdmVkX2VsLnBvcCgpO1xyXG5cdFx0XHRcdFx0XHRwX2JhbGFuY2VyWyAnd2FpdCcgXSA9IHBfYmFsYW5jZXJbICd3YWl0JyBdLmZpbHRlciggZnVuY3Rpb24gKCB2ICl7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHY7XHJcblx0XHRcdFx0XHRcdH0gKTtcdFx0XHRcdFx0Ly8gUmVpbmRleCBhcnJheVxyXG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVtb3ZlZF9lbDtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHJlbW92ZWRfZWw7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQqIElzIGFscmVhZHkgV0FJVFxyXG5cdFx0KlxyXG5cdFx0KiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHRcdCogQHBhcmFtIGZ1bmN0aW9uX25
3411hbWVcclxuXHRcdCogQHJldHVybnMge2Jvb2xlYW59XHJcblx0XHQqL1xyXG5cdFx0b2JqLmJhbGFuY2VyX19pc19hbHJlYWR5X3dhaXQgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICl7XHJcblxyXG5cdFx0XHRpZiAoIHBfYmFsYW5jZXJbICd3YWl0JyBdLmxlbmd0aCApe1x0XHRcdFx0Ly8gRml4SW46IDkuOC4xMC4xLlxyXG5cdFx0XHRcdGZvciAoIHZhciBpIGluIHBfYmFsYW5jZXJbICd3YWl0JyBdICl7XHJcblx0XHRcdFx0XHRpZiAoXHJcblx0XHRcdFx0XHRcdChyZXNvdXJjZV9pZCA9PT0gcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ3Jlc291cmNlX2lkJyBdKVxyXG5cdFx0XHRcdFx0XHQmJiAoZnVuY3Rpb25fbmFtZSA9PT0gcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ2Z1bmN0aW9uX25hbWUnIF0pXHJcblx0XHRcdFx0XHQpe1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHQgLyoqXHJcblx0XHQgICogQWRkIHRvIFJVTlxyXG5cdFx0ICAqIEBwYXJhbSBiYWxhbmNlX29ialxyXG5cdFx0ICAqL1xyXG5cdFx0b2JqLmJhbGFuY2VyX19hZGRfdG9fX3J1biA9IGZ1bmN0aW9uICggYmFsYW5jZV9vYmogKSB7XHJcblx0XHRcdHBfYmFsYW5jZXJbJ2luX3Byb2Nlc3MnXS5wdXNoKCBiYWxhbmNlX29iaiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0KiBSZW1vdmUgZnJvbSBSVU4gbGlzdFxyXG5cdFx0KlxyXG5cdFx0KiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHRcdCogQHBhcmFtIGZ1bmN0aW9uX25
3411hbWVcclxuXHRcdCogQHJldHVybnMgeyp8Ym9vbGVhbn1cclxuXHRcdCovXHJcblx0XHRvYmouYmFsYW5jZXJfX3JlbW92ZV9mcm9tX19ydW5fbGlzdCA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQsIGZ1bmN0aW9uX25hbWUgKXtcclxuXHJcblx0XHRcdCB2YXIgcmVtb3ZlZF9lbCA9IGZhbHNlO1xyXG5cclxuXHRcdFx0IGlmICggcF9iYWxhbmNlclsgJ2luX3Byb2Nlc3MnIF0ubGVuZ3RoICl7XHRcdFx0XHQvLyBGaXhJbjogOS44LjEwLjEuXHJcblx0XHRcdFx0IGZvciAoIHZhciBpIGluIHBfYmFsYW5jZXJbICdpbl9wcm9jZXNzJyBdICl7XHJcblx0XHRcdFx0XHQgaWYgKFxyXG5cdFx0XHRcdFx0XHQgKHJlc291cmNlX2lkID09PSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXVsgaSBdWyAncmVzb3VyY2VfaWQnIF0pXHJcblx0XHRcdFx0XHRcdCAmJiAoZnVuY3Rpb25fbmFtZSA9PT0gcF9iYWxhbmNlclsgJ2luX3Byb2Nlc3MnIF1bIGkgXVsgJ2Z1bmN0aW9uX25hbWUnIF0pXHJcblx0XHRcdFx0XHQgKXtcclxuXHRcdFx0XHRcdFx0IHJlbW92ZWRfZWwgPSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXS5zcGxpY2UoIGksIDEgKTtcclxuXHRcdFx0XHRcdFx0IHJlbW92ZWRfZWwgPSByZW1vdmVkX2VsLnBvcCgpO1xyXG5cdFx0XHRcdFx0XHQgcF9iYWxhbmNlclsgJ2luX3Byb2Nlc3MnIF0gPSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXS5maWx0ZXIoIGZ1bmN0aW9uICggdiApe1xyXG5cdFx0XHRcdFx0XHRcdCByZXR1cm4gdjtcclxuXHRcdFx0XHRcdFx0IH0gKTtcdFx0Ly8gUmVpbmRleCBhcnJheVxyXG5cdFx0XHRcdFx0XHQgcmV0dXJuIHJlbW92ZWRfZWw7XHJcblx0XHRcdFx0XHQgfVxyXG5cdFx0XHRcdCB9XHJcblx0XHRcdCB9XHJcblx0XHRcdCByZXR1cm4gcmVtb3ZlZF9lbDtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCogSXMgYWxyZWFkeSBSVU5cclxuXHRcdCpcclxuXHRcdCogQHBhcmFtIHJlc291cmNlX2lkXHJcblx0XHQqIEBwYXJhbSBmdW5jdGlvbl9uYW1lXHJcblx0XHQqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdFx0Ki9cclxuXHRcdG9iai5iYWxhbmNlcl9faXNfYWxyZWFkeV9ydW4gPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICl7XHJcblxyXG5cdFx0XHRpZiAoIHBfYmFsYW5jZXJbICdpbl9wcm9jZXNzJyBdLmxlbmd0aCApe1x0XHRcdFx0XHQvLyBGaXhJbjogOS44LjEwLjEuXHJcblx0XHRcdFx0Zm9yICggdmFyIGkgaW4gcF9iYWxhbmNlclsgJ2luX3Byb2Nlc3MnIF0gKXtcclxuXHRcdFx0XHRcdGlmIChcclxuXHRcdFx0XHRcdFx0KHJlc291cmNlX2lkID09PSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXVsgaSBdWyAncmVzb3VyY2VfaWQnIF0pXHJcblx0XHRcdFx0XHRcdCYmIChmdW5jdGlvbl9uYW1lID09PSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXVsgaSBdWyAnZnVuY3Rpb25fbmFtZScgXSlcclxuXHRcdFx0XHRcdCl7XHJcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cclxuXHJcblx0b2JqLmJhbGFuY2VyX19ydW5fbmV4dCA9IGZ1bmN0aW9uICgpe1xyXG5cclxuXHRcdC8vIEdldCAxc3QgZnJvbSAgV2FpdCBsaXN0XHJcblx0XHR2YXIgcmVtb3ZlZF9lbCA9IGZhbHNlO1xyXG5cdFx0aWYgKCBwX2JhbGFuY2VyWyAnd2FpdCcgXS5sZW5ndGggKXtcdFx0XHRcdFx0Ly8gRml4SW46IDkuOC4xMC4xLlxyXG5cdFx0XHRmb3IgKCB2YXIgaSBpbiBwX2JhbGFuY2VyWyAnd2FpdCcgXSApe1xyXG5cdFx0XHRcdHJlbW92ZWRfZWwgPSBvYmouYmFsYW5jZXJfX3JlbW92ZV9mcm9tX193YWl0X2xpc3QoIHBfYmFsYW5jZXJbICd3YWl0JyBdWyBpIF1bICdyZXNvdXJjZV9pZCcgXSwgcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ2Z1bmN0aW9uX25
3411hbWUnIF0gKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggZmFsc2UgIT09IHJlbW92ZWRfZWwgKXtcclxuXHJcblx0XHRcdC8vIFJ1blxyXG5cdFx0XHRvYmouYmFsYW5jZXJfX3J1biggcmVtb3ZlZF9lbCApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0IC8qKlxyXG5cdCAgKiBSdW5cclxuXHQgICogQHBhcmFtIGJhbGFuY2Vfb2JqXHJcblx0ICAqL1xyXG5cdG9iai5iYWxhbmNlcl9fcnVuID0gZnVuY3Rpb24gKCBiYWxhbmNlX29iaiApe1xyXG5cclxuXHRcdHN3aXRjaCAoIGJhbGFuY2Vfb2JqWyAnZnVuY3Rpb25fbmFtZScgXSApe1xyXG5cclxuXHRcdFx0Y2FzZSAnd3BiY19jYWxlbmRhcl9fbG9hZF9kYXRhX19hangnOlxyXG5cclxuXHRcdFx0XHQvLyBBZGQgdG8gcnVuIGxpc3RcclxuXHRcdFx0XHRvYmouYmFsYW5jZXJfX2FkZF90b19fcnVuKCBiYWxhbmNlX29iaiApO1xyXG5cclxuXHRcdFx0XHR3cGJjX2NhbGVuZGFyX19sb2FkX2RhdGFfX2FqeCggYmFsYW5jZV9vYmpbICdwYXJhbXMnIF0gKVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0ZGVmYXVsdDpcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBvYmo7XHJcblxyXG59KCBfd3BiYyB8fCB7fSwgalF1ZXJ5ICkpO1xyXG5cclxuXHJcbiBcdC8qKlxyXG4gXHQgKiAtLSBIZWxwIGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0ICovXHJcblxyXG5cdGZ1bmN0aW9uIHdwYmNfYmFsYW5jZXJfX2lzX3dhaXQoIHBhcmFtcywgZnVuY3Rpb25fbmFtZSApe1xyXG4vL2NvbnNvbGUubG9nKCc6OndwYmNfYmFsYW5jZXJfX2lzX3dhaXQnLHBhcmFtcyAsIGZ1bmN0aW9uX25
3411hbWUgKTtcclxuXHRcdGlmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAocGFyYW1zWyAncmVzb3VyY2VfaWQnIF0pICl7XHJcblxyXG5cdFx0XHR2YXIgYmFsYW5jZXJfc3RhdHVzID0gX3dwYmMuYmFsYW5jZXJfX2luaXQoIHBhcmFtc1sgJ3Jlc291cmNlX2lkJyBdLCBmdW5jdGlvbl9uYW1lLCBwYXJhbXMgKTtcclxuXHJcblx0XHRcdHJldHVybiAoICd3YWl0JyA9PT0gYmFsYW5jZXJfc3RhdHVzICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHJcblxyXG5cdGZ1bmN0aW9uIHdwYmNfYmFsYW5jZXJfX2NvbXBsZXRlZCggcmVzb3VyY2VfaWQgLCBmdW5jdGlvbl9uYW1lICl7XHJcbi8vY29uc29sZS5sb2coJzo6d3BiY19iYWxhbmNlcl9fY29tcGxldGVkJyxyZXNvdXJjZV9pZCAsIGZ1bmN0aW9uX25hbWUgKTtcclxuXHRcdF93cGJjLmJhbGFuY2VyX19yZW1vdmVfZnJvbV9fcnVuX2xpc3QoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICk7XHJcblx0XHRfd3BiYy5iYWxhbmNlcl9fcnVuX25leHQoKTtcclxuXHR9IiwiLyoqXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKlx0aW5jbHVkZXMvX19qcy9jYWwvd3BiY19jYWwuanNcclxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIE9yZGVyIG9yIGNoaWxkIGJvb2tpbmcgcmVzb3VyY2VzIHNhdmVkIGhlcmU6ICBcdF93cGJjLmJvb2tpbmdfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdyZXNvdXJjZXNfaWRfYXJyX19pbl9kYXRlcycgKVx0XHRbMiwxMCwxMiwxMV1cclxuICovXHJcblxyXG4vKipcclxuICogSG93IHRvIGNoZWNrICBib29rZWQgdGltZXMgb24gIHNwZWNpZmljIGRhdGU6ID9cclxuICpcclxuXHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJyk7XHJcblxyXG5cdFx0XHRjb25zb2xlLmxvZyhcclxuXHRcdFx0XHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3NlY29uZHMsXHJcblx0XHRcdFx0XHRcdF93cGJjLmJvb2tpbmdzX2luX2NhbGVuZGFyX19nZXRfZm9yX2RhdGUoMiwnMjAyMy0wOC0yMScpWzEwXS5ib29rZWRfdGltZV9zbG90cy5tZXJnZWRfc2Vjb25kcyxcclxuXHRcdFx0XHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMTFdLmJvb2tlZF90aW1lX3Nsb3RzLm1lcmdlZF9zZWNvbmRzLFxyXG5cdFx0XHRcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKDIsJzIwMjMtMDgtMjEnKVsxMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3NlY29uZHNcclxuXHRcdFx0XHRcdCk7XHJcbiAqICBPUlxyXG5cdFx0XHRjb25zb2xlLmxvZyhcclxuXHRcdFx0XHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3JlYWRhYmxlLFxyXG5cdFx0XHRcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKDIsJzIwMjMtMDgtMjEnKVsxMF0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3JlYWRhYmxlLFxyXG5cdFx0XHRcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKDIsJzIwMjMtMDgtMjEnKVsxMV0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3JlYWRhYmxlLFxyXG5cdFx0XHRcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKDIsJzIwMjMtMDgtMjEnKVsxMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3JlYWRhYmxlXHJcblx0XHRcdFx0XHQpO1xyXG4gKlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBEYXlzIHNlbGVjdGlvbjpcclxuICogXHRcdFx0XHRcdHdwYmNfY2FsZW5kYXJfX3Vuc2VsZWN0X2FsbF9kYXRlcyggcmVzb3VyY2VfaWQgKTtcclxuICpcclxuICpcdFx0XHRcdFx0dmFyIHJlc291cmNlX2lkID0gMTtcclxuICogXHRFeGFtcGxlIDE6XHRcdHZhciBudW1fc2VsZWN0ZWRfZGF5cyA9IHdwYmNfYXV0b19zZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXIoIHJlc291cmNlX2lkLCAnMjAyNC0wNS0xNScsICcyMDI0LTA1LTI1JyApO1xyXG4gKiBcdEV4YW1wbGUgMjpcdFx0dmFyIG51bV9zZWxlY3RlZF9kYXlzID0gd3BiY19hdXRvX3NlbGVjdF9kYXRlc19pbl9jYWxlbmRhciggcmVzb3VyY2VfaWQsIFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTknLCcyMDI0LTA1LTI1J10gKTtcclxuICpcclxuICovXHJcblxyXG5cclxuLyoqXHJcbiAqIEMgQSBMIEUgTiBEIEEgUiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAqL1xyXG5cclxuXHJcbi8qKlxyXG4gKiAgU2hvdyBXUEJDIENhbGVuZGFyXHJcbiAqXHJcbiAqIEBwYXJhbSByZXNvdXJjZV9pZFx0XHRcdC0gcmVzb3VyY2UgSURcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2NhbGVuZGFyX3Nob3coIHJlc291cmNlX2lkICl7XHJcblxyXG5cdC8vIElmIG5vIGNhbGVuZGFyIEhUTUwgdGFnLCAgdGhlbiAgZXhpdFxyXG5cdGlmICggMCA9PT0galF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS5sZW5ndGggKXsgcmV0dXJuIGZhbHNlOyB9XHJcblxyXG5cdC8vIElmIHRoZSBjYWxlbmRhciB3aXRoIHRoZSBzYW1lIEJvb2tpbmcgcmVzb3VyY2UgaXMgYWN0aXZhdGVkIGFscmVhZHksIHRoZW4gZXhpdC5cclxuXHRpZiAoIHRydWUgPT09IGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkuaGFzQ2xhc3MoICdoYXNEYXRlcGljaycgKSApeyByZXR1cm4gZmFsc2U7IH1cclxuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvLyBEYXlzIHNlbGVjdGlvblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0dmFyIGxvY2FsX19pc19yYW5nZV9zZWxlY3QgPSBmYWxzZTtcclxuXHR2YXIgbG9jYWxfX211bHRpX2RheXNfc2VsZWN0X251bSAgID0gMzY1O1x0XHRcdFx0XHQvLyBtdWx0aXBsZSB8IGZpeGVkXHJcblx0aWYgKCAnZHluYW1pYycgPT09IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZGF5c19zZWxlY3RfbW9kZScgKSApe1xyXG5cdFx0bG9jYWxfX2lzX3JhbmdlX3NlbGVjdCA9IHRydWU7XHJcblx0XHRsb2NhbF9fbXVsdGlfZGF5c19zZWxlY3RfbnVtID0gMDtcclxuXHR9XHJcblx0aWYgKCAnc2luZ2xlJyAgPT09IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZGF5c19zZWxlY3RfbW9kZScgKSApe1xyXG5cdFx0bG9jYWxfX211bHRpX2RheXNfc2VsZWN0X251bSA9IDA7XHJcblx0fVxyXG5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8vIE1pbiAtIE1heCBkYXlzIHRvIHNjcm9sbC9zaG93XHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHR2YXIgbG9jYWxfX21pbl9kYXRlID0gMDtcclxuIFx0bG9jYWxfX21pbl9kYXRlID0gbmV3IERhdGUoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RvZGF5X2FycicgKVsgMCBdLCAocGFyc2VJbnQoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RvZGF5X2FycicgKVsgMSBdICkgLSAxKSwgX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndG9kYXlfYXJyJyApWyAyIF0sIDAsIDAsIDAgKTtcdFx0XHQvLyBGaXhJbjogOS45LjAuMTcuXHJcbi8vY29uc29sZS5sb2coIGxvY2FsX19taW5fZGF0ZSApO1xyXG5cdHZhciBsb2NhbF9fbWF4X2RhdGUgPSBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2Jvb2tpbmdfbWF4X21vbnRoZXNfaW5fY2FsZW5kYXInICk7XHJcblx0Ly9sb2NhbF9fbWF4X2RhdGUgPSBuZXcgRGF0ZSgyMDI0LCA1LCAyOCk7ICBJdCBpcyBoZXJlIGlzc3VlIG9mIG5vdCBzZWxlY3RhYmxlIGRhdGVzLCBidXQgc29tZSBkYXRlcyBzaG93aW5nIGluIGNhbGVuZGFyIGFzIGF2YWlsYWJsZSwgYnV0IHdlIGNhbiBub3Qgc2VsZWN0IGl0LlxyXG5cclxuXHQvLy8vIERlZmluZSBsYXN0IGRheSBpbiBjYWxlbmRhciAoYXMgYSBsYXN0IGRheSBvZiBtb250aCAoYW5kIG5vdCBkYXRlLCB3aGljaCBpcyByZWxhdGVkIHRvIGFjdHVhbCAnVG9kYXknIGRhdGUpLlxyXG5cdC8vLy8gRS5nLiBpZiB0b2RheSBpcyAyMDIzLTA5LTI1LCBhbmQgd2Ugc2V0ICdOdW1iZXIgb2YgbW9udGhzIHRvIHNjcm9sbCcgYXMgNSBtb250aHMsIHRoZW4gbGFzdCBkYXkgd2lsbCBiZSAyMDI0LTAyLTI5IGFuZCBub3QgdGhlIDIwMjQtMDItMjUuXHJcblx0Ly8gdmFyIGNhbF9sYXN0X2RheV9pbl9tb250aCA9IGpRdWVyeS5kYXRlcGljay5fZGV0ZXJtaW5lRGF0ZSggbnVsbCwgbG9jYWxfX21heF9kYXRlLCBuZXcgRGF0ZSgpICk7XHJcblx0Ly8gY2FsX2xhc3RfZGF5X2luX2
34111vbnRoID0gbmV3IERhdGUoIGNhbF9sYXN0X2RheV9pbl9tb250aC5nZXRGdWxsWWVhcigpLCBjYWxfbGFzdF9kYXlfaW5fbW9udGguZ2V0TW9udGgoKSArIDEsIDAgKTtcclxuXHQvLyBsb2NhbF9fbWF4X2RhdGUgPSBjYWxfbGFzdF9kYXlfaW5fbW9udGg7XHRcdFx0Ly8gRml4SW46IDEwLjAuMC4yNi5cclxuXHJcblx0Ly8gR2V0IHN0YXJ0IC8gZW5kIGRhdGVzIGZyb20gIHRoZSBCb29raW5nIENhbGVuZGFyIHNob3J0Y29kZS4gRXhhbXBsZTogW2Jvb2tpbmcgY2FsZW5kYXJfZGF0ZXNfc3RhcnQ9JzIwMjYtMDEtMDEnIGNhbGVuZGFyX2RhdGVzX2VuZD0nMjAyNi0xMi0zMScgIHJlc291cmNlX2lkPTFdIC8vIEZpeEluOiAxMC4xMy4xLjQuXHJcblx0aWYgKCBmYWxzZSAhPT0gd3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX3N0YXJ0KCByZXNvdXJjZV9pZCApICkge1xyXG5cdFx0bG9jYWxfX21pbl9kYXRlID0gd3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX3N0YXJ0KCByZXNvdXJjZV9pZCApOyAgLy8gRS5nLiAtIGxvY2FsX19taW5fZGF0ZSA9IG5ldyBEYXRlKCAyMDI1LCAwLCAxICk7XHJcblx0fVxyXG5cdGlmICggZmFsc2UgIT09IHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlc19lbmQoIHJlc291cmNlX2lkICkgKSB7XHJcblx0XHRsb2NhbF9fbWF4X2RhdGUgPSB3cGJjX2NhbGVuZGFyX19nZXRfZGF0ZXNfZW5kKCByZXNvdXJjZV9pZCApOyAgICAvLyBFLmcuIC0gbG9jYWxfX21heF9kYXRlID0gbmV3IERhdGUoIDIwMjUsIDExLCAzMSApO1xyXG5cdH1cclxuXHJcblx0Ly8gSW4gY2FzZSB3ZSBlZGl0IGJvb2tpbmcgaW4gcGFzdCBvciBoYXZlIHNwZWNpZmljIHBhcmFtZXRlciBpbiBVUkwuXHJcblx0aWYgKCAgICggbG9jYXRpb24uaHJlZi5pbmRleE9mKCdwYWdlPXdwYmMtbmV3JykgIT0gLTEgKVxyXG5cdFx0JiYgKFxyXG5cdFx0XHQgICggbG9jYXRpb24uaHJlZi5pbmRleE9mKCdib29raW5nX2hhc2gnKSAhPSAtMSApICAgICAgICAgICAgICAgICAgLy8gQ29tbWVudCB0aGlzIGxpbmUgZm9yIGFiaWxpdHkgdG8gYWRkICBib29raW5nIGluIHBhc3QgZGF5cyBhdCAgQm9va2luZyA+IEFkZCBib29raW5nIHBhZ2UuXHJcblx0XHQgICB8fCAoIGxvY2F0aW9uLmhyZWYuaW5kZXhPZignYWxsb3dfcGFzdCcpICE9IC0xICkgICAgICAgICAgICAgICAgLy8gRml4SW46IDEwLjcuMS4yLlxyXG5cdFx0KVxyXG5cdCl7XHJcblx0XHQvLyBsb2NhbF9fbWluX2RhdGUgPSBudWxsO1xyXG5cdFx0Ly8gRml4SW46IDEwLjE0LjEuNC5cclxuXHRcdGxvY2FsX19taW5fZGF0ZSAgPSBuZXcgRGF0ZSggX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndGltZV9sb2NhbF9hcnInIClbMF0sICggcGFyc2VJbnQoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RpbWVfbG9jYWxfYXJyJyApWzFdICkgLSAxKSwgX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndGltZV9sb2NhbF9hcnInIClbMl0sIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RpbWVfbG9jYWxfYXJyJyApWzNdLCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICd0aW1lX2xvY2FsX2FycicgKVs0XSwgMCApO1xyXG5cdFx0bG9jYWxfX21heF9kYXRlID0gbnVsbDtcclxuXHR9XHJcblxyXG5cdHZhciBsb2NhbF9fc3RhcnRfd2Vla2RheSAgICA9IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnYm9va2luZ19zdGFydF9kYXlfd2VlZWsnICk7XHJcblx0dmFyIGxvY2FsX19udW1iZXJfb2ZfbW9udGhzID0gcGFyc2VJbnQoIF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnY2FsZW5kYXJfbnVtYmVyX29mX21vbnRocycgKSApO1xyXG5cclxuXHRqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLnRleHQoICcnICk7XHRcdFx0XHRcdC8vIFJlbW92ZSBhbGwgSFRNTCBpbiBjYWxlbmRhciB0YWdcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8vIFNob3cgY2FsZW5kYXJcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdGpRdWVyeSgnI2NhbGVuZGFyX2Jvb2tpbmcnKyByZXNvdXJjZV9pZCkuZGF0ZXBpY2soXHJcblx0XHRcdHtcclxuXHRcdFx0XHRiZWZvcmVTaG93RGF5OiBmdW5jdGlvbiAoIGpzX2RhdGUgKXtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHdwYmNfX2NhbGVuZGFyX19hcHBseV9jc3NfdG9fZGF5cygganNfZGF0ZSwgeydyZXNvdXJjZV9pZCc6IHJlc291cmNlX2lkfSwgdGhpcyApO1xyXG5cdFx0XHRcdFx0XHRcdCAgfSxcclxuXHRcdFx0XHRvblNlbGVjdDogZnVuY3Rpb24gKCBzdHJpbmdfZGF0ZXMsIGpzX2RhdGVzX2FyciApeyAgLyoqXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgKlx0c3RyaW5nX2RhdGVzICAgPSAgICcyMy4wOC4yMDIzIC0gMjYuMDguMjAyMycgICAgfCAgICAnMjMuMDguMjAyMyAtIDIzLjA4LjIwMjMnICAgIHwgICAgJzE5LjA5LjIwMjMsIDI0LjA4LjIwMjMsIDMwLjA5LjIwMjMnXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgKiAganNfZGF0ZXNfYXJyICAgPSAgIHJhbmdlOiBbIERhdGUgKEF1ZyAyMyAyMDIzKSwgRGF0ZSAoQXVnIDI1IDIwMjMpXSAgICAgfCAgICAgbXVsdGlwbGU6IFsgRGF0ZShPY3QgMjQgMjAyMyksIERhdGUoT2N0IDIwIDIwMjMpLCBEYXRlKE9jdCAxNiAyMDIzKSBdXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgKi9cclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHdwYmNfX2NhbGVuZGFyX19vbl9zZWxlY3RfZGF5cyggc3RyaW5nX2RhdGVzLCB7J3Jlc291cmNlX2lkJzogcmVzb3VyY2VfaWR9LCB0aGlzICk7XHJcblx0XHRcdFx0XHRcdFx0ICB9LFxyXG5cdFx0XHRcdG9uSG92ZXI6IGZ1bmN0aW9uICggc3RyaW5nX2RhdGUsIGpzX2RhdGUgKXtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHdwYmNfX2NhbGVuZGFyX19vbl9ob3Zlcl9kYXlzKCBzdHJpbmdfZGF0ZSwganNfZGF0ZSwgeydyZXNvdXJjZV9pZCc6IHJlc291cmNlX2lkfSwgdGhpcyApO1xyXG5cdFx0XHRcdFx0XHRcdCAgfSxcclxuXHRcdFx0XHRvbkNoYW5nZU1vbnRoWWVhcjogZnVuY3Rpb24gKCB5ZWFyLCByZWFsX21vbnRoLCBqc19kYXRlX18xc3RfZGF5X2luX2
34111vbnRoICl7IH0sXHJcblx0XHRcdFx0c2hvd09uICAgICAgICA6ICdib3RoJyxcclxuXHRcdFx0XHRudW1iZXJPZk1vbnRoczogbG9jYWxfX251bWJlcl9vZl9tb250aHMsXHJcblx0XHRcdFx0c3RlcE1vbnRocyAgICA6IDEsXHJcblx0XHRcdFx0Ly8gcHJldlRleHQgICAgICA6ICcmbGFxdW87JyxcclxuXHRcdFx0XHQvLyBuZXh0VGV4dCAgICAgIDogJyZyYXF1bzsnLFxyXG5cdFx0XHRcdHByZXZUZXh0ICAgICAgOiAnJmxzYXF1bzsnLFxyXG5cdFx0XHRcdG5leHRUZXh0ICAgICAgOiAnJnJzYXF1bzsnLFxyXG5cdFx0XHRcdGRhdGVGb3JtYXQgICAgOiAnZGQubW0ueXknLFxyXG5cdFx0XHRcdGNoYW5nZU1vbnRoICAgOiBmYWxzZSxcclxuXHRcdFx0XHRjaGFuZ2VZZWFyICAgIDogZmFsc2UsXHJcblx0XHRcdFx0bWluRGF0ZSAgICAgICA6IGxvY2FsX19taW5fZGF0ZSxcclxuXHRcdFx0XHRtYXhEYXRlICAgICAgIDogbG9jYWxfX21heF9kYXRlLCBcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzFZJyxcclxuXHRcdFx0XHQvLyBtaW5EYXRlOiBuZXcgRGF0ZSgyMDIwLCAyLCAxKSwgbWF4RGF0ZTogbmV3IERhdGUoMjAyMCwgOSwgMzEpLCAgICAgICAgICAgICBcdC8vIEFiaWxpdHkgdG8gc2V0IGFueSAgc3RhcnQgYW5kIGVuZCBkYXRlIGluIGNhbGVuZGFyXHJcblx0XHRcdFx0c2hvd1N0YXR1cyAgICAgIDogZmFsc2UsXHJcblx0XHRcdFx0bXVsdGlTZXBhcmF0b3IgIDogJywgJyxcclxuXHRcdFx0XHRjbG9zZUF0VG9wICAgICAgOiBmYWxzZSxcclxuXHRcdFx0XHRmaXJzdERheSAgICAgICAgOiBsb2NhbF9fc3RhcnRfd2Vla2RheSxcclxuXHRcdFx0XHRnb3RvQ3VycmVudCAgICAgOiBmYWxzZSxcclxuXHRcdFx0XHRoaWRlSWZOb1ByZXZOZXh0OiB0cnVlLFxyXG5cdFx0XHRcdG11bHRpU2VsZWN0ICAgICA6IGxvY2FsX19tdWx0aV9kYXlzX3NlbGVjdF9udW0sXHJcblx0XHRcdFx0cmFuZ2VTZWxlY3QgICAgIDogbG9jYWxfX2lzX3JhbmdlX3NlbGVjdCxcclxuXHRcdFx0XHQvLyBzaG93V2Vla3M6IHRydWUsXHJcblx0XHRcdFx0dXNlVGhlbWVSb2xsZXI6IGZhbHNlXHJcblx0XHRcdH1cclxuXHQpO1xyXG5cclxuXHJcblx0XHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvLyBDbGVhciB0b2RheSBkYXRlIGhpZ2hsaWdodGluZ1xyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0c2V0VGltZW91dCggZnVuY3Rpb24gKCl7ICB3cGJjX2NhbGVuZGFyc19fY2xlYXJfZGF5c19oaWdobGlnaHRpbmcoIHJlc291cmNlX2lkICk7ICB9LCA1MDAgKTsgICAgICAgICAgICAgICAgICAgIFx0Ly8gRml4SW46IDcuMS4yLjguXHJcblx0XHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvLyBTY3JvbGwgY2FsZW5kYXIgdG8gIHNwZWNpZmljIG1vbnRoXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHR2YXIgc3RhcnRfYmtfbW9udGggPSBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2NhbGVuZGFyX3Njcm9sbF90bycgKTtcclxuXHRpZiAoIGZhbHNlICE9PSBzdGFydF9ia19tb250aCApe1xyXG5cdFx0d3BiY19jYWxlbmRhcl9fc2Nyb2xsX3RvKCByZXNvdXJjZV9pZCwgc3RhcnRfYmtfbW9udGhbIDAgXSwgc3RhcnRfYmtfbW9udGhbIDEgXSApO1xyXG5cdH1cclxufVxyXG5cclxuXHJcblx0LyoqXHJcblx0ICogQXBwbHkgQ1NTIHRvIGNhbGVuZGFyIGRhdGUgY2VsbHNcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBkYXRlXHRcdFx0XHRcdFx0XHRcdFx0XHQtICBKYXZhU2NyaXB0IERhdGUgT2JqOiAgXHRcdE1vbiBEZWMgMTEgMjAyMyAwMDowMDowMCBHTVQrMDIwMCAoRWFzdGVybiBFdXJvcGVhbiBTdGFuZGFyZCBUaW1lKVxyXG5cdCAqIEBwYXJhbSBjYWxlbmRhcl9wYXJhbXNfYXJyXHRcdFx0XHRcdFx0LSAgQ2FsZW5kYXIgU2V0dGluZ3MgT2JqZWN0OiAgXHR7XHJcblx0ICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgXHRcdFx0XHRcdFx0XCJyZXNvdXJjZV9pZFwiOiA0XHJcblx0ICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0ICogQHBhcmFtIGRhdGVwaWNrX3RoaXNcdFx0XHRcdFx0XHRcdFx0LSB0aGlzIG9mIGRhdGVwaWNrIE9ialxyXG5cdCAqIEByZXR1cm5zIHsoKnxzdHJpbmcpW118KGJvb2xlYW58c3RyaW5nKVtdfVx0XHQtIFsge3RydWUgLWF2YWlsYWJsZSB8IGZhbHNlIC0gdW5hdmFpbGFibGV9LCAnQ1NTIGNsYXNzZXMgZm9yIGNhbGVuZGFyIGRheSBjZWxsJyBdXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19fY2FsZW5kYXJfX2FwcGx5X2Nzc190b19kYXlzKCBkYXRlLCBjYWxlbmRhcl9wYXJhbXNfYXJyLCBkYXRlcGlja190aGlzICl7XHJcblxyXG5cdFx0dmFyIHRvZGF5X2RhdGUgPSBuZXcgRGF0ZSggX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndG9kYXlfYXJyJyApWyAwIF0sIChwYXJzZUludCggX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndG9kYXlfYXJyJyApWyAxIF0gKSAtIDEpLCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICd0b2RheV9hcnInIClbIDIgXSwgMCwgMCwgMCApO1x0XHRcdFx0XHRcdFx0XHQvLyBUb2RheSBKU19EYXRlX09iai5cclxuXHRcdHZhciBjbGFzc19kYXkgICAgID0gd3BiY19fZ2V0X190ZF9jbGFzc19kYXRlKCBkYXRlICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzEtOS0yMDIzJ1xyXG5cdFx0dmFyIHNxbF9jbGFzc19kYXkgPSB3cGJjX19nZXRfX3NxbF9jbGFzc19kYXRlKCBkYXRlICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzIwMjMtMDEtMDknXHJcblx0XHR2YXIgcmVzb3VyY2VfaWQgPSAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YoY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdKSApID8gY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdIDogJzEnOyBcdFx0Ly8gJzEnXHJcblxyXG5cdFx0Ly8gR2V0IFNlbGVjdGVkIGRhdGVzIGluIGNhbGVuZGFyXHJcblx0XHR2YXIgc2VsZWN0ZWRfZGF0ZXNfc3FsID0gd3BiY19nZXRfX3NlbGVjdGVkX2RhdGVzX3NxbF9fYXNfYXJyKCByZXNvdXJjZV9pZCApO1xyXG5cclxuXHRcdC8vIEdldCBEYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHR2YXIgZGF0ZV9ib29raW5nc19vYmogPSBfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKCByZXNvdXJjZV9pZCwgc3FsX2NsYXNzX2RheSApO1xyXG5cclxuXHJcblx0XHQvLyBBcnJheSB3aXRoIENTUyBjbGFzc2VzIGZvciBkYXRlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIGNzc19jbGFzc2VzX19mb3JfZGF0ZSA9IFtdO1xyXG5cdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdzcWxfZGF0ZV8nICAgICArIHNxbF9jbGFzc19kYXkgKTtcdFx0XHRcdC8vICAnc3FsX2RhdGVfMjAyMy0wNy0yMSdcclxuXHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2FsNGRhdGUtJyAgICAgKyBjbGFzc19kYXkgKTtcdFx0XHRcdFx0Ly8gICdjYWw0ZGF0ZS03LTIxLTIwMjMnXHJcblx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ3dwYmNfd2Vla2RheV8nICsgZGF0ZS5nZXREYXkoKSApO1x0XHRcdFx0Ly8gICd3cGJjX3dlZWtkYXlfNCdcclxuXHJcblx0XHQvLyBEZWZpbmUgU2VsZWN0ZWQgQ2hlY2sgSW4vT3V0IGRhdGVzIGluIFREICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0aWYgKFxyXG5cdFx0XHRcdCggc2VsZWN0ZWRfZGF0ZXNfc3FsLmxlbmd0aCAgKVxyXG5cdFx0XHQvLyYmICAoIHNlbGVjdGVkX2RhdGVzX3NxbFsgMCBdICE9PSBzZWxlY3RlZF9kYXRlc19zcWxbIChzZWxlY3RlZF9kYXRlc19zcWwubGVuZ3RoIC0gMSkgXSApXHJcblx0XHQpe1xyXG5cdFx0XHRpZiAoIHNxbF9jbGFzc19kYXkgPT09IHNlbGVjdGVkX2RhdGVzX3NxbFsgMCBdICl7XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdzZWxlY3RlZF9jaGVja19pbicgKTtcclxuXHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ3NlbGVjdGVkX2NoZWNrX2luX291dCcgKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoICAoIHNlbGVjdGVkX2RhdGVzX3NxbC5sZW5ndGggPiAxICkgJiYgKCBzcWxfY2xhc3NfZGF5ID09PSBzZWxlY3RlZF9kYXRlc19zcWxbIChzZWxlY3RlZF9kYXRlc19zcWwubGVuZ3RoIC0gMSkgXSApICkge1xyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnc2VsZWN0ZWRfY2hlY2tfb3V0JyApO1xyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnc2VsZWN0ZWRfY2hlY2tfaW5fb3V0JyApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdHZhciBpc19kYXlfc2VsZWN0YWJsZSA9IGZhbHNlO1xyXG5cclxuXHRcdC8vIElmIHNvbWV0aGluZyBub3QgZGVmaW5lZCwgIHRoZW4gIHRoaXMgZGF0ZSBjbG9zZWQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIC8vIEZpeEluOiAxMC4xMi40LjYuXHJcblx0XHRpZiAoIChmYWxzZSA9PT0gZGF0ZV9ib29raW5nc19vYmopIHx8ICgndW5kZWZpbmVkJyA9PT0gdHlwZW9mIChkYXRlX2Jvb2tpbmdzX29ialtyZXNvdXJjZV9pZF0pKSApIHtcclxuXHJcblx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZGF0ZV91c2VyX3VuYXZhaWxhYmxlJyApO1xyXG5cclxuXHRcdFx0cmV0dXJuIFsgaXNfZGF5X3NlbGVjdGFibGUsIGNzc19jbGFzc2VzX19mb3JfZGF0ZS5qb2luKCcgJykgIF07XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHQvLyAgIGRhdGVfYm9va2luZ3Nfb2JqICAtIERlZmluZWQuICAgICAgICAgICAgRGF0ZXMgY2FuIGJlIHNlbGVjdGFibGUuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHQvLyBBZGQgc2Vhc29uIG5hbWVzIHRvIHRoZSBkYXkgQ1NTIGNsYXNzZXMgLS0gaXQgaXMgcmVxdWlyZWQgZm9yIGNvcnJlY3QgIHdvcmsgIG9mIGNvbmRpdGlvbmFsIGZpZWxkcyAtLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIHNlYXNvbl9uYW1lc19hcnIgPSBfd3BiYy5zZWFzb25zX19nZXRfZm9yX2RhdGUoIHJlc291cmNlX2lkLCBzcWxfY2xhc3NfZGF5ICk7XHJcblxyXG5cdFx0Zm9yICggdmFyIHNlYXNvbl9rZXkgaW4gc2Vhc29uX25hbWVzX2FyciApe1xyXG5cclxuXHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goIHNlYXNvbl9uYW1lc19hcnJbIHNlYXNvbl9rZXkgXSApO1x0XHRcdFx0Ly8gICd3cGRldmJrX3NlYXNvbl9zZXB0ZW1iZXJfMjAyMydcclxuXHRcdH1cclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5cclxuXHRcdC8vIENvc3QgUmF0ZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ3JhdGVfJyArIGRhdGVfYm9va2luZ3Nfb2JqWyByZXNvdXJjZV9pZCBdWyAnZGF0ZV9jb3N0X3JhdGUnIF0udG9TdHJpbmc
3411oKS5yZXBsYWNlKCAvW1xcLlxcc10vZywgJ18nICkgKTtcdFx0XHRcdFx0XHQvLyAgJ3JhdGVfOTlfMDAnIC0+IDk5LjAwXHJcblxyXG5cclxuXHRcdGlmICggcGFyc2VJbnQoIGRhdGVfYm9va2luZ3Nfb2JqWyAnZGF5X2F2YWlsYWJpbGl0eScgXSApID4gMCApe1xyXG5cdFx0XHRpc19kYXlfc2VsZWN0YWJsZSA9IHRydWU7XHJcblx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZGF0ZV9hdmFpbGFibGUnICk7XHJcblx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAncmVzZXJ2ZWRfZGF5c19jb3VudCcgKyBwYXJzZUludCggZGF0ZV9ib29raW5nc19vYmpbICdtYXhfY2FwYWNpdHknIF0gLSBkYXRlX2Jvb2tpbmdzX29ialsgJ2RheV9hdmFpbGFiaWxpdHknIF0gKSApO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0aXNfZGF5X3NlbGVjdGFibGUgPSBmYWxzZTtcclxuXHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdkYXRlX3VzZXJfdW5hdmFpbGFibGUnICk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdHN3aXRjaCAoIGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeSddWydzdGF0dXNfZm9yX2RheScgXSApe1xyXG5cclxuXHRcdFx0Y2FzZSAnYXZhaWxhYmxlJzpcclxuXHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdGNhc2UgJ3RpbWVfc2xvdHNfYm9va2luZyc6XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICd0aW1lc3BhcnRseScsICd0aW1lc19jbG9jaycgKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdGNhc2UgJ2Z1bGxfZGF5X2Jvb2tpbmcnOlxyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZnVsbF9kYXlfYm9va2luZycgKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdGNhc2UgJ3NlYXNvbl9maWx0ZXInOlxyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZGF0ZV91c2VyX3VuYXZhaWxhYmxlJywgJ3NlYXNvbl91bmF2YWlsYWJsZScgKTtcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSA9ICcnO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXNldCBib29raW5nIHN0YXR1cyBjb2xvciBmb3IgcG9zc2libGUgb2xkIGJvb2tpbmdzIG9uIHRoaXMgZGF0ZVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAncmVzb3VyY2VfYXZhaWxhYmlsaXR5JzpcclxuXHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2RhdGVfdXNlcl91bmF2YWlsYWJsZScsICdyZXNvdXJjZV91bmF2YWlsYWJsZScgKTtcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSA9ICcnO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXNldCBib29raW5nIHN0YXR1cyBjb2xvciBmb3IgcG9zc2libGUgb2xkIGJvb2tpbmdzIG9uIHRoaXMgZGF0ZVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAnd2Vla2RheV91bmF2YWlsYWJsZSc6XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdkYXRlX3VzZXJfdW5hdmFpbGFibGUnLCAnd2Vla2RheV91bmF2YWlsYWJsZScgKTtcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSA9ICcnO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXNldCBib29raW5nIHN0YXR1cyBjb2xvciBmb3IgcG9zc2libGUgb2xkIGJvb2tpbmdzIG9uIHRoaXMgZGF0ZVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAnZnJvbV90b2RheV91bmF2YWlsYWJsZSc6XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdkYXRlX3VzZXJfdW5hdmFpbGFibGUnLCAnZnJvbV90b2RheV91bmF2YWlsYWJsZScgKTtcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSA9ICcnO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXNldCBib29raW5nIHN0YXR1cyBjb2xvciBmb3IgcG9zc2libGUgb2xkIGJvb2tpbmdzIG9uIHRoaXMgZGF0ZVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAnbGltaXRfYXZhaWxhYmxlX2Zyb21fdG9kYXknOlxyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZGF0ZV91c2VyX3VuYXZhaWxhYmxlJywgJ2xpbWl0X2F2YWlsYWJsZV9mcm9tX3RvZGF5JyApO1xyXG5cdFx0XHRcdGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeSddWydzdGF0dXNfZm9yX2Jvb2tpbmdzJyBdID0gJyc7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFJlc2V0IGJvb2tpbmcgc3RhdHVzIGNvbG9yIGZvciBwb3NzaWJsZSBvbGQgYm9va2luZ3Mgb24gdGhpcyBkYXRlXHJcblx0XHRcdFx0YnJlYWs7XHJcblxyXG5cdFx0XHRjYXNlICdjaGFuZ2Vfb3Zlcic6XHJcblx0XHRcdFx0LypcclxuXHRcdFx0XHQgKlxyXG5cdFx0XHRcdC8vICBjaGVja19vdXRfdGltZV9kYXRlMmFwcHJvdmUgXHQgXHRjaGVja19pbl90aW1lX2RhdGUyYXBwcm92ZVxyXG5cdFx0XHRcdC8vICBjaGVja19vdXRfdGltZV9kYXRlMmFwcHJvdmUgXHQgXHRjaGVja19pbl90aW1lX2RhdGVfYXBwcm92ZWRcclxuXHRcdFx0XHQvLyAgY2hlY2tfaW5fdGltZV9kYXRlMmFwcHJvdmUgXHRcdCBcdGNoZWNrX291dF90aW1lX2RhdGVfYXBwcm92ZWRcclxuXHRcdFx0XHQvLyAgY2hlY2tfb3V0X3RpbWVfZGF0ZV9hcHByb3ZlZCBcdCBcdGNoZWNrX2luX3RpbWVfZGF0ZV9hcHByb3ZlZFxyXG5cdFx0XHRcdCAqL1xyXG5cclxuXHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ3RpbWVzcGFydGx5JywgJ2NoZWNrX2luX3RpbWUnLCAnY2hlY2tfb3V0X3RpbWUnICk7XHJcblx0XHRcdFx0Ly8gRml4SW46IDEwLjAuMC4yLlxyXG5cdFx0XHRcdGlmICggZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5JyBdWyAnc3RhdHVzX2Zvcl9ib29raW5ncycgXS5pbmRleE9mKCAnYXBwcm92ZWRfcGVuZGluZycgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGVfYXBwcm92ZWQnLCAnY2hlY2tfaW5fdGltZV9kYXRlMmFwcHJvdmUnICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICggZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5JyBdWyAnc3R
3411hdHVzX2Zvcl9ib29raW5ncycgXS5pbmRleE9mKCAncGVuZGluZ19hcHByb3ZlZCcgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGUyYXBwcm92ZScsICdjaGVja19pbl90aW1lX2RhdGVfYXBwcm92ZWQnICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAnY2hlY2tfaW4nOlxyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAndGltZXNwYXJ0bHknLCAnY2hlY2tfaW5fdGltZScgKTtcclxuXHJcblx0XHRcdFx0Ly8gRml4SW46IDkuOS4wLjMzLlxyXG5cdFx0XHRcdGlmICggZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5JyBdWyAnc3RhdHVzX2Zvcl9ib29raW5ncycgXS5pbmRleE9mKCAncGVuZGluZycgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX2luX3RpbWVfZGF0ZTJhcHByb3ZlJyApO1xyXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeScgXVsgJ3N0YXR1c19mb3JfYm9va2luZ3MnIF0uaW5kZXhPZiggJ2FwcHJvdmVkJyApID4gLTEgKXtcclxuXHRcdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2hlY2tfaW5fdGltZV9kYXRlX2FwcHJvdmVkJyApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdGNhc2UgJ2NoZWNrX291dCc6XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICd0aW1lc3BhcnRseScsICdjaGVja19vdXRfdGltZScgKTtcclxuXHJcblx0XHRcdFx0Ly8gRml4SW46IDkuOS4wLjMzLlxyXG5cdFx0XHRcdGlmICggZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5JyBdWyAnc3RhdHVzX2Zvcl9ib29raW5ncycgXS5pbmRleE9mKCAncGVuZGluZycgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGUyYXBwcm92ZScgKTtcclxuXHRcdFx0XHR9IGVsc2UgaWYgKCBkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknIF1bICdzdGF0dXNfZm9yX2Jvb2tpbmdzJyBdLmluZGV4T2YoICdhcHByb3ZlZCcgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGVfYXBwcm92ZWQnICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0ZGVmYXVsdDpcclxuXHRcdFx0XHQvLyBtaXhlZCBzdGF0dXNlczogJ2NoYW5nZV9vdmVyIGNoZWNrX291dCcgLi4uLiB2YXJpYXRpb25zLi4uLiBjaGVjayBtb3JlIGluIFx0XHRmdW5jdGlvbiB3cGJjX2dldF9hdmFpbGFiaWxpdHlfcGVyX2RheXNfYXJyKClcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9kYXknIF0gPSAnYXZhaWxhYmxlJztcclxuXHRcdH1cclxuXHJcblxyXG5cclxuXHRcdGlmICggJ2F2YWlsYWJsZScgIT0gZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5J11bJ3N0YXR1c19mb3JfZGF5JyBdICl7XHJcblxyXG5cdFx0XHR2YXIgaXNfc2V0X3BlbmRpbmdfZGF5c19zZWxlY3RhYmxlID0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdwZW5kaW5nX2RheXNfc2VsZWN0YWJsZScgKTtcdC8vIHNldCBwZW5kaW5nIGRheXMgc2VsZWN0YWJsZSAgICAgICAgICAvLyBGaXhJbjogOC42LjEuMTguXHJcblxyXG5cdFx0XHRzd2l0Y2ggKCBkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSApe1xyXG5cclxuXHRcdFx0XHRjYXNlICcnOlxyXG5cdFx0XHRcdFx0Ly8gVXN1YWxseSAgaXQncyBtZWFucyB0aGF0IGRheSAgaXMgYXZhaWxhYmxlIG9yIHVuYXZhaWxhYmxlIHdpdGhvdXQgdGhlIGJvb2tpbmdzXHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0Y2FzZSAncGVuZGluZyc6XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2RhdGUyYXBwcm92ZScgKTtcclxuXHRcdFx0XHRcdGlzX2RheV9zZWxlY3RhYmxlID0gKGlzX2RheV9zZWxlY3RhYmxlKSA/IHRydWUgOiBpc19zZXRfcGVuZGluZ19kYXlzX3NlbGVjdGFibGU7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0Y2FzZSAnYXBwcm92ZWQnOlxyXG5cdFx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdkYXRlX2FwcHJvdmVkJyApO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblxyXG5cdFx0XHRcdC8vIFNpdHVhdGlvbnMgZm9yIFwiY2hhbmdlLW92ZXJcIiBkYXlzOiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHRcdFx0Y2FzZSAncGVuZGluZ19wZW5kaW5nJzpcclxuXHRcdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2hlY2tfb3V0X3RpbWVfZGF0ZTJhcHByb3ZlJywgJ2NoZWNrX2luX3RpbWVfZGF0ZTJhcHByb3ZlJyApO1xyXG5cdFx0XHRcdFx0aXNfZGF5X3NlbGVjdGFibGUgPSAoaXNfZGF5X3NlbGVjdGFibGUpID8gdHJ1ZSA6IGlzX3NldF9wZW5kaW5nX2RheXNfc2VsZWN0YWJsZTtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0XHRjYXNlICdwZW5kaW5nX2FwcHJvdmVkJzpcclxuXHRcdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2hlY2tfb3V0X3RpbWVfZGF0ZTJhcHByb3ZlJywgJ2NoZWNrX2luX3RpbWVfZGF0ZV9hcHByb3ZlZCcgKTtcclxuXHRcdFx0XHRcdGlzX2RheV9zZWxlY3RhYmxlID0gKGlzX2RheV9zZWxlY3RhYmxlKSA/IHRydWUgOiBpc19zZXRfcGVuZGluZ19kYXlzX3NlbGVjdGFibGU7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0Y2FzZSAnYXBwcm92ZWRfcGVuZGluZyc6XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGVfYXBwcm92ZWQnLCAnY2hlY2tfaW5fdGltZV9kYXRlMmFwcHJvdmUnICk7XHJcblx0XHRcdFx0XHRpc19kYXlfc2VsZWN0YWJsZSA9IChpc19kYXlfc2VsZWN0YWJsZSkgPyB0cnVlIDogaXNfc2V0X3BlbmRpbmdfZGF5c19zZWxlY3RhYmxlO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblxyXG5cdFx0XHRcdGNhc2UgJ2FwcHJvdmVkX2FwcHJvdmVkJzpcclxuXHRcdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2hlY2tfb3V0X3RpbWVfZGF0ZV9hcHByb3ZlZCcsICdjaGVja19pbl90aW1lX2RhdGVfYXBwcm92ZWQnICk7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0ZGVmYXVsdDpcclxuXHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gWyBpc19kYXlfc2VsZWN0YWJsZSwgY3NzX2NsYXNzZXNfX2Zvcl9kYXRlLmpvaW4oICcgJyApIF07XHJcblx0fVxyXG5cclxuXHJcblx0LyoqXHJcblx0ICogTW91c2VvdmVyIGNhbGVuZGFyIGRhdGUgY2VsbHNcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBzdHJpbmdfZGF0ZVxyXG5cdCAqIEBwYXJhbSBkYXRlXHRcdFx0XHRcdFx0XHRcdFx0XHQtICBKYXZhU2NyaXB0IERhdGUgT2JqOiAgXHRcdE1vbiBEZWMgMTEgMjAyMyAwMDowMDowMCBHTVQrMDIwMCAoRWFzdGVybiBFdXJvcGVhbiBTdGFuZGFyZCBUaW
34111lKVxyXG5cdCAqIEBwYXJhbSBjYWxlbmRhcl9wYXJhbXNfYXJyXHRcdFx0XHRcdFx0LSAgQ2FsZW5kYXIgU2V0dGluZ3MgT2JqZWN0OiAgXHR7XHJcblx0ICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgXHRcdFx0XHRcdFx0XCJyZXNvdXJjZV9pZFwiOiA0XHJcblx0ICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0ICogQHBhcmFtIGRhdGVwaWNrX3RoaXNcdFx0XHRcdFx0XHRcdFx0LSB0aGlzIG9mIGRhdGVwaWNrIE9ialxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfX2NhbGVuZGFyX19vbl9ob3Zlcl9kYXlzKCBzdHJpbmdfZGF0ZSwgZGF0ZSwgY2FsZW5kYXJfcGFyYW1zX2FyciwgZGF0ZXBpY2tfdGhpcyApIHtcclxuXHJcblx0XHRpZiAoIG51bGwgPT09IGRhdGUgKSB7XHJcblx0XHRcdHdwYmNfY2FsZW5kYXJzX19jbGVhcl9kYXlzX2hpZ2hsaWdodGluZyggKCd1bmRlZmluZWQnICE9PSB0eXBlb2YgKGNhbGVuZGFyX3BhcmFtc19hcnJbICdyZXNvdXJjZV9pZCcgXSkpID8gY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdIDogJzEnICk7XHRcdC8vIEZpeEluOiAxMC41LjIuNC5cclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBjbGFzc19kYXkgICAgID0gd3BiY19fZ2V0X190ZF9jbGFzc19kYXRlKCBkYXRlICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzEtOS0yMDIzJ1xyXG5cdFx0dmFyIHNxbF9jbGFzc19kYXkgPSB3cGJjX19nZXRfX3NxbF9jbGFzc19kYXRlKCBkYXRlICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzIwMjMtMDEtMDknXHJcblx0XHR2YXIgcmVzb3VyY2VfaWQgPSAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YoY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdKSApID8gY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdIDogJzEnO1x0XHQvLyAnMSdcclxuXHJcblx0XHQvLyBHZXQgRGF0YSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIGRhdGVfYm9va2luZ19vYmogPSBfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKCByZXNvdXJjZV9pZCwgc3FsX2NsYXNzX2RheSApO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyB7Li4ufVxyXG5cclxuXHRcdGlmICggISBkYXRlX2Jvb2tpbmdfb2JqICl7IHJldHVybiBmYWxzZTsgfVxyXG5cclxuXHJcblx0XHQvLyBUIG8gbyBsIHQgaSBwIHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIHRvb2x0aXBfdGV4dCA9ICcnO1xyXG5cdFx0aWYgKCBkYXRlX2Jvb2tpbmdfb2JqWyAnc3VtbWFyeSddWyd0b29sdGlwX2F2YWlsYWJpbGl0eScgXS5sZW5ndGggPiAwICl7XHJcblx0XHRcdHRvb2x0aXBfdGV4dCArPSAgZGF0ZV9ib29raW5nX29ialsgJ3N1bW1hcnknXVsndG9vbHRpcF9hdmFpbGFiaWxpdHknIF07XHJcblx0XHR9XHJcblx0XHRpZiAoIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfZGF5X2Nvc3QnIF0ubGVuZ3RoID4gMCApe1xyXG5cdFx0XHR0b29sdGlwX3RleHQgKz0gIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfZGF5X2Nvc3QnIF07XHJcblx0XHR9XHJcblx0XHRpZiAoIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfdGltZXMnIF0ubGVuZ3RoID4gMCApe1xyXG5cdFx0XHR0b29sdGlwX3RleHQgKz0gIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfdGltZXMnIF07XHJcblx0XHR9XHJcblx0XHRpZiAoIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfYm9va2luZ19kZXRhaWxzJyBdLmxlbmd0aCA+IDAgKXtcclxuXHRcdFx0dG9vbHRpcF90ZXh0ICs9ICBkYXRlX2Jvb2tpbmdfb2JqWyAnc3VtbWFyeSddWyd0b29sdGlwX2Jvb2tpbmdfZGV0YWlscycgXTtcclxuXHRcdH1cclxuXHRcdHdwYmNfc2V0X3Rvb2x0aXBfX19mb3JfX2NhbGVuZGFyX2RhdGUoIHRvb2x0aXBfdGV4dCwgcmVzb3VyY2VfaWQsIGNsYXNzX2RheSApO1xyXG5cclxuXHJcblxyXG5cdFx0Ly8gIFUgbiBoIG8gdiBlIHIgaSBuIGcgICAgaW4gICAgVU5TRUxFQ1RBQkxFX0NBTEVOREFSICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdHZhciBpc191bnNlbGVjdGFibGVfY2FsZW5kYXIgPSAoIGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nX3Vuc2VsZWN0YWJsZScgKyByZXNvdXJjZV9pZCApLmxlbmd0aCA+IDApO1x0XHRcdFx0Ly8gRml4SW46IDguMC4xLjIuXHJcblx0XHR2YXIgaXNfYm9va2luZ19mb3JtX2V4aXN0ICAgID0gKCBqUXVlcnkoICcjYm9va2luZ19mb3JtX2RpdicgKyByZXNvdXJjZV9pZCApLmxlbmd0aCA+IDAgKTtcclxuXHJcblx0XHRpZiAoICggaXNfdW5zZWxlY3RhYmxlX2NhbGVuZGFyICkgJiYgKCAhIGlzX2Jvb2tpbmdfZm9ybV9leGlzdCApICl7XHJcblxyXG5cdFx0XHQvKipcclxuXHRcdFx0ICogIFVuIE
3411hvdmVyIGFsbCBkYXRlcyBpbiBjYWxlbmRhciAod2l0aG91dCB0aGUgYm9va2luZyBmb3JtKSwgaWYgb25seSBBdmFpbGFiaWxpdHkgQ2FsZW5kYXIgaGVyZSBhbmQgd2UgZG8gbm90IGluc2VydCBCb29raW5nIGZvcm0gYnkgbWlzdGFrZS5cclxuXHRcdFx0ICovXHJcblxyXG5cdFx0XHR3cGJjX2NhbGVuZGFyc19fY2xlYXJfZGF5c19oaWdobGlnaHRpbmcoIHJlc291cmNlX2lkICk7IFx0XHRcdFx0XHRcdFx0Ly8gQ2xlYXIgZGF5cyBoaWdobGlnaHRpbmdcclxuXHJcblx0XHRcdHZhciBjc3Nfb2ZfY2FsZW5kYXIgPSAnLndwYmNfb25seV9jYWxlbmRhciAjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZDtcclxuXHRcdFx0alF1ZXJ5KCBjc3Nfb2ZfY2FsZW5kYXIgKyAnIC5kYXRlcGljay1kYXlzLWNlbGwsICdcclxuXHRcdFx0XHQgICsgY3NzX29mX2NhbGVuZGFyICsgJyAuZGF0ZXBpY2stZGF5cy1jZWxsIGEnICkuY3NzKCAnY3Vyc29yJywgJ2RlZmF1bHQnICk7XHQvLyBTZXQgY3Vyc29yIHRvIERlZmF1bHRcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHJcblxyXG5cdFx0Ly8gIEQgYSB5IHMgICAgSCBvIHYgZSByIGkgbiBnICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdGlmIChcclxuXHRcdFx0ICAgKCBsb2NhdGlvbi5ocmVmLmluZGV4T2YoICdwYWdlPXdwYmMnICkgPT0gLTEgKVxyXG5cdFx0XHR8fCAoIGxvY2F0aW9uLmhyZWYuaW5kZXhPZiggJ3BhZ2U9d3BiYy1uZXcnICkgPiAwIClcclxuXHRcdFx0fHwgKCBsb2NhdGlvbi5ocmVmLmluZGV4T2YoICdwYWdlPXdwYmMtc2V0dXAnICkgPiAwIClcclxuXHRcdFx0fHwgKCBsb2NhdGlvbi5ocmVmLmluZGV4T2YoICdwYWdlPXdwYmMtYXZhaWxhYmlsaXR5JyApID4gMCApXHJcblx0XHRcdHx8ICggICggbG9jYXRpb24uaHJlZi5pbmRleE9mKCAncGFnZT13cGJjLXNldHRpbmdzJyApID4gMCApICAmJlxyXG5cdFx0XHRcdCAgKCBsb2NhdGlvbi5ocmVmLmluZGV4T2YoICcmdGFiPWZvcm0nICkgPiAwIClcclxuXHRcdFx0ICAgKVxyXG5cdFx0KXtcclxuXHRcdFx0Ly8gVGhlIHNhbWUgYXMgZGF0ZXMgc2VsZWN0aW9uLCAgYnV0IGZvciBkYXlzIGhvdmVyaW5nXHJcblxyXG5cdFx0XHRpZiAoICdmdW5jdGlvbicgPT0gdHlwZW9mKCB3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19oaWdobGlnaHRfX2JzICkgKXtcclxuXHRcdFx0XHR3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19oaWdobGlnaHRfX2JzKCBzcWxfY2xhc3NfZGF5LCBkYXRlLCByZXNvdXJjZV9pZCApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdH1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIFNlbGVjdCBjYWxlbmRhciBkYXRlIGNlbGxzXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gZGF0ZVx0XHRcdFx0XHRcdFx0XHRcdFx0LSAgSmF2YVNjcmlwdCBEYXRlIE9iajogIFx0XHRNb24gRGVjIDExIDIwMjMgMDA6MDA6MDAgR01UKzAyMDAgKEVhc3Rlcm4gRXVyb3BlYW4gU3RhbmRhcmQgVGltZSlcclxuXHQgKiBAcGFyYW0gY2FsZW5kYXJfcGFyYW1zX2Fyclx0XHRcdFx0XHRcdC0gIENhbGVuZGFyIFNldHRpbmdzIE9iamVjdDogIFx0e1xyXG5cdCAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgIFx0XHRcdFx0XHRcdFwicmVzb3VyY2VfaWRcIjogNFxyXG5cdCAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdCAqIEBwYXJhbSBkYXRlcGlja190aGlzXHRcdFx0XHRcdFx0XHRcdC0gdGhpcyBvZiBkYXRlcGljayBPYmpcclxuXHQgKlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfX2NhbGVuZGFyX19vbl9zZWxlY3RfZGF5cyggZGF0ZSwgY2FsZW5kYXJfcGFyYW1zX2FyciwgZGF0ZXBpY2tfdGhpcyApe1xyXG5cclxuXHRcdHZhciByZXNvdXJjZV9pZCA9ICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZihjYWxlbmRhcl9wYXJhbXNfYXJyWyAncmVzb3VyY2VfaWQnIF0pICkgPyBjYWxlbmRhcl9wYXJhbXNfYXJyWyAncmVzb3VyY2VfaWQnIF0gOiAnMSc7XHRcdC8vICcxJ1xyXG5cclxuXHRcdC8vIFNldCB1bnNlbGVjdGFibGUsICBpZiBvbmx5IEF2YWlsYWJpbGl0eSBDYWxlbmRhciAgaGVyZSAoYW5kIHdlIGRvIG5vdCBpbnNlcnQgQm9va2luZyBmb3JtIGJ5IG1pc3Rha2UpLlxyXG5cdFx0dmFyIGlzX3Vuc2VsZWN0YWJsZV9jYWxlbmRhciA9ICggalF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmdfdW5zZWxlY3RhYmxlJyArIHJlc291cmNlX2lkICkubGVuZ3RoID4gMCk7XHRcdFx0XHQvLyBGaXhJbjogOC4wLjEuMi5cclxuXHRcdHZhciBpc19ib29raW5nX2Zvcm1fZXhpc3QgICAgPSAoIGpRdWVyeSggJyNib29raW5nX2Zvcm1fZGl2JyArIHJlc291cmNlX2lkICkubGVuZ3RoID4gMCApO1xyXG5cdFx0aWYgKCAoIGlzX3Vuc2VsZWN0YWJsZV9jYWxlbmRhciApICYmICggISBpc19ib29raW5nX2Zvcm1fZXhpc3QgKSApe1xyXG5cdFx0XHR3cGJjX2NhbGVuZGFyX191bnNlbGVjdF9hbGxfZGF0ZXMoIHJlc291cmNlX2lkICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBVbnNlbGVjdCBEYXRlc1xyXG5cdFx0XHRqUXVlcnkoJy53cGJjX29ubHlfY2FsZW5kYXIgLnBvcG92ZXJfY2FsZW5kYXJfaG92ZXInKS5yZW1vdmUoKTsgICAgICAgICAgICAgICAgICAgICAgXHRcdFx0XHRcdFx0XHQvLyBIaWRlIGFsbCBvcGVuZWQgcG9wb3ZlcnNcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdGpRdWVyeSggJyNkYXRlX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS52YWwoIGRhdGUgKTtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEFkZCBzZWxlY3RlZCBkYXRlcyB0byAgaGlkZGVuIHRleHRhcmVhXHJcblxyXG5cclxuXHRcdGlmICggJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mICh3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19zZWxlY3RfX2JzKSApeyB3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19zZWxlY3RfX2JzKCBkYXRlLCByZXNvdXJjZV9pZCApOyB9XHJcblxyXG5cdFx0d3BiY19kaXNhYmxlX3RpbWVfZmllbGRzX2luX2Jvb2tpbmdfZm9ybSggcmVzb3VyY2VfaWQgKTtcclxuXHJcblx0XHQvLyBIb29rIC0tIHRyaWdnZXIgZGF5IHNlbGVjdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIG1vdXNlX2NsaWNrZWRfZGF0ZXMgPSBkYXRlO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gQ2FuIGJlOiBcIjA1LjEwLjIwMjMgLSAwNy4xMC4yMDIzXCIgIHwgIFwiMTAuMTAuMjAyMyAtIDEwLjEwLjIwMjNcIiAgfFxyXG5cdFx0dmFyIGFsbF9zZWxlY3RlZF9kYXRlc19hcnIgPSB3cGJjX2dldF9fc2VsZWN0ZWRfZGF0ZXNfc3FsX19hc19hcnIoIHJlc291cmNlX2lkICk7XHRcdFx0XHRcdFx0XHRcdFx0Ly8gQ2FuIGJlOiBbIFwiMjAyMy0xMC0wNVwiLCBcIjIwMjMtMTAtMDZcIiwgXCIyMDIzLTEwLTA3XCIsIOKApiBdXHJcblx0XHRqUXVlcnkoIFwiLmJvb2tpbmdfZm9ybV9kaXZcIiApLnRyaWdnZXIoIFwiZGF0ZV9zZWxlY3RlZFwiLCBbIHJlc291cmNlX2lkLCBtb3VzZV9jbGlja2VkX2RhdGVzLCBhbGxfc2VsZWN0ZWRfZGF0ZXNfYXJyIF0gKTtcclxuXHR9XHJcblxyXG5cdC8vIE1hcmsgbWlkZGxlIHNlbGVjdGVkIGRhdGVzIHdpdGggMC41IG9wYWNpdHlcdFx0Ly8gRml4SW46IDEwLjMuMC45LlxyXG5cdGpRdWVyeSggZG9jdW1lbnQgKS5yZWFkeSggZnVuY3Rpb24gKCl7XHJcblx0XHRqUXVlcnkoIFwiLmJvb2tpbmdfZm9ybV9kaXZcIiApLm9uKCAnZGF0ZV9zZWxlY3RlZCcsIGZ1bmN0aW9uICggZXZlbnQsIHJlc291cmNlX2lkLCBkYXRlICl7XHJcblx0XHRcdFx0aWYgKFxyXG5cdFx0XHRcdFx0ICAgKCAgJ2ZpeGVkJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApKVxyXG5cdFx0XHRcdFx0fHwgKCdkeW5hbWljJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApKVxyXG5cdFx0XHRcdCl7XHJcblx0XHRcdFx0XHR2YXIgY2xvc2VkX3RpbWVyID0gc2V0VGltZW91dCggZnVuY3Rpb24gKCl7XHJcblx0XHRcdFx0XHRcdHZhciBtaWRkbGVfZGF5c19vcGFjaXR5ID0gX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAnY2FsZW5kYXJzX19kYXlzX3NlbGVjdGlvbl9fbWlkZGxlX2RheXNfb3BhY2l0eScgKTtcclxuXHRcdFx0XHRcdFx0alF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKyAnIC5kYXRlcGljay1jdXJyZW50LWRheScgKS5ub3QoIFwiLnNlbGVjdGVkX2NoZWNrX2luX291dFwiICkuY3NzKCAnb3BhY2l0eScsIG1pZGRsZV9kYXlzX29wYWNpdHkgKTtcclxuXHRcdFx0XHRcdH0sIDEwICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0gKTtcclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIC0tICBUIGkgbSBlICAgIEYgaSBlIGwgZCBzICAgICBzdGFydCAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQgKi9cclxuXHJcblx0LyoqXHJcblx0ICogRGlzYWJsZSB0aW1lIHNsb3RzIGluIGJvb2tpbmcgZm9ybSBkZXBlbmQgb24gc2VsZWN0ZWQgZGF0ZXMgYW5kIGJvb2tlZCBkYXRlcy90aW1lc1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19kaXNhYmxlX3RpbWVfZmllbGRzX2luX2Jvb2tpbmdfZm9ybSggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFx0MS4gR2V0IGFsbCB0aW1lIGZpZWxkcyBpbiB0aGUgYm9va2luZyBmb3JtIGFzIGFycmF5ICBvZiBvYmplY3RzXHJcblx0XHQgKiBcdFx0XHRcdFx0W1xyXG5cdFx0ICogXHRcdFx0XHRcdCBcdCAgIHtcdGpxdWVyeV9vcHRpb246ICAgICAgalF1ZXJ5X09iamVjdCB7fVxyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbW
3411U6ICAgICAgICAgICAgICAgJ3JhbmdldGltZTJbXSdcclxuXHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR0aW1lc19hc19zZWNvbmRzOiAgIFsgMjE2MDAsIDIzNDAwIF1cclxuXHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCAtIDA2OjMwJ1xyXG5cdFx0ICogXHRcdFx0XHRcdCAgICAgfVxyXG5cdFx0ICogXHRcdFx0XHRcdCAgLi4uXHJcblx0XHQgKiBcdFx0XHRcdFx0XHQgICB7XHRqcXVlcnlfb3B0aW9uOiAgICAgIGpRdWVyeV9PYmplY3Qge31cclxuXHRcdCAqIFx0XHRcdFx0XHRcdFx0XHRuYW1lOiAgICAgICAgICAgICAgICdzdGFydHRpbWUyW10nXHJcblx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kczogICBbIDIxNjAwIF1cclxuXHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCdcclxuXHRcdCAqICBcdFx0XHRcdFx0ICAgIH1cclxuXHRcdCAqIFx0XHRcdFx0XHQgXVxyXG5cdFx0ICovXHJcblx0XHR2YXIgdGltZV9maWVsZHNfb2JqX2FyciA9IHdwYmNfZ2V0X190aW1lX2ZpZWxkc19faW5fYm9va2luZ19mb3JtX19hc19hcnIoIHJlc291cmNlX2lkICk7XHJcblxyXG5cdFx0Ly8gMi4gR2V0IGFsbCBzZWxlY3RlZCBkYXRlcyBpbiAgU1FMIGZvcm1hdCAgbGlrZSB0aGlzIFsgXCIyMDIzLTA4LTIzXCIsIFwiMjAyMy0wOC0yNFwiLCBcIjIwMjMtMDgtMjVcIiwgLi4uIF1cclxuXHRcdHZhciBzZWxlY3RlZF9kYXRlc19hcnIgPSB3cGJjX2dldF9fc2VsZWN0ZWRfZGF0ZXNfc3FsX19hc19hcnIoIHJlc291cmNlX2lkICk7XHJcblxyXG5cdFx0Ly8gMy4gR2V0IGNoaWxkIGJvb2tpbmcgcmVzb3VyY2VzICBvciBzaW5nbGUgYm9va2luZyByZXNvdXJjZSAgdGhhdCAgZXhpc3QgIGluIGRhdGVzXHJcblx0XHR2YXIgY2hpbGRfcmVzb3VyY2VzX2FyciA9IHdwYmNfY2xvbmVfb2JqKCBfd3BiYy5ib29raW5nX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAncmVzb3VyY2VzX2lkX2Fycl9faW5fZGF0ZXMnICkgKTtcclxuXHJcblx0XHR2YXIgc3FsX2RhdGU7XHJcblx0XHR2YXIgY2hpbGRfcmVzb3VyY2VfaWQ7XHJcblx0XHR2YXIgbWVyZ2VkX3NlY29uZHM7XHJcblx0XHR2YXIgdGltZV9maWVsZHNfb2JqO1xyXG5cdFx0dmFyIGlzX2ludGVyc2VjdDtcclxuXHRcdHZhciBpc19jaGVja19pbjtcclxuXHJcblx0XHR2YXIgdG9kYXlfdGltZV9fcmVhbCAgPSBuZXcgRGF0ZSggX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndGltZV9sb2NhbF9hcnInIClbMF0sICggcGFyc2VJbnQoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RpbWVfbG9jYWxfYXJyJyApWzFdICkgLSAxKSwgX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndGltZV9sb2NhbF9hcnInIClbMl0sIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RpbWVfbG9jYWxfYXJyJyApWzNdLCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICd0aW1lX2xvY2FsX2FycicgKVs0XSwgMCApO1xyXG5cdFx0dmFyIHRvZGF5X3RpbWVfX3NoaWZ0ID0gbmV3IERhdGUoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RvZGF5X2FycicgICAgICApWzBdLCAoIHBhcnNlSW50KCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICAgICAgJ3RvZGF5X2FycicgKVsxXSApIC0gMSksIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RvZGF5X2FycicgICAgICApWzJdLCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICd0b2RheV9hcnInICAgICAgKVszXSwgX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndG9kYXlfYXJyJyAgICAgIClbNF0sIDAgKTtcclxuXHJcblx0XHQvLyA0LiBMb29wICBhbGwgIHRpbWUgRmllbGRzIG9wdGlvbnNcdFx0Ly8gRml4SW46IDEwLjMuMC4yLlxyXG5cdFx0Zm9yICggbGV0IGZpZWxkX2tleSA9IDA7IGZpZWxkX2tleSA8IHRpbWVfZmllbGRzX29ial9hcnIubGVuZ3RoOyBmaWVsZF9rZXkrKyApe1xyXG5cclxuXHRcdFx0dGltZV9maWVsZHNfb2JqX2FyclsgZmllbGRfa2V5IF0uZGlzYWJsZWQgPSAwOyAgICAgICAgICAvLyBCeSBkZWZhdWx0LCB0aGlzIHRpbWUgZmllbGQgaXMgbm90IGRpc2FibGVkLlxyXG5cclxuXHRcdFx0dGltZV9maWVsZHNfb2JqID0gdGltZV9maWVsZHNfb2JqX2FyclsgZmllbGRfa2V5IF07XHRcdC8vIHsgdGltZXNfYXNfc2Vjb25kczogWyAyMTYwMCwgMjM0MDAgXSwgdmFsdWVfb3B0aW9uXzI0aDogJzA2OjAwIC0gMDY6MzAnLCBuYW1lOiAncmFuZ2V0aW1lMltdJywganF1ZXJ5X29wdGlvbjogalF1ZXJ5X09iamVjdCB7fX1cclxuXHJcblx0XHRcdC8vIExvb3AgIGFsbCAgc2VsZWN0ZWQgZGF0ZXMuXHJcblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHNlbGVjdGVkX2RhdGVzX2Fyci5sZW5ndGg7IGkrKyApIHtcclxuXHJcblx0XHRcdFx0Ly8gR2V0IERhdGU6ICcyMDIzLTA4LTE4Jy5cclxuXHRcdFx0XHRzcWxfZGF0ZSA9IHNlbGVjdGVkX2RhdGVzX2FycltpXTtcclxuXHJcblx0XHRcdFx0dmFyIGlzX3RpbWVfaW5fcGFzdCA9IHdwYmNfY2hlY2tfaXNfdGltZV9pbl9wYXN0KCB0b2RheV90aW1lX19zaGlmdCwgc3FsX2RhdGUsIHRpbWVfZmllbGRzX29iaiApO1xyXG5cdFx0XHRcdC8vIEV4Y2VwdGlvbiAgZm9yICdFbmQgVGltZScgZmllbGQsICB3aGVuICBzZWxlY3RlZCBzZXZlcmFsIGRhdGVzLiAvLyBGaXhJbjogMTAuMTQuMS41LlxyXG5cdFx0XHRcdGlmICggKCdPbicgIT09IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnYm9va2luZ19yZWN1cnJlbnRfdGltZScgKSkgJiZcclxuXHRcdFx0XHRcdCgtMSAhPT0gdGltZV9maWVsZHNfb2JqLm5hbWUuaW5kZXhPZiggJ2VuZHRpbWUnICkpICYmXHJcblx0XHRcdFx0XHQoc2VsZWN0ZWRfZGF0ZXNfYXJyLmxlbmd0aCA+IDEpXHJcblx0XHRcdFx0KSB7XHJcblx0XHRcdFx0XHRpc190aW1lX2luX3Bhc3QgPSB3cGJjX2NoZWNrX2lzX3RpbWVfaW5fcGFzdCggdG9kYXlfdGltZV9fc2hpZnQsIHNlbGVjdGVkX2RhdGVzX2Fyclsoc2VsZWN0ZWRfZGF0ZXNfYXJyLmxlbmd0aCAtIDEpXSwgdGltZV9maWVsZHNfb2JqICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICggaXNfdGltZV9pbl9wYXN0ICkge1xyXG5cdFx0XHRcdFx0Ly8gVGhpcyB0aW1lIGZvciBzZWxlY3RlZCBkYXRlIGFscmVhZHkgIGluIHRoZSBwYXN0LlxyXG5cdFx0XHRcdFx0dGltZV9maWVsZHNfb2JqX2FycltmaWVsZF9rZXldLmRpc2FibGVkID0gMTtcclxuXHRcdFx0XHRcdGJyZWFrO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBleGlzdCAgZnJvbSAgIERhdGVzIExPT1AuXHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdC8vIEZpeEluOiA5LjkuMC4zMS5cclxuXHRcdFx0XHRpZiAoXHJcblx0XHRcdFx0XHQgICAoICdPZmYnID09PSBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2Jvb2tpbmdfcmVjdXJyZW50X3RpbW
3411UnICkgKVxyXG5cdFx0XHRcdFx0JiYgKCBzZWxlY3RlZF9kYXRlc19hcnIubGVuZ3RoPjEgKVxyXG5cdFx0XHRcdCl7XHJcblx0XHRcdFx0XHQvL1RPRE86IHNraXAgc29tZSBmaWVsZHMgY2hlY2tpbmcgaWYgaXQncyBzdGFydCAvIGVuZCB0aW1lIGZvciBtdWxwbGUgZGF0ZXMgIHNlbGVjdGlvbiAgbW9kZS5cclxuXHRcdFx0XHRcdC8vVE9ETzogd2UgbmVlZCB0byBmaXggc2l0dWF0aW9uICBmb3IgZW50aW1lcywgIHdoZW4gIHVzZXIgIHNlbGVjdCAgc2V2ZXJhbCAgZGF0ZXMsICBhbmQgaW4gc3RhcnQgIHRpbWUgYm9va2VkIDAwOjAwIC0gMTU6MDAgLCBidXQgc3lzdHNtZSBibG9jayB1bnRpbGwgMTU6MDAgdGhlIGVuZCB0aW1lIGFzIHdlbGwsICB3aGljaCAgaXMgd3JvbmcsICBiZWNhdXNlIGl0IDIgb3IgMyBkYXRlcyBzZWxlY3Rpb24gIGFuZCBlbmQgZGF0ZSBjYW4gYmUgZnVsbHUgIGF2YWlsYWJsZVxyXG5cclxuXHRcdFx0XHRcdGlmICggKDAgPT0gaSkgJiYgKHRpbWVfZmllbGRzX29ialsgJ25hbWUnIF0uaW5kZXhPZiggJ2VuZHRpbWUnICkgPj0gMCkgKXtcclxuXHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRpZiAoICggKHNlbGVjdGVkX2RhdGVzX2Fyci5sZW5ndGgtMSkgPT0gaSApICYmICh0aW1lX2ZpZWxkc19vYmpbICduYW1lJyBdLmluZGV4T2YoICdzdGFydHRpbWUnICkgPj0gMCkgKXtcclxuXHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHJcblxyXG5cdFx0XHRcdHZhciBob3dfbWFueV9yZXNvdXJjZXNfaW50ZXJzZWN0ZWQgPSAwO1xyXG5cdFx0XHRcdC8vIExvb3AgYWxsIHJlc291cmNlcyBJRFxyXG5cdFx0XHRcdFx0Ly8gZm9yICggdmFyIHJlc19rZXkgaW4gY2hpbGRfcmVzb3VyY2VzX2FyciApe1x0IFx0XHRcdFx0XHRcdC8vIEZpeEluOiAxMC4zLjAuMi5cclxuXHRcdFx0XHRmb3IgKCBsZXQgcmVzX2tleSA9IDA7IHJlc19rZXkgPCBjaGlsZF9yZXNvdXJjZXNfYXJyLmxlbmd0aDsgcmVzX2tleSsrICl7XHJcblxyXG5cdFx0XHRcdFx0Y2hpbGRfcmVzb3VyY2VfaWQgPSBjaGlsZF9yZXNvdXJjZXNfYXJyWyByZXNfa2V5IF07XHJcblxyXG5cdFx0XHRcdFx0Ly8gX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMTJdLmJvb2tlZF90aW1lX3Nsb3RzLm1lcmdlZF9zZWNvbmRzXHRcdD0gWyBcIjA3OjAwOjExIC0gMDc6MzA6MDJcIiwgXCIxMDowMDoxMSAtIDAwOjAwOjAwXCIgXVxyXG5cdFx0XHRcdFx0Ly8gX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3NlY29uZHNcdFx0XHQ9IFsgIFsgMjUyMTEsIDI3MDAyIF0sIFsgMzYwMTEsIDg2NDAwIF0gIF1cclxuXHJcblx0XHRcdFx0XHRpZiAoIGZhbHNlICE9PSBfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKCByZXNvdXJjZV9pZCwgc3FsX2RhdGUgKSApe1xyXG5cdFx0XHRcdFx0XHRtZXJnZWRfc2Vjb25kcyA9IF93cGJjLmJvb2tpbmdzX2luX2NhbGVuZGFyX19nZXRfZm9yX2RhdGUoIHJlc291cmNlX2lkLCBzcWxfZGF0ZSApWyBjaGlsZF9yZXNvdXJjZV9pZCBdLmJvb2tlZF90aW1lX3Nsb3RzLm1lcmdlZF9zZWNvbmRzO1x0XHQvLyBbICBbIDI1MjExLCAyNzAwMiBdLCBbIDM2MDExLCA4NjQwMCBdICBdXHJcblx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRtZXJnZWRfc2Vjb25kcyA9IFtdO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYgKCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kcy5sZW5ndGggPiAxICl7XHJcblx0XHRcdFx0XHRcdGlzX2ludGVyc2VjdCA9IHdwYmNfaXNfaW50ZXJzZWN0X19yYW5nZV90aW1lX2ludGVydmFsKCAgW1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRbXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KCBwYXJzZUludCggdGltZV9maWVsZHNfb2JqLnRpbWVzX2FzX3NlY29uZHNbMF0gKSArIDIwICksXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KCBwYXJzZUludCggdGltZV9maWVsZHNfb2JqLnRpbWVzX2FzX3NlY29uZHNbMV0gKSAtIDIwIClcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0LCBtZXJnZWRfc2Vjb25kcyApO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0aXNfY2hlY2tfaW4gPSAoLTEgIT09IHRpbWVfZmllbGRzX29iai5uYW1lLmluZGV4T2YoICdzdGFydCcgKSk7XHJcblx0XHRcdFx0XHRcdGlzX2ludGVyc2VjdCA9IHdwYmNfaXNfaW50ZXJzZWN0X19vbmVfdGltZV9pbnRlcnZhbChcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCggKCBpc19jaGVja19pbiApXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgID8gcGFyc2VJbnQoIHRpbWVfZmllbGRzX29iai50aW1lc19hc19zZWNvbmRzICkgKyAyMFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICA6IHBhcnNlSW50KCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kcyApIC0gMjBcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdClcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCwgbWVyZ2VkX3NlY29uZHMgKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGlmIChpc19pbnRlcnNlY3Qpe1xyXG5cdFx0XHRcdFx0XHRob3dfbWFueV9yZXNvdXJjZXNfaW50ZXJzZWN0ZWQrKztcdFx0XHQvLyBJbmNyZWFzZVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmICggY2hpbGRfcmVzb3VyY2VzX2Fyci5sZW5ndGggPT0gaG93X2
34111hbnlfcmVzb3VyY2VzX2ludGVyc2VjdGVkICkge1xyXG5cdFx0XHRcdFx0Ly8gQWxsIHJlc291cmNlcyBpbnRlcnNlY3RlZCwgIHRoZW4gIGl0J3MgbWVhbnMgdGhhdCB0aGlzIHRpbWUtc2xvdCBvciB0aW1lIG11c3QgIGJlICBEaXNhYmxlZCwgYW5kIHdlIGNhbiAgZXhpc3QgIGZyb20gICBzZWxlY3RlZF9kYXRlc19hcnIgTE9PUFxyXG5cclxuXHRcdFx0XHRcdHRpbWVfZmllbGRzX29ial9hcnJbIGZpZWxkX2tleSBdLmRpc2FibGVkID0gMTtcclxuXHRcdFx0XHRcdGJyZWFrO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBleGlzdCAgZnJvbSAgIERhdGVzIExPT1BcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblxyXG5cdFx0Ly8gNS4gTm93IHdlIGNhbiBkaXNhYmxlIHRpbWUgc2xvdCBpbiBIVE1MIGJ5ICB1c2luZyAgKCBmaWVsZC5kaXNhYmxlZCA9PSAxICkgcHJvcGVydHlcclxuXHRcdHdwYmNfX2h0bWxfX3RpbWVfZmllbGRfb3B0aW9uc19fc2V0X2Rpc2FibGVkKCB0aW1lX2ZpZWxkc19vYmpfYXJyICk7XHJcblxyXG5cdFx0alF1ZXJ5KCBcIi5ib29raW5nX2Zvcm1fZGl2XCIgKS50cmlnZ2VyKCAnd3BiY19ob29rX3RpbWVzbG90c19kaXNhYmxlZCcsIFtyZXNvdXJjZV9pZCwgc2VsZWN0ZWRfZGF0ZXNfYXJyXSApO1x0XHRcdFx0XHQvLyBUcmlnZ2VyIGhvb2sgb24gZGlzYWJsaW5nIHRpbWVzbG90cy5cdFx0VXNhZ2U6IFx0alF1ZXJ5KCBcIi5ib29raW5nX2Zvcm1fZGl2XCIgKS5vbiggJ3dwYmNfaG9va190aW1lc2xvdHNfZGlzYWJsZWQnLCBmdW5jdGlvbiAoIGV2ZW50LCBia190eXBlLCBhbGxfZGF0ZXMgKXsgLi4uIH0gKTtcdFx0Ly8gRml4SW46IDguNy4xMS45LlxyXG5cdH1cclxuXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBDaGVjayBpZiBzcGVjaWZpYyB0aW1lKC1zbG90KSBhbHJlYWR5ICBpbiB0aGUgcGFzdCBmb3Igc2VsZWN0ZWQgZGF0ZVxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSBqc19jdXJyZW50X3RpbWVfdG9fY2hlY2tcdFx0LSBKUyBEYXRlXHJcblx0XHQgKiBAcGFyYW0gc3FsX2RhdGVcdFx0XHRcdFx0XHQtICcyMDI1LTAxLTI2J1xyXG5cdFx0ICogQHBhcmFtIHRpbWVfZmllbGRzX29ialx0XHRcdFx0LSBPYmplY3RcclxuXHRcdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2NoZWNrX2lzX3RpbWVfaW5fcGFzdCgganNfY3VycmVudF90aW1lX3RvX2NoZWNrLCBzcWxfZGF0ZSwgdGltZV9maWVsZHNfb2JqICkge1xyXG5cclxuXHRcdFx0Ly8gRml4SW46IDEwLjkuNi40XHJcblx0XHRcdHZhciBzcWxfZGF0ZV9hcnIgPSBzcWxfZGF0ZS5zcGxpdCggJy0nICk7XHJcblx0XHRcdHZhciBzcWxfZGF0ZV9fbWlkbmlnaHQgPSBuZXcgRGF0ZSggcGFyc2VJbnQoIHNxbF9kYXRlX2FyclswXSApLCAoIHBhcnNlSW50KCBzcWxfZGF0ZV9hcnJbMV0gKSAtIDEgKSwgcGFyc2VJbnQoIHNxbF9kYXRlX2FyclsyXSApLCAwLCAwLCAwICk7XHJcblx0XHRcdHZhciBzcWxfZGF0ZV9fbWlkbmlnaHRfbWlsaXNlY29uZHMgPSBzcWxfZGF0ZV9fbWlkbmlnaHQuZ2V0VGltZSgpO1xyXG5cclxuXHRcdFx0dmFyIGlzX2ludGVyc2VjdCA9IGZhbHNlO1xyXG5cclxuXHRcdFx0aWYgKCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kcy5sZW5ndGggPiAxICkge1xyXG5cclxuXHRcdFx0XHRpZiAoIGpzX2N1cnJlbnRfdGltZV90b19jaGVjay5nZXRUaW1lKCkgPiAoc3FsX2RhdGVfX21pZG5pZ2h0X21pbGlzZWNvbmRzICsgKHBhcnNlSW50KCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kc1swXSApICsgMjApICogMTAwMCkgKSB7XHJcblx0XHRcdFx0XHRpc19pbnRlcnNlY3QgPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoIGpzX2N1cnJlbnRfdGltZV90b19jaGVjay5nZXRUaW1lKCkgPiAoc3FsX2RhdGVfX21pZG5pZ2h0X21pbGlzZWNvbmRzICsgKHBhcnNlSW50KCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kc1sxXSApIC0gMjApICogMTAwMCkgKSB7XHJcblx0XHRcdFx0XHRpc19pbnRlcnNlY3QgPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dmFyIGlzX2NoZWNrX2luID0gKC0xICE9PSB0aW1lX2ZpZWxkc19vYmoubmFtZS5pbmRleE9mKCAnc3RhcnQnICkpO1xyXG5cclxuXHRcdFx0XHR2YXIgdGltZXNfYXNfc2Vjb25kc19jaGVjayA9IChpc19jaGVja19pbikgPyBwYXJzZUludCggdGltZV9maWVsZHNfb2JqLnRpbWVzX2FzX3NlY29uZHMgKSArIDIwIDogcGFyc2VJbnQoIHRpbWVfZmllbGRzX29iai50aW1lc19hc19zZWNvbmRzICkgLSAyMDtcclxuXHJcblx0XHRcdFx0dGltZXNfYXNfc2Vjb25kc19jaGVjayA9IHNxbF9kYXRlX19taWRuaWdodF9taWxpc2Vjb25kcyArIHRpbWVzX2FzX3NlY29uZHNfY2hlY2sgKiAxMDAwO1xyXG5cclxuXHRcdFx0XHRpZiAoIGpzX2N1cnJlbnRfdGltZV90b19jaGVjay5nZXRUaW1lKCkgPiB0aW1lc19hc19zZWNvbmRzX2NoZWNrICkge1xyXG5cdFx0XHRcdFx0aXNfaW50ZXJzZWN0ID0gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiBpc19pbnRlcnNlY3Q7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBJcyBudW1iZXIgaW5zaWRlIC9pbnRlcnNlY3QgIG9mIGFycmF5IG9mIGludGVydmFscyA/XHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHRpbWVfQVx0XHQgICAgIFx0LSAyNTgwMFxyXG5cdFx0ICogQHBhcmFtIHRpbWVfaW50ZXJ2YWxfQlx0XHQtIFsgIFsgMjUyMTEsIDI3MDAyIF0sIFsgMzYwMTEsIDg2NDAwIF0gIF1cclxuXHRcdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2lzX2ludGVyc2VjdF9fb25lX3RpbWVfaW50ZXJ2YWwoIHRpbWVfQSwgdGltZV9pbnRlcnZhbF9CICl7XHJcblxyXG5cdFx0XHRmb3IgKCB2YXIgaiA9IDA7IGogPCB0aW1lX2ludGVydmFsX0IubGVuZ3RoOyBqKysgKXtcclxuXHJcblx0XHRcdFx0aWYgKCAocGFyc2VJbnQoIHRpbWVfQSApID4gcGFyc2VJbnQoIHRpbWVfaW50ZXJ2YWxfQlsgaiBdWyAwIF0gKSkgJiYgKHBhcnNlSW50KCB0aW1lX0EgKSA8IHBhcnNlSW50KCB0aW1lX2ludGVydmFsX0JbIGogXVsgMSBdICkpICl7XHJcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gaWYgKCAoIHBhcnNlSW50KCB0aW1lX0EgKSA9PSBwYXJzZUludCggdGltZV9pbnRlcnZhbF9CWyBqIF1bIDAgXSApICkgfHwgKCBwYXJzZUludCggdGltZV9BICkgPT0gcGFyc2VJbnQoIHRpbWVfaW50ZXJ2YWxfQlsgaiBdWyAxIF0gKSApICkge1xyXG5cdFx0XHRcdC8vIFx0XHRcdC8vIFRpbWUgQSBqdXN0ICBhdCAgdGhlIGJvcmRlciBvZiBpbnRlcnZhbFxyXG5cdFx0XHRcdC8vIH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdCAgICByZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBJcyB0aGVzZSBhcnJheSBvZiBpbnRlcnZhbHMgaW50ZXJzZWN0ZWQgP1xyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB0aW1lX2ludGVydmFsX0FcdFx0LSBbIFsgMjE2MDAsIDIzNDAwIF0gXVxyXG5cdFx0ICogQHBhcmFtIHRpbWVfaW50ZXJ2YWxfQlx0XHQtIFsgIFsgMjUyMTEsIDI3MDAyIF0sIFsgMzYwMTEsIDg2NDAwIF0gIF1cclxuXHRcdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2lzX2ludGVyc2VjdF9fcmFuZ2VfdGltZV9pbnRlcnZhbCggdGltZV9pbnRlcnZhbF9BLCB0aW1lX2ludGVydmFsX0IgKXtcclxuXHJcblx0XHRcdHZhciBpc19pbnRlcnNlY3Q7XHJcblxyXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aW1lX2ludGVydmFsX0EubGVuZ3RoOyBpKysgKXtcclxuXHJcblx0XHRcdFx0Zm9yICggdmFyIGogPSAwOyBqIDwgdGltZV9pbnRlcnZhbF9CLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHRcdFx0aXNfaW50ZXJzZWN0ID0gd3BiY19pbnRlcnZhbHNfX2lzX2ludGVyc2VjdGVkKCB0aW1lX2ludGVydmFsX0FbIGkgXSwgdGltZV9pbnRlcnZhbF9CWyBqIF0gKTtcclxuXHJcblx0XHRcdFx0XHRpZiAoIGlzX2ludGVyc2VjdCApe1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybi
3411BmYWxzZTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEdldCBhbGwgdGltZSBmaWVsZHMgaW4gdGhlIGJvb2tpbmcgZm9ybSBhcyBhcnJheSAgb2Ygb2JqZWN0c1xyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSByZXNvdXJjZV9pZFxyXG5cdFx0ICogQHJldHVybnMgW11cclxuXHRcdCAqXHJcblx0XHQgKiBcdFx0RXhhbXBsZTpcclxuXHRcdCAqIFx0XHRcdFx0XHRbXHJcblx0XHQgKiBcdFx0XHRcdFx0IFx0ICAge1xyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdHZhbHVlX29wdGlvbl8yNGg6ICAgJzA2OjAwIC0gMDY6MzAnXHJcblx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kczogICBbIDIxNjAwLCAyMzQwMCBdXHJcblx0XHQgKiBcdFx0XHRcdFx0IFx0ICAgXHRcdGpxdWVyeV9vcHRpb246ICAgICAgalF1ZXJ5X09iamVjdCB7fVxyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbWU6ICAgICAgICAgICAgICAgJ3JhbmdldGltZTJbXSdcclxuXHRcdCAqIFx0XHRcdFx0XHQgICAgIH1cclxuXHRcdCAqIFx0XHRcdFx0XHQgIC4uLlxyXG5cdFx0ICogXHRcdFx0XHRcdFx0ICAge1xyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdHZhbHVlX29wdGlvbl8yNGg6ICAgJzA2OjAwJ1xyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdHRpbWVzX2FzX3NlY29uZHM6ICAgWyAyMTYwMCBdXHJcblx0XHQgKiBcdFx0XHRcdFx0XHQgICBcdFx0anF1ZXJ5X29wdGlvbjogICAgICBqUXVlcnlfT2JqZWN0IHt9XHJcblx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0bmFtZTogICAgICAgICAgICAgICAnc3RhcnR0aW1lMltdJ1xyXG5cdFx0ICogIFx0XHRcdFx0XHQgICAgfVxyXG5cdFx0ICogXHRcdFx0XHRcdCBdXHJcblx0XHQgKi9cclxuXHRcdGZ1bmN0aW9uIHdwYmNfZ2V0X190aW1lX2ZpZWxkc19faW5fYm9va2luZ19mb3JtX19hc19hcnIoIHJlc291cmNlX2lkICl7XHJcblx0XHQgICAgLyoqXHJcblx0XHRcdCAqIEZpZWxkcyB3aXRoICBbXSAgbGlrZSB0aGlzICAgc2VsZWN0W25hbWU9XCJyYW5nZXRpbWUxW11cIl1cclxuXHRcdFx0ICogaXQncyB3aGVuIHdlIGhhdmUgJ211bHRpcGxlJyBpbiBzaG9ydGNvZGU6ICAgW3NlbGVjdCogcmFuZ2V0aW1lIG11bHRpcGxlICBcIjA2OjAwIC0gMDY6MzBcIiAuLi4gXVxyXG5cdFx0XHQgKi9cclxuXHRcdFx0dmFyIHRpbWVfZmllbGRzX2Fycj1bXHJcblx0XHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cInJhbmdldGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnc2VsZWN0W25hbWU9XCJyYW5nZXRpbWUnICsgcmVzb3VyY2VfaWQgKyAnW11cIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnc2VsZWN0W25hbWU9XCJzdGFydHRpbWUnICsgcmVzb3VyY2VfaWQgKyAnXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwic3RhcnR0aW1lJyArIHJlc291cmNlX2lkICsgJ1tdXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwiZW5kdGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnc2VsZWN0W25hbWU9XCJlbmR0aW1lJyArIHJlc291cmNlX2lkICsgJ1tdXCJdJ1xyXG5cdFx0XHRcdFx0XHRcdFx0XTtcclxuXHJcblx0XHRcdHZhciB0aW1lX2ZpZWxkc19vYmpfYXJyID0gW107XHJcblxyXG5cdFx0XHQvLyBMb29wIGFsbCBUaW1lIEZpZWxkc1xyXG5cdFx0XHRmb3IgKCB2YXIgY3RmPSAwOyBjdGYgPCB0aW1lX2ZpZWxkc19hcnIubGVuZ3RoOyBjdGYrKyApe1xyXG5cclxuXHRcdFx0XHR2YXIgdGltZV9maWVsZCA9IHRpbWVfZmllbGRzX2FyclsgY3RmIF07XHJcblx0XHRcdFx0dmFyIHRpbWVfb3B0aW9uID0galF1ZXJ5KCB0aW1lX2ZpZWxkICsgJyBvcHRpb24nICk7XHJcblxyXG5cdFx0XHRcdC8vIExvb3AgYWxsIG9wdGlvbnMgaW4gdGltZSBmaWVsZFxyXG5cdFx0XHRcdGZvciAoIHZhciBqID0gMDsgaiA8IHRpbWVfb3B0aW9uLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHRcdFx0dmFyIGpxdWVyeV9vcHRpb24gPSBqUXVlcnkoIHRpbWVfZmllbGQgKyAnIG9wdGlvbjplcSgnICsgaiArICcpJyApO1xyXG5cdFx0XHRcdFx0dmFyIHZhbHVlX29wdGlvbl9zZWNvbmRzX2FyciA9IGpxdWVyeV9vcHRpb24udmFsKCkuc3BsaXQoICctJyApO1xyXG5cdFx0XHRcdFx0dmFyIHRpbWVzX2FzX3NlY29uZHMgPSBbXTtcclxuXHJcblx0XHRcdFx0XHQvLyBHZXQgdGltZSBhcyBzZWNvbmRzXHJcblx0XHRcdFx0XHRpZiAoIHZhbHVlX29wdGlvbl9zZWNvbmRzX2Fyci5sZW5ndGggKXtcdFx0XHRcdFx0XHRcdFx0XHQvLyBGaXhJbjogOS44LjEwLjEuXHJcblx0XHRcdFx0XHRcdGZvciAoIGxldCBpID0gMDsgaSA8IHZhbHVlX29wdGlvbl9zZWNvbmRzX2Fyci5sZW5ndGg7IGkrKyApe1x0XHQvLyBGaXhJbjogMTAuMC4wLjU2LlxyXG5cdFx0XHRcdFx0XHRcdC8vIHZhbHVlX29wdGlvbl9zZWNvbmRzX2FycltpXSA9ICcxNDowMCAnICB8ICcgMTY6MDAnICAgKGlmIGZyb20gJ3JhbmdldGltZScpIGFuZCAnMTY6MDAnICBpZiAoc3RhcnQvZW5kIHRpbWUpXHJcblxyXG5cdFx0XHRcdFx0XHRcdHZhciBzdGFydF9lbmRfdGltZXNfYXJyID0gdmFsdWVfb3B0aW9uX3NlY29uZHNfYXJyWyBpIF0udHJpbSgpLnNwbGl0KCAnOicgKTtcclxuXHJcblx0XHRcdFx0XHRcdFx0dmFyIHRpbWVfaW5fc2Vjb25kcyA9IHBhcnNlSW50KCBzdGFydF9lbmRfdGltZXNfYXJyWyAwIF0gKSAqIDYwICogNjAgKyBwYXJzZUludCggc3RhcnRfZW5kX3RpbWVzX2FyclsgMSBdICkgKiA2MDtcclxuXHJcblx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kcy5wdXNoKCB0aW1lX2luX3NlY29uZHMgKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdHRpbWVfZmllbGRzX29ial9hcnIucHVzaCgge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnbmFtZScgICAgICAgICAgICA6IGpRdWVyeSggdGltZV9maWVsZCApLmF0dHIoICduYW1lJyApLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndmFsdWVfb3B0aW9uXzI0aCc6IGpxdWVyeV9vcHRpb24udmFsKCksXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdqcXVlcnlfb3B0aW9uJyAgIDoganF1ZXJ5X29wdGlvbixcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3RpbWVzX2FzX3
3411NlY29uZHMnOiB0aW1lc19hc19zZWNvbmRzXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gdGltZV9maWVsZHNfb2JqX2FycjtcclxuXHRcdH1cclxuXHJcblx0XHRcdC8qKlxyXG5cdFx0XHQgKiBEaXNhYmxlIEhUTUwgb3B0aW9ucyBhbmQgYWRkIGJvb2tlZCBDU1MgY2xhc3NcclxuXHRcdFx0ICpcclxuXHRcdFx0ICogQHBhcmFtIHRpbWVfZmllbGRzX29ial9hcnIgICAgICAtIHRoaXMgdmFsdWUgaXMgZnJvbSAgdGhlIGZ1bmM6ICBcdHdwYmNfZ2V0X190aW1lX2ZpZWxkc19faW5fYm9va2luZ19mb3JtX19hc19hcnIoIHJlc291cmNlX2lkIClcclxuXHRcdFx0ICogXHRcdFx0XHRcdFtcclxuXHRcdFx0ICogXHRcdFx0XHRcdCBcdCAgIHtcdGpxdWVyeV9vcHRpb246ICAgICAgalF1ZXJ5X09iamVjdCB7fVxyXG5cdFx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0bmFtZTogICAgICAgICAgICAgICAncmFuZ2V0aW1lMltdJ1xyXG5cdFx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kczogICBbIDIxNjAwLCAyMzQwMCBdXHJcblx0XHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCAtIDA2OjMwJ1xyXG5cdFx0XHQgKiBcdCAgXHRcdFx0XHRcdFx0ICAgIGRpc2FibGVkID0gMVxyXG5cdFx0XHQgKiBcdFx0XHRcdFx0ICAgICB9XHJcblx0XHRcdCAqIFx0XHRcdFx0XHQgIC4uLlxyXG5cdFx0XHQgKiBcdFx0XHRcdFx0XHQgICB7XHRqcXVlcnlfb3B0aW9uOiAgICAgIGpRdWVyeV9PYmplY3Qge31cclxuXHRcdFx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbWU6ICAgICAgICAgICAgICAgJ3N0YXJ0dGltZTJbXSdcclxuXHRcdFx0ICogXHRcdFx0XHRcdFx0XHRcdHRpbWVzX2FzX3NlY29uZHM6ICAgWyAyMTYwMCBdXHJcblx0XHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCdcclxuXHRcdFx0ICogICBcdFx0XHRcdFx0XHRcdGRpc2FibGVkID0gMFxyXG5cdFx0XHQgKiAgXHRcdFx0XHRcdCAgICB9XHJcblx0XHRcdCAqIFx0XHRcdFx0XHQgXVxyXG5cdFx0XHQgKlxyXG5cdFx0XHQgKi9cclxuXHRcdFx0ZnVuY3Rpb24gd3BiY19faHRtbF9fdGltZV9maWVsZF9vcHRpb25zX19zZXRfZGlzYWJsZWQoIHRpbWVfZmllbGRzX29ial9hcnIgKXtcclxuXHJcblx0XHRcdFx0dmFyIGpxdWVyeV9vcHRpb247XHJcblxyXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHRpbWVfZmllbGRzX29ial9hcnIubGVuZ3RoOyBpKysgKXtcclxuXHJcblx0XHRcdFx0XHR2YXIganF1ZXJ5X29wdGlvbiA9IHRpbWVfZmllbGRzX29ial9hcnJbIGkgXS5qcXVlcnlfb3B0aW9uO1xyXG5cclxuXHRcdFx0XHRcdGlmICggMSA9PSB0aW1lX2ZpZWxkc19vYmpfYXJyWyBpIF0uZGlzYWJsZWQgKXtcclxuXHRcdFx0XHRcdFx0anF1ZXJ5X29wdGlvbi5wcm9wKCAnZGlzYWJsZWQnLCB0cnVlICk7IFx0XHQvLyBNYWtlIGRpc2FibGUgc29tZSBvcHRpb25zXHJcblx0XHRcdFx0XHRcdGpxdWVyeV9vcHRpb24uYWRkQ2xhc3MoICdib29rZWQnICk7ICAgICAgICAgICBcdC8vIEFkZCBcImJvb2tlZFwiIENTUyBjbGFzc1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gaWYgdGhpcyBib29rZWQgZWxlbWVudCBzZWxlY3RlZCAtLT4gdGhlbiBkZXNlbGVjdCAgaXRcclxuXHRcdFx0XHRcdFx0aWYgKCBqcXVlcnlfb3B0aW9uLnByb3AoICdzZWxlY3RlZCcgKSApe1xyXG5cdFx0XHRcdFx0XHRcdGpxdWVyeV9vcHRpb24ucHJvcCggJ3NlbGVjdGVkJywgZmFsc2UgKTtcclxuXHJcblx0XHRcdFx0XHRcdFx0anF1ZXJ5X29wdGlvbi5wYXJlbnQoKS5maW5kKCAnb3B0aW9uOm5vdChbZGlzYWJsZWRdKTpmaXJzdCcgKS5wcm9wKCAnc2VsZWN0ZWQnLCB0cnVlICkudHJpZ2dlciggXCJjaGFuZ2VcIiApO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0anF1ZXJ5X29wdGlvbi5wcm9wKCAnZGlzYWJsZWQnLCBmYWxzZSApOyAgXHRcdC8vIE1ha2UgYWN0aXZlIGFsbCB0aW1lc1xyXG5cdFx0XHRcdFx0XHRqcXVlcnlfb3B0aW9uLnJlbW92ZUNsYXNzKCAnYm9va2VkJyApOyAgIFx0XHQvLyBSZW1vdmUgY2xhc3MgXCJib29rZWRcIlxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdH1cclxuXHJcblx0LyoqXHJcblx0ICogQ2hlY2sgaWYgdGhpcyB0aW1lX3JhbmdlIHwgVGltZV9TbG90IGlzIEZ1bGwgRGF5ICBib29rZWRcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB0aW1lc2xvdF9hcnJfaW5fc2Vjb25kc1x0XHQtIFsgMzYwMTEsIDg2NDAwIF1cclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2lzX3RoaXNfdGltZXNsb3RfX2Z1bGxfZGF5X2Jvb2tlZCggdGltZXNsb3RfYXJyX2luX3NlY29uZHMgKXtcclxuXHJcblx0XHRpZiAoXHJcblx0XHRcdFx0KCB0aW1lc2xvdF9hcnJfaW5fc2Vjb25kcy5sZW5ndGggPiAxIClcclxuXHRcdFx0JiYgKCBwYXJzZUludCggdGltZXNsb3RfYXJyX2luX3NlY29uZHNbIDAgXSApIDwgMzAgKVxyXG5cdFx0XHQmJiAoIHBhcnNlSW50KCB0aW1lc2xvdF9hcnJfaW5fc2Vjb25kc1sgMSBdICkgPiAgKCAoMjQgKiA2MCAqIDYwKSAtIDMwKSApXHJcblx0XHQpe1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cclxuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvKiAgPT0gIFMgZSBsIGUgYyB0IGUgZCAgICBEIGEgdCBlIHMgIC8gIFQgaSBtIGUgLSBGIGkgZSBsIGQgcyAgPT1cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGFsbCBzZWxlY3RlZCBkYXRlcyBpbiBTUUwgZm9ybWF0IGxpa2UgdGhpcyBbIFwiMjAyMy0wOC0yM1wiLCBcIjIwMjMtMDgtMjRcIiAsIC4uLiBdXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHQgKiBAcmV0dXJucyB7W119XHRcdFx0WyBcIjIwMjMtMDgtMjNcIiwgXCIyMDIzLTA4LTI0XCIsIFwiMjAyMy0wOC0yNVwiLCBcIjIwMjMtMDgtMjZcIiwgXCIyMDIzLTA4LTI3XCIsIFwiMjAyMy0wOC0yOFwiLCBcIjIwMjMtMDgtMjlc
3411IiBdXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19nZXRfX3NlbGVjdGVkX2RhdGVzX3NxbF9fYXNfYXJyKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRcdHZhciBzZWxlY3RlZF9kYXRlc19hcnIgPSBbXTtcclxuXHRcdHNlbGVjdGVkX2RhdGVzX2FyciA9IGpRdWVyeSggJyNkYXRlX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS52YWwoKS5zcGxpdCgnLCcpO1xyXG5cclxuXHRcdGlmICggc2VsZWN0ZWRfZGF0ZXNfYXJyLmxlbmd0aCApe1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiA5LjguMTAuMS5cclxuXHRcdFx0Zm9yICggbGV0IGkgPSAwOyBpIDwgc2VsZWN0ZWRfZGF0ZXNfYXJyLmxlbmd0aDsgaSsrICl7XHRcdFx0XHRcdFx0Ly8gRml4SW46IDEwLjAuMC41Ni5cclxuXHRcdFx0XHRzZWxlY3RlZF9kYXRlc19hcnJbIGkgXSA9IHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdLnRyaW0oKTtcclxuXHRcdFx0XHRzZWxlY3RlZF9kYXRlc19hcnJbIGkgXSA9IHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdLnNwbGl0KCAnLicgKTtcclxuXHRcdFx0XHRpZiAoIHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdLmxlbmd0aCA+IDEgKXtcclxuXHRcdFx0XHRcdHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdID0gc2VsZWN0ZWRfZGF0ZXNfYXJyWyBpIF1bIDIgXSArICctJyArIHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdWyAxIF0gKyAnLScgKyBzZWxlY3RlZF9kYXRlc19hcnJbIGkgXVsgMCBdO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlbW92ZSBlbXB0eSBlbGVtZW50cyBmcm9tIGFuIGFycmF5XHJcblx0XHRzZWxlY3RlZF9kYXRlc19hcnIgPSBzZWxlY3RlZF9kYXRlc19hcnIuZmlsdGVyKCBmdW5jdGlvbiAoIG4gKXsgcmV0dXJuIHBhcnNlSW50KG4pOyB9ICk7XHJcblxyXG5cdFx0c2VsZWN0ZWRfZGF0ZXNfYXJyLnNvcnQoKTtcclxuXHJcblx0XHRyZXR1cm4gc2VsZWN0ZWRfZGF0ZXNfYXJyO1xyXG5cdH1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBhbGwgdGltZSBmaWVsZHMgaW4gdGhlIGJvb2tpbmcgZm9ybSBhcyBhcnJheSAgb2Ygb2JqZWN0c1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHJcblx0ICogQHBhcmFtIGlzX29ubHlfc2VsZWN0ZWRfdGltZVxyXG5cdCAqIEByZXR1cm5zIFtdXHJcblx0ICpcclxuXHQgKiBcdFx0RXhhbXBsZTpcclxuXHQgKiBcdFx0XHRcdFx0W1xyXG5cdCAqIFx0XHRcdFx0XHQgXHQgICB7XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdHZhbHVlX29wdGlvbl8yNGg6ICAgJzA2OjAwIC0gMDY6MzAnXHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdHRpbWVzX2FzX3NlY29uZHM6ICAgWyAyMTYwMCwgMjM0MDAgXVxyXG5cdCAqIFx0XHRcdFx0XHQgXHQgICBcdFx0anF1ZXJ5X29wdGlvbjogICAgICBqUXVlcnlfT2JqZWN0IHt9XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbWU6ICAgICAgICAgICAgICAgJ3JhbmdldGltZTJbXSdcclxuXHQgKiBcdFx0XHRcdFx0ICAgICB9XHJcblx0ICogXHRcdFx0XHRcdCAgLi4uXHJcblx0ICogXHRcdFx0XHRcdFx0ICAge1xyXG5cdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCdcclxuXHQgKiBcdFx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kczogICBbIDIxNjAwIF1cclxuXHQgKiBcdFx0XHRcdFx0XHQgICBcdFx0anF1ZXJ5X29wdGlvbjogICAgICBqUXVlcnlfT2JqZWN0IHt9XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbWU6ICAgICAgICAgICAgICAgJ3N0YXJ0dGltZTJbXSdcclxuXHQgKiAgXHRcdFx0XHRcdCAgICB9XHJcblx0ICogXHRcdFx0XHRcdCBdXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19nZXRfX3NlbGVjdGVkX3RpbWVfZmllbGRzX19pbl9ib29raW5nX2Zvcm1fX2FzX2FyciggcmVzb3VyY2VfaWQsIGlzX29ubHlfc2VsZWN0ZWRfdGltZSA9IHRydWUgKXtcclxuXHRcdC8qKlxyXG5cdFx0ICogRmllbGRzIHdpdGggIFtdICBsaWtlIHRoaXMgICBzZWxlY3RbbmFtZT1cInJhbmdldGltZTFbXVwiXVxyXG5cdFx0ICogaXQncyB3aGVuIHdlIGhhdmUgJ211bHRpcGxlJyBpbiBzaG9ydGNvZGU6ICAgW3NlbGVjdCogcmFuZ2V0aW1lIG11bHRpcGxlICBcIjA2OjAwIC0gMDY6MzBcIiAuLi4gXVxyXG5cdFx0ICovXHJcblx0XHR2YXIgdGltZV9maWVsZHNfYXJyPVtcclxuXHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cInJhbmdldGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwicmFuZ2V0aW1lJyArIHJlc291cmNlX2lkICsgJ1tdXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cInN0YXJ0dGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwic3RhcnR0aW1lJyArIHJlc291cmNlX2lkICsgJ1tdXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cImVuZHRpbWUnICsgcmVzb3VyY2VfaWQgKyAnXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cImVuZHRpbWUnICsgcmVzb3VyY2VfaWQgKyAnW11cIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwiZHVyYXRpb250aW1lJyArIHJlc291cmNlX2lkICsgJ1wiXScsXHJcblx0XHRcdFx0XHRcdFx0XHQnc2VsZWN0W25hbWU9XCJkdXJhdGlvbnRpbWUnICsgcmVzb3VyY2VfaWQgKyAnW11cIl0nXHJcblx0XHRcdFx0XHRcdFx0XTtcclxuXHJcblx0XHR2YXIgdGltZV9maWVsZHNfb2JqX2FyciA9IFtdO1xyXG5cclxuXHRcdC8vIExvb3AgYWxsIFRpbWUgRmllbGRzXHJcblx0XHRmb3IgKCB2YXIgY3RmPSAwOyBjdGYgPCB0aW1lX2ZpZWxkc19hcnIubGVuZ3RoOyBjdGYrKyApe1xyXG5cclxuXHRcdFx0dmFyIHRpbWVfZmllbGQgPSB0aW1lX2ZpZWxkc19hcnJbIGN0ZiBdO1xyXG5cclxuXHRcdFx0dmFyIHRpbWVfb3B0aW9uO1xyXG5cdFx0XHRpZiAoIGlzX29ubHlfc2VsZWN0ZWRfdGltZSApe1xyXG5cdFx0XHRcdHRpbWVfb3B0aW9uID0galF1ZXJ5KCAnI2Jvb2tpbmdfZm9ybScgKyByZXNvdXJjZV9pZCArICcgJyArIHRpbWVfZmllbGQgKyAnIG9wdGlvbjpzZWxlY3RlZCcgKTtcdFx0XHQvLyBFeGNsdWRlIGNvbmRpdGlvbmFsICBmaWVsZHMsICBiZWNhdXNlIG9mIHVzaW5nICcjYm9va2luZ19mb3JtMyAuLi4nXHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dGltZV9vcHRpb24gPSBqUXVlcnkoICcjYm9va2luZ19mb3JtJyArIHJlc291cmNlX2lkICsgJyAnICsgdGltZV9maWVsZCArICcgb3B0aW9uJyApO1x0XHRcdFx0Ly8gQWxsICB0aW1lIGZpZWxkc1xyXG5cdFx0XHR9XHJcblxyXG5cclxuXHRcdFx0Ly8gTG9vcCBhbGwgb3B0aW9ucyBpbiB0aW1lIGZpZWxkXHJcblx0XHRcdGZvciAoIHZhciBqID0gMDsgaiA8IHRpbWVfb3B0aW9uLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHRcdHZhciBqcXVlcnlfb3B0aW9uID0galF1ZXJ5KCB0aW1lX29wdGlvblsgaiBdICk7XHRcdC8vIEdldCBvbmx5ICBzZWxlY3RlZCBvcHRpb25zIFx0Ly9qUXVlcnkoIHRpbWVfZmllbGQgKyAnIG9wdGlvbjplcSgnICsgaiArICcpJyApO1xyXG5cdFx0XHRcdHZhciB2YWx1ZV9vcHRpb25fc2Vjb25kc19hcnIgPSBqcXVlcnlfb3B0aW9uLnZhbCgpLnNwbGl0KCAnLScgKTtcclxuXHRcdFx0XHR2YXIgdGltZXNfYXNfc2Vjb25kcyA9IFtdO1xyXG5cclxuXHRcdFx0XHQvLyBHZXQgdGltZSBhcyBzZWNvbmRzXHJcblx0XHRcdFx0aWYgKCB2YWx1ZV9vcHRpb25fc2Vjb25kc19hcnIubGVuZ3RoICl7XHRcdFx0XHQgXHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiA5LjguMTAuMS5cclxuXHRcdFx0XHRcdGZvciAoIGxldCBpID0gMDsgaSA8IHZhbHVlX29wdGlvbl9zZWNvbmRzX2Fyci5sZW5ndGg7IGkrKyApe1x0XHRcdFx0XHQvLyBGaXhJbjogMTAuMC4wLjU2LlxyXG5cdFx0XHRcdFx0XHQvLyB2YWx1ZV9vcHRpb25fc2Vjb25kc19hcnJbaV0gPSAnMTQ6MDAgJyAgfCAnIDE2OjAwJyAgIChpZiBmcm9tICdyYW5nZXRpbWUnKSBhbmQgJzE2OjAwJyAgaWYgKHN0YXJ0L2VuZCB0aW1lKVxyXG5cclxuXHRcdFx0XHRcdFx0dmFyIHN0YXJ0X2VuZF90aW1lc19hcnIgPSB2YWx1ZV9vcHRpb25fc2Vjb25kc19hcnJbIGkgXS50cmltKCkuc3BsaXQoICc6JyApO1xyXG5cclxuXHRcdFx0XHRcdFx0dmFyIHRpbWVfaW5fc2Vjb25kcyA9IHBhcnNlSW50KCBzdGFydF9lbmRfdGltZXNfYXJyWyAwIF0gKSAqIDYwICogNjAgKyBwYXJzZUludCggc3RhcnRfZW5kX3RpbWVzX2FyclsgMSBdICkgKiA2MDtcclxuXHJcblx0XHRcdFx0XHRcdHRpbWVzX2FzX3
3411NlY29uZHMucHVzaCggdGltZV9pbl9zZWNvbmRzICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR0aW1lX2ZpZWxkc19vYmpfYXJyLnB1c2goIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCduYW1lJyAgICAgICAgICAgIDogalF1ZXJ5KCAnI2Jvb2tpbmdfZm9ybScgKyByZXNvdXJjZV9pZCArICcgJyArIHRpbWVfZmllbGQgKS5hdHRyKCAnbmFtZScgKSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd2YWx1ZV9vcHRpb25fMjRoJzoganF1ZXJ5X29wdGlvbi52YWwoKSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdqcXVlcnlfb3B0aW9uJyAgIDoganF1ZXJ5X29wdGlvbixcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0aW1lc19hc19zZWNvbmRzJzogdGltZXNfYXNfc2Vjb25kc1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFRleHQ6ICAgW3N0YXJ0dGltZV0gLSBbZW5kdGltZV0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcblx0XHR2YXIgdGV4dF90aW1lX2ZpZWxkc19hcnI9W1xyXG5cdFx0XHRcdFx0XHRcdFx0XHQnaW5wdXRbbmFtZT1cInN0YXJ0dGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnaW5wdXRbbmFtZT1cImVuZHRpbWUnICsgcmVzb3VyY2VfaWQgKyAnXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdF07XHJcblx0XHRmb3IgKCB2YXIgdGY9IDA7IHRmIDwgdGV4dF90aW1lX2ZpZWxkc19hcnIubGVuZ3RoOyB0ZisrICl7XHJcblxyXG5cdFx0XHR2YXIgdGV4dF9qcXVlcnkgPSBqUXVlcnkoICcjYm9va2luZ19mb3JtJyArIHJlc291cmNlX2lkICsgJyAnICsgdGV4dF90aW1lX2ZpZWxkc19hcnJbIHRmIF0gKTtcdFx0XHRcdFx0XHRcdFx0Ly8gRXhjbHVkZSBjb25kaXRpb25hbCAgZmllbGRzLCAgYmVjYXVzZSBvZiB1c2luZyAnI2Jvb2tpbmdfZm9ybTMgLi4uJ1xyXG5cdFx0XHRpZiAoIHRleHRfanF1ZXJ5Lmxlbmd0aCA+IDAgKXtcclxuXHJcblx0XHRcdFx0dmFyIHRpbWVfX2hfbV9fYXJyID0gdGV4dF9qcXVlcnkudmFsKCkudHJpbSgpLnNwbGl0KCAnOicgKTtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzE0OjAwJ1xyXG5cdFx0XHRcdGlmICggMCA9PSB0aW1lX19oX21fX2Fyci5sZW5ndGggKXtcclxuXHRcdFx0XHRcdGNvbnRpbnVlO1x0XHRcdFx0XHRcdFx0XHRcdC8vIE5vdCBlbnRlcmVkIHRpbWUgdmFsdWUgaW4gYSBmaWVsZFxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoIDEgPT0gdGltZV9faF9tX19hcnIubGVuZ3RoICl7XHJcblx0XHRcdFx0XHRpZiAoICcnID09PSB0aW1lX19oX21fX2FyclsgMCBdICl7XHJcblx0XHRcdFx0XHRcdGNvbnRpbnVlO1x0XHRcdFx0XHRcdFx0XHQvLyBOb3QgZW50ZXJlZCB0aW1lIHZhbHVlIGluIGEgZmllbGRcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHRpbWVfX2hfbV9fYXJyWyAxIF0gPSAwO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR2YXIgdGV4dF90aW1lX2luX3NlY29uZHMgPSBwYXJzZUludCggdGltZV9faF9tX19hcnJbIDAgXSApICogNjAgKiA2MCArIHBhcnNlSW50KCB0aW1lX19oX21fX2FyclsgMSBdICkgKiA2MDtcclxuXHJcblx0XHRcdFx0dmFyIHRleHRfdGltZXNfYXNfc2Vjb25kcyA9IFtdO1xyXG5cdFx0XHRcdHRleHRfdGltZXNfYXNfc2Vjb25kcy5wdXNoKCB0ZXh0X3RpbWVfaW5fc2Vjb25kcyApO1xyXG5cclxuXHRcdFx0XHR0aW1lX2ZpZWxkc19vYmpfYXJyLnB1c2goIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCduYW1lJyAgICAgICAgICAgIDogdGV4dF9qcXVlcnkuYXR0ciggJ25hbWUnICksXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndmFsdWVfb3B0aW9uXzI0aCc6IHRleHRfanF1ZXJ5LnZhbCgpLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2pxdWVyeV9vcHRpb24nICAgOiB0ZXh0X2pxdWVyeSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0aW1lc19hc19zZWNvbmRzJzogdGV4dF90aW1lc19hc19zZWNvbmRzXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHRpbWVfZmllbGRzX29ial9hcnI7XHJcblx0fVxyXG5cclxuXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyogID09ICBTIFUgUCBQIE8gUiBUICAgIGZvciAgICBDIEEgTCBFIE4gRCBBIFIgID09XHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgQ2FsZW5kYXIgZGF0ZXBpY2sgIEluc3RhbmNlXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkICBvZiBib29raW5nIHJlc291cmNlXHJcblx0ICogQHJldHVybnMgeyp8bnVsbH1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19nZXRfaW5zdCggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHRpZiAoICd1bmRlZmluZWQnID09PSB0eXBlb2YgKHJlc291cmNlX2lkKSApe1xyXG5cdFx0XHRyZXNvdXJjZV9pZCA9ICcxJztcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkubGVuZ3RoID4gMCApe1xyXG5cdFx0XHRyZXR1cm4galF1ZXJ5LmRhdGVwaWNrLl9nZXRJbnN0KCBqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLmdldCggMCApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVbnNlbGVjdCAgYWxsIGRhdGVzIGluIGNhbGVuZGFyIGFuZCB2aXN1YWxseSB1cGRhdGUgdGhpcyBjYWxlbmRhclxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHRcdElEIG9mIGJvb2tpbmcgcmVzb3VyY2VcclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cdFx0dHJ1ZSBvbiBzdWNjZXNzIHwgZmFsc2UsICBpZiBubyBzdWNoICBjYWxlbmRhclxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfY2FsZW5kYXJfX3Vuc2VsZWN0X2FsbF9kYXRlcyggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHRpZiAoICd1bmRlZmluZWQnID09PSB0eXBlb2YgKHJl
3411c291cmNlX2lkKSApe1xyXG5cdFx0XHRyZXNvdXJjZV9pZCA9ICcxJztcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgaW5zdCA9IHdwYmNfY2FsZW5kYXJfX2dldF9pbnN0KCByZXNvdXJjZV9pZCApXHJcblxyXG5cdFx0aWYgKCBudWxsICE9PSBpbnN0ICl7XHJcblxyXG5cdFx0XHQvLyBVbnNlbGVjdCBhbGwgZGF0ZXMgYW5kIHNldCAgcHJvcGVydGllcyBvZiBEYXRlcGlja1xyXG5cdFx0XHRqUXVlcnkoICcjZGF0ZV9ib29raW5nJyArIHJlc291cmNlX2lkICkudmFsKCAnJyApOyAgICAgIC8vRml4SW46IDUuNC4zXHJcblx0XHRcdGluc3Quc3RheU9wZW4gPSBmYWxzZTtcclxuXHRcdFx0aW5zdC5kYXRlcyA9IFtdO1xyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3VwZGF0ZURhdGVwaWNrKCBpbnN0ICk7XHJcblxyXG5cdFx0XHRyZXR1cm4gdHJ1ZVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBDbGVhciBkYXlzIGhpZ2hsaWdodGluZyBpbiBBbGwgb3Igc3BlY2lmaWMgQ2FsZW5kYXJzXHJcblx0ICpcclxuICAgICAqIEBwYXJhbSByZXNvdXJjZV9pZCAgLSBjYW4gYmUgc2tpcGVkIHRvICBjbGVhciBoaWdobGlnaHRpbmcgaW4gYWxsIGNhbGVuZGFyc1xyXG4gICAgICovXHJcblx0ZnVuY3Rpb24gd3BiY19jYWxlbmRhcnNfX2NsZWFyX2RheXNfaGlnaGxpZ2h0aW5nKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRcdGlmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHJlc291cmNlX2lkICkgKXtcclxuXHJcblx0XHRcdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICsgJyAuZGF0ZXBpY2stZGF5cy1jZWxsLW92ZXInICkucmVtb3ZlQ2xhc3MoICdkYXRlcGljay1kYXlzLWNlbGwtb3ZlcicgKTtcdFx0Ly8gQ2xlYXIgaW4gc3BlY2lmaWMgY2FsZW5kYXJcclxuXHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRqUXVlcnkoICcuZGF0ZXBpY2stZGF5cy1jZWxsLW92ZXInICkucmVtb3ZlQ2xhc3MoICdkYXRlcGljay1kYXlzLWNlbGwtb3ZlcicgKTtcdFx0XHRcdFx0XHRcdFx0Ly8gQ2xlYXIgaW4gYWxsIGNhbGVuZGFyc1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogU2Nyb2xsIHRvIHNwZWNpZmljIG1vbnRoIGluIGNhbGVuZGFyXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcdFx0SUQgb2YgcmVzb3VyY2VcclxuXHQgKiBAcGFyYW0geWVhclx0XHRcdFx0LSByZWFsIHllYXIgIC0gMjAyM1xyXG5cdCAqIEBwYXJhbSBtb250aFx0XHRcdFx0LSByZWFsIG1vbnRoIC0gMTJcclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19zY3JvbGxfdG8oIHJlc291cmNlX2lkLCB5ZWFyLCBtb250aCApe1xyXG5cclxuXHRcdGlmICggJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiAocmVzb3VyY2VfaWQpICl7IHJlc291cmNlX2lkID0gJzEnOyB9XHJcblx0XHR2YXIgaW5zdCA9IHdwYmNfY2FsZW5kYXJfX2dldF9pbnN0KCByZXNvdXJjZV9pZCApXHJcblx0XHRpZiAoIG51bGwgIT09IGluc3QgKXtcclxuXHJcblx0XHRcdHllYXIgID0gcGFyc2VJbnQoIHllYXIgKTtcclxuXHRcdFx0bW9udGggPSBwYXJzZUludCggbW9udGggKSAtIDE7XHRcdC8vIEluIEpTIGRhdGUsICBtb250aCAtMVxyXG5cclxuXHRcdFx0aW5zdC5jdXJzb3JEYXRlID0gbmV3IERhdGUoKTtcclxuXHRcdFx0Ly8gSW4gc29tZSBjYXNlcywgIHRoZSBzZXRGdWxsWWVhciBjYW4gIHNldCAgb25seSBZZWFyLCAgYW5kIG5vdCB0aGUgTW9udGggYW5kIGRheSAgICAgIC8vIEZpeEluOiA2LjIuMy41LlxyXG5cdFx0XHRpbnN0LmN1cnNvckRhdGUuc2V0RnVsbFllYXIoIHllYXIsIG1vbnRoLCAxICk7XHJcblx0XHRcdGluc3QuY3Vyc29yRGF0ZS5zZXRNb250aCggbW9udGggKTtcclxuXHRcdFx0aW5zdC5jdXJzb3JEYXRlLnNldERhdGUoIDEgKTtcclxuXHJcblx0XHRcdGluc3QuZHJhd01vbnRoID0gaW5zdC5jdXJzb3JEYXRlLmdldE1vbnRoKCk7XHJcblx0XHRcdGluc3QuZHJhd1llYXIgPSBpbnN0LmN1cnNvckRhdGUuZ2V0RnVsbFllYXIoKTtcclxuXHJcblx0XHRcdGpRdWVyeS5kYXRlcGljay5fbm90aWZ5Q2hhbmdlKCBpbnN0ICk7XHJcblx0XHRcdGpRdWVyeS5kYXRlcGljay5fYWRqdXN0SW5zdERhdGUoIGluc3QgKTtcclxuXHRcdFx0alF1ZXJ5LmRhdGVwaWNrLl9zaG93RGF0ZSggaW5zdCApO1xyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3VwZGF0ZURhdGVwaWNrKCBpbnN0ICk7XHJcblxyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIElzIHRoaXMgZGF0ZSBzZWxlY3RhYmxlIGluIGNhbGVuZGFyIChtYWlubHkgaXQncyBtZWFucyBBVkFJTEFCTEUgZGF0ZSlcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7aW50fHN0cmluZ30gcmVzb3VyY2VfaWRcdFx0MVxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzcWxfY2xhc3NfZGF5XHRcdCcyMDIzLTA4LTExJ1xyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVx0XHRcdFx0XHR0cnVlIHwgZmFsc2VcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2lzX3RoaXNfZGF5X3NlbGVjdGFibGUoIHJlc291cmNlX2lkLCBzcWxfY2xhc3NfZGF5ICl7XHJcblxyXG5cdFx0Ly8gR2V0IERhdGEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdHZhciBkYXRlX2Jvb2tpbmdzX29iaiA9IF93cGJjLmJvb2tpbmdzX2luX2NhbGVuZGFyX19nZXRfZm9yX2RhdGUoIHJlc291cmNlX2lkLCBzcWxfY2xhc3NfZGF5ICk7XHJcblxyXG5cdFx0dmFyIGlzX2RheV9zZWxlY3RhYmxlID0gKCBwYXJzZUludCggZGF0ZV9ib29raW5nc19vYmpbICdkYXlfYXZhaWxhYmlsaXR5JyBdICkgPiAwICk7XHJcblxyXG5cdFx0aWYgKCB0eXBlb2YgKGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeScgXSkgPT09ICd1bmRlZmluZWQnICl7XHJcblx0XHRcdHJldHVybi
3411Bpc19kYXlfc2VsZWN0YWJsZTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoICdhdmFpbGFibGUnICE9IGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeSddWydzdGF0dXNfZm9yX2RheScgXSApe1xyXG5cclxuXHRcdFx0dmFyIGlzX3NldF9wZW5kaW5nX2RheXNfc2VsZWN0YWJsZSA9IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAncGVuZGluZ19kYXlzX3NlbGVjdGFibGUnICk7XHRcdC8vIHNldCBwZW5kaW5nIGRheXMgc2VsZWN0YWJsZSAgICAgICAgICAvLyBGaXhJbjogOC42LjEuMTguXHJcblxyXG5cdFx0XHRzd2l0Y2ggKCBkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSApe1xyXG5cdFx0XHRcdGNhc2UgJ3BlbmRpbmcnOlxyXG5cdFx0XHRcdC8vIFNpdHVhdGlvbnMgZm9yIFwiY2hhbmdlLW92ZXJcIiBkYXlzOlxyXG5cdFx0XHRcdGNhc2UgJ3BlbmRpbmdfcGVuZGluZyc6XHJcblx0XHRcdFx0Y2FzZSAncGVuZGluZ19hcHByb3ZlZCc6XHJcblx0XHRcdFx0Y2FzZSAnYXBwcm92ZWRfcGVuZGluZyc6XHJcblx0XHRcdFx0XHRpc19kYXlfc2VsZWN0YWJsZSA9IChpc19kYXlfc2VsZWN0YWJsZSkgPyB0cnVlIDogaXNfc2V0X3BlbmRpbmdfZGF5c19zZWxlY3RhYmxlO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0ZGVmYXVsdDpcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBpc19kYXlfc2VsZWN0YWJsZTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIElzIGRhdGUgdG8gY2hlY2sgSU4gYXJyYXkgb2Ygc2VsZWN0ZWQgZGF0ZXNcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7ZGF0ZX1qc19kYXRlX3RvX2NoZWNrXHRcdC0gSlMgRGF0ZVx0XHRcdC0gc2ltcGxlICBKYXZhU2NyaXB0IERhdGUgb2JqZWN0XHJcblx0ICogQHBhcmFtIHtbXX0ganNfZGF0ZXNfYXJyXHRcdFx0LSBbIEpTRGF0ZSwgLi4uIF0gICAtIGFycmF5ICBvZiBKUyBkYXRlc1xyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfaXNfdGhpc19kYXlfYW1vbmdfc2VsZWN0ZWRfZGF5cygganNfZGF0ZV90b19jaGVjaywganNfZGF0ZXNfYXJyICl7XHJcblxyXG5cdFx0Zm9yICggdmFyIGRhdGVfaW5kZXggPSAwOyBkYXRlX2luZGV4IDwganNfZGF0ZXNfYXJyLmxlbmd0aCA7IGRhdGVfaW5kZXgrKyApeyAgICAgXHRcdFx0XHRcdFx0XHRcdFx0Ly8gRml4SW46IDguNC41LjE2LlxyXG5cdFx0XHRpZiAoICgganNfZGF0ZXNfYXJyWyBkYXRlX2luZGV4IF0uZ2V0RnVsbFllYXIoKSA9PT0ganNfZGF0ZV90b19jaGVjay5nZXRGdWxsWWVhcigpICkgJiZcclxuXHRcdFx0XHQgKCBqc19kYXRlc19hcnJbIGRhdGVfaW5kZXggXS5nZXRNb250aCgpID09PSBqc19kYXRlX3RvX2NoZWNrLmdldE1vbnRoKCkgKSAmJlxyXG5cdFx0XHRcdCAoIGpzX2RhdGVzX2FyclsgZGF0ZV9pbmRleCBdLmdldERhdGUoKSA9PT0ganNfZGF0ZV90b19jaGVjay5nZXREYXRlKCkgKSApIHtcclxuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuICBmYWxzZTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBTUUwgQ2xhc3MgRGF0ZSAnMjAyMy0wOC0wMScgZnJvbSAgSlMgRGF0ZVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGRhdGVcdFx0XHRcdEpTIERhdGVcclxuXHQgKiBAcmV0dXJucyB7c3RyaW5nfVx0XHQnMjAyMy0wOC0xMidcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX19nZXRfX3NxbF9jbGFzc19kYXRlKCBkYXRlICl7XHJcblxyXG5cdFx0dmFyIHNxbF9jbGFzc19kYXkgPSBkYXRlLmdldEZ1bGxZZWFyKCkgKyAnLSc7XHJcblx0XHRcdHNxbF9jbGFzc19kYXkgKz0gKCAoIGRhdGUuZ2V0TW9udGgoKSArIDEgKSA8IDEwICkgPyAnMCcgOiAnJztcclxuXHRcdFx0c3FsX2NsYXNzX2RheSArPSAoIGRhdGUuZ2V0TW9udGgoKSArIDEgKSArICctJ1xyXG5cdFx0XHRzcWxfY2xhc3NfZGF5ICs9ICggZGF0ZS5nZXREYXRlKCkgPCAxMCApID8gJzAnIDogJyc7XHJcblx0XHRcdHNxbF9jbGFzc19kYXkgKz0gZGF0ZS5nZXREYXRlKCk7XHJcblxyXG5cdFx0XHRyZXR1cm4gc3FsX2NsYXNzX2RheTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBKUyBEYXRlIGZyb20gIHRoZSBTUUwgZGF0ZSBmb3JtYXQgJzIwMjQtMDUtMTQnXHJcblx0ICogQHBhcmFtIHNxbF9jbGFzc19kYXRlXHJcblx0ICogQHJldHVybnMge0RhdGV9XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19fZ2V0X19qc19kYXRlKCBzcWxfY2xhc3NfZGF0ZSApe1xyXG5cclxuXHRcdHZhciBzcWxfY2xhc3NfZGF0ZV9hcnIgPSBzcWxfY2xhc3NfZGF0ZS5zcGxpdCggJy0nICk7XHJcblxyXG5cdFx0dmFyIGRhdGVfanMgPSBuZXcgRGF0ZSgpO1xyXG5cclxuXHRcdGRhdGVfanMuc2V0RnVsbFllYXIoIHBhcnNlSW50KCBzcWxfY2xhc3NfZGF0ZV9hcnJbIDAgXSApLCAocGFyc2VJbnQoIHNxbF9jbGFzc19kYXRlX2FyclsgMSBdICkgLSAxKSwgcGFyc2VJbnQoIHNxbF9jbGFzc19kYXRlX2FyclsgMiBdICkgKTsgIC8vIHllYXIsIG1vbnRoLCBkYXRlXHJcblxyXG5cdFx0Ly8gV2l0aG91dCB0aGlzIHRpbWUgYWRqdXN0IERhdGVzIHNlbGVjdGlvbiAgaW4gRGF0ZXBpY2tlciBjYW4gbm90IHdvcmshISFcclxuXHRcdGRhdGVfanMuc2V0SG91cnMoMCk7XHJcblx0XHRkYXRlX2pzLnNldE1pbnV0ZXMoMCk7XHJcblx0XHRkYXRlX2pzLnNldFNlY29uZHMoMCk7XHJcblx0XHRkYXRlX2pzLnNldE1pbGxpc2Vjb25kcygwKTtcclxuXHJcblx0XHRyZXR1cm4gZGF0ZV9qcztcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBURCBDbGFzcyBEYXRlICcxLTMxLTIwMjMnIGZyb20gIEpTIERhdGVcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBkYXRlXHRcdFx0XHRKUyBEYXRlXHJcblx0ICogQHJldHVybnMge3N0cmluZ31cdFx0JzEtMzEtMjAyMydcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX19nZXRfX3RkX2NsYXNzX2RhdGUoIGRhdGUgKXtcclxuXHJcblx0XHR2YXIgdGRfY2xhc3NfZGF5ID0gKGRhdGUuZ2V0TW9udGgoKSArIDEpICsgJy0nICsgZGF0ZS5nZXREYXRlKCkgKyAnLScgKyBkYXRlLmdldEZ1bGxZZWFyKCk7XHRcdFx0XHRcdFx0XHRcdC8vICcxLTktMjAyMydcclxuXHJcblx0XHRyZXR1cm4gdGRfY2xhc3NfZGF5O1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IGRhdGUgcGFyYW1zIGZyb20gIHN0cmluZyBkYXRlXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gZGF0ZVx0XHRcdHN0cmluZyBkYXRlIGxpa2UgJzMxLjUuMjAyMydcclxuXHQgKiBAcGFyYW0gc2VwYXJhdG9yXHRcdGRlZmF1bHQgJy4nICBjYW4gYmUgc2tpcHBlZC5cclxuXHQgKiBAcmV0dXJucyB7ICB7ZGF0ZTogbnVtYmVyLCBtb250aDogbnVtYmVyLCB5ZWFyOiBudW1iZXJ9ICB9XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19fZ2V0X19kYXRlX3BhcmFtc19fZnJvbV9zdHJpbmdfZGF0ZSggZGF0ZSAsIHNlcGFyYXRvcil7XHJcblxyXG5cdFx0c2VwYXJhdG9yID0gKCAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIChzZXBhcmF0b3IpICkgPyBzZXBhcmF0b3IgOiAnLic7XHJcblxyXG5cdFx0dmFyIGRhdGVfYXJyID0gZGF0ZS5zcGxpdCggc2
3411VwYXJhdG9yICk7XHJcblx0XHR2YXIgZGF0ZV9vYmogPSB7XHJcblx0XHRcdCd5ZWFyJyA6ICBwYXJzZUludCggZGF0ZV9hcnJbIDIgXSApLFxyXG5cdFx0XHQnbW9udGgnOiAocGFyc2VJbnQoIGRhdGVfYXJyWyAxIF0gKSAtIDEpLFxyXG5cdFx0XHQnZGF0ZScgOiAgcGFyc2VJbnQoIGRhdGVfYXJyWyAwIF0gKVxyXG5cdFx0fTtcclxuXHRcdHJldHVybiBkYXRlX29iajtcdFx0Ly8gZm9yIFx0XHQgPSBuZXcgRGF0ZSggZGF0ZV9vYmoueWVhciAsIGRhdGVfb2JqLm1vbnRoICwgZGF0ZV9vYmouZGF0ZSApO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQWRkIFNwaW4gTG9hZGVyIHRvICBjYWxlbmRhclxyXG5cdCAqIEBwYXJhbSByZXNvdXJjZV9pZFxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfY2FsZW5kYXJfX2xvYWRpbmdfX3N0YXJ0KCByZXNvdXJjZV9pZCApe1xyXG5cdFx0aWYgKCAhIGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkubmV4dCgpLmhhc0NsYXNzKCAnd3BiY19zcGluc19sb2FkZXJfd3JhcHBlcicgKSApe1xyXG5cdFx0XHRqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLmFmdGVyKCAnPGRpdiBjbGFzcz1cIndwYmNfc3BpbnNfbG9hZGVyX3dyYXBwZXJcIj48ZGl2IGNsYXNzPVwid3BiY19zcGluc19sb2FkZXJcIj48L2Rpdj48L2Rpdj4nICk7XHJcblx0XHR9XHJcblx0XHRpZiAoICEgalF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS5oYXNDbGFzcyggJ3dwYmNfY2FsZW5kYXJfYmx1cl9zbWFsbCcgKSApe1xyXG5cdFx0XHRqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLmFkZENsYXNzKCAnd3BiY19jYWxlbmRhcl9ibHVyX3NtYWxsJyApO1xyXG5cdFx0fVxyXG5cdFx0d3BiY19jYWxlbmRhcl9fYmx1cl9fc3RhcnQoIHJlc291cmNlX2lkICk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZW1vdmUgU3BpbiBMb2FkZXIgdG8gIGNhbGVuZGFyXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19jYWxlbmRhcl9fbG9hZGluZ19fc3RvcCggcmVzb3VyY2VfaWQgKXtcclxuXHRcdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICsgJyArIC53cGJjX3NwaW5zX2xvYWRlcl93cmFwcGVyJyApLnJlbW92ZSgpO1xyXG5cdFx0alF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS5yZW1vdmVDbGFzcyggJ3dwYmNfY2FsZW5kYXJfYmx1cl9zbWFsbCcgKTtcclxuXHRcdHdwYmNfY2FsZW5kYXJfX2JsdXJfX3N0b3AoIHJlc291cmNlX2lkICk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBBZGQgQmx1ciB0byAgY2FsZW5kYXJcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19ibHVyX19zdGFydCggcmVzb3VyY2VfaWQgKXtcclxuXHRcdGlmICggISBqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLmhhc0NsYXNzKCAnd3BiY19jYWxlbmRhcl9ibHVyJyApICl7XHJcblx0XHRcdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkuYWRkQ2xhc3MoICd3cGJjX2NhbGVuZGFyX2JsdXInICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZW1vdmUgQmx1ciBpbiAgY2FsZW5kYXJcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19ibHVyX19zdG9wKCByZXNvdXJjZV9pZCApe1xyXG5cdFx0alF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS5yZW1vdmVDbGFzcyggJ3dwYmNfY2FsZW5kYXJfYmx1cicgKTtcclxuXHR9XHJcblxyXG5cclxuXHQvLyAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLlxyXG5cdC8qICA9PSAgQ2FsZW5kYXIgVXBkYXRlICAtIFZpZXcgID09XHJcblx0Ly8gLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4gKi9cclxuXHJcblx0LyoqXHJcblx0ICogVXBkYXRlIExvb2sgIG9mIGNhbGVuZGFyXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX191cGRhdGVfbG9vayggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHR2YXIgaW5zdCA9IHdwYmNfY2FsZW5kYXJfX2dldF9pbnN0KCByZXNvdXJjZV9pZCApO1xyXG5cclxuXHRcdGpRdWVyeS5kYXRlcGljay5fdXBkYXRlRGF0ZXBpY2soIGluc3QgKTtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBVcGRhdGUgZHluYW1pY2FsbHkgTnVtYmVyIG9mIE1vbnRocyBpbiBjYWxlbmRhclxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkIGludFxyXG5cdCAqIEBwYXJhbSBtb250aHNfbnVtYmVyIGludFxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfY2FsZW5kYXJfX3VwZGF0ZV9tb250aHNfbnVtYmVyKCByZXNvdXJjZV9pZCwgbW9udGhzX251bWJlciApe1xyXG5cdFx0dmFyIGluc3QgPSB3cGJjX2NhbGVuZGFyX19nZXRfaW5zdCggcmVzb3VyY2VfaWQgKTtcclxuXHRcdGlmICggbnVsbCAhPT0gaW5zdCApe1xyXG5cdFx0XHRpbnN0LnNldHRpbmdzWyAnbnVtYmVyT2ZNb250aHMnIF0gPSBtb250aHNfbnVtYmVyO1xyXG5cdFx0XHQvL193cGJjLmNhbGVuZGFyX19zZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnY2FsZW5kYXJfbnVtYmVyX29mX21vbnRocycsIG1vbnRoc19udW1iZXIgKTtcclxuXHRcdFx0d3BiY19jYWxlbmRhcl9fdXBkYXRlX2xvb2soIHJlc291cmNlX2lkICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHJcblx0LyoqXHJcblx0ICogU2hvdyBjYWxlbmRhciBpbiAgZGlmZmVyZW50IFNraW5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBzZWxlY3RlZF9za2luX3VybFxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfX2NhbGVuZGFyX19jaGFuZ2Vfc2tpbiggc2VsZWN0ZWRfc2tpbl91cmwgKXtcclxuXHJcblx0Ly9jb25zb2xlLmxvZyggJ1NLSU4gU0VMRUNUSU9OIDo6Jywgc2VsZWN0ZWRfc2tpbl91cmwgKTtcclxuXHJcblx0XHQvLyBSZW1vdmUgQ1NTIHNraW5cclxuXHRcdHZhciBzdHlsZXNoZWV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoICd3cGJjLWNhbGVuZGFyLXNraW4tY3NzJyApO1xyXG5cdFx0c3R5bGVzaGVldC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBzdHlsZXNoZWV0ICk7XHJcblxyXG5cclxuXHRcdC8vIEFkZCBuZXcgQ1NTIHNraW5cclxuXHRcdHZhciBoZWFkSUQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJoZWFkXCIgKVsgMCBdO1xyXG5cdFx0dmFyIGNzc05vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnbGluaycgKTtcclxuXHRcdGNzc05vZGUudHlwZSA9ICd0ZXh0L2Nzcyc7XHJcblx0XHRjc3NOb2RlLnNldEF0dHJpYnV0ZSggXCJpZFwiLCBcIndwYmMtY2FsZW5kYXItc2tpbi1jc3NcIiApO1xyXG5cdFx0Y3NzTm9kZS5yZWwgPSAnc3R5bGVzaGVldCc7XHJcblx0XHRjc3NOb2RlLm1lZGlhID0gJ3NjcmVlbic7XHJcblx0XHRjc3NOb2RlLmhyZWYgPSBzZWxlY3RlZF9za2luX3VybDtcdC8vXCJodHRwOi8vYmV0YS93cC1jb250ZW50L3BsdWdpbnMvYm9va2luZy9jc3Mvc2tpbnMvZ3JlZW4tMDEuY3NzXCI7XHJcblx0XHRoZWFkSUQuYXBwZW5kQ2hpbGQoIGNzc05vZGUgKTtcclxuXHR9XHJcblxyXG5cclxuXHRmdW5jdGlvbiB3cGJjX19jc3NfX2NoYW5nZV9za2luKCBzZWxlY3RlZF9za2luX3VybCwgc3R5bGVzaGVldF9pZCA9ICd3cGJjLXRpbWVfcGlja2VyLXNraW4tY3NzJyApe1xyXG5cclxuXHRcdC8vIFJlbW92ZSBDU1Mgc2tpblxyXG5cdFx0dmFyIHN0eWxlc2hlZXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggc3R5bGVzaGVldF9pZCApO1xyXG5cdFx0c3R5bGVzaGVldC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBzdHlsZXNoZWV0ICk7XHJcblxyXG5cclxuXHRcdC8vIEFkZCBuZXcgQ1NTIHNraW5cclxuXHRcdHZhciBoZWFkSUQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJoZWFkXCIgKVsgMCBdO1xyXG5cdFx0dmFyIGNzc05vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnbGluaycgKTtcclxuXHRcdGNzc05vZGUudHlwZSA9ICd0ZXh0L2Nzcyc7XHJcblx0XHRjc3NOb2RlLnNldEF0dHJpYnV0ZSggXCJpZFwiLCBzdHlsZXNoZWV0X2lkICk7XHJcblx0XHRjc3NOb2RlLnJlbCA9ICdzdHlsZXNoZWV0JztcclxuXHRcdGNzc05vZGUubWVkaWEgPSAnc2NyZWVuJztcclxuXHRcdGNzc05vZGUuaHJlZiA9IHNlbGVjdGVkX3NraW5fdXJsO1x0Ly9cImh0dHA6Ly9iZXRhL3dwLWNvbnRlbnQvcGx1Z2lucy9ib29raW5nL2Nzcy9za2lucy9ncmVlbi0wMS5jc3NcIjtcclxuXHRcdGhlYWRJRC5hcHBlbmRDaGlsZCggY3NzTm9kZSApO1xyXG5cdH1cclxuXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyogID09ICBTIFUgUCBQIE8gUiBUICAgIE0gQSBUIEggID09XHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogTWVyZ2Ugc2V2ZXJhbCAgaW50ZXJzZWN0ZWQgaW50ZXJ2YWxzIG9yIHJldHVybi
3411Bub3QgaW50ZXJzZWN0ZWQ6ICAgICAgICAgICAgICAgICAgICAgICAgW1sxLDNdLFsyLDZdLFs4LDEwXSxbMTUsMThdXSAgLT4gICBbWzEsNl0sWzgsMTBdLFsxNSwxOF1dXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIFtdIGludGVydmFsc1x0XHRcdCBbIFsxLDNdLFsyLDRdLFs2LDhdLFs5LDEwXSxbMyw3XSBdXHJcblx0XHQgKiBAcmV0dXJucyBbXVx0XHRcdFx0XHQgWyBbMSw4XSxbOSwxMF0gXVxyXG5cdFx0ICpcclxuXHRcdCAqIEV4bWFtcGxlOiB3cGJjX2ludGVydmFsc19fbWVyZ2VfaW5lcnNlY3RlZCggIFsgWzEsM10sWzIsNF0sWzYsOF0sWzksMTBdLFszLDddIF0gICk7XHJcblx0XHQgKi9cclxuXHRcdGZ1bmN0aW9uIHdwYmNfaW50ZXJ2YWxzX19tZXJnZV9pbmVyc2VjdGVkKCBpbnRlcnZhbHMgKXtcclxuXHJcblx0XHRcdGlmICggISBpbnRlcnZhbHMgfHwgaW50ZXJ2YWxzLmxlbmd0aCA9PT0gMCApe1xyXG5cdFx0XHRcdHJldHVybiBbXTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dmFyIG1lcmdlZCA9IFtdO1xyXG5cdFx0XHRpbnRlcnZhbHMuc29ydCggZnVuY3Rpb24gKCBhLCBiICl7XHJcblx0XHRcdFx0cmV0dXJuIGFbIDAgXSAtIGJbIDAgXTtcclxuXHRcdFx0fSApO1xyXG5cclxuXHRcdFx0dmFyIG1lcmdlZEludGVydmFsID0gaW50ZXJ2YWxzWyAwIF07XHJcblxyXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDE7IGkgPCBpbnRlcnZhbHMubGVuZ3RoOyBpKysgKXtcclxuXHRcdFx0XHR2YXIgaW50ZXJ2YWwgPSBpbnRlcnZhbHNbIGkgXTtcclxuXHJcblx0XHRcdFx0aWYgKCBpbnRlcnZhbFsgMCBdIDw9IG1lcmdlZEludGVydmFsWyAxIF0gKXtcclxuXHRcdFx0XHRcdG1lcmdlZEludGVydmFsWyAxIF0gPSBNYXRoLm1heCggbWVyZ2VkSW50ZXJ2YWxbIDEgXSwgaW50ZXJ2YWxbIDEgXSApO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRtZXJnZWQucHVzaCggbWVyZ2VkSW50ZXJ2YWwgKTtcclxuXHRcdFx0XHRcdG1lcmdlZEludGVydmFsID0gaW50ZXJ2YWw7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRtZXJnZWQucHVzaCggbWVyZ2VkSW50ZXJ2YWwgKTtcclxuXHRcdFx0cmV0dXJuIG1lcmdlZDtcclxuXHRcdH1cclxuXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBJcyAyIGludGVydmFscyBpbnRlcnNlY3RlZDogICAgICAgWzM2MDExLCA4NjM5Ml0gICAgPD0+ICAgIFsxLCA0MzE5Ml0gID0+ICB0cnVlICAgICAgKCBpbnRlcnNlY3RlZCApXHJcblx0XHQgKlxyXG5cdFx0ICogR29vZCBleHBsYW5hdGlvbiAgaGVyZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zMjY5NDM0L3doYXRzLXRoZS1tb3N0LWVmZmljaWVudC13YXktdG8tdGVzdC1pZi10d28tcmFuZ2VzLW92ZXJsYXBcclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0gIGludGVydmFsX0EgICAtIFsgMzYwMTEsIDg2MzkyIF1cclxuXHRcdCAqIEBwYXJhbSAgaW50ZXJ2YWxfQiAgIC0gWyAgICAgMSwgNDMxOTIgXVxyXG5cdFx0ICpcclxuXHRcdCAqIEByZXR1cm4gYm9vbFxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2ludGVydmFsc19faXNfaW50ZXJzZWN0ZWQoIGludGVydmFsX0EsIGludGVydmFsX0IgKSB7XHJcblxyXG5cdFx0XHRpZiAoXHJcblx0XHRcdFx0XHQoIDAgPT0gaW50ZXJ2YWxfQS5sZW5ndGggKVxyXG5cdFx0XHRcdCB8fCAoIDAgPT0gaW50ZXJ2YWxfQi5sZW5ndGggKVxyXG5cdFx0XHQpe1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aW50ZXJ2YWxfQVsgMCBdID0gcGFyc2VJbnQoIGludGVydmFsX0FbIDAgXSApO1xyXG5cdFx0XHRpbnRlcnZhbF9BWyAxIF0gPSBwYXJzZUludCggaW50ZXJ2YWxfQVsgMSBdICk7XHJcblx0XHRcdGludGVydmFsX0JbIDAgXSA9IHBhcnNlSW50KCBpbnRlcnZhbF9CWyAwIF0gKTtcclxuXHRcdFx0aW50ZXJ2YWxfQlsgMSBdID0gcGFyc2VJbnQoIGludGVydmFsX0JbIDEgXSApO1xyXG5cclxuXHRcdFx0dmFyIGlzX2ludGVyc2VjdGVkID0gTWF0aC5tYXgoIGludGVydmFsX0FbIDAgXSwgaW50ZXJ2YWxfQlsgMCBdICkgLSBNYXRoLm1pbiggaW50ZXJ2YWxfQVsgMSBdLCBpbnRlcnZhbF9CWyAxIF0gKTtcclxuXHJcblx0XHRcdC8vIGlmICggMCA9PSBpc19pbnRlcnNlY3RlZCApIHtcclxuXHRcdFx0Ly9cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1Y2ggcmFuZ2VzIGdvaW5nIG9uZSBhZnRlciBvdGhlciwgZS5nLjogWyAxMiwgMTUgXSBhbmQgWyAxNSwgMjEgXVxyXG5cdFx0XHQvLyB9XHJcblxyXG5cdFx0XHRpZiAoIGlzX2ludGVyc2VjdGVkIDwgMCApIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAvLyBJTlRFUlNFQ1RFRFxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gZmFsc2U7ICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3QgaW50ZXJzZWN0ZWRcclxuXHRcdH1cclxuXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBHZXQgdGhlIGNsb3NldHMgQUJTIHZhbHVlIG9mIGVsZW1lbnQgaW4gYXJyYXkgdG8gdGhlIGN1cnJlbnQgbXlWYWx1ZVxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSBteVZhbHVlIFx0LSBpbnQgZWxlbWVudCB0byBzZWFyY2ggY2xvc2V0IFx0XHRcdDRcclxuXHRcdCAqIEBwYXJhbSBteUFycmF5XHQtIGFycmF5IG9mIGVsZW1lbnRzIHdoZXJlIHRvIHNlYXJjaCBcdFs1LDgsMSw3XVxyXG5cdFx0ICogQHJldHVybnMgaW50XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0NVxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2dldF9hYnNfY2xvc2VzdF92YWx1ZV9pbl9hcnIoIG15VmFsdWUsIG15QXJyYXkgKXtcclxuXHJcblx0XHRcdGlmICggbXlBcnJheS5sZW5ndGggPT0gMCApeyBcdFx0XHRcdFx0XHRcdFx0Ly8gSWYgdGhlIGFycmF5IGlzIGVtcHR5IC0+IHJldHVybiAgdGhlIG15VmFsdWVcclxuXHRcdFx0XHRyZXR1cm4gbXlWYWx1ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dmFyIG9iaiA9IG15QXJyYXlbIDAgXTtcclxuXHRcdFx0dmFyIGRpZmYgPSBNYXRoLmFicyggbXlWYWx1ZSAtIG9iaiApOyAgICAgICAgICAgICBcdC8vIEdldCBkaXN0YW5jZSBiZXR3ZWVuICAxc3QgZWxlbWVudFxyXG5cdFx0XHR2YXIgY2xvc2V0VmFsdWUgPSBteUFycmF5WyAwIF07ICAgICAgICAgICAgICAgICAgIFx0XHRcdC8vIFNhdmUgMXN0IGVsZW1lbnRcclxuXHJcblx0XHRcdGZvciAoIHZhciBpID0gMTsgaSA8IG15QXJyYXkubGVuZ3RoOyBpKysgKXtcclxuXHRcdFx0XHRvYmogPSBteUFycmF5WyBpIF07XHJcblxyXG5cdFx0XHRcdGlmICggTWF0aC5hYnMoIG15VmFsdWUgLSBvYmogKSA8IGRpZmYgKXsgICAgIFx0XHRcdC8vIHdlIGZvdW5kIGNsb3NlciB2YWx1ZSAtPiBzY
3411XZlIGl0XHJcblx0XHRcdFx0XHRkaWZmID0gTWF0aC5hYnMoIG15VmFsdWUgLSBvYmogKTtcclxuXHRcdFx0XHRcdGNsb3NldFZhbHVlID0gb2JqO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIGNsb3NldFZhbHVlO1xyXG5cdFx0fVxyXG5cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKiAgPT0gIFQgTyBPIEwgVCBJIFAgUyAgPT1cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG5cdC8qKlxyXG5cdCAqIERlZmluZSB0b29sdGlwIHRvIHNob3csICB3aGVuICBtb3VzZSBvdmVyIERhdGUgaW4gQ2FsZW5kYXJcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSAgdG9vbHRpcF90ZXh0XHRcdFx0LSBUZXh0IHRvIHNob3dcdFx0XHRcdCdCb29rZWQgdGltZTogMTI6MDAgLSAxMzowMDxicj5Db3N0OiAkMjAuMDAnXHJcblx0ICogQHBhcmFtICByZXNvdXJjZV9pZFx0XHRcdC0gSUQgb2YgYm9va2luZyByZXNvdXJjZVx0JzEnXHJcblx0ICogQHBhcmFtICB0ZF9jbGFzc1x0XHRcdFx0LSBTUUwgY2xhc3NcdFx0XHRcdFx0JzEtOS0yMDIzJ1xyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVx0XHRcdFx0XHQtIGRlZmluZWQgdG8gc2hvdyBvciBub3RcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX3NldF90b29sdGlwX19fZm9yX19jYWxlbmRhcl9kYXRlKCB0b29sdGlwX3RleHQsIHJlc291cmNlX2lkLCB0ZF9jbGFzcyApe1xyXG5cclxuXHRcdC8vVE9ETzogbWFrZSBlc2NhcGluZyBvZiB0ZXh0IGZvciBxdW90IHN5bWJvbHMsICBhbmQgSlMvSFRNTC4uLlxyXG5cclxuXHRcdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICsgJyB0ZC5jYWw0ZGF0ZS0nICsgdGRfY2xhc3MgKS5hdHRyKCAnZGF0YS1jb250ZW50JywgdG9vbHRpcF90ZXh0ICk7XHJcblxyXG5cdFx0dmFyIHRkX2VsID0galF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKyAnIHRkLmNhbDRkYXRlLScgKyB0ZF9jbGFzcyApLmdldCggMCApO1x0XHRcdFx0XHQvLyBGaXhJbjogOS4wLjEuMS5cclxuXHJcblx0XHRpZiAoXHJcblx0XHRcdCAgICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZih0ZF9lbCkgKVxyXG5cdFx0XHQmJiAoIHVuZGVmaW5lZCA9PSB0ZF9lbC5fdGlwcHkgKVxyXG5cdFx0XHQmJiAoICcnICE9PSB0b29sdGlwX3RleHQgKVxyXG5cdFx0KXtcclxuXHJcblx0XHRcdHdwYmNfdGlwcHkoIHRkX2VsICwge1xyXG5cdFx0XHRcdFx0Y29udGVudCggcmVmZXJlbmNlICl7XHJcblxyXG5cdFx0XHRcdFx0XHR2YXIgcG9wb3Zlcl9jb250ZW50ID0gcmVmZXJlbmNlLmdldEF0dHJpYnV0ZSggJ2RhdGEtY29udGVudCcgKTtcclxuXHJcblx0XHRcdFx0XHRcdHJldHVybiAnPGRpdiBjbGFzcz1cInBvcG92ZXIgcG9wb3Zlcl90aXBweVwiPidcclxuXHRcdFx0XHRcdFx0XHRcdFx0KyAnPGRpdiBjbGFzcz1cInBvcG92ZXItY29udGVudFwiPidcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQrIHBvcG92ZXJfY29udGVudFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQrICc8L2Rpdj4nXHJcblx0XHRcdFx0XHRcdFx0ICsgJzwvZGl2Pic7XHJcblx0XHRcdFx0XHR9LFxyXG5cdFx0XHRcdFx0YWxsb3dIVE1MICAgICAgICA6IHRydWUsXHJcblx0XHRcdFx0XHR0cmlnZ2VyXHRcdFx0IDogJ21vdXNlZW50ZXIgZm9jdXMnLFxyXG5cdFx0XHRcdFx0aW50ZXJhY3RpdmUgICAgICA6IGZhbHNlLFxyXG5cdFx0XHRcdFx0aGlkZU9uQ2xpY2sgICAgICA6IHRydWUsXHJcblx0XHRcdFx0XHRpbnRlcmFjdGl2ZUJvcmRlcjogMTAsXHJcblx0XHRcdFx0XHRtYXhXaWR0aCAgICAgICAgIDogNTUwLFxyXG5cdFx0XHRcdFx0dGhlbWUgICAgICAgICAgICA6ICd3cGJjLXRpcHB5LXRpbWVzJyxcclxuXHRcdFx0XHRcdHBsYWNlbWVudCAgICAgICAgOiAndG9wJyxcclxuXHRcdFx0XHRcdGRlbGF5XHRcdFx0IDogWzQwMCwgMF0sXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gRml4SW46IDkuNC4yLjIuXHJcblx0XHRcdFx0XHQvL2RlbGF5XHRcdFx0IDogWzAsIDk5OTk5OTk5OTldLFx0XHRcdFx0XHRcdC8vIERlYnVnZSAgdG9vbHRpcFxyXG5cdFx0XHRcdFx0aWdub3JlQXR0cmlidXRlcyA6IHRydWUsXHJcblx0XHRcdFx0XHR0b3VjaFx0XHRcdCA6IHRydWUsXHRcdFx0XHRcdFx0XHRcdC8vWydob2xkJywgNTAwXSwgLy8gNTAwbXMgZGVsYXlcdFx0XHRcdC8vIEZpeEluOiA5LjIuMS41LlxyXG5cdFx0XHRcdFx0YXBwZW5kVG86ICgpID0+IGRvY3VtZW50LmJvZHksXHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0cmV0dXJuICB0cnVlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiAgZmFsc2U7XHJcblx0fVxyXG5cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKiAgPT0gIERhdGVzIEZ1bmN0aW9ucyAgPT1cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG4vKipcclxuICogR2V0IG51bWJlciBvZiBkYXRlcyBiZXR3ZWVuIDIgSlMgRGF0ZXNcclxuICpcclxuICogQHBhcmFtIGRhdGUxXHRcdEpTIERhdGVcclxuICogQHBhcmFtIGRhdGUyXHRcdEpTIERhdGVcclxuICogQHJldHVybnMge251bWJlcn1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfZGF0ZXNfX2RheXNfYmV0d2VlbihkYXRlMSwgZGF0ZTIpIHtcclxuXHJcbiAgICAvLyBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpbiBvbmUgZGF5XHJcbiAgICB2YXIgT05FX0RBWSA9IDEwMDAgKiA2MCAqIDYwICogMjQ7XHJcblxyXG4gICAgLy8gQ29udmVydCBib3RoIGRhdGVzIHRvIG1pbGxpc2Vjb25kc1xyXG4gICAgdmFyIGRhdGUxX21zID0gZGF0ZTEuZ2V0VGltZSgpO1xyXG4gICAgdmFyIGRhdGUyX21zID0gZGF0ZTIuZ2V0VGltZSgpO1xyXG5cclxuICAgIC8vIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiBtaWxsaXNlY29uZHNcclxuICAgIHZhciBkaWZmZXJlbmNlX21zID0gIGRhdGUxX21zIC0gZGF0ZTJfbXM7XHJcblxyXG4gICAgLy8gQ29udmVydCBiYWNrIHRvIGRheXMgYW5kIHJldHVyblxyXG4gICAgcmV0dXJuIE1hdGgucm91bmQoZGlmZmVyZW5jZV9tcy9PTkVfREFZKTtcclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiBDaGVjayAgaWYgdGhpcyBhcnJheSAgb2YgZGF0ZXMgaXMgY29uc2VjdXRpdmUgYXJyYXkgIG9mIGRhdGVzIG9yIG5vdC5cclxuICogXHRcdGUuZy4gIFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTknLCcyMDI0LTA1LTMwJ10gLT4gZmFsc2VcclxuICogXHRcdGUuZy4gIFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTAnLCcyMDI0LTA1LTExJ10gLT4gdHJ1ZVxyXG4gKiBAcGFyYW0gc3FsX2RhdGVzX2Fyclx0IGFycmF5XHRcdGUuZy46IFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTknLCcyMDI0LTA1LTMwJ11cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2RhdGVzX19pc19jb25zZWN1dGl2ZV9kYXRlc19hcnJfcmFuZ2UoIHNxbF9kYXRlc19hcnIgKXtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiAxMC4wLjAuNTAuXHJcblxyXG5cdGlmICggc3FsX2RhdGVzX2Fyci5sZW5ndGggPiAxICl7XHJcblx0XHR2YXIgcHJldmlvc19kYXRlID0gd3BiY19fZ2V0X19qc19kYXRlKCBzcWxfZGF0ZXNfYXJyWyAwIF0gKTtcclxuXHRcdHZhciBjdXJyZW50X2RhdGU7XHJcblxyXG5cdFx0Zm9yICggdmFyIGkgPSAxOyBpIDwgc3FsX2RhdGVzX2Fyci5sZW5ndGg7IGkrKyApe1xyXG5cdFx0XHRjdXJyZW50X2RhdGUgPSB3cGJjX19nZXRfX2pzX2RhdGUoIHNxbF9kYXRlc19hcnJbaV0gKTtcclxuXHJcblx0XHRcdGlmICggd3BiY19kYXRlc19fZGF5c19iZXR3ZWVuKCBjdXJyZW50X2RhdGUsIHByZXZpb3NfZGF0ZSApICE9IDEgKXtcclxuXHRcdFx0XHRyZXR1cm4gIGZhbHNlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRwcmV2aW9zX2RhdGUgPSBjdXJyZW50X2RhdGU7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdHJ1ZTtcclxufVxyXG5cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKiAgPT
34110gIEF1dG8gRGF0ZXMgU2VsZWN0aW9uICA9PVxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cclxuXHJcbi8qKlxyXG4gKiAgPT0gSG93IHRvICB1c2UgPyA9PVxyXG4gKlxyXG4gKiAgRm9yIERhdGVzIHNlbGVjdGlvbiwgd2UgbmVlZCB0byB1c2UgdGhpcyBsb2dpYyEgICAgIFdlIG5lZWQgc2VsZWN0IHRoZSBkYXRlcyBvbmx5IGFmdGVyIGJvb2tpbmcgZGF0YSBsb2FkZWQhXHJcbiAqXHJcbiAqICBDaGVjayBleGFtcGxlIGJlbGxvdy5cclxuICpcclxuICpcdC8vIEZpcmUgb24gYWxsIGJvb2tpbmcgZGF0ZXMgbG9hZGVkXHJcbiAqXHRqUXVlcnkoICdib2R5JyApLm9uKCAnd3BiY19jYWxlbmRhcl9hanhfX2xvYWRlZF9kYXRhJywgZnVuY3Rpb24gKCBldmVudCwgbG9hZGVkX3Jlc291cmNlX2lkICl7XHJcbiAqXHJcbiAqXHRcdGlmICggbG9hZGVkX3Jlc291cmNlX2lkID09IHNlbGVjdF9kYXRlc19pbl9jYWxlbmRhcl9pZCApe1xyXG4gKlx0XHRcdHdwYmNfYXV0b19zZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXIoIHNlbGVjdF9kYXRlc19pbl9jYWxlbmRhcl9pZCwgJzIwMjQtMDUtMTUnLCAnMjAyNC0wNS0yNScgKTtcclxuICpcdFx0fVxyXG4gKlx0fSApO1xyXG4gKlxyXG4gKi9cclxuXHJcblxyXG4vKipcclxuICogVHJ5IHRvIEF1dG8gc2VsZWN0IGRhdGVzIGluIHNwZWNpZmljIGNhbGVuZGFyIGJ5IHNpbXVsYXRlZCBjbGlja3MgaW4gZGF0ZXBpY2tlclxyXG4gKlxyXG4gKiBAcGFyYW0gcmVzb3VyY2VfaWRcdFx0MVxyXG4gKiBAcGFyYW0gY2hlY2tfaW5feW1kXHRcdCcyMDI0LTA1LTA5J1x0XHRPUiAgXHRbJzIwMjQtMDUtMDknLCcyMDI0LTA1LTE5JywnMjAyNC0wNS0yMCddXHJcbiAqIEBwYXJhbSBjaGVja19vdXRfeW1kXHRcdCcyMDI0LTA1LTE1J1x0XHRPcHRpb25hbFxyXG4gKlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVx0XHRudW1iZXIgb2Ygc2VsZWN0ZWQgZGF0ZXNcclxuICpcclxuICogXHRFeGFtcGxlIDE6XHRcdFx0XHR2YXIgbnVtX3NlbGVjdGVkX2RheXMgPSB3cGJjX2F1dG9fc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyKCAxLCAnMjAyNC0wNS0xNScsICcyMDI0LTA1LTI1JyApO1xyXG4gKiBcdEV4YW1wbGUgMjpcdFx0XHRcdHZhciBudW1fc2VsZWN0ZWRfZGF5cyA9IHdwYmNfYXV0b19zZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXIoIDEsIFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTknLCcyMDI0LTA1LTIwJ10gKTtcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfYXV0b19zZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXIoIHJlc291cmNlX2lkLCBjaGVja19pbl95bWQsIGNoZWNrX291dF95bWQgPSAnJyApe1x0XHRcdFx0XHRcdFx0XHQvLyBGaXhJbjogMTAuMC4wLjQ3LlxyXG5cclxuXHRjb25zb2xlLmxvZyggJ1dQQkNfQVVUT19TRUxFQ1RfREFURVNfSU5fQ0FMRU5EQVIoIFJFU09VUkNFX0lELCBDSEVDS19JTl9ZTUQsIENIRUNLX09VVF9ZTUQgKScsIHJlc291cmNlX2lkLCBjaGVja19pbl95bWQsIGNoZWNrX291dF95bWQgKTtcclxuXHJcblx0aWYgKFxyXG5cdFx0ICAgKCAnMjEwMC0wMS0wMScgPT0gY2hlY2tfaW5feW1kIClcclxuXHRcdHx8ICggJzIxMDAtMDEtMDEnID09IGNoZWNrX291dF95bWQgKVxyXG5cdFx0fHwgKCAoICcnID09IGNoZWNrX2luX3ltZCApICYmICggJycgPT0gY2hlY2tfb3V0X3ltZCApIClcclxuXHQpe1xyXG5cdFx0cmV0dXJuIDA7XHJcblx0fVxyXG5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8vIElmIFx0Y2hlY2tfaW5feW1kICA9ICBbICcyMDI0LTA1LTA5JywnMjAyNC0wNS0xOScsJzIwMjQtMDUtMzAnIF1cdFx0XHRcdEFSUkFZIG9mIERBVEVTXHRcdFx0XHRcdFx0Ly8gRml4SW46IDEwLjAuMC41MC5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdHZhciBkYXRlc190b19zZWxlY3RfYXJyID0gW107XHJcblx0aWYgKCBBcnJheS5pc0FycmF5KCBjaGVja19pbl95bWQgKSApe1xyXG5cdFx0ZGF0ZXNfdG9fc2VsZWN0X2FyciA9IHdwYmNfY2xvbmVfb2JqKCBjaGVja19pbl95bWQgKTtcclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHQvLyBFeGNlcHRpb25zIHRvICBzZXQgIFx0TVVMVElQTEUgREFZUyBcdG1vZGVcclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vIGlmIGRhdGVzIGFzIE5PVCBDT05TRUNVVElWRTogWycyMDI0LTA1LTA5JywnMjAyNC0wNS0xOScsJzIwMjQtMDUtMzAnXSwgLT4gc2V0IE1VTFRJUExFIERBWVMgbW9kZVxyXG5cdFx0aWYgKFxyXG5cdFx0XHQgICAoIGRhdGVzX3RvX3NlbGVjdF9hcnIubGVuZ3RoID4gMCApXHJcblx0XHRcdCYmICggJycgPT0gY2hlY2tfb3V0X3ltZCApXHJcblx0XHRcdCYmICggISB3cGJjX2RhdGVzX19pc19jb25zZWN1dGl2ZV9kYXRlc19hcnJfcmFuZ2UoIGRhdGVzX3RvX3NlbGVjdF9hcnIgKSApXHJcblx0XHQpe1xyXG5cdFx0XHR3cGJjX2NhbF9kYXlzX3NlbGVjdF9fbXVsdGlwbGUoIHJlc291cmNlX2lkICk7XHJcblx0XHR9XHJcblx0XHQvLyBpZiBtdWx0aXBsZSBkYXlzIHRvIHNlbGVjdCwgYnV0IGVuYWJsZWQgU0lOR0xFIGRheSBtb2RlLCAtPiBzZXQgTVVMVElQTEUgREFZUyBtb2RlXHJcblx0XHRpZiAoXHJcblx0XHRcdCAgICggZGF0ZXNfdG9fc2VsZWN0X2Fyci5sZW5ndGggPiAxIClcclxuXHRcdFx0JiYgKCAnJyA9PSBjaGVja19vdXRfeW1kIClcclxuXHRcdFx0JiYgKCAnc2luZ2xlJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApIClcclxuXHRcdCl7XHJcblx0XHRcdHdwYmNfY2FsX2RheXNfc2VsZWN0X19tdWx0aXBsZSggcmVzb3VyY2VfaWQgKTtcclxuXHRcdH1cclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdGNoZWNrX2luX3ltZCA9IGRhdGVzX3RvX3NlbGVjdF9hcnJbIDAgXTtcclxuXHRcdGlmICggJycgPT0gY2hlY2tfb3V0X3ltZCApe1xyXG5cdFx0XHRjaGVja19vdXRfeW1kID0gZGF0ZXNfdG9fc2VsZWN0X2FyclsgKGRhdGVzX3RvX3NlbGVjdF9hcnIubGVuZ3RoLTEpIF07XHJcblx0XHR9XHJcblx0fVxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5cclxuXHRpZiAoICcnID09IGNoZWNrX2luX3ltZCApe1xyXG5cdFx0Y2hlY2tfaW5feW1kID0gY2hlY2tfb3V0X3ltZDtcclxuXHR9XHJcblx0aWYgKCAnJyA9PSBjaGVja19vdXRfeW1kICl7XHJcblx0XHRjaGVja19vdXRfeW1kID0gY2hlY2tfaW5feW1kO1xyXG5cdH1cclxuXHJcblx0aWYgKCAndW5kZWZpbmVkJyA9PT0gdHlwZW9mIChyZXNvdXJjZV9pZCkgKXtcclxuXHRcdHJlc291cmNlX2lkID0gJzEnO1xyXG5cdH1cclxuXHJcblxyXG5cdHZhciBpbnN0ID0gd3BiY19jYWxlbmRhcl9fZ2V0X2luc3QoIHJlc291cmNlX2lkICk7XHJcblxyXG5cdGlmICggbnVsbCAhPT0gaW5zdCApe1xyXG5cclxuXHRcdC8vIFVuc2VsZWN0IGFsbCBkYXRlcyBhbmQgc2V0ICBwcm9wZXJ0aWVzIG9mIERhdGVwaWNrXHJcblx0XHRqUXVlcnkoICcjZGF0ZV9ib29raW5nJyArIHJlc291cmNlX2lkICkudmFsKCAnJyApOyAgICAgIFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvL0ZpeEluOiA1LjQuM1xyXG5cdFx0aW5zdC5zdGF5T3BlbiA9IGZ
3411hbHNlO1xyXG5cdFx0aW5zdC5kYXRlcyA9IFtdO1xyXG5cdFx0dmFyIGNoZWNrX2luX2pzID0gd3BiY19fZ2V0X19qc19kYXRlKCBjaGVja19pbl95bWQgKTtcclxuXHRcdHZhciB0ZF9jZWxsICAgICA9IHdwYmNfZ2V0X2NsaWNrZWRfdGQoIGluc3QuaWQsIGNoZWNrX2luX2pzICk7XHJcblxyXG5cdFx0Ly8gSXMgb21lIHR5cGUgb2YgZXJyb3IsIHRoZW4gc2VsZWN0IG11bHRpcGxlIGRheXMgc2VsZWN0aW9uICBtb2RlLlxyXG5cdFx0aWYgKCAnJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApICkge1xyXG4gXHRcdFx0X3dwYmMuY2FsZW5kYXJfX3NldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJywgJ211bHRpcGxlJyApO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vICA9PSBEWU5BTUlDID09XHJcblx0XHRpZiAoICdkeW5hbWljJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApICl7XHJcblx0XHRcdC8vIDEtc3QgY2xpY2tcclxuXHRcdFx0aW5zdC5zdGF5T3BlbiA9IGZhbHNlO1xyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3NlbGVjdERheSggdGRfY2VsbCwgJyMnICsgaW5zdC5pZCwgY2hlY2tfaW5fanMuZ2V0VGltZSgpICk7XHJcblx0XHRcdGlmICggMCA9PT0gaW5zdC5kYXRlcy5sZW5ndGggKXtcclxuXHRcdFx0XHRyZXR1cm4gMDsgIFx0XHRcdFx0XHRcdFx0XHQvLyBGaXJzdCBjbGljayAgd2FzIHVuc3VjY2Vzc2Z1bCwgc28gd2UgbXVzdCBub3QgbWFrZSBvdGhlciBjbGlja1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyAyLW5kIGNsaWNrXHJcblx0XHRcdHZhciBjaGVja19vdXRfanMgPSB3cGJjX19nZXRfX2pzX2RhdGUoIGNoZWNrX291dF95bWQgKTtcclxuXHRcdFx0dmFyIHRkX2NlbGxfb3V0ID0gd3BiY19nZXRfY2xpY2tlZF90ZCggaW5zdC5pZCwgY2hlY2tfb3V0X2pzICk7XHJcblx0XHRcdGluc3Quc3RheU9wZW4gPSB0cnVlO1xyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3NlbGVjdERheSggdGRfY2VsbF9vdXQsICcjJyArIGluc3QuaWQsIGNoZWNrX291dF9qcy5nZXRUaW1lKCkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vICA9PSBGSVhFRCA9PVxyXG5cdFx0aWYgKCAgJ2ZpeGVkJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApKSB7XHJcblx0XHRcdGpRdWVyeS5kYXRlcGljay5fc2VsZWN0RGF5KCB0ZF9jZWxsLCAnIycgKyBpbnN0LmlkLCBjaGVja19pbl9qcy5nZXRUaW1lKCkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vICA9PSBTSU5HTEUgPT1cclxuXHRcdGlmICggJ3NpbmdsZScgPT09IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZGF5c19zZWxlY3RfbW9kZScgKSApe1xyXG5cdFx0XHQvL2pRdWVyeS5kYXRlcGljay5fcmVzdHJpY3RNaW5NYXgoIGluc3QsIGpRdWVyeS5kYXRlcGljay5fZGV0ZXJtaW5lRGF0ZSggaW5zdCwgY2hlY2tfaW5fanMsIG51bGwgKSApO1x0XHQvLyBEbyB3ZSBuZWVkIHRvIHJ1biAgdGhpcyA/IFBsZWFzZSBub3RlLCBjaGVja19pbl9qcyBtdXN0ICBoYXZlIHRpbWUsICBtaW4sIHNlYyBkZWZpbmVkIHRvIDAhXHJcblx0XHRcdGpRdWVyeS5kYXRlcGljay5fc2VsZWN0RGF5KCB0ZF9jZWxsLCAnIycgKyBpbnN0LmlkLCBjaGVja19pbl9qcy5nZXRUaW1lKCkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vICA9PSBNVUxUSVBMRSA9PVxyXG5cdFx0aWYgKCAnbXVsdGlwbGUnID09PSBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2RheXNfc2VsZWN0X21vZGUnICkgKXtcclxuXHJcblx0XHRcdHZhciBkYXRlc19hcnI7XHJcblxyXG5cdFx0XHRpZiAoIGRhdGVzX3RvX3NlbGVjdF9hcnIubGVuZ3RoID4gMCApe1xyXG5cdFx0XHRcdC8vIFNpdHVhdGlvbiwgd2hlbiB3ZSBoYXZlIGRhdGVzIGFycmF5OiBbJzIwMjQtMDUtMDknLCcyMDI0LTA1LTE5JywnMjAyNC0wNS0zMCddLiAgYW5kIG5vdCB0aGUgQ2hlY2sgSW4gLyBDaGVjayAgb3V0IGRhdGVzIGFzIHBhcmFtZXRlciBpbiB0aGlzIGZ1bmN0aW9uXHJcblx0XHRcdFx0ZGF0ZXNfYXJyID0gd3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fYXJyKCBkYXRlc190b19zZWxlY3RfYXJyICk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0ZGF0ZXNfYXJyID0gd3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fY2hlY2tfaW5fb3V0KCBjaGVja19pbl95bWQsIGNoZWNrX291dF95bWQsIGluc3QgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKCAwID09PSBkYXRlc19hcnIuZGF0ZXNfanMubGVuZ3RoICl7XHJcblx0XHRcdFx0cmV0dXJuIDA7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEZvciBDYWxlbmRhciBEYXlzIHNlbGVjdGlvblxyXG5cdFx0XHRmb3IgKCB2YXIgaiA9IDA7IGogPCBkYXRlc19hcnIuZGF0ZXNfanMubGVuZ3RoOyBqKysgKXsgICAgICAgLy8gTG9vcCBhcnJheSBvZiBkYXRlc1xyXG5cclxuXHRcdFx0XHR2YXIgc3RyX2RhdGUgPSB3cGJjX19nZXRfX3NxbF9jbGFzc19kYXRlKCBkYXRlc19hcnIuZGF0ZXNfanNbIGogXSApO1xyXG5cclxuXHRcdFx0XHQvLyBEYXRlIHVuYXZhaWxhYmxlICFcclxuXHRcdFx0XHRpZiAoIDAgPT0gX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSggcmVzb3VyY2VfaWQsIHN0cl9kYXRlICkuZGF5X2F2YWlsYWJpbGl0eSApe1xyXG5cdFx0XHRcdFx0cmV0dXJuIDA7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoIGRhdGVzX2Fyci5kYXRlc19qc1sgaiBdICE9IC0xICkge1xyXG5cdFx0XHRcdFx0aW5zdC5kYXRlcy5wdXNoKCBkYXRlc19hcnIuZGF0ZXNfanNbIGogXSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dmFyIGNoZWNrX291dF9kYXRlID0gZGF0ZXNfYXJyLmRhdGVzX2pzWyAoZGF0ZXNfYXJyLmRhdGVzX2pzLmxlbmd0aCAtIDEpIF07XHJcblxyXG5cdFx0XHRpbnN0LmRhdGVzLnB1c2goIGNoZWNrX291dF9kYXRlICk7IFx0XHRcdC8vIE5lZWQgYWRkIG9uZSBhZGRpdGlvbmFsIFNBTUUgZGF0ZSBmb3IgY29ycmVjdCAgd29ya3Mgb2YgZGF0ZXMgc2VsZWN0aW9uICEhISEhXHJcblxyXG5cdFx0XHR2YXIgY2hlY2tvdXRfdGltZXN0YW1wID0gY2hlY2tfb3V0X2RhdGUuZ2V0VGltZSgpO1xyXG5cdFx0XHR2YXIgdGRfY2VsbCA9IHdwYmNfZ2V0X2NsaWNrZWRfdGQoIGluc3QuaWQsIGNoZWNrX291dF9kYXRlICk7XHJcblxyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3NlbGVjdERhe
3411SggdGRfY2VsbCwgJyMnICsgaW5zdC5pZCwgY2hlY2tvdXRfdGltZXN0YW1wICk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdGlmICggMCAhPT0gaW5zdC5kYXRlcy5sZW5ndGggKXtcclxuXHRcdFx0Ly8gU2Nyb2xsIHRvIHNwZWNpZmljIG1vbnRoLCBpZiB3ZSBzZXQgZGF0ZXMgaW4gc29tZSBmdXR1cmUgbW9udGhzXHJcblx0XHRcdHdwYmNfY2FsZW5kYXJfX3Njcm9sbF90byggcmVzb3VyY2VfaWQsIGluc3QuZGF0ZXNbIDAgXS5nZXRGdWxsWWVhcigpLCBpbnN0LmRhdGVzWyAwIF0uZ2V0TW9udGgoKSsxICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGluc3QuZGF0ZXMubGVuZ3RoO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIDA7XHJcbn1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IEhUTUwgdGQgZWxlbWVudCAod2hlcmUgd2FzIGNsaWNrIGluIGNhbGVuZGFyICBkYXkgIGNlbGwpXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gY2FsZW5kYXJfaHRtbF9pZFx0XHRcdCdjYWxlbmRhcl9ib29raW5nMSdcclxuXHQgKiBAcGFyYW0gZGF0ZV9qc1x0XHRcdFx0XHRKUyBEYXRlXHJcblx0ICogQHJldHVybnMgeyp8alF1ZXJ5fVx0XHRcdFx0RG9tIEhUTUwgdGQgZWxlbWVudFxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZ2V0X2NsaWNrZWRfdGQoIGNhbGVuZGFyX2h0bWxfaWQsIGRhdGVfanMgKXtcclxuXHJcblx0ICAgIHZhciB0ZF9jZWxsID0galF1ZXJ5KCAnIycgKyBjYWxlbmRhcl9odG1sX2lkICsgJyAuc3FsX2RhdGVfJyArIHdwYmNfX2dldF9fc3FsX2NsYXNzX2RhdGUoIGRhdGVfanMgKSApLmdldCggMCApO1xyXG5cclxuXHRcdHJldHVybiB0ZF9jZWxsO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IGFycmF5cyBvZiBKUyBhbmQgU1FMIGRhdGVzIGFzIGRhdGVzIGFycmF5XHJcblx0ICpcclxuXHQgKiBAcGFyYW0gY2hlY2tfaW5feW1kXHRcdFx0XHRcdFx0XHQnMjAyNC0wNS0xNSdcclxuXHQgKiBAcGFyYW0gY2hlY2tfb3V0X3ltZFx0XHRcdFx0XHRcdFx0JzIwMjQtMDUtMjUnXHJcblx0ICogQHBhcmFtIGluc3RcdFx0XHRcdFx0XHRcdFx0XHREYXRlcGljayBJbnN0LiBVc2Ugd3BiY19jYWxlbmRhcl9fZ2V0X2luc3QoIHJlc291cmNlX2lkICk7XHJcblx0ICogQHJldHVybnMge3tkYXRlc19qczogKltdLCBkYXRlc19zdHI6ICpbXX19XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fY2hlY2tfaW5fb3V0KCBjaGVja19pbl95bWQsIGNoZWNrX291dF95bWQgLCBpbnN0ICl7XHJcblxyXG5cdFx0dmFyIG9yaWdpbmFsX2FycmF5ID0gW107XHJcblx0XHR2YXIgZGF0ZTtcclxuXHRcdHZhciBia19kaXN0aW5jdF9kYXRlcyA9IFtdO1xyXG5cclxuXHRcdHZhciBjaGVja19pbl9kYXRlID0gY2hlY2tfaW5feW1kLnNwbGl0KCAnLScgKTtcclxuXHRcdHZhciBjaGVja19vdXRfZGF0ZSA9IGNoZWNrX291dF95bWQuc3BsaXQoICctJyApO1xyXG5cclxuXHRcdGRhdGUgPSBuZXcgRGF0ZSgpO1xyXG5cdFx0ZGF0ZS5zZXRGdWxsWWVhciggY2hlY2tfaW5fZGF0ZVsgMCBdLCAoY2hlY2tfaW5fZGF0ZVsgMSBdIC0gMSksIGNoZWNrX2luX2RhdGVbIDIgXSApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHllYXIsIG1vbnRoLCBkYXRlXHJcblx0XHR2YXIgb3JpZ2luYWxfY2hlY2tfaW5fZGF0ZSA9IGRhdGU7XHJcblx0XHRvcmlnaW5hbF9hcnJheS5wdXNoKCBqUXVlcnkuZGF0ZXBpY2suX3Jlc3RyaWN0TWluTWF4KCBpbnN0LCBqUXVlcnkuZGF0ZXBpY2suX2RldGVybWluZURhdGUoIGluc3QsIGRhdGUsIG51bGwgKSApICk7IC8vYWRkIGRhdGVcclxuXHRcdGlmICggISB3cGJjX2luX2FycmF5KCBia19kaXN0aW5jdF9kYXRlcywgKGNoZWNrX2luX2RhdGVbIDIgXSArICcuJyArIGNoZWNrX2luX2RhdGVbIDEgXSArICcuJyArIGNoZWNrX2luX2RhdGVbIDAgXSkgKSApe1xyXG5cdFx0XHRia19kaXN0aW5jdF9kYXRlcy5wdXNoKCBwYXJzZUludChjaGVja19pbl9kYXRlWyAyIF0pICsgJy4nICsgcGFyc2VJbnQoY2hlY2tfaW5fZGF0ZVsgMSBdKSArICcuJyArIGNoZWNrX2luX2RhdGVbIDAgXSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBkYXRlX291dCA9IG5ldyBEYXRlKCk7XHJcblx0XHRkYXRlX291dC5zZXRGdWxsWWVhciggY2hlY2tfb3V0X2RhdGVbIDAgXSwgKGNoZWNrX291dF9kYXRlWyAxIF0gLSAxKSwgY2hlY2tfb3V0X2RhdGVbIDIgXSApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHllYXIsIG1vbnRoLCBkYXRlXHJcblx0XHR2YXIgb3JpZ2luYWxfY2hlY2tfb3V0X2RhdGUgPSBkYXRlX291dDtcclxuXHJcblx0XHR2YXIgbWV3RGF0ZSA9IG5ldyBEYXRlKCBvcmlnaW5hbF9jaGVja19pbl9kYXRlLmdldEZ1bGxZZWFyKCksIG9yaWdpbmFsX2NoZWNrX2luX2RhdGUuZ2V0TW9udGgoKSwgb3JpZ2luYWxfY2hlY2tfaW5fZGF0ZS5nZXREYXRlKCkgKTtcclxuXHRcdG1ld0RhdGUuc2V0RGF0ZSggb3JpZ2luYWxfY2hlY2tfaW5fZGF0ZS5nZXREYXRlKCkgKyAxICk7XHJcblxyXG5cdFx0d2hpbGUgKFxyXG5cdFx0XHQob3JpZ2luYWxfY2hlY2tfb3V0X2RhdGUgPiBkYXRlKSAmJlxyXG5cdFx0XHQob3JpZ2luYWxfY2hlY2tfaW5fZGF0ZSAhPSBvcmlnaW5hbF9jaGVja19vdXRfZGF0ZSkgKXtcclxuXHRcdFx0ZGF0ZSA9IG5ldyBEYXRlKCBtZXdEYXRlLmdldEZ1bGxZZWFyKCksIG1ld0RhdGUuZ2V0TW9udGgoKSwgbWV3RGF0ZS5nZXREYXRlKCkgKTtcclxuXHJcblx0XHRcdG9yaWdpbmFsX2FycmF5LnB1c2goIGpRdWVyeS5kYXRlcGljay5fcmVzdHJpY3RNaW5NYXgoIGluc3QsIGpRdWVyeS5kYXRlcGljay5fZGV0ZXJtaW5lRGF0ZSggaW5zdCwgZGF0ZSwgbnVsbCApICkgKTsgLy9hZGQgZGF0ZVxyXG5cdFx0XHRpZiAoICF3cGJjX2luX2FycmF5KCBia19kaXN0aW5jdF9kYXRlcywgKGRhdGUuZ2V0RGF0ZSgpICsgJy4nICsgcGFyc2VJbnQoIGRhdGUuZ2V0TW9udGgoKSArIDEgKSArICcuJyArIGRhdGUuZ2V0RnVsbFllYXIoKSkgKSApe1xyXG5cdFx0XHRcdGJrX2Rpc3RpbmN0X2RhdGVzLnB1c2goIChwYXJzZUludChkYXRlLmdldERhdGUoKSkgKyAnLicgKyBwYXJzZUludCggZGF0ZS5nZXRNb250aCgpICsgMSApICsgJy4nICsgZGF0ZS5nZXRGdWxsWWVhcigpKSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRtZXdEYXRlID0gbmV3IERhdGUoIGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpLCBkYXRlLmdldERhdGUoKSApO1xyXG5cdFx0XHRtZXdEYXRlLnNldERhdGUoIG1ld0RhdGUuZ2V0RGF0ZSgpICsgMSApO1xyXG5cdFx0fVxyXG5cdFx0b3JpZ2luYWxfYXJyYXkucG9wKCk7XHJcblx0XHRia19kaXN0aW5jdF9kYXRlcy5wb3AoKTtcclxuXHJcblx0XHRyZXR1cm4geydkYXRlc19qcyc6IG9yaWdpbmFsX2FycmF5LCAnZGF0ZXNfc3RyJzogYmtfZGlzdGluY3RfZGF0ZXN9O1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IGFycmF5cyBvZiBKUyBhbmQgU1FMIGRhdGVzIGFzIGRhdGVzIGFycmF5XHJcblx0ICpcclxuXHQgKiBAcGFyYW0gZGF0ZXNfdG9fc2VsZWN0X2Fyclx0PSBbJzIwMjQtMDUtMDknLCcyMDI0LTA1LTE5JywnMjAyNC0wNS0zMCddXHJcblx0ICpcclxuXHQgKiBAcmV0dXJucyB7e2RhdGVzX2pzOiAqW10sIGRhdGVzX3N0cjogKltdfX1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2dldF9zZWxlY3Rpb25fZGF0ZXNfanNfc3RyX2Fycl9fZnJvbV9hcnIoIGRhdGVzX3RvX3NlbGVjdF9hcnIgKXtcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiAxMC4wLjAuNTAuXHJcblxyXG5cdFx0dmFyIG9yaWdpbmFsX2FycmF5ICAgID0gW107XHJcblx0XHR2YXIgYmtfZGlzdGluY3RfZGF0ZXMgPSBbXTtcclxuXHRcdHZhciBvbmVfZGF0ZV9zdHI7XHJcblxyXG5cdFx0Zm9yICggdmFyIGQgPSAwOyBkIDwgZGF0ZXNfdG9fc2VsZWN0X2Fyci5sZW5ndGg7IGQrKyApe1
3411xyXG5cclxuXHRcdFx0b3JpZ2luYWxfYXJyYXkucHVzaCggd3BiY19fZ2V0X19qc19kYXRlKCBkYXRlc190b19zZWxlY3RfYXJyWyBkIF0gKSApO1xyXG5cclxuXHRcdFx0b25lX2RhdGVfc3RyID0gZGF0ZXNfdG9fc2VsZWN0X2FyclsgZCBdLnNwbGl0KCctJylcclxuXHRcdFx0aWYgKCAhIHdwYmNfaW5fYXJyYXkoIGJrX2Rpc3RpbmN0X2RhdGVzLCAob25lX2RhdGVfc3RyWyAyIF0gKyAnLicgKyBvbmVfZGF0ZV9zdHJbIDEgXSArICcuJyArIG9uZV9kYXRlX3N0clsgMCBdKSApICl7XHJcblx0XHRcdFx0YmtfZGlzdGluY3RfZGF0ZXMucHVzaCggcGFyc2VJbnQob25lX2RhdGVfc3RyWyAyIF0pICsgJy4nICsgcGFyc2VJbnQob25lX2RhdGVfc3RyWyAxIF0pICsgJy4nICsgb25lX2RhdGVfc3RyWyAwIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB7J2RhdGVzX2pzJzogb3JpZ2luYWxfYXJyYXksICdkYXRlc19zdHInOiBvcmlnaW5hbF9hcnJheX07XHJcblx0fVxyXG5cclxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbi8qICA9PSAgQXV0byBGaWxsIEZpZWxkcyAvIEF1dG8gU2VsZWN0IERhdGVzICA9PVxyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cclxuXHJcbmpRdWVyeSggZG9jdW1lbnQgKS5yZWFkeSggZnVuY3Rpb24gKCl7XHJcblxyXG5cdHZhciB1cmxfcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyggd2luZG93LmxvY2F0aW9uLnNlYXJjaCApO1xyXG5cclxuXHQvLyBEaXNhYmxlIGRheXMgc2VsZWN0aW9uICBpbiBjYWxlbmRhciwgIGFmdGVyICByZWRpcmVjdGlvbiAgZnJvbSAgdGhlIFwiU2VhcmNoIHJlc3VsdHMgcGFnZSwgIGFmdGVyICBzZWFyY2ggIGF2YWlsYWJpbGl0eVwiIFx0XHRcdC8vIEZpeEluOiA4LjguMi4zLlxyXG5cdGlmICAoICdPbicgIT0gX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAnaXNfZW5hYmxlZF9ib29raW5nX3NlYXJjaF9yZXN1bHRzX2RheXNfc2VsZWN0JyApICkge1xyXG5cdFx0aWYgKFxyXG5cdFx0XHQoIHVybF9wYXJhbXMuaGFzKCAnd3BiY19zZWxlY3RfY2hlY2tfaW4nICkgKSAmJlxyXG5cdFx0XHQoIHVybF9wYXJhbXMuaGFzKCAnd3BiY19zZWxlY3RfY2hlY2tfb3V0JyApICkgJiZcclxuXHRcdFx0KCB1cmxfcGFyYW1zLmhhcyggJ3dwYmNfc2VsZWN0X2NhbGVuZGFyX2lkJyApIClcclxuXHRcdCl7XHJcblxyXG5cdFx0XHR2YXIgc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyX2lkID0gcGFyc2VJbnQoIHVybF9wYXJhbXMuZ2V0KCAnd3BiY19zZWxlY3RfY2FsZW5kYXJfaWQnICkgKTtcclxuXHJcblx0XHRcdC8vIEZpcmUgb24gYWxsIGJvb2tpbmcgZGF0ZXMgbG9hZGVkXHJcblx0XHRcdGpRdWVyeSggJ2JvZHknICkub24oICd3cGJjX2NhbGVuZGFyX2FqeF9fbG9hZGVkX2RhdGEnLCBmdW5jdGlvbiAoIGV2ZW50LCBsb2FkZWRfcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHRcdFx0aWYgKCBsb2FkZWRfcmVzb3VyY2VfaWQgPT0gc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyX2lkICl7XHJcblx0XHRcdFx0XHR3cGJjX2F1dG9fc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyKCBzZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXJfaWQsIHVybF9wYXJhbXMuZ2V0KCAnd3BiY19zZWxlY3RfY2hlY2tfaW4nICksIHVybF9wYXJhbXMuZ2V0KCAnd3BiY19zZWxlY3RfY2hlY2tfb3V0JyApICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9ICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoIHVybF9wYXJhbXMuaGFzKCAnd3BiY19hdXRvX2ZpbGwnICkgKXtcclxuXHJcblx0XHR2YXIgd3BiY19hdXRvX2ZpbGxfdmFsdWUgPSB1cmxfcGFyYW1zLmdldCggJ3dwYmNfYXV0b19maWxsJyApO1xyXG5cclxuXHRcdC8vIENvbnZlcnQgYmFjay4gICAgIFNvbWUgc3lzdGVtcyBkbyBub3QgbGlrZSBzeW1ib2wgJ34nIGluIFVSTCwgc28gIHdlIG5lZWQgdG8gcmVwbGFjZSB0byAgc29tZSBvdGhlciBzeW1ib2xzXHJcblx0XHR3cGJjX2F1dG9fZmlsbF92YWx1ZSA9IHdwYmNfYXV0b19maWxsX3ZhbHVlLnJlcGxhY2VBbGwoICdfXl8nLCAnficgKTtcclxuXHJcblx0XHR3cGJjX2F1dG9fZmlsbF9ib29raW5nX2ZpZWxkcyggd3BiY19hdXRvX2ZpbGxfdmFsdWUgKTtcclxuXHR9XHJcblxyXG59ICk7XHJcblxyXG4vKipcclxuICogQXV0b2ZpbGwgLyBzZWxlY3QgYm9va2luZyBmb3JtICBmaWVsZHMgYnkgIHZhbHVlcyBmcm9tICB0aGUgR0VUIHJlcXVlc3QgIHBhcmFtZXRlcjogP3dwYmNfYXV0b19maWxsPVxyXG4gKlxyXG4gKiBAcGFyYW0gYXV0b19maWxsX3N0clxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19hdXRvX2ZpbGxfYm9va2luZ19maWVsZHMoIGF1dG9fZmlsbF9zdHIgKXtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiAxMC4wLjAuNDguXHJcblxyXG5cdGlmICggJycgPT0gYXV0b19maWxsX3N0ciApe1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcbi8vIGNvbnNvbGUubG9nKCAnV1BCQ19BVVRPX0ZJTExfQk9PS0lOR19GSUVMRFMoIEFVVE9fRklMTF9TVFIgKScsIGF1dG9fZmlsbF9zdHIpO1xyXG5cclxuXHR2YXIgZmllbGRzX2FyciA9IHdwYmNfYXV0b19maWxsX2Jvb2tpbmdfZmllbGRzX19wYXJzZSggYXV0b19maWxsX3N0ciApO1xyXG5cclxuXHRmb3IgKCBsZXQgaSA9IDA7IGkgPCBmaWVsZHNfYXJyLmxlbmd0aDsgaSsrICl7XHJcblx0XHRqUXVlcnkoICdbbmFtZT1cIicgKyBmaWVsZHNfYXJyWyBpIF1bICduYW1lJyBdICsgJ1wiXScgKS52YWwoIGZpZWxkc19hcnJbIGkgXVsgJ3ZhbHVlJyBdICk7XHJcblx0fVxyXG59XHJcblxyXG5cdC8qKlxyXG5cdCAqIFBhcnNlIGRhdGEgZnJvbSAgZ2V0IHBhcmFtZXRlcjpcdD93cGJjX2F1dG9fZmlsbD12aXNpdG9yczIzMV4yfm1heF9jYXBhY2l0eTIzMV4yXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gZGF0YV9zdHIgICAgICA9ICAgJ3Zpc2l0b3JzMjMxXjJ+bWF4X2NhcGFjaXR5MjMxXjInO1xyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfYXV0b19maWxsX2Jvb2tpbmdfZmllbGRzX19wYXJzZSggZGF0YV9zdHIgKXtcclxuXHJcblx0XHR2YXIgZmlsdGVyX29wdGlvbnNfYXJyID0gW107XHJcblxyXG5cdFx0dmFyIGRhdGFfYXJyID0gZGF0YV9zdHIuc3BsaXQoICd+JyApO1xyXG5cclxuXHRcdGZvciAoIHZhciBqID0gMDsgaiA8IGRhdGFfYXJyLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHR2YXIgbXlfZm9ybV9maWVsZCA9IGRhdGFfYXJyWyBqIF0uc3BsaXQoICdeJyApO1xyXG5cclxuXHRcdFx0dmFyIGZpbHRlcl9uYW1lICA9ICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIChteV9mb3JtX2ZpZWxkWyAwIF0pKSA/IG15X2Zvcm1fZmllbGRbIDAgXSA6ICcnO1xyXG5cdFx0XHR2YXIgZmlsdGVyX3ZhbHVlID0gKCd1bmRlZmluZWQnICE9PSB0eXBlb2YgKG15X2Zvcm1fZmllbGRbIDEgXSkpID8gbXlfZm9ybV9maWVsZFsgMSBdIDogJyc7XHJcblxyXG5cdFx0XHRmaWx0ZXJfb3B0aW9uc19hcnIucHVzaChcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnbmFtZScgIDogZmlsdGVyX25hbWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndmFsdWUnIDogZmlsdGVyX3ZhbHVlXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0ICAgKTtcclxuXHRcdH1cclxuXHRcdHJldHVybi
3411BmaWx0ZXJfb3B0aW9uc19hcnI7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBQYXJzZSBkYXRhIGZyb20gIGdldCBwYXJhbWV0ZXI6XHQ/c2VhcmNoX2dldF9fY3VzdG9tX3BhcmFtcz0uLi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBkYXRhX3N0ciAgICAgID0gICAndGV4dF5zZWFyY2hfZmllbGRfX2Rpc3BsYXlfY2hlY2tfaW5eMjMuMDUuMjAyNH50ZXh0XnNlYXJjaF9maWVsZF9fZGlzcGxheV9jaGVja19vdXReMjYuMDUuMjAyNH5zZWxlY3Rib3gtb25lXnNlYXJjaF9xdWFudGl0eV4yfnNlbGVjdGJveC1vbmVebG9jYXRpb25eU3BhaW5+c2VsZWN0Ym94LW9uZV5tYXhfY2FwYWNpdHleMn5zZWxlY3Rib3gtb25lXmFtZW5pdHlecGFya2luZ35jaGVja2JveF5zZWFyY2hfZmllbGRfX2V4dGVuZF9zZWFyY2hfZGF5c141fnN1Ym1pdF5eU2VhcmNofmhpZGRlbl5zZWFyY2hfZ2V0X19jaGVja19pbl95bWReMjAyNC0wNS0yM35oaWRkZW5ec2VhcmNoX2dldF9fY2hlY2tfb3V0X3ltZF4yMDI0LTA1LTI2fmhpZGRlbl5zZWFyY2hfZ2V0X190aW1lXn5oaWRkZW5ec2VhcmNoX2dldF9fcXVhbnRpdHleMn5oaWRkZW5ec2VhcmNoX2dldF9fZXh0ZW5kXjV+aGlkZGVuXnNlYXJjaF9nZXRfX3VzZXJzX2lkXn5oaWRkZW5ec2VhcmNoX2dldF9fY3VzdG9tX3BhcmFtc15+JztcclxuXHQgKiBAcmV0dXJucyB7Kn1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2F1dG9fZmlsbF9zZWFyY2hfZmllbGRzX19wYXJzZSggZGF0YV9zdHIgKXtcclxuXHJcblx0XHR2YXIgZmlsdGVyX29wdGlvbnNfYXJyID0gW107XHJcblxyXG5cdFx0dmFyIGRhdGFfYXJyID0gZGF0YV9zdHIuc3BsaXQoICd+JyApO1xyXG5cclxuXHRcdGZvciAoIHZhciBqID0gMDsgaiA8IGRhdGFfYXJyLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHR2YXIgbXlfZm9ybV9maWVsZCA9IGRhdGFfYXJyWyBqIF0uc3BsaXQoICdeJyApO1xyXG5cclxuXHRcdFx0dmFyIGZpbHRlcl90eXBlICA9ICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIChteV9mb3JtX2ZpZWxkWyAwIF0pKSA/IG15X2Zvcm1fZmllbGRbIDAgXSA6ICcnO1xyXG5cdFx0XHR2YXIgZmlsdGVyX25hbWUgID0gKCd1bmRlZmluZWQnICE9PSB0eXBlb2YgKG15X2Zvcm1fZmllbGRbIDEgXSkpID8gbXlfZm9ybV9maWVsZFsgMSBdIDogJyc7XHJcblx0XHRcdHZhciBmaWx0ZXJfdmFsdWUgPSAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAobXlfZm9ybV9maWVsZFsgMiBdKSkgPyBteV9mb3JtX2ZpZWxkWyAyIF0gOiAnJztcclxuXHJcblx0XHRcdGZpbHRlcl9vcHRpb25zX2Fyci5wdXNoKFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0eXBlJyAgOiBmaWx0ZXJfdHlwZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCduYW1lJyAgOiBmaWx0ZXJfbmFtZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd2YWx1ZScgOiBmaWx0ZXJfdmFsdWVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHQgICApO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGZpbHRlcl9vcHRpb25zX2FycjtcclxuXHR9XHJcblxyXG5cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qICA9PSAgQXV0byBVcGRhdGUgbnVtYmVyIG9mIG1vbnRocyBpbiBjYWxlbmRhcnMgT04gc2NyZWVuIHNpemUgY2hhbmdlZCAgPT1cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG4vKipcclxuICogQXV0byBVcGRhdGUgTnVtYmVyIG9mIE1vbnRocyBpbiBDYWxlbmRhciwgZS5nLjogIFx0XHRpZiAgICAoIFdJTkRPV19XSURUSCA8PSA3ODJweCApICAgPj4+IFx0TU9OVEhTX05VTUJFUiA9IDFcclxuICogICBFTFNFOiAgbnVtYmVyIG9mIG1vbnRocyBkZWZpbmVkIGluIHNob3J0Y29kZS5cclxuICogQHBhcmFtIHJlc291cmNlX2lkIGludFxyXG4gKlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jYWxlbmRhcl9fYXV0b191cGRhdGVfbW9udGhzX251bWJlcl9fb25fcmVzaXplKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRpZiAoIHRydWUgPT09IF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ2lzX2FsbG93X3NldmVyYWxfbW9udGhzX29uX21vYmlsZScgKSApIHtcclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcblxyXG5cdHZhciBsb2NhbF9fbnVtYmVyX29mX21vbnRocyA9IHBhcnNlSW50KCBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2NhbGVuZGFyX251bWJlcl9vZl9tb250aHMnICkgKTtcclxuXHJcblx0aWYgKCBsb2NhbF9fbnVtYmVyX29mX21vbnRocyA+IDEgKXtcclxuXHJcblx0XHRpZiAoIGpRdWVyeSggd2luZG93ICkud2lkdGgoKSA8PSA3ODIgKXtcclxuXHRcdFx0d3BiY19jYWxlbmRhcl9fdXBkYXRlX21vbnRoc19udW1iZXIoIHJlc291cmNlX2lkLCAxICk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR3cGJjX2NhbGVuZGFyX191cGRhdGVfbW9udGhzX251bWJlciggcmVzb3VyY2VfaWQsIGxvY2FsX19udW1iZXJfb2ZfbW9udGhzICk7XHJcblx0XHR9XHJcblxyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEF1dG8gVXBkYXRlIE51bWJlciBvZiBNb250aHMgaW4gICBBTEwgICBDYWxlbmRhcnNcclxuICpcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsZW5kYXJzX19hdXRvX3VwZGF0ZV9tb250aHNfbnVtYmVyKCl7XHJcblxyXG5cdHZhciBhbGxfY2FsZW5kYXJzX2FyciA9IF93cGJjLmNhbGVuZGFyc19hbGxfX2dldCgpO1xyXG5cclxuXHQvLyBUaGlzIExPT1AgXCJmb3IgaW5cIiBpcyBHT09ELCBiZWNhdXNlIHdlIGNoZWNrICBoZXJlIGtleXMgICAgJ2NhbGVuZGFyXycgPT09IGNhbGVuZGFyX2lkLnNsaWNlKCAwLCA5IClcclxuXHRmb3IgKCB2YXIgY2FsZW5kYXJfaWQgaW4gYWxsX2NhbGVuZGFyc19hcnIgKXtcclxuXHRcdGlmICggJ2NhbGVuZGFyXycgPT09IGNhbGVuZGFyX2lkLnNsaWNlKCAwLCA5ICkgKXtcclxuXHRcdFx0dmFyIHJlc291cmNlX2lkID0gcGFyc2VJbnQoIGNhbGVuZGFyX2lkLnNsaWNlKCA5ICkgKTtcdFx0XHQvLyAgJ2NhbGVuZGFyXzMnIC0+IDNcclxuXHRcdFx0aWYgKCByZXNvdXJjZV9pZCA+IDAgKXtcclxuXHRcdFx0XHR3cGJjX2NhbGVuZGFyX19hdXRvX3VwZGF0ZV9tb250aHNfbnVtYmVyX19vbl9yZXNpemUoIHJlc291cmNlX2lkICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJZiBicm93c2VyIHdpbmRvdyBjaGFuZ2VkLCAgdGhlbiAgdXBkYXRlIG51bWJlciBvZiBtb250aHMuXHJcbiAqL1xyXG5qUXVlcnkoIHdpbmRvdyApLm9uKCAncmVzaXplJywgZnVuY3Rpb24gKCl7XHJcblx0d3BiY19jYWxlbmRhcnNfX2F1dG9fdXBkYXRlX21vbnRoc19udW1iZXIoKTtcclxufSApO1xyXG5cclxuLyoqXHJcbiAqIEF1dG8gdXBkYXRlIGNhbGVuZGFyIG51bWJlciBvZiBtb250aHMgb24gaW5pdGlhbCBwYWdlIGxvYWRcclxuICovXHJcbmpRdWVyeSggZG9jdW1lbnQgKS5yZWFkeSggZnVuY3Rpb24gKCl7XHJcblx0dmFyIGNsb3NlZF90aW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uICgpe1xyXG5cdFx0d3BiY19jYWxlbmRhcnNfX2F1dG9fdXBkYXRlX21vbnRoc19udW1iZXIoKTtcclxuXHR9LCAxM
3411DAgKTtcclxufSk7XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyogID09ICBDaGVjazogY2FsZW5kYXJfZGF0ZXNfc3RhcnQ6IFwiMjAyNi0wMS0wMVwiLCBjYWxlbmRhcl9kYXRlc19lbmQ6IFwiMjAyNi0xMi0zMVwiID09ICAvLyBGaXhJbjogMTAuMTMuMS40LlxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cclxuXHQvKipcclxuXHQgKiBHZXQgU3RhcnQgSlMgRGF0ZSBvZiBzdGFydGluZyBkYXRlcyBpbiBjYWxlbmRhciwgZnJvbSB0aGUgX3dwYmMgb2JqZWN0LlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGludGVnZXIgcmVzb3VyY2VfaWQgLSByZXNvdXJjZSBJRCwgZS5nLjogMS5cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19nZXRfZGF0ZXNfc3RhcnQoIHJlc291cmNlX2lkICkge1xyXG5cdFx0cmV0dXJuIHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlX3BhcmFtZXRlciggcmVzb3VyY2VfaWQsICdjYWxlbmRhcl9kYXRlc19zdGFydCcgKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBFbmQgSlMgRGF0ZSBvZiBlbmRpbmcgZGF0ZXMgaW4gY2FsZW5kYXIsIGZyb20gdGhlIF93cGJjIG9iamVjdC5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBpbnRlZ2VyIHJlc291cmNlX2lkIC0gcmVzb3VyY2UgSUQsIGUuZy46IDEuXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX2VuZChyZXNvdXJjZV9pZCkge1xyXG5cdFx0cmV0dXJuIHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlX3BhcmFtZXRlciggcmVzb3VyY2VfaWQsICdjYWxlbmRhcl9kYXRlc19lbmQnICk7XHJcblx0fVxyXG5cclxuLyoqXHJcbiAqIEdldCB2YWxpZGF0ZXMgZGF0ZSBwYXJhbWV0ZXIuXHJcbiAqXHJcbiAqIEBwYXJhbSByZXNvdXJjZV9pZCAgIC0gMVxyXG4gKiBAcGFyYW0gcGFyYW1ldGVyX3N0ciAtICdjYWxlbmRhcl9kYXRlc19zdGFydCcgfCAnY2FsZW5kYXJfZGF0ZXNfZW5kJyB8IC4uLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVfcGFyYW1ldGVyKHJlc291cmNlX2lkLCBwYXJhbWV0ZXJfc3RyKSB7XHJcblxyXG5cdHZhciBkYXRlX2V4cGVjdGVkX3ltZCA9IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCBwYXJhbWV0ZXJfc3RyICk7XHJcblxyXG5cdGlmICggISBkYXRlX2V4cGVjdGVkX3ltZCApIHtcclxuXHRcdHJldHVybiBmYWxzZTsgICAgICAgICAgICAgLy8gJycgfCAwIHwgbnVsbCB8IHVuZGVmaW5lZCAgLT4gZmFsc2UuXHJcblx0fVxyXG5cclxuXHRpZiAoIC0xICE9PSBkYXRlX2V4cGVjdGVkX3ltZC5pbmRleE9mKCAnLScgKSApIHtcclxuXHJcblx0XHR2YXIgZGF0ZV9leHBlY3RlZF95bWRfYXJyID0gZGF0ZV9leHBlY3RlZF95bWQuc3BsaXQoICctJyApO1x0Ly8gJzIwMjUtMDctMjYnIC0+IFsnMjAyNScsICcwNycsICcyNiddXHJcblxyXG5cdFx0aWYgKCBkYXRlX2V4cGVjdGVkX3ltZF9hcnIubGVuZ3RoID4gMCApIHtcclxuXHRcdFx0dmFyIHllYXIgID0gKGRhdGVfZXhwZWN0ZWRfeW1kX2Fyci5sZW5ndGggPiAwKSA/IHBhcnNlSW50KCBkYXRlX2V4cGVjdGVkX3ltZF9hcnJbMF0gKSA6IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcdC8vIFllYXIuXHJcblx0XHRcdHZhciBtb250aCA9IChkYXRlX2V4cGVjdGVkX3ltZF9hcnIubGVuZ3RoID4gMSkgPyAocGFyc2VJbnQoIGRhdGVfZXhwZWN0ZWRfeW1kX2FyclsxXSApIC0gMSkgOiAwOyAgLy8gKG1vbnRoIC0gMSkgb3IgMCAtIEphbi5cclxuXHRcdFx0dmFyIGRheSAgID0gKGRhdGVfZXhwZWN0ZWRfeW1kX2Fyci5sZW5ndGggPiAyKSA/IHBhcnNlSW50KCBkYXRlX2V4cGVjdGVkX3ltZF9hcnJbMl0gKSA6IDE7ICAvLyBkYXRlIG9yIE90aGVyd2lzZSAxc3Qgb2YgbW9udGhcclxuXHJcblx0XHRcdHZhciBkYXRlX2pzID0gbmV3IERhdGUoIHllYXIsIG1vbnRoLCBkYXksIDAsIDAsIDAsIDAgKTtcclxuXHJcblx0XHRcdHJldHVybiBkYXRlX2pzO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIGZhbHNlOyAgLy8gRmFsbGJhY2ssICBpZiB3ZSBub3QgcGFyc2VkIHRoaXMgcGFyYW1ldGVyICAnY2FsZW5kYXJfZGF0ZXNfc3RhcnQnID0gJzIwMjUtMDctMjYnLCAgZm9yIGV4YW1wbGUgYmVjYXVzZSBvZiAnY2FsZW5kYXJfZGF0ZXNfc3RhcnQnID0gJ3Nmc2RmJy5cclxufSIsIi8qKlxyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKlx0aW5jbHVkZXMvX19qcy9jYWwvZGF5c19zZWxlY3RfY3VzdG9tLmpzXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqL1xyXG5cclxuLy8gRml4SW46IDkuOC45LjIuXHJcblxyXG4vKipcclxuICogUmUtSW5pdCBDYWxlbmRhciBhbmQgUmUtUmVuZGVyIGl0LlxyXG4gKlxyXG4gKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX19yZV9pbml0KCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHQvLyBSZW1vdmUgQ0xBU1MgIGZvciBhYmlsaXR5IHRvIHJlLXJlbmRlciBhbmQgcmVpbml0IGNhbGVuZGFyLlxyXG5cdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkucmVtb3ZlQ2xhc3MoICdoYXNEYXRlcGljaycgKTtcclxuXHR3cGJjX2NhbGVuZGFyX3Nob3coIHJlc291cmNlX2lkICk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogUmUtSW5
3411pdCBwcmV2aW91c2x5ICBzYXZlZCBkYXlzIHNlbGVjdGlvbiAgdmFyaWFibGVzLlxyXG4gKlxyXG4gKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX2RheXNfc2VsZWN0X19yZV9pbml0KCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ3NhdmVkX3ZhcmlhYmxlX19fZGF5c19zZWxlY3RfaW5pdGlhbCdcclxuXHRcdCwge1xyXG5cdFx0XHQnZHluYW1pY19fZGF5c19taW4nICAgICAgICA6IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZHluYW1pY19fZGF5c19taW4nICksXHJcblx0XHRcdCdkeW5hbWljX19kYXlzX21heCcgICAgICAgIDogX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkeW5hbWljX19kYXlzX21heCcgKSxcclxuXHRcdFx0J2R5bmFtaWNfX2RheXNfc3BlY2lmaWMnICAgOiBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2R5bmFtaWNfX2RheXNfc3BlY2lmaWMnICksXHJcblx0XHRcdCdkeW5hbWljX193ZWVrX2RheXNfX3N0YXJ0JzogX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkeW5hbWljX193ZWVrX2RheXNfX3N0YXJ0JyApLFxyXG5cdFx0XHQnZml4ZWRfX2RheXNfbnVtJyAgICAgICAgICA6IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZml4ZWRfX2RheXNfbnVtJyApLFxyXG5cdFx0XHQnZml4ZWRfX3dlZWtfZGF5c19fc3RhcnQnICA6IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZml4ZWRfX3dlZWtfZGF5c19fc3RhcnQnIClcclxuXHRcdH1cclxuXHQpO1xyXG59XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBTZXQgU2luZ2xlIERheSBzZWxlY3Rpb24gLSBhZnRlciBwYWdlIGxvYWRcclxuICpcclxuICogQHBhcmFtIHJlc291cmNlX2lkXHRcdElEIG9mIGJvb2tpbmcgcmVzb3VyY2VcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX3JlYWR5X2RheXNfc2VsZWN0X19zaW5nbGUoIHJlc291cmNlX2lkICl7XHJcblxyXG5cdC8vIFJlLWRlZmluZSBzZWxlY3Rpb24sIG9ubHkgYWZ0ZXIgcGFnZSBsb2FkZWQgd2l0aCBhbGwgaW5pdCB2YXJzXHJcblx0alF1ZXJ5KGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpe1xyXG5cclxuXHRcdC8vIFdhaXQgMSBzZWNvbmQsIGp1c3QgdG8gIGJlIHN1cmUsIHRoYXQgYWxsIGluaXQgdmFycyBkZWZpbmVkXHJcblx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XHJcblxyXG5cdFx0XHR3cGJjX2NhbF9kYXlzX3NlbGVjdF9fc2luZ2xlKCByZXNvdXJjZV9pZCApO1xyXG5cclxuXHRcdH0sIDEwMDApO1xyXG5cdH0pO1xyXG59XHJcblxyXG4vKipcclxuICogU2V0IFNpbmdsZSBEYXkgc2VsZWN0aW9uXHJcbiAqIENhbiBiZSBydW4gYXQgYW55ICB0aW1lLCAgd2hlbiAgY2FsZW5kYXIgZGVmaW5lZCAtIHVzZWZ1bCBmb3IgY29uc29sZSBydW4uXHJcbiAqXHJcbiAqIEBwYXJhbSByZXNvdXJjZV9pZFx0XHRJRCBvZiBib29raW5nIHJlc291cmNlXHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2NhbF9kYXlzX3NlbGVjdF9fc2luZ2xlKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMoIHJlc291cmNlX2lkLCB7J2RheXNfc2VsZWN0X21vZGUnOiAnc2luZ2xlJ30gKTtcclxuXHJcblx0d3BiY19jYWxfZGF5c19zZWxlY3RfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcblx0d3BiY19jYWxfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuLyoqXHJcbiAqIFNldCBNdWx0aXBsZSBEYXlzIHNlbGVjdGlvbiAgLSBhZnRlciBwYWdlIGxvYWRcclxuICpcclxuICogQHBhcmFtIHJlc291cmNlX2lkXHRcdElEIG9mIGJvb2tpbmcgcmVzb3VyY2VcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX3JlYWR5X2RheXNfc2VsZWN0X19tdWx0aXBsZSggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0Ly8gUmUtZGVmaW5lIHNlbGVjdGlvbiwgb25seSBhZnRlciBwYWdlIGxvYWRlZCB3aXRoIGFsbCBpbml0IHZhcnNcclxuXHRqUXVlcnkoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCl7XHJcblxyXG5cdFx0Ly8gV2FpdCAxIHNlY29uZCwganVzdCB0byAgYmUgc3VyZSwgdGhhdCBhbGwgaW5pdCB2YXJzIGRlZmluZWRcclxuXHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcclxuXHJcblx0XHRcdHdwYmNfY2FsX2RheXNfc2VsZWN0X19tdWx0aXBsZSggcmVzb3VyY2VfaWQgKTtcclxuXHJcblx0XHR9LCAxMDAwKTtcclxuXHR9KTtcclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiBTZXQgTXVsdGlwbGUgRGF5cyBzZWxlY3Rpb25cclxuICogQ2FuIGJlIHJ1biBhdCBhbnkgIHRpbWUsICB3aGVuICBjYWxlbmRhciBkZWZpbmVkIC0gdXNlZnVsIGZvciBjb25zb2xlIHJ1bi5cclxuICpcclxuICogQHBhcmFtIHJlc291cmNlX2lkXHRcdElEIG9mIGJvb2tpbmcgcmVzb3VyY2VcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX2RheXNfc2VsZWN0X19tdWx0aXBsZSggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0X3dwYmMuY2FsZW5kYXJfX3NldF9wYXJhbWV0ZXJzKCByZXNvdXJjZV9pZCwgeydkYXlzX3NlbGVjdF9tb2RlJzogJ211bHRpcGxlJ30gKTtcclxuXHJcblx0d3BiY19jYWxfZGF5c19zZWxlY3RfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcblx0d3BiY19jYWxfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcbn1cclxuXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBTZXQgRml4ZWQgRGF5cyBzZWxlY3Rpb24gd2l0aCAgMSBtb3VzZSBjbGljayAgLSBhZnRlciBwYWdlIGxvYWRcclxuICpcclxuICogQGludGVnZXIgcmVzb3VyY2VfaWRcdFx0XHQtIDFcdFx0XHRcdCAgIC0tIElEIG9mIGJvb2tpbmcgcmVzb3VyY2UgKGNhbGVuZGFyKSAtXHJcbiAqIEBpbnRlZ2VyIGRheXNfbnVtYmVyXHRcdFx0LSAzXHRcdFx0XHQgICAtLSBudW1iZXIgb2YgZGF5cyB0byAgc2VsZWN0XHQtXHJcbiAqIEBhcnJheSB3ZWVrX2RheXNfX3N0YXJ0XHQtIFstMV0gfCBbIDEsIDVdICAgLS0gIHsgLTEgLSBBbnkgfCAwIC0gU3UsICAxIC0gTW8sICAyIC0gVHUsIDMgLSBXZSwgNCAtIFRoLCA1IC0gRnIsIDYgLSBTYXQgfVxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jYWxfcmVhZHlfZGF5c19zZWxlY3RfX2ZpeGVkKCByZXNvdXJjZV9pZCwgZGF5c19udW1iZXIsIHdlZWtfZGF5c19fc3RhcnQgPSBbLTFdICl7XHJcblxyXG5cdC8vIFJlLWRlZmluZSBzZWxlY3Rpb24sIG9ubHkgYWZ0ZXIgcGFnZSBsb2FkZWQgd2l0aCBhbGwgaW5pdCB2YXJzXHJcblx0alF1ZXJ5KGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpe1xyXG5cclxuXHRcdC8vIFdhaXQgMSBzZWNvbmQsIGp1c3QgdG8gIGJlIHN1cmUsIHRoYXQgYWxsIGluaXQgdmFycyBkZWZpbmVkXHJcblx0XHRzZXRUaW
34111lb3V0KGZ1bmN0aW9uKCl7XHJcblxyXG5cdFx0XHR3cGJjX2NhbF9kYXlzX3NlbGVjdF9fZml4ZWQoIHJlc291cmNlX2lkLCBkYXlzX251bWJlciwgd2Vla19kYXlzX19zdGFydCApO1xyXG5cclxuXHRcdH0sIDEwMDApO1xyXG5cdH0pO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFNldCBGaXhlZCBEYXlzIHNlbGVjdGlvbiB3aXRoICAxIG1vdXNlIGNsaWNrXHJcbiAqIENhbiBiZSBydW4gYXQgYW55ICB0aW1lLCAgd2hlbiAgY2FsZW5kYXIgZGVmaW5lZCAtIHVzZWZ1bCBmb3IgY29uc29sZSBydW4uXHJcbiAqXHJcbiAqIEBpbnRlZ2VyIHJlc291cmNlX2lkXHRcdFx0LSAxXHRcdFx0XHQgICAtLSBJRCBvZiBib29raW5nIHJlc291cmNlIChjYWxlbmRhcikgLVxyXG4gKiBAaW50ZWdlciBkYXlzX251bWJlclx0XHRcdC0gM1x0XHRcdFx0ICAgLS0gbnVtYmVyIG9mIGRheXMgdG8gIHNlbGVjdFx0LVxyXG4gKiBAYXJyYXkgd2Vla19kYXlzX19zdGFydFx0LSBbLTFdIHwgWyAxLCA1XSAgIC0tICB7IC0xIC0gQW55IHwgMCAtIFN1LCAgMSAtIE1vLCAgMiAtIFR1LCAzIC0gV2UsIDQgLSBUaCwgNSAtIEZyLCA2IC0gU2F0IH1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX2RheXNfc2VsZWN0X19maXhlZCggcmVzb3VyY2VfaWQsIGRheXNfbnVtYmVyLCB3ZWVrX2RheXNfX3N0YXJ0ID0gWy0xXSApe1xyXG5cclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMoIHJlc291cmNlX2lkLCB7J2RheXNfc2VsZWN0X21vZGUnOiAnZml4ZWQnfSApO1xyXG5cclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMoIHJlc291cmNlX2lkLCB7J2ZpeGVkX19kYXlzX251bSc6IHBhcnNlSW50KCBkYXlzX251bWJlciApfSApO1x0XHRcdC8vIE51bWJlciBvZiBkYXlzIHNlbGVjdGlvbiB3aXRoIDEgbW91c2UgY2xpY2tcclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMoIHJlc291cmNlX2lkLCB7J2ZpeGVkX193ZWVrX2RheXNfX3N0YXJ0Jzogd2Vla19kYXlzX19zdGFydH0gKTsgXHQvLyB7IC0xIC0gQW55IHwgMCAtIFN1LCAgMSAtIE1vLCAgMiAtIFR1LCAzIC0gV2UsIDQgLSBUaCwgNSAtIEZyLCA2IC0gU2F0IH1cclxuXHJcblx0d3BiY19jYWxfZGF5c19zZWxlY3RfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcblx0d3BiY19jYWxfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuLyoqXHJcbiAqIFNldCBSYW5nZSBEYXlzIHNlbGVjdGlvbiAgd2l0aCAgMiBtb3VzZSBjbGlja3MgIC0gYWZ0ZXIgcGFnZSBsb2FkXHJcbiAqXHJcbiAqIEBpbnRlZ2VyIHJlc291cmNlX2lkXHRcdFx0LSAxXHRcdFx0XHQgICBcdFx0LS0gSUQgb2YgYm9va2luZyByZXNvdXJjZSAoY2FsZW5kYXIpXHJcbiAqIEBpbnRlZ2VyIGRheXNfbWluXHRcdFx0LSA3XHRcdFx0XHQgICBcdFx0LS0gTWluIG51bWJlciBvZiBkYXlzIHRvIHNlbGVjdFxyXG4gKiBAaW50ZWdlciBkYXlzX21heFx0XHRcdC0gMzBcdFx0XHQgICBcdFx0LS0gTWF4IG51bWJlciBvZiBkYXlzIHRvIHNlbGVjdFxyXG4gKiBAYXJyYXkgZGF5c19zcGVjaWZpY1x0XHRcdC0gW10gfCBbNywxNCwyMSwyOF1cdFx0LS0gUmVzdHJpY3Rpb24gZm9yIFNwZWNpZmljIG51bWJlciBvZiBkYXlzIHNlbGVjdGlvblxyXG4gKiBAYXJyYXkgd2Vla19kYXlzX19zdGFydFx0XHQtIFstMV0gfCBbIDEsIDVdICAgXHRcdC0tICB7IC0xIC0gQW55IHwgMCAtIFN1LCAgMSAtIE1vLCAgMiAtIFR1LCAzIC0gV2UsIDQgLSBUaCwgNSAtIEZyLCA2IC0gU2F0IH1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX3JlYWR5X2RheXNfc2VsZWN0X19yYW5nZSggcmVzb3VyY2VfaWQsIGRheXNfbWluLCBkYXlzX21heCwgZGF5c19zcGVjaWZpYyA9IFtdLCB3ZWVrX2RheXNfX3N0YXJ0ID0gWy0xXSApe1xyXG5cclxuXHQvLyBSZS1kZWZpbmUgc2VsZWN0aW9uLCBvbmx5IGFmdGVyIHBhZ2UgbG9hZGVkIHdpdGggYWxsIGluaXQgdmFyc1xyXG5cdGpRdWVyeShkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKXtcclxuXHJcblx0XHQvLyBXYWl0IDEgc2Vjb25kLCBqdXN0IHRvICBiZSBzdXJlLCB0aGF0IGFsbCBpbml0IHZhcnMgZGVmaW5lZFxyXG5cdFx0c2V0VGltZW91dChmdW5jdGlvbigpe1xyXG5cclxuXHRcdFx0d3BiY19jYWxfZGF5c19zZWxlY3RfX3JhbmdlKCByZXNvdXJjZV9pZCwgZGF5c19taW4sIGRheXNfbWF4LCBkYXlzX3NwZWNpZmljLCB3ZWVrX2RheXNfX3N0YXJ0ICk7XHJcblx0XHR9LCAxMDAwKTtcclxuXHR9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFNldCBSYW5nZSBEYXlzIHNlbGVjdGlvbiAgd2l0aCAgMiBtb3VzZSBjbGlja3NcclxuICogQ2FuIGJlIHJ1biBhdCBhbnkgIHRpbWUsICB3aGVuICBjYWxlbmRhciBkZWZpbmVkIC0gdXNlZnVsIGZvciBjb25zb2xlIHJ1bi5cclxuICpcclxuICogQGludGVnZXIgcmVzb3VyY2VfaWRcdFx0XHQtIDFcdFx0XHRcdCAgIFx0XHQtLSBJRCBvZiBib29raW5nIHJlc291cmNlIChjYWxlbmRhcilcclxuICogQGludGVnZXIgZGF5c19taW5cdFx0XHQtIDdcdFx0XHRcdCAgIFx0XHQtLSBNaW4gbnVtYmVyIG9mIGRheXMgdG8gc2VsZWN0XHJcbiAqIEBpbnRlZ2VyIGRheXNfbWF4XHRcdFx0LSAzMFx0XHRcdCAgIFx0XHQtLSBNYXggbnVtYmVyIG9mIGRheXMgdG8gc2VsZWN0XHJcbiAqIEBhcnJheSBkYXlzX3NwZWNpZmljXHRcdFx0LSBbXSB8IFs3LDE0LDIxLDI4XVx0XHQtLSBSZXN0cmljdGlvbiBmb3IgU3BlY2lmaWMgbnVtYmVyIG9mIGRheXMgc2VsZWN0aW9uXHJcbiAqIEBhcnJheSB3ZWVrX2RheXNfX3N0YXJ0XHRcdC0gWy0xXSB8IFsgMSwgNV0gICBcdFx0LS0gIHsgLTEgLSBBbnkgfCAwIC0gU3UsICAxIC0gTW8sICAyIC0gVHUsIDMgLSBXZSwgNCAtIFRoLCA1IC0gRnIsIDYgLSBTYXQgfVxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jYWxfZGF5c19zZWxlY3RfX3JhbmdlKCByZXNvdXJjZV9pZCwgZGF5c19taW4sIGRheXNfbWF4LCBkYXlzX3NwZWNpZmljID0gW10sIHdlZWtfZGF5c19fc3RhcnQgPSBbLTFdICl7XHJcblxyXG5cdF93cGJjLmNhbGVuZGFyX19zZXRfcGFyYW1ldGVycyggIHJlc291cmNlX2lkLCB7J2R
3411heXNfc2VsZWN0X21vZGUnOiAnZHluYW1pYyd9ICApO1xyXG5cdF93cGJjLmNhbGVuZGFyX19zZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZHluYW1pY19fZGF5c19taW4nICAgICAgICAgLCBwYXJzZUludCggZGF5c19taW4gKSAgKTsgICAgICAgICAgIFx0XHQvLyBNaW4uIE51bWJlciBvZiBkYXlzIHNlbGVjdGlvbiB3aXRoIDIgbW91c2UgY2xpY2tzXHJcblx0X3dwYmMuY2FsZW5kYXJfX3NldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkeW5hbWljX19kYXlzX21heCcgICAgICAgICAsIHBhcnNlSW50KCBkYXlzX21heCApICApOyAgICAgICAgICBcdFx0Ly8gTWF4LiBOdW1iZXIgb2YgZGF5cyBzZWxlY3Rpb24gd2l0aCAyIG1vdXNlIGNsaWNrc1xyXG5cdF93cGJjLmNhbGVuZGFyX19zZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZHluYW1pY19fZGF5c19zcGVjaWZpYycgICAgLCBkYXlzX3NwZWNpZmljICApO1x0ICAgICAgXHRcdFx0XHQvLyBFeGFtcGxlIFs1LDddXHJcblx0X3dwYmMuY2FsZW5kYXJfX3NldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkeW5hbWljX193ZWVrX2RheXNfX3N0YXJ0JyAsIHdlZWtfZGF5c19fc3RhcnQgICk7ICBcdFx0XHRcdFx0Ly8geyAtMSAtIEFueSB8IDAgLSBTdSwgIDEgLSBNbywgIDIgLSBUdSwgMyAtIFdlLCA0IC0gVGgsIDUgLSBGciwgNiAtIFNhdCB9XHJcblxyXG5cdHdwYmNfY2FsX2RheXNfc2VsZWN0X19yZV9pbml0KCByZXNvdXJjZV9pZCApO1xyXG5cdHdwYmNfY2FsX19yZV9pbml0KCByZXNvdXJjZV9pZCApO1xyXG59XHJcbiIsIi8qKlxyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKlx0aW5jbHVkZXMvX19qcy9jYWxfYWp4X2xvYWQvd3BiY19jYWxfYWp4LmpzXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqL1xyXG5cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vICBBIGogYSB4ICAgIEwgbyBhIGQgICAgQyBhIGwgZSBuIGQgYSByICAgIEQgYSB0IGFcclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5mdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19sb2FkX2RhdGFfX2FqeCggcGFyYW1zICl7XHJcblxyXG5cdC8vIEZpeEluOiA5LjguNi4yLlxyXG5cdHdwYmNfY2FsZW5kYXJfX2xvYWRpbmdfX3N0YXJ0KCBwYXJhbXNbJ3Jlc291cmNlX2lkJ10gKTtcclxuXHJcblx0Ly8gVHJpZ2dlciBldmVudCBmb3IgY2FsZW5kYXIgYmVmb3JlIGxvYWRpbmcgQm9va2luZyBkYXRhLCAgYnV0IGFmdGVyIHNob3dpbmcgQ2FsZW5kYXIuXHJcblx0aWYgKCBqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyBwYXJhbXNbJ3Jlc291cmNlX2lkJ10gKS5sZW5ndGggPiAwICl7XHJcblx0XHR2YXIgdGFyZ2V0X2VsbSA9IGpRdWVyeSggJ2JvZHknICkudHJpZ2dlciggXCJ3cGJjX2NhbGVuZGFyX2FqeF9fYmVmb3JlX2xvYWRlZF9kYXRhXCIsIFtwYXJhbXNbJ3Jlc291cmNlX2lkJ11dICk7XHJcblx0XHQgLy9qUXVlcnkoICdib2R5JyApLm9uKCAnd3BiY19jYWxlbmRhcl9hanhfX2JlZm9yZV9sb2FkZWRfZGF0YScsIGZ1bmN0aW9uKCBldmVudCwgcmVzb3VyY2VfaWQgKSB7IC4uLiB9ICk7XHJcblx0fVxyXG5cclxuXHRpZiAoIHdwYmNfYmFsYW5jZXJfX2lzX3dhaXQoIHBhcmFtcyAsICd3cGJjX2NhbGVuZGFyX19sb2FkX2RhdGFfX2FqeCcgKSApe1xyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHJcblx0Ly8gRml4SW46IDkuOC42LjIuXHJcblx0d3BiY19jYWxlbmRhcl9fYmx1cl9fc3RvcCggcGFyYW1zWydyZXNvdXJjZV9pZCddICk7XHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0Ly8gPT0gR2V0IHN0YXJ0IC8gZW5kIGRhdGVzIGZyb20gIHRoZSBCb29raW5nIENhbGVuZGFyIHNob3J0Y29kZS4gPT1cclxuXHQvLyBFeGFtcGxlOiBbYm9va2luZyBjYWxlbmRhcl9kYXRlc19zdGFydD0nMjAyNi0wMS0wMScgY2FsZW5kYXJfZGF0ZXNfZW5kPScyMDI2LTEyLTMxJyAgcmVzb3VyY2VfaWQ9MV0gICAgICAgICAgICAgIC8vIEZpeEluOiAxMC4xMy4xLjQuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRpZiAoIGZhbHNlICE9PSB3cGJjX2NhbGVuZGFyX19nZXRfZGF0ZXNfc3RhcnQoIHBhcmFtc1sncmVzb3VyY2VfaWQnXSApICkge1xyXG5cdFx0aWYgKCAhIHBhcmFtc1snZGF0ZXNfdG9fY2hlY2snXSApIHsgcGFyYW1zWydkYXRlc190b19jaGVjayddID0gW107IH1cclxuXHRcdHZhciBkYXRlc19zdGFydCA9IHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlc19zdGFydCggcGFyYW1zWydyZXNvdXJjZV9pZCddICk7ICAvLyBFLmcuIC0gbG9jYWxfX21pbl9kYXRlID0gbmV3IERhdGUoIDIwMjUsIDAsIDEgKTtcclxuXHRcdGlmICggZmFsc2UgIT09IGRhdGVzX3N0YXJ0ICl7XHJcblx0XHRcdHBhcmFtc1snZGF0ZXNfdG9fY2hlY2snXVswXSA9IHdwYmNfX2dldF9fc3FsX2NsYXNzX2RhdGUoIGRhdGVzX3N0YXJ0ICk7XHJcblx0XHR9XHJcblx0fVxyXG5cdGlmICggZmFsc2UgIT09IHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlc19lbmQoIHBhcmFtc1sncmVzb3VyY2VfaWQnXSApICkge1xyXG5cdFx0aWYgKCAhcGFyYW1zWydkYXRlc190b19jaGVjayddICkgeyBwYXJhbXNbJ2RhdGVzX3RvX2NoZWNrJ10gPSBbXTsgfVxyXG5cdFx0dmFyIGRhdGVzX2VuZCA9IHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlc19lbmQoIHBhcmFtc1sncmVzb3VyY2VfaWQnXSApOyAgLy8gRS5nLiAtIGxvY2FsX19taW5fZGF0ZSA9IG5ldyBEYXRlKCAyMDI1LCAwLCAxICk7XHJcblx0XHRpZiAoIGZhbHNlICE9PSBkYXRlc19lbmQgKSB7XHJcblx0XHRcdHBhcmFtc1snZGF0ZXNfdG9fY2hlY2snXVsxXSA9IHdwYmNfX2dldF9fc3FsX2NsYXNzX2RhdGUoIGRhdGVzX2VuZCApO1xyXG5cdFx0XHRpZiAoICFwYXJhbXNbJ2RhdGVzX3RvX2NoZWNrJ11bMF0gKSB7XHJcblx0XHRcdFx0cGFyYW1zWydkYXRlc190b19jaGVjayddWzBdID0gd3BiY19fZ2V0X19zcWxfY2xhc3NfZGF0ZSggbmV3IERhdGUoKSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4vLyBjb25zb2xlLmdyb3VwRW5kKCk7IGNvbnNvbGUudGltZSgncmVzb3VyY2VfaWRfJyArIHBhcmFtc1sncmVzb3VyY2VfaWQnXSk7XHJcbmNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQoICdXUEJDX0FKWF9DQUxFTkRBUl9MT0FEJyApOyBjb25zb2xlLmxvZyggJyA9PSBCZWZvcmUgQWpheCBTZW5kIC0gY2FsZW5kYXJzX2FsbF9fZ2V0KCkgPT0gJyAsIF93cGJjLmNhbGVuZGFyc19hbGxfX2dldCgpICk7XHJcblx0aWYgKCAnZnVuY3Rpb24nID09PSB0eXBlb2YgKHdwYmNfaG9va19faW5pdF90aW1lc2VsZWN0b3IpICkge1xyXG5cdFx0d3BiY19ob29rX19pbml0X3RpbWVzZWxlY3RvcigpO1xyXG5cdH1cclxuXHJcblx0Ly8gU3RhcnQgQWpheFxyXG5cdGpRdWVyeS5wb3N0KCB3cGJjX3VybF9hamF4LFxyXG5cdFx0XHRcdHtcclxuXHRcdFx0XHRcdGFjdGlvbiAgICAgICAgICA6ICdXUEJDX0FKWF9DQUxFTkRBUl9MT0FEJyxcclxuXHRcdFx0XHRcdHdwYmNfYWp4X3VzZXJfaWQ6IF93cGJjLmdldF9zZWN1cmVfcGFyYW0oICd1c2VyX2lkJyApLFxyXG5cdFx0XHRcdFx0bm9uY2UgICAgICAgICAgIDogX3dwYmMuZ2V0X3NlY3VyZV9wYXJhbSggJ25vbmNlJyApLFxyXG5cdFx0XHRcdFx0d3BiY19hanhfbG9jYWxlIDogX3dwYmMuZ2V0X3NlY3VyZV9wYXJhbSggJ2xvY2FsZScgKSxcclxuXHJcblx0XHRcdFx0XHRjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyA6IHBhcmFtcyBcdFx0XHRcdFx0XHQvLyBVc3VhbGx5IGxpa2U6IHsgJ3Jlc291cmNlX2lkJzogMSwgJ21heF9kYXlzX2NvdW50JzogMzY1IH1cclxuXHRcdFx0XHR9LFxyXG5cclxuXHRcdFx0XHQvKipcclxuXHRcdFx0XHQgKiBTIHUgYyBjIGUgcyBzXHJcblx0XHRcdFx0ICpcclxuXHRcdFx0XHQgKiBAcGFyYW0gcmVzcG9uc2VfZGF0YVx0XHQtXHRpdHMgb2JqZWN0IHJldHVybmVkIGZyb20gIEFqYXggLSBjbGFzcy1saXZlLXNlYXJjaC5waHBcclxuXHRcdFx0XHQgKiBAcGFyYW0gdGV4dFN0YXR1c1x0XHQtXHQnc3VjY2VzcydcclxuXHRcdFx0XHQgKiBAcGFyYW0ganFYSFJcdFx0XHRcdC1cdE9iamVjdFxyXG5cdFx0XHRcdCAqL1xyXG5cdFx0XHRcdGZ1bmN0aW9uICggcmVzcG9uc2VfZGF0YSwgdGV4dFN0YXR1cywganFYSFIgKSB7XHJcbi8vIGNvbnNvbGUudGltZUVuZCgncmVzb3VyY2VfaWRfJyArIHJlc3BvbnNlX2RhdGFbJ3Jlc291cmNlX2lkJ10pO1xyXG5jb25zb2xlLmxvZyggJyA9PSBSZXNwb25zZSBXUEJDX0FKWF9DQUxFTkRBUl9MT0FEID09ICcsIHJlc3BvbnNlX2RhdGEgKTsgY29uc29sZS5ncm91cEVuZCgpO1xyXG5cclxuXHRcdFx0XHRcdC8vIEZpeEluOiA5LjguNi4yLlxyXG5cdFx0XHRcdFx0dmFyIGFqeF9wb3N0X2RhdGFfX3Jlc291cmNlX2lkID0gd3BiY19nZXRfcmVzb3VyY2VfaWRfX2Zyb21fYWp4X3Bvc3RfZGF0YV91cmwoIHRoaXMuZGF0YSApO1xyXG5cdFx0XHRcdFx0d3BiY19iYWxhbmNlcl9fY29tcGxldGVkKCBhanhfcG9zdF9kYXRhX19yZXNvdXJjZV9pZCAsICd3cGJjX2NhbGVuZGFyX19sb2FkX2RhdGFfX2FqeCcgKTtcclxuXHJcblx0XHRcdFx0XHQvLyBQcm9iYWJseSBFcnJvclxyXG5cdFx0XHRcdFx0aWYgKCAodHlwZW9mIHJlc3BvbnNlX2RhdGEgIT09ICdvYmplY3QnKSB8fCAocmVzcG9uc2VfZGF0YSA9PT0gbnVsbCkgKXtcclxuXHJcblx0XHRcdFx0XHRcdHZhciBqcV9ub2RlICA9IHdwYmNfZ2V0X2NhbGVuZGFyX19qcV9ub2RlX19mb3JfbWVzc2FnZXMoIHRoaXMuZGF0YSApO1xyXG5cdFx0XHRcdFx0XHR2YXIgbWVzc2FnZV90eXBlID0gJ2luZm8nO1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKCAnJyA9PT0gcmVzcG9uc2VfZGF0YSApe1xyXG5cdFx0XHRcdFx0XHRcdHJlc3BvbnNlX2RhdGEgPSAnVGhlIHNlcnZlciByZXNwb25kcyB3aXRoIGFuIGVtcHR5IHN0cmluZy4gVGhlIHNlcnZlciBwcm9iYWJseSBzdG9wcGVkIHdvcmtpbmcgdW5leHBlY3RlZGx5LiA8YnI+UGxlYXNlIGNoZWNrIHlvdXIgPHN0cm9uZz5lcnJvci5sb2c8L3N0cm9uZz4gaW4geW91ciBzZXJ2ZXIgY29uZmlndXJhdGlvbiBmb3IgcmVsYXRpdmUgZXJyb3JzLic7XHJcblx0XHRcdFx0XHRcdFx0bWVzc2FnZV90eXBlID0gJ3dhcm5pbmcnO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBTaG93IE1lc3NhZ2VcclxuXHRcdFx0XHRcdFx0d3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZSggcmVzcG9uc2VfZGF0YSAsIHsgJ3R
34115cGUnICAgICA6IG1lc3NhZ2VfdHlwZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3Nob3dfaGVyZSc6IHsnanFfbm9kZSc6IGpxX25vZGUsICd3aGVyZSc6ICdhZnRlcid9LFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnaXNfYXBwZW5kJzogdHJ1ZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3N0eWxlJyAgICA6ICd0ZXh0LWFsaWduOmxlZnQ7JyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICA6IDBcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIFNob3cgQ2FsZW5kYXJcclxuXHRcdFx0XHRcdHdwYmNfY2FsZW5kYXJfX2xvYWRpbmdfX3N0b3AoIHJlc3BvbnNlX2RhdGFbICdyZXNvdXJjZV9pZCcgXSApO1xyXG5cclxuXHRcdFx0XHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdFx0XHRcdC8vIEJvb2tpbmdzIC0gRGF0ZXNcclxuXHRcdFx0XHRcdF93cGJjLmJvb2tpbmdzX2luX2NhbGVuZGFyX19zZXRfZGF0ZXMoICByZXNwb25zZV9kYXRhWyAncmVzb3VyY2VfaWQnIF0sIHJlc3BvbnNlX2RhdGFbICdhanhfZGF0YScgXVsnZGF0ZXMnXSAgKTtcclxuXHJcblx0XHRcdFx0XHQvLyBCb29raW5ncyAtIENoaWxkIG9yIG9ubHkgc2luZ2xlIGJvb2tpbmcgcmVzb3VyY2UgaW4gZGF0ZXNcclxuXHRcdFx0XHRcdF93cGJjLmJvb2tpbmdfX3NldF9wYXJhbV92YWx1ZSggcmVzcG9uc2VfZGF0YVsgJ3Jlc291cmNlX2lkJyBdLCAncmVzb3VyY2VzX2lkX2Fycl9faW5fZGF0ZXMnLCByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdyZXNvdXJjZXNfaWRfYXJyX19pbl9kYXRlcycgXSApO1xyXG5cclxuXHRcdFx0XHRcdC8vIEFnZ3JlZ2F0ZSBib29raW5nIHJlc291cmNlcywgIGlmIGFueSA/XHJcblx0XHRcdFx0XHRfd3BiYy5ib29raW5nX19zZXRfcGFyYW1fdmFsdWUoIHJlc3BvbnNlX2RhdGFbICdyZXNvdXJjZV9pZCcgXSwgJ2FnZ3JlZ2F0ZV9yZXNvdXJjZV9pZF9hcnInLCByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhZ2dyZWdhdGVfcmVzb3VyY2VfaWRfYXJyJyBdICk7XHJcblx0XHRcdFx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5cdFx0XHRcdFx0Ly8gVXBkYXRlIGNhbGVuZGFyXHJcblx0XHRcdFx0XHR3cGJjX2NhbGVuZGFyX191cGRhdGVfbG9vayggcmVzcG9uc2VfZGF0YVsgJ3Jlc291cmNlX2lkJyBdICk7XHJcblxyXG5cdFx0XHRcdFx0aWYgKCAnZnVuY3Rpb24nID09PSB0eXBlb2YgKHdwYmNfaG9va19faW5pdF90aW1lc2VsZWN0b3IpICkge1xyXG5cdFx0XHRcdFx0XHR3cGJjX2hvb2tfX2luaXRfdGltZXNlbGVjdG9yKCk7XHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0aWYgKFxyXG5cdFx0XHRcdFx0XHRcdCggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAocmVzcG9uc2VfZGF0YVsgJ2FqeF9kYXRhJyBdWyAnYWp4X2FmdGVyX2FjdGlvbl9tZXNzYWdlJyBdKSApXHJcblx0XHRcdFx0XHRcdCAmJiAoICcnICE9IHJlc3BvbnNlX2RhdGFbICdhanhfZGF0YScgXVsgJ2FqeF9hZnRlcl9hY3Rpb25fbWVzc2FnZScgXS5yZXBsYWNlKCAvXFxuL2csIFwiPGJyIC8+XCIgKSApXHJcblx0XHRcdFx0XHQpe1xyXG5cclxuXHRcdFx0XHRcdFx0dmFyIGpxX25vZGUgID0gd3BiY19nZXRfY2FsZW5kYXJfX2pxX25vZGVfX2Zvcl9tZXNzYWdlcyggdGhpcy5kYXRhICk7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBTaG93IE1lc3NhZ2VcclxuXHRcdFx0XHRcdFx0d3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZSggcmVzcG9uc2VfZGF0YVsgJ2FqeF9kYXRhJyBdWyAnYWp4X2FmdGVyX2FjdGlvbl9tZXNzYWdlJyBdLnJlcGxhY2UoIC9cXG4vZywgXCI8YnIgLz5cIiApLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0eyAgICd0eXBlJyAgICAgOiAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YoIHJlc3BvbnNlX2RhdGFbICdhanhfZGF0YScgXVsgJ2FqeF9hZnRlcl9hY3Rpb25fbWVzc2FnZV9zdGF0dXMnIF0gKSApXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgPyByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhanhfYWZ0ZXJfYWN0aW9uX21lc3NhZ2Vfc3RhdHVzJyBdIDogJ2luZm8nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJzogeydqcV9ub2RlJzoganFfbm9kZSwgJ3doZXJlJzogJ2FmdGVyJ30sXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdpc19hcHBlbmQnOiB0cnVlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc3R5bGUnICAgIDogJ3RleHQtYWxpZ246bGVmdDsnLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnZGVsYXknICAgIDogMTAwMDBcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBUcmlnZ2VyIGV2ZW50IHRoYXQgY2FsZW5kYXIgaGFzIGJlZW5cdFx0IC8vIEZpeEluOiAxMC4wLjAuNDQuXHJcblx0XHRcdFx0XHRpZiAoIGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc3BvbnNlX2RhdGFbICdyZXNvdXJjZV9pZCcgXSApLmxlbmd0aCA+IDAgKXtcclxuXHRcdFx0XHRcdFx0dmFyIHRhcmdldF9lbG0gPSBqUXVlcnkoICdib2R5JyApLnRyaWdnZXIoIFwid3BiY19jYWxlbmRhcl9hanhfX2xvYWRlZF9kYXRhXCIsIFtyZXNwb25zZV9kYXRhWyAncmVzb3VyY2VfaWQnIF1dICk7XHJcblx0XHRcdFx0XHRcdCAvL2pRdWVyeSggJ2JvZHknICkub24oICd3cGJjX2NhbGVuZGFyX2FqeF9fbG9hZGVkX2RhdGEnLCBmdW5jdGlvbiggZXZlbnQsIHJlc291cmNlX2lkICkgeyAuLi4gfSApO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8valF1ZXJ5KCAnI2FqYXhfcmVzcG9uZCcgKS5odG1sKCByZXNwb25zZV9kYXRhICk7XHRcdC8vIEZvciBhYmlsaXR5IHRvIHNob3cgcmVzcG9uc2UsIGFkZCBzdWNoIERJViBlbGVtZW50IHRvIHBhZ2VcclxuXHRcdFx0XHR9XHJcblx0XHRcdCAgKS5mYWlsKCBmdW5jdGlvbiAoIGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93biApIHsgICAgaWYgKCB3aW5kb3cuY29uc29sZSAmJiB3aW5kb3cuY29uc29sZS5sb2cgKXsgY29uc29sZS5sb2coICd
3411BamF4X0Vycm9yJywganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICk7IH1cclxuXHJcblx0XHRcdFx0XHR2YXIgYWp4X3Bvc3RfZGF0YV9fcmVzb3VyY2VfaWQgPSB3cGJjX2dldF9yZXNvdXJjZV9pZF9fZnJvbV9hanhfcG9zdF9kYXRhX3VybCggdGhpcy5kYXRhICk7XHJcblx0XHRcdFx0XHR3cGJjX2JhbGFuY2VyX19jb21wbGV0ZWQoIGFqeF9wb3N0X2RhdGFfX3Jlc291cmNlX2lkICwgJ3dwYmNfY2FsZW5kYXJfX2xvYWRfZGF0YV9fYWp4JyApO1xyXG5cclxuXHRcdFx0XHRcdC8vIEdldCBDb250ZW50IG9mIEVycm9yIE1lc3NhZ2VcclxuXHRcdFx0XHRcdHZhciBlcnJvcl9tZXNzYWdlID0gJzxzdHJvbmc+JyArICdFcnJvciEnICsgJzwvc3Ryb25nPiAnICsgZXJyb3JUaHJvd24gO1xyXG5cdFx0XHRcdFx0aWYgKCBqcVhIUi5zdGF0dXMgKXtcclxuXHRcdFx0XHRcdFx0ZXJyb3JfbWVzc2FnZSArPSAnICg8Yj4nICsganFYSFIuc3RhdHVzICsgJzwvYj4pJztcclxuXHRcdFx0XHRcdFx0aWYgKDQwMyA9PSBqcVhIUi5zdGF0dXMgKXtcclxuXHRcdFx0XHRcdFx0XHRlcnJvcl9tZXNzYWdlICs9ICc8YnI+IFByb2JhYmx5IG5vbmNlIGZvciB0aGlzIHBhZ2UgaGFzIGJlZW4gZXhwaXJlZC4gUGxlYXNlIDxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMClcIiBvbmNsaWNrPVwiamF2YXNjcmlwdDpsb2NhdGlvbi5yZWxvYWQoKTtcIj5yZWxvYWQgdGhlIHBhZ2U8L2E+Lic7XHJcblx0XHRcdFx0XHRcdFx0ZXJyb3JfbWVzc2FnZSArPSAnPGJyPiBPdGhlcndpc2UsIHBsZWFzZSBjaGVjayB0aGlzIDxhIHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDtcIiBocmVmPVwiaHR0cHM6Ly93cGJvb2tpbmdjYWxlbmRhci5jb20vZmFxL3JlcXVlc3QtZG8tbm90LXBhc3Mtc2VjdXJpdHktY2hlY2svP2FmdGVyX3VwZGF0ZT0xMC4xLjFcIj50cm91Ymxlc2hvb3RpbmcgaW5zdHJ1Y3Rpb248L2E+Ljxicj4nXHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHZhciBtZXNzYWdlX3Nob3dfZGVsYXkgPSAzMDAwO1xyXG5cdFx0XHRcdFx0aWYgKCBqcVhIUi5yZXNwb25zZVRleHQgKXtcclxuXHRcdFx0XHRcdFx0ZXJyb3JfbWVzc2FnZSArPSAnICcgKyBqcVhIUi5yZXNwb25zZVRleHQ7XHJcblx0XHRcdFx0XHRcdG1lc3NhZ2Vfc2hvd19kZWxheSA9IDEwO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZXJyb3JfbWVzc2FnZSA9IGVycm9yX21lc3NhZ2UucmVwbGFjZSggL1xcbi9nLCBcIjxiciAvPlwiICk7XHJcblxyXG5cdFx0XHRcdFx0dmFyIGpxX25vZGUgID0gd3BiY19nZXRfY2FsZW5kYXJfX2pxX25vZGVfX2Zvcl9tZXNzYWdlcyggdGhpcy5kYXRhICk7XHJcblxyXG5cdFx0XHRcdFx0LyoqXHJcblx0XHRcdFx0XHQgKiBJZiB3ZSBtYWtlIGZhc3QgY2xpY2tpbmcgb24gZGlmZmVyZW50IHBhZ2VzLFxyXG5cdFx0XHRcdFx0ICogdGhlbiB1bmRlciBjYWxlbmRhciB3aWxsIHNob3cgZXJyb3IgbWVzc2FnZSB3aXRoICBlbXB0eSAgdGV4dCwgYmVjYXVzZSBhamF4IHdhcyBub3QgcmVjZWl2ZWQuXHJcblx0XHRcdFx0XHQgKiBUbyAgbm90IHNob3cgc3VjaCB3YXJuaW5ncyB3ZSBhcmUgc2V0IGRlbGF5ICBpbiAzIHNlY29uZHMuICB2YXIgbWVzc2FnZV9zaG93X2RlbGF5ID0gMzAwMDtcclxuXHRcdFx0XHRcdCAqL1xyXG5cdFx0XHRcdFx0dmFyIGNsb3NlZF90aW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uICgpe1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTaG93IE1lc3NhZ2VcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKCBlcnJvcl9tZXNzYWdlICwgeyAndHlwZScgICAgIDogJ2Vycm9yJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJzogeydqcV9ub2RlJzoganFfbm9kZSwgJ3doZXJlJzogJ2FmdGVyJ30sXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2lzX2FwcGVuZCc6IHRydWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3N0eWxlJyAgICA6ICd0ZXh0LWFsaWduOmxlZnQ7JyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnY3NzX2NsYXNzJzond3BiY19mZV9tZXNzYWdlX2FsdCcsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICA6IDBcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fSApO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICAgfSAsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICBwYXJzZUludCggbWVzc2FnZV9zaG93X2RlbGF5ICkgICApO1xyXG5cclxuXHRcdFx0ICB9KVxyXG5cdCAgICAgICAgICAvLyAuZG9uZSggICBmdW5jdGlvbiAoIGRhdGEsIHRleHRTdGF0dXMsIGpxWEhSICkgeyAgIGlmICggd2luZG93LmNvbnNvbGUgJiYgd2luZG93LmNvbnNvbGUubG9nICl7IGNvbnNvbGUubG9nKCAnc2Vjb25kIHN1Y2Nlc3MnLCBkYXRhLCB0ZXh0U3RhdHVzLCBqcVhIUiApOyB9ICAgIH0pXHJcblx0XHRcdCAgLy8gLmFsd2F5cyggZnVuY3Rpb24gKCBkYXRhX2pxWEhSLCB0ZXh0U3RhdHVzLCBqcVhIUl9lcnJvclRocm93biApIHsgICBpZiAoIHdpbmRvdy5jb25zb2xlICYmIHdpbmRvdy5jb25zb2xlLmxvZyApeyBjb25zb2xlLmxvZyggJ2Fsd2F5cyBmaW5pc2hlZCcsIGRhdGFfanFYSFIsIHRleHRTdGF0dXMsIGpxWEhSX2Vycm9yVGhyb3duICk7IH0gICAgIH0pXHJcblx0XHRcdCAgOyAgLy8gRW5kIEFqYXhcclxufVxyXG5cclxuXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gU3VwcG9ydFxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IENhbGVuZGFyIGpRdWVyeSBub2RlIGZvciBzaG93aW5nIG1lc3NhZ2VzIGR1cmluZyBBamF4XHJcblx0ICogVGhpcyBwYXJhbWV0ZXI6ICAgY2FsZW5kYXJfcmVx
3411dWVzdF9wYXJhbXNbcmVzb3VyY2VfaWRdICAgcGFyc2VkIGZyb20gdGhpcy5kYXRhIEFqYXggcG9zdCAgZGF0YVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGFqeF9wb3N0X2RhdGFfdXJsX3BhcmFtc1x0XHQgJ2FjdGlvbj1XUEJDX0FKWF9DQUxFTkRBUl9MT0FELi4uJmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zJTVCcmVzb3VyY2VfaWQlNUQ9MiZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyU1QmJvb2tpbmdfaGFzaCU1RD0mY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMnXHJcblx0ICogQHJldHVybnMge3N0cmluZ31cdCcnI2NhbGVuZGFyX2Jvb2tpbmcxJyAgfCAgICcuYm9va2luZ19mb3JtX2RpdicgLi4uXHJcblx0ICpcclxuXHQgKiBFeGFtcGxlICAgIHZhciBqcV9ub2RlICA9IHdwYmNfZ2V0X2NhbGVuZGFyX19qcV9ub2RlX19mb3JfbWVzc2FnZXMoIHRoaXMuZGF0YSApO1xyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZ2V0X2NhbGVuZGFyX19qcV9ub2RlX19mb3JfbWVzc2FnZXMoIGFqeF9wb3N0X2RhdGFfdXJsX3BhcmFtcyApe1xyXG5cclxuXHRcdHZhciBqcV9ub2RlID0gJy5ib29raW5nX2Zvcm1fZGl2JztcclxuXHJcblx0XHR2YXIgY2FsZW5kYXJfcmVzb3VyY2VfaWQgPSB3cGJjX2dldF9yZXNvdXJjZV9pZF9fZnJvbV9hanhfcG9zdF9kYXRhX3VybCggYWp4X3Bvc3RfZGF0YV91cmxfcGFyYW1zICk7XHJcblxyXG5cdFx0aWYgKCBjYWxlbmRhcl9yZXNvdXJjZV9pZCA+IDAgKXtcclxuXHRcdFx0anFfbm9kZSA9ICcjY2FsZW5kYXJfYm9va2luZycgKyBjYWxlbmRhcl9yZXNvdXJjZV9pZDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4ganFfbm9kZTtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgcmVzb3VyY2UgSUQgZnJvbSBhanggcG9zdCBkYXRhIHVybCAgIHVzdWFsbHkgIGZyb20gIHRoaXMuZGF0YSAgPSAnYWN0aW9uPVdQQkNfQUpYX0NBTEVOREFSX0xPQUQuLi4mY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMlNUJyZXNvdXJjZV9pZCU1RD0yJmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zJTVCYm9va2luZ19oYXNoJTVEPSZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcydcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBhanhfcG9zdF9kYXRhX3VybF9wYXJhbXNcdFx0ICdhY3Rpb249V1BCQ19BSlhfQ0FMRU5EQVJfTE9BRC4uLiZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyU1QnJlc291cmNlX2lkJTVEPTImY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMlNUJib29raW5nX2hhc2glNUQ9JmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zJ1xyXG5cdCAqIEByZXR1cm5zIHtpbnR9XHRcdFx0XHRcdFx0IDEgfCAwICAoaWYgZXJycm9yIHRoZW4gIDApXHJcblx0ICpcclxuXHQgKiBFeGFtcGxlICAgIHZhciBqcV9ub2RlICA9IHdwYmNfZ2V0X2NhbGVuZGFyX19qcV9ub2RlX19mb3JfbWVzc2FnZXMoIHRoaXMuZGF0YSApO1xyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZ2V0X3Jlc291cmNlX2lkX19mcm9tX2FqeF9wb3N0X2RhdGFfdXJsKCBhanhfcG9zdF9kYXRhX3VybF9wYXJhbXMgKXtcclxuXHJcblx0XHQvLyBHZXQgYm9va2luZyByZXNvdXJjZSBJRCBmcm9tIEFqYXggUG9zdCBSZXF1ZXN0ICAtPiB0aGlzLmRhdGEgPSAnYWN0aW9uPVdQQkNfQUpYX0NBTEVOREFSX0xPQUQuLi4mY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMlNUJyZXNvdXJjZV9pZCU1RD0yJmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zJTVCYm9va2luZ19oYXNoJTVEPSZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcydcclxuXHRcdHZhciBjYWxlbmRhcl9yZXNvdXJjZV9pZCA9IHdwYmNfZ2V0X3VyaV9wYXJhbV9ieV9uYW1lKCAnY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXNbcmVzb3VyY2VfaWRdJywgYWp4X3Bvc3RfZGF0YV91cmxfcGFyYW1zICk7XHJcblx0XHRpZiAoIChudWxsICE9PSBjYWxlbmRhcl9yZXNvdXJjZV9pZCkgJiYgKCcnICE9PSBjYWxlbmRhcl9yZXNvdXJjZV9pZCkgKXtcclxuXHRcdFx0Y2FsZW5kYXJfcmVzb3VyY2VfaWQgPSBwYXJzZUludCggY2FsZW5kYXJfcmVzb3VyY2VfaWQgKTtcclxuXHRcdFx0aWYgKCBjYWxlbmRhcl9yZXNvdXJjZV9pZCA+IDAgKXtcclxuXHRcdFx0XHRyZXR1cm4gY2FsZW5kYXJfcmVzb3VyY2VfaWQ7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiAwO1xyXG5cdH1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBwYXJhbWV0ZXIgZnJvbSBVUkwgIC0gIHBhcnNlIFVSTCBwYXJhbWV0ZXJzLCAgbGlrZSB0aGlzOiBhY3Rpb249V1BCQ19BSlhfQ0FMRU5EQVJfTE9BRC4uLiZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyU1QnJlc291cmNlX2lkJTVEPTImY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMlNUJib29raW5nX2hhc2glNUQ9JmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zXHJcblx0ICogQHBhcmFtIG5hbWUgIHBhcmFtZXRlciAgbmFtZSwgIGxpa2UgJ2NhbGVuZGFyX3JlcXVlc3RfcGFyYW1zW3Jlc291cmNlX2lkXSdcclxuXHQgKiBAcGFyYW0gdXJsXHQncGFyYW1ldGVyICBzdHJpbmcgVVJMJ1xyXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gICBwYXJhbWV0ZXIgdmFsdWVcclxuXHQgKlxyXG5cdCAqIEV4YW1wbGU6IFx0XHR3cGJjX2dldF91cmlfcGFyYW1fYnlfbmFtZSggJ2NhbGVuZGFyX3JlcXVlc3RfcGFyYW1zW3Jlc291cmNlX2lkXScsIHRoaXMuZGF0YSApOyAgLT4gJzInXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19nZXRfdXJpX3BhcmFtX2J5X25hbWUoIG5hbWUsIHVybCApe1xyXG5cclxuXHRcdHVybCA9IGRlY29kZVVSSUNvbXBvbmVudCggdXJsICk7XHJcblxyXG5cdFx0bmFtZSA9IG5hbWUucmVwbGFjZSggL1tcXFtcXF1dL2csICdcXFxcJCYnICk7XHJcblx0XHR2YXIgcmVnZXggPSBuZXcgUmVnRXhwKCAnWz8mXScgKyBuYW1lICsgJyg9KFteJiNdKil8JnwjfCQpJyApLFxyXG5cdFx0XHRyZXN1bHRzID0gcmVnZXguZXhlYyggdXJsICk7XHJcblx0XHRpZiAoICFyZXN1bHRzICkgcmV0dXJuIG51bGw7XHJcblx0XHRpZiAoICFyZXN1bHRzWyAyIF0gKSByZXR1cm4gJyc7XHJcblx0XHRyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KCByZXN1bHRzWyAyIF0ucmVwbGFjZSggL1xcKy9nLCAnICcgKSApO1xyXG5cdH1cclxuIiwiLyoqXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKlx0aW5jbHVkZXMvX19qcy9mcm9udF9lbmRfbWVzc2FnZXMvd3BiY19mZV9tZXNzYWdlcy5qc1xyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICovXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gU2hvdyBNZXNzYWdlcyBhdCBGcm9udC1FZG4gc2lkZVxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBTaG93IG1lc3NhZ2UgaW4gY29udGVudFxyXG4gKlxyXG4gKiBAcGFyYW0gbWVzc2FnZVx0XHRcdFx0TWVzc2FnZSBIVE1MXHJcbiAqIEBwYXJhbSBwYXJhbXMgPSB7XHJcbiAqXHRcdFx0XHRcdFx0XHRcdCd0eXBlJyAgICAgOiAnd2FybmluZycsXHRcdFx0XHRcdFx0XHQvLyAnZXJyb3InIHwgJ3dhcm5pbmcnIHwgJ2luZm8nIHwgJ3N1Y2Nlc3MnXHJcbiAqXHRcdFx0XHRcdFx0XHRcdCdzaG93X2hlcmUnIDoge1xyXG4gKlx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2pxX25vZGUnIDogJycsXHRcdFx0XHQvLyBhbnkgalF1ZXJ5IG5vZGUgZGVmaW5pdGlvblxyXG4gKlx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3doZXJlJyAgIDogJ2luc2lkZSdcdFx0Ly8gJ2luc2lkZScgfCAnYmVmb3JlJyB8ICdhZnRlcicgfCAncmlnaHQnIHwgJ2xlZnQnXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgfSxcclxuICpcdFx0XHRcdFx0XHRcdFx0J2lzX2FwcGVuZCc6IHRydWUsXHRcdFx0XHRcdFx0XHRcdC8vIEFwcGx5ICBvbmx5IGlmIFx0J3doZXJlJyAgIDogJ2luc2lkZSdcclxuICpcdFx0XHRcdFx0XHRcdFx0J3N0eWxlJyAgICA6ICd0ZXh0LWFsaWduOmxlZnQ7JyxcdFx0XHRcdC8vIHN0eWxlcywgaWYgbmVlZGVkXHJcbiAqXHRcdFx0XHRcdFx0XHQgICAgJ2Nzc19jbGFzcyc6ICcnLFx0XHRcdFx0XHRcdFx0XHQvLyBGb3IgZXhhbXBsZSBjYW4gIGJlOiAnd3BiY19mZV9tZXNzYWdlX2FsdCdcclxuICpcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICA6IDAsXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaG93IG1hbnkgbWljcm9zZWNvbmQgdG8gIHNob3csICBpZiAwICB0aGVuICBzaG93IGZvcmV2ZXJcclxuICpcdFx0XHRcdFx0XHRcdFx0J2lmX3Zpc2libGVfbm90X3Nob3cnOiBmYWxzZVx0XHRcdFx0XHQvLyBpZiB0cnVlLCAgdGhlbiBkbyBub3Qgc2hvdyBtZXNzYWdlLCAgaWYgcHJldmlvcyBtZXNzYWdlIHdhcyBub3QgaGlkZWQgKG5vdCBhcHBseSBpZiAnd2hlcmUnICAgOiAnaW5zaWRlJyApXHJcbiAqXHRcdFx0XHR9O1xyXG4gKiBFeGFtcGxlczpcclxuICogXHRcdFx0dmFyIGh0bWxfaWQgPSB3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKCAnWW91IGNhbiB0ZXN0IGRheXMgc2VsZWN0aW9uIGluIGNhbGVuZGFyJywge30gKTtcclxuICpcclxuICpcdFx0XHR2YXIgbm90aWNlX21lc3NhZ2VfaWQgPSB3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKCBfd3BiYy5nZXRfbWVzc2FnZSggJ21lc3NhZ2VfY2hlY2tfcmVxdWlyZWQnICksIHsgJ3R5cGUnOiAnd2FybmluZycsICdkZWxheSc6IDEwMDAwLCAnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IHRydWUsXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICdzaG93X2hlcmUnOiB7J3doZXJlJzogJ3JpZ2h0JywgJ2pxX25vZGUnOiBlbCx9IH0gKTtcclxuICpcclxuICpcdFx0XHR3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKCByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhanhfYWZ0ZXJfYWN0aW9uX21lc3NhZ2UnIF0ucmVwbGFjZSggL1xcbi9nLCBcIjxiciAvPlwiICksXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHsgICAndHlwZScgICAgIDogKCAn
3411dW5kZWZpbmVkJyAhPT0gdHlwZW9mKCByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhanhfYWZ0ZXJfYWN0aW9uX21lc3NhZ2Vfc3RhdHVzJyBdICkgKVxyXG4gKlx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgPyByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhanhfYWZ0ZXJfYWN0aW9uX21lc3NhZ2Vfc3RhdHVzJyBdIDogJ2luZm8nLFxyXG4gKlx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdzaG93X2hlcmUnOiB7J2pxX25vZGUnOiBqcV9ub2RlLCAnd2hlcmUnOiAnYWZ0ZXInfSxcclxuICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnY3NzX2NsYXNzJzond3BiY19mZV9tZXNzYWdlX2FsdCcsXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICA6IDEwMDAwXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdH0gKTtcclxuICpcclxuICpcclxuICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZSggbWVzc2FnZSwgcGFyYW1zID0ge30gKXtcclxuXHJcblx0dmFyIHBhcmFtc19kZWZhdWx0ID0ge1xyXG5cdFx0XHRcdFx0XHRcdFx0J3R5cGUnICAgICA6ICd3YXJuaW5nJyxcdFx0XHRcdFx0XHRcdC8vICdlcnJvcicgfCAnd2FybmluZycgfCAnaW5mbycgfCAnc3VjY2VzcydcclxuXHRcdFx0XHRcdFx0XHRcdCdzaG93X2hlcmUnIDoge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdqcV9ub2RlJyA6ICcnLFx0XHRcdFx0Ly8gYW55IGpRdWVyeSBub2RlIGRlZmluaXRpb25cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnd2hlcmUnICAgOiAnaW5zaWRlJ1x0XHQvLyAnaW5zaWRlJyB8ICdiZWZvcmUnIHwgJ2FmdGVyJyB8ICdyaWdodCcgfCAnbGVmdCdcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgfSxcclxuXHRcdFx0XHRcdFx0XHRcdCdpc19hcHBlbmQnOiB0cnVlLFx0XHRcdFx0XHRcdFx0XHQvLyBBcHBseSAgb25seSBpZiBcdCd3aGVyZScgICA6ICdpbnNpZGUnXHJcblx0XHRcdFx0XHRcdFx0XHQnc3R5bGUnICAgIDogJ3RleHQtYWxpZ246bGVmdDsnLFx0XHRcdFx0Ly8gc3R5bGVzLCBpZiBuZWVkZWRcclxuXHRcdFx0XHRcdFx0XHQgICAgJ2Nzc19jbGFzcyc6ICcnLFx0XHRcdFx0XHRcdFx0XHQvLyBGb3IgZXhhbXBsZSBjYW4gIGJlOiAnd3BiY19mZV9tZXNzYWdlX2FsdCdcclxuXHRcdFx0XHRcdFx0XHRcdCdkZWxheScgICAgOiAwLFx0XHRcdFx0XHRcdFx0XHRcdC8vIGhvdyBtYW55IG1pY3Jvc2Vjb25kIHRvICBzaG93LCAgaWYgMCAgdGhlbiAgc2hvdyBmb3JldmVyXHJcblx0XHRcdFx0XHRcdFx0XHQnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IGZhbHNlLFx0XHRcdFx0XHQvLyBpZiB0cnVlLCAgdGhlbiBkbyBub3Qgc2hvdyBtZXNzYWdlLCAgaWYgcHJldmlvcyBtZXNzYWdlIHdhcyBub3QgaGlkZWQgKG5vdCBhcHBseSBpZiAnd2hlcmUnICAgOiAnaW5zaWRlJyApXHJcblx0XHRcdFx0XHRcdFx0XHQnaXNfc2Nyb2xsJzogdHJ1ZVx0XHRcdFx0XHRcdFx0XHQvLyBpcyBzY3JvbGwgIHRvICB0aGlzIGVsZW1lbnRcclxuXHRcdFx0XHRcdFx0fTtcclxuXHRmb3IgKCB2YXIgcF9rZXkgaW4gcGFyYW1zICl7XHJcblx0XHRwYXJhbXNfZGVmYXVsdFsgcF9rZXkgXSA9IHBhcmFtc1sgcF9rZXkgXTtcclxuXHR9XHJcblx0cGFyYW1zID0gcGFyYW1zX2RlZmF1bHQ7XHJcblxyXG4gICAgdmFyIHVuaXF1ZV9kaXZfaWQgPSBuZXcgRGF0ZSgpO1xyXG4gICAgdW5pcXVlX2Rpdl9pZCA9ICd3cGJjX25vdGljZV8nICsgdW5pcXVlX2Rpdl9pZC5nZXRUaW1lKCk7XHJcblxyXG5cdHBhcmFtc1snY3NzX2NsYXNzJ10gKz0gJyB3cGJjX2ZlX21lc3NhZ2UnO1xyXG5cdGlmICggcGFyYW1zWyd0eXBlJ10gPT0gJ2Vycm9yJyApe1xyXG5cdFx0cGFyYW1zWydjc3NfY2xhc3MnXSArPSAnIHdwYmNfZmVfbWVzc2FnZV9lcnJvcic7XHJcblx0XHRtZXNzYWdlID0gJzxpIGNsYXNzPVwibWVudV9pY29uIGljb24tMXggd3BiY19pY25fcmVwb3J0X2dtYWlsZXJyb3JyZWRcIj48L2k+JyArIG1lc3NhZ2U7XHJcblx0fVxyXG5cdGlmICggcGFyYW1zWyd0eXBlJ10gPT0gJ3dhcm5pbmcnICl7XHJcblx0XHRwYXJhbXNbJ2Nzc19jbGFzcyddICs9ICcgd3BiY19mZV9tZXNzYWdlX3dhcm5pbmcnO1xyXG5cdFx0bWVzc2FnZSA9ICc8aSBjbGFzcz1cIm1lbnVfaWNvbiBpY29uLTF4IHdwYmNfaWNuX3dhcm5pbmdcIj48L2k+JyArIG1lc3NhZ2U7XHJcblx0fVxyXG5cdGlmICggcGFyYW1zWyd0eXBlJ10gPT0gJ2luZm8nICl7XHJcblx0XHRwYXJhbXNbJ2Nzc19jbGFzcyddICs9ICcgd3BiY19mZV9tZXNzYWdlX2luZm8nO1xyXG5cdH1cclxuXHRpZiAoIHBhcmFtc1sndHlwZSddID09ICdzdWNjZXNzJyApe1xyXG5cdFx0cGFyYW1zWydjc3NfY2xhc3MnXSArPSAnIHdwYmNfZmVfbWVzc2FnZV9zdWNjZXNzJztcclxuXHRcdG1lc3NhZ2UgPSAnPGkgY2xhc3M9XCJtZW51X2ljb24gaWNvbi0xeCB3cGJjX2ljbl9kb25lX291dGxpbmVcIj48L2k+JyArIG1lc3NhZ2U7XHJcblx0fVxyXG5cclxuXHR2YXIgc2Nyb2xsX3RvX2VsZW1lbnQgPSAnPGRpdiBpZD1cIicgKyB1bmlxdWVfZGl2X2lkICsgJ19zY3JvbGxcIiBzdHlsZT1cImRpc3BsYXk6bm9uZTtcIj48L2Rpdj4nO1xyXG5cdG1lc3NhZ2UgPSAnPGRpdiBpZD1cIicgKyB1bmlxdWVfZGl2X2lkICsgJ1wiIGNsYXNzPVwid3BiY19mcm9udF9lbmRfX21lc3NhZ2UgJyArIHBhcmFtc1snY3NzX2NsYXNzJ10gKyAnXCIgc3R5bGU9XCInICsgcGFyYW1zWyAnc3R5bGUnIF0gKyAnXCI+JyArIG1lc3NhZ2UgKyAnPC9kaXY+JztcclxuXHJcblxyXG5cdHZhciBqcV9lbF9tZXNzYWdlID0gZmFsc2U7XHJcblx0dmFyIGlzX3Nob3dfbWVzc2FnZSA9IHRydWU7XHJcblxyXG5cdGlmICggJ2luc2lkZScgPT09IHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ3doZXJlJyBdICl7XHJcblxyXG5cdFx0aWYgKCBwYXJhbXNbICdpc19hcHBlbmQnIF0gKXtcclxuXHRcdFx0alF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuYXBwZW5kKCBzY3JvbGxfdG9fZWxlbWVudCApO1xyXG5cdFx0XHRqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5hcHBlbmQo
3411IG1lc3NhZ2UgKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLmh0bWwoIHNjcm9sbF90b19lbGVtZW50ICsgbWVzc2FnZSApO1xyXG5cdFx0fVxyXG5cclxuXHR9IGVsc2UgaWYgKCAnYmVmb3JlJyA9PT0gcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnd2hlcmUnIF0gKXtcclxuXHJcblx0XHRqcV9lbF9tZXNzYWdlID0galF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuc2libGluZ3MoICdbaWRePVwid3BiY19ub3RpY2VfXCJdJyApO1xyXG5cdFx0aWYgKCAocGFyYW1zWyAnaWZfdmlzaWJsZV9ub3Rfc2hvdycgXSkgJiYgKGpxX2VsX21lc3NhZ2UuaXMoICc6dmlzaWJsZScgKSkgKXtcclxuXHRcdFx0aXNfc2hvd19tZXNzYWdlID0gZmFsc2U7XHJcblx0XHRcdHVuaXF1ZV9kaXZfaWQgPSBqUXVlcnkoIGpxX2VsX21lc3NhZ2UuZ2V0KCAwICkgKS5hdHRyKCAnaWQnICk7XHJcblx0XHR9XHJcblx0XHRpZiAoIGlzX3Nob3dfbWVzc2FnZSApe1xyXG5cdFx0XHRqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5iZWZvcmUoIHNjcm9sbF90b19lbGVtZW50ICk7XHJcblx0XHRcdGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLmJlZm9yZSggbWVzc2FnZSApO1xyXG5cdFx0fVxyXG5cclxuXHR9IGVsc2UgaWYgKCAnYWZ0ZXInID09PSBwYXJhbXNbICdzaG93X2hlcmUnIF1bICd3aGVyZScgXSApe1xyXG5cclxuXHRcdGpxX2VsX21lc3NhZ2UgPSBqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5uZXh0QWxsKCAnW2lkXj1cIndwYmNfbm90aWNlX1wiXScgKTtcclxuXHRcdGlmICggKHBhcmFtc1sgJ2lmX3Zpc2libGVfbm90X3Nob3cnIF0pICYmIChqcV9lbF9tZXNzYWdlLmlzKCAnOnZpc2libGUnICkpICl7XHJcblx0XHRcdGlzX3Nob3dfbWVzc2FnZSA9IGZhbHNlO1xyXG5cdFx0XHR1bmlxdWVfZGl2X2lkID0galF1ZXJ5KCBqcV9lbF9tZXNzYWdlLmdldCggMCApICkuYXR0ciggJ2lkJyApO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCBpc19zaG93X21lc3NhZ2UgKXtcclxuXHRcdFx0alF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuYmVmb3JlKCBzY3JvbGxfdG9fZWxlbWVudCApO1x0XHQvLyBXZSBuZWVkIHRvICBzZXQgIGhlcmUgYmVmb3JlKGZvciBoYW5keSBzY3JvbGwpXHJcblx0XHRcdGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLmFmdGVyKCBtZXNzYWdlICk7XHJcblx0XHR9XHJcblxyXG5cdH0gZWxzZSBpZiAoICdyaWdodCcgPT09IHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ3doZXJlJyBdICl7XHJcblxyXG5cdFx0anFfZWxfbWVzc2FnZSA9IGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLm5leHRBbGwoICcud3BiY19mcm9udF9lbmRfX21lc3NhZ2VfY29udGFpbmVyX3JpZ2h0JyApLmZpbmQoICdbaWRePVwid3BiY19ub3RpY2VfXCJdJyApO1xyXG5cdFx0aWYgKCAocGFyYW1zWyAnaWZfdmlzaWJsZV9ub3Rfc2hvdycgXSkgJiYgKGpxX2VsX21lc3NhZ2UuaXMoICc6dmlzaWJsZScgKSkgKXtcclxuXHRcdFx0aXNfc2hvd19tZXNzYWdlID0gZmFsc2U7XHJcblx0XHRcdHVuaXF1ZV9kaXZfaWQgPSBqUXVlcnkoIGpxX2VsX21lc3NhZ2UuZ2V0KCAwICkgKS5hdHRyKCAnaWQnICk7XHJcblx0XHR9XHJcblx0XHRpZiAoIGlzX3Nob3dfbWVzc2FnZSApe1xyXG5cdFx0XHRqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5iZWZvcmUoIHNjcm9sbF90b19lbGVtZW50ICk7XHRcdC8vIFdlIG5lZWQgdG8gIHNldCAgaGVyZSBiZWZvcmUoZm9yIGhhbmR5IHNjcm9sbClcclxuXHRcdFx0alF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuYWZ0ZXIoICc8ZGl2IGNsYXNzPVwid3BiY19mcm9udF9lbmRfX21lc3NhZ2VfY29udGFpbmVyX3JpZ2h0XCI+JyArIG1lc3NhZ2UgKyAnPC9kaXY+JyApO1xyXG5cdFx0fVxyXG5cdH0gZWxzZSBpZiAoICdsZWZ0JyA9PT0gcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnd2hlcmUnIF0gKXtcclxuXHJcblx0XHRqcV9lbF9tZXNzYWdlID0galF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuc2libGluZ3MoICcud3BiY19mcm9udF9lbmRfX21lc3NhZ2VfY29udGFpbmVyX2xlZnQnICkuZmluZCggJ1tpZF49XCJ3cGJjX25vdGljZV9cIl0nICk7XHJcblx0XHRpZiAoIChwYXJhbXNbICdpZl92aXNpYmxlX25vdF9zaG93JyBdKSAmJiAoanFfZWxfbWVzc2FnZS5pcyggJzp2aXNpYmxlJyApKSApe1xyXG5cdFx0XHRpc19zaG93X21lc3NhZ2UgPSBmYWxzZTtcclxuXHRcdFx0dW5pcXVlX2Rpdl9pZCA9IGpRdWVyeSgganFfZWxfbWVzc2FnZS5nZXQoIDAgKSApLmF0dHIoICdpZCcgKTtcclxuXHRcdH1cclxuXHRcdGlmICggaXNfc2hvd19tZXNzYWdlICl7XHJcblx0XHRcdGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLmJlZm9yZSggc2Nyb2xsX3RvX2VsZW1lbnQgKTtcdFx0Ly8gV2UgbmVlZCB0byAgc2V0ICBoZXJlIGJlZm9yZShmb3IgaGFuZHkgc2Nyb2xsKVxyXG5cdFx0XHRqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5iZWZvcmUoICc8ZGl2IGNsYXNzPVwid3BiY19mcm9udF9lbmRfX21lc3NhZ2VfY29udGFpbmVyX2xlZnRcIj4nICsgbWVzc2FnZSArICc8L2Rpdj4nICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoICAgKCBpc19zaG93X21lc3NhZ2UgKSAgJiYgICggcGFyc2VJbnQoIHBhcmFtc1sgJ2RlbGF5JyBdICkgPiAwICkgICApe1xyXG5cdFx0dmFyIGNsb3NlZF90aW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uICgpe1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGpRdWVyeSggJyMnICsgdW5pcXVlX2Rpdl9pZCApLmZhZGVPdXQoIDE1MDAgKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9ICwgcGFyc2VJbnQoIHBhcmFtc1sgJ2RlbGF5JyBdICkgICApO1xyXG5cclxuXHRcdHZhciBjbG9zZWRfdGltZXIyID0gc2V0VGltZW91dCggZnVuY3Rpb24gKCl7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRqUXVlcnkoICcjJyArIHVuaXF1ZV9kaXZfaWQgKS50cmlnZ2VyKCAnaGlkZScgKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9LCAoIHBhcnNlSW50KCBwYXJhbXNbICdkZWxheScgXSApICsgMTUwMSApICk7XHJcblx0fVxyXG5cclxuXHQvLyBDaGVjayAgaWYgc2hvd2VkIG1lc3NhZ2UgaW4gc29tZSBoaWRkZW4gcGFyZW50IHNlY3Rpb24gYW5kIHNob3cgaXQuIEJ1dCBpdCBtdXN0ICBiZSBsb3dlciB0aGFuICcud3BiY19jb250YWluZXInXHJcblx0dmFyIHBhcmVudF9lbHMgPSBqUXVlcnkoICcjJyArIHVuaXF1ZV9kaXZfaWQgKS5wYXJlbnRzKCkubWFwKCBmdW5jdGlvbiAoKXtcclxuXHRcdGlmICggKCFqUXVlcnkoIHRoaXMgKS5pcyggJ3Zpc2libGUnICkpICYmIChqUXVlcnkoICcud3BiY19jb250YWluZXInICkuaGFzKCB0aGlzICkpICl7XHJcblx0XHRcdGpRdWVyeSggdGhpcyApLnNob3coKTtcclxuXHRcdH1cclxuXHR9ICk7XHJcblxyXG5cdGlmICggcGFyYW1zWyAnaXNfc2Nyb2xsJyBdICl7XHJcblx0XHR3cGJjX2RvX3Njcm9sbCggJy
3411MnICsgdW5pcXVlX2Rpdl9pZCArICdfc2Nyb2xsJyApO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHVuaXF1ZV9kaXZfaWQ7XHJcbn1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEVycm9yIG1lc3NhZ2UuIFx0UHJlc2V0IG9mIHBhcmFtZXRlcnMgZm9yIHJlYWwgbWVzc2FnZSBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBlbFx0XHQtIGFueSBqUXVlcnkgbm9kZSBkZWZpbml0aW9uXHJcblx0ICogQHBhcmFtIG1lc3NhZ2VcdC0gTWVzc2FnZSBIVE1MXHJcblx0ICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2VfX2Vycm9yKCBqcV9ub2RlLCBtZXNzYWdlICl7XHJcblxyXG5cdFx0dmFyIG5vdGljZV9tZXNzYWdlX2lkID0gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZShcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtZXNzYWdlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0eXBlJyAgICAgICAgICAgICAgIDogJ2Vycm9yJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdkZWxheScgICAgICAgICAgICAgIDogMTAwMDAsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IHRydWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJyAgICAgICAgICA6IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd3aGVyZScgIDogJ3JpZ2h0JyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdqcV9ub2RlJzoganFfbm9kZVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xyXG5cdFx0cmV0dXJuIG5vdGljZV9tZXNzYWdlX2lkO1xyXG5cdH1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEVycm9yIG1lc3NhZ2UgVU5ERVIgZWxlbWVudC4gXHRQcmVzZXQgb2YgcGFyYW1ldGVycyBmb3IgcmVhbCBtZXNzYWdlIGZ1bmN0aW9uLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGVsXHRcdC0gYW55IGpRdWVyeSBub2RlIGRlZmluaXRpb25cclxuXHQgKiBAcGFyYW0gbWVzc2FnZVx0LSBNZXNzYWdlIEhUTUxcclxuXHQgKiBAcmV0dXJucyBzdHJpbmcgIC0gSFRNTCBJRFx0XHRvciAwIGlmIG5vdCBzaG93aW5nIGR1cmluZyB0aGlzIHRpbWUuXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZV9fZXJyb3JfdW5kZXJfZWxlbWVudCgganFfbm9kZSwgbWVzc2FnZSwgbWVzc2FnZV9kZWxheSApe1xyXG5cclxuXHRcdGlmICggJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiAobWVzc2FnZV9kZWxheSkgKXtcclxuXHRcdFx0bWVzc2FnZV9kZWxheSA9IDBcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgbm90aWNlX21lc3NhZ2VfaWQgPSB3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1lc3NhZ2UsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3R5cGUnICAgICAgICAgICAgICAgOiAnZXJyb3InLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICAgICAgICAgICAgOiBtZXNzYWdlX2RlbGF5LFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2lmX3Zpc2libGVfbm90X3Nob3cnOiB0cnVlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3Nob3dfaGVyZScgICAgICAgICAgOiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnd2hlcmUnICA6ICdhZnRlcicsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnanFfbm9kZSc6IGpxX25vZGVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcclxuXHRcdHJldHVybiBub3RpY2VfbWVzc2FnZV9pZDtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBFcnJvciBtZXNzYWdlIFVOREVSIGVsZW1lbnQuIFx0UHJlc2V0IG9mIHBhcmFtZXRlcnMgZm9yIHJlYWwgbWVzc2FnZSBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBlbFx0XHQtIGFueSBqUXVlcnkgbm9kZSBkZWZpbml0aW9uXHJcblx0ICogQHBhcmFtIG1lc3NhZ2VcdC0gTWVzc2FnZSBIVE1MXHJcblx0ICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2VfX2Vycm9yX2Fib3ZlX2VsZW1lbnQoIGpxX25vZGUsIG1lc3NhZ2UsIG1lc3NhZ2VfZGVsYXkgKXtcclxuXHJcblx0XHRpZiAoICd1bmRlZmluZWQnID09PSB0eXBlb2YgKG1lc3NhZ2VfZGVsYXkpICl7XHJcblx0XHRcdG1lc3NhZ2VfZGVsYXkgPSAxMDAwMFxyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBub3RpY2VfbWVzc2FnZV9pZCA9IHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2UoXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWVzc2FnZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndHlwZScgICAgICAgICAgICAgICA6ICdlcnJvcicsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnZGVsYXknICAgICAgICAgICAgICA6IG1lc3NhZ2VfZGVsYXksXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IHRydWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJyAgICAgICAgICA6IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd3aGVyZScgIDogJ2JlZm9yZScsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnanFfbm9kZSc6IGpxX25vZGVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcclxuXHRcdHJldHVybi
3411Bub3RpY2VfbWVzc2FnZV9pZDtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBXYXJuaW5nIG1lc3NhZ2UuIFx0UHJlc2V0IG9mIHBhcmFtZXRlcnMgZm9yIHJlYWwgbWVzc2FnZSBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBlbFx0XHQtIGFueSBqUXVlcnkgbm9kZSBkZWZpbml0aW9uXHJcblx0ICogQHBhcmFtIG1lc3NhZ2VcdC0gTWVzc2FnZSBIVE1MXHJcblx0ICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2VfX3dhcm5pbmcoIGpxX25vZGUsIG1lc3NhZ2UgKXtcclxuXHJcblx0XHR2YXIgbm90aWNlX21lc3NhZ2VfaWQgPSB3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1lc3NhZ2UsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3R5cGUnICAgICAgICAgICAgICAgOiAnd2FybmluZycsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnZGVsYXknICAgICAgICAgICAgICA6IDEwMDAwLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2lmX3Zpc2libGVfbm90X3Nob3cnOiB0cnVlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3Nob3dfaGVyZScgICAgICAgICAgOiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnd2hlcmUnICA6ICdyaWdodCcsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnanFfbm9kZSc6IGpxX25vZGVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcclxuXHRcdHdwYmNfaGlnaGxpZ2h0X2Vycm9yX29uX2Zvcm1fZmllbGQoIGpxX25vZGUgKTtcclxuXHRcdHJldHVybiBub3RpY2VfbWVzc2FnZV9pZDtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBXYXJuaW5nIG1lc3NhZ2UgVU5ERVIgZWxlbWVudC4gXHRQcmVzZXQgb2YgcGFyYW1ldGVycyBmb3IgcmVhbCBtZXNzYWdlIGZ1bmN0aW9uLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGVsXHRcdC0gYW55IGpRdWVyeSBub2RlIGRlZmluaXRpb25cclxuXHQgKiBAcGFyYW0gbWVzc2FnZVx0LSBNZXNzYWdlIEhUTUxcclxuXHQgKiBAcmV0dXJucyBzdHJpbmcgIC0gSFRNTCBJRFx0XHRvciAwIGlmIG5vdCBzaG93aW5nIGR1cmluZyB0aGlzIHRpbWUuXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZV9fd2FybmluZ191bmRlcl9lbGVtZW50KCBqcV9ub2RlLCBtZXNzYWdlICl7XHJcblxyXG5cdFx0dmFyIG5vdGljZV9tZXNzYWdlX2lkID0gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZShcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtZXNzYWdlLF
3411xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0eXBlJyAgICAgICAgICAgICAgIDogJ3dhcm5pbmcnLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICAgICAgICAgICAgOiAxMDAwMCxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdpZl92aXNpYmxlX25vdF9zaG93JzogdHJ1ZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdzaG93X2hlcmUnICAgICAgICAgIDoge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3doZXJlJyAgOiAnYWZ0ZXInLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2pxX25vZGUnOiBqcV9ub2RlXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICAgfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCk7XHJcblx0XHRyZXR1cm4gbm90aWNlX21lc3NhZ2VfaWQ7XHJcblx0fVxyXG5cclxuXHJcblx0LyoqXHJcblx0ICogV2FybmluZyBtZXNzYWdlIEFCT1ZFIGVsZW1lbnQuIFx0UHJlc2V0IG9mIHBhcmFtZXRlcnMgZm9yIHJlYWwgbWVzc2FnZSBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBlbFx0XHQtIGFueSBqUXVlcnkgbm9kZSBkZWZpbml0aW9uXHJcblx0ICogQHBhcmFtIG1lc3NhZ2VcdC0gTWVzc2FnZSBIVE1MXHJcblx0ICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2VfX3dhcm5pbmdfYWJvdmVfZWxlbWVudCgganFfbm9kZSwgbWVzc2FnZSApe1xyXG5cclxuXHRcdHZhciBub3RpY2VfbWVzc2FnZV9pZCA9IHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2UoXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWVzc2FnZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndHlwZScgICAgICAgICAgICAgICA6ICd3YXJuaW5nJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdkZWxheScgICAgICAgICAgICAgIDogMTAwMDAsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IHRydWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJyAgICAgICAgICA6IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd3aGVyZScgIDogJ2JlZm9yZScsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnanFfbm9kZSc6IGpxX25vZGVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcclxuXHRcdHJldHVybiBub3RpY2VfbWVzc2FnZV9pZDtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEhpZ2hsaWdodCBFcnJvciBpbiBzcGVjaWZpYyBmaWVsZFxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGpxX25vZGVcdFx0XHRcdFx0c3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LCAgd2hlcmUgc2Nyb2xsICB0b1xyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfaGlnaGxpZ2h0X2Vycm9yX29uX2Zvcm1fZmllbGQoIGpxX25vZGUgKXtcclxuXHJcblx0XHRpZiAoICFqUXVlcnkoIGpxX25vZGUgKS5sZW5ndGggKXtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCAhIGpRdWVyeSgganFfbm9kZSApLmlzKCAnOmlucHV0JyApICl7XHJcblx0XHRcdC8vIFNpdHVhdGlvbiB3aXRoICBjaGVja2JveGVzIG9yIHJhZGlvICBidXR0b25zXHJcblx0XHRcdHZhciBqcV9ub2RlX2FyciA9IGpRdWVyeSgganFfbm9kZSApLmZpbmQoICc6aW5wdXQnICk7XHJcblx0XHRcdGlmICggIWpxX25vZGVfYXJyLmxlbmd0aCApe1xyXG5cdFx0XHRcdHJldHVyblxyXG5cdFx0XHR9XHJcblx0XHRcdGpxX25vZGUgPSBqcV9ub2RlX2Fyci5nZXQoIDAgKTtcclxuXHRcdH1cclxuXHRcdHZhciBwYXJhbXMgPSB7fTtcclxuXHRcdHBhcmFtc1sgJ2RlbGF5JyBdID0gMTAwMDA7XHJcblxyXG5cdFx0aWYgKCAhalF1ZXJ5KCBqcV9ub2RlICkuaGFzQ2xhc3MoICd3cGJjX2Zvcm1fZmllbGRfZXJyb3InICkgKXtcclxuXHJcblx0XHRcdGpRdWVyeSgganFfbm9kZSApLmFkZENsYXNzKCAnd3BiY19mb3JtX2ZpZWxkX2Vycm9yJyApXHJcblxyXG5cdFx0XHRpZiAoIHBhcnNlSW50KCBwYXJhbXNbICdkZWxheScgXSApID4gMCApe1xyXG5cdFx0XHRcdHZhciBjbG9zZWRfdGltZXIgPSBzZXRUaW1lb3V0KCBmdW5jdGlvbiAoKXtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IGpRdWVyeSgganFfbm9kZSApLnJlbW92ZUNsYXNzKCAnd3BiY19mb3JtX2ZpZWxkX2Vycm9yJyApO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICAsIHBhcnNlSW50KCBwYXJhbXNbICdkZWxheScgXSApXHJcblx0XHRcdFx0XHRcdFx0XHRcdCk7XHJcblxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuLyoqXHJcbiAqIFNjcm9sbCB0byBzcGVjaWZpYyBlbGVtZW50XHJcbiAqXHJcbiAqIEBwYXJhbSBqcV9ub2RlXHRcdFx0XHRcdHN0cmluZyBvciBqUXVlcnkgZWxlbWVudCwgIHdoZXJlIHNjcm9sbCAgdG9cclxuICogQHBhcmFtIGV4dHJhX3NoaWZ0X29mZnNldFx0XHRpbnQgc2hpZnQgb2Zmc2V0IGZyb20gIGpxX25vZGVcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfZG9fc2Nyb2xsKCBqcV9ub2RlICwgZXh0cmFfc2hpZnRfb2Zmc2V0ID0gMCApe1xyXG5cclxuXHRpZiAoICFqUXVlcnkoIGpxX25vZGUgKS5sZW5ndGggKXtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0dmFyIHRhcmdldE9mZnNldCA9IGpRdWVyeSgganFfbm9kZSApLm9mZnNldCgpLnRvcDtcclxuXHJcblx0aWYgKCB0YXJnZXRPZmZzZXQgPD0gMCApe1xyXG5cdFx0aWYgKCAwICE9IGpRdWVyeSgganFfbm9kZSApLm5leHRBbGwoICc6dmlzaWJsZScgKS5sZW5ndGggKXtcclxuXHRcdFx0dGFyZ2V0T2Zmc2V0ID0galF1ZXJ5KCBqcV9ub2RlICkubmV4dEFsbCggJzp2aXNpYmxlJyApLmZpcnN0KCkub2Zmc2V0KCkudG9wO1xyXG5cdFx0fSBlbHNlIGlmICggMCAhPSBqUXVlcnkoIGpxX25vZGUgKS5wYXJlbnQoKS5uZXh0QWxsKCAnOnZpc2libGUnICkubGVuZ3RoICl7XHJcblx0XHRcdHRhcmdldE9mZnNldCA9IGpRdWVyeSgganFfbm9kZSApLnBhcmVudCgpLm5leHRBbGwoICc6dmlzaWJsZScgKS5maXJzdCgpLm9mZnNldCgpLnRvcDtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGlmICggalF1ZXJ5KCAnI3dwYWRtaW5iYXInICkubGVuZ3RoID4gMCApe1xyXG5cdFx0dGFyZ2V0T2Zmc2V0ID0gdGFyZ2V0T2Zmc2V0IC0gNTAgLSA1MDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0dGFyZ2V0T2Zmc2V0ID0gdGFyZ2V0T2Zmc2V0IC0gMjAgLSA1MDtcclxuXHR9XHJcblx0dGFyZ2V0T2Zmc2V0ICs9IGV4dHJhX3NoaWZ0X29mZnNldDtcclxuXHJcblx0Ly8gU2Nyb2xsIG9ubHkgIGlmIHdlIGRpZCBub3Qgc2Nyb2xsIGJlZm9yZVxyXG5cdGlmICggISBqUXVlcnkoICdodG1sLGJvZHknICkuaXMoICc6YW5pbWF0ZWQnICkgKXtcclxuXHRcdGpRdWVyeSggJ2h0bWwsYm9keScgKS5hbmltYXRlKCB7c2Nyb2xsVG9wOiB0YXJnZXRPZmZzZXR9LCA1MDAgKTtcclxuXHR9XHJcbn1cclxuXHJcbiIsIlxyXG4vLyBGaXhJbjogMTAuMi4wLjQuXHJcbi8qKlxyXG4gKiBEZWZpbmUgUG9wb3ZlcnMgZm9yIFRpbWVsaW5lcyBpbiBXUCBCb29raW5nIENhbGVuZGFyXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd8Ym9vbGVhbn1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfZGVmaW5lX3RpcHB5X3BvcG92ZXIoKXtcclxuXHRpZiAoICdmdW5jdGlvbicgIT09I
3411HR5cGVvZiAod3BiY190aXBweSkgKXtcclxuXHRcdGNvbnNvbGUubG9nKCAnV1BCQyBFcnJvci4gd3BiY190aXBweSB3YXMgbm90IGRlZmluZWQuJyApO1xyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHR3cGJjX3RpcHB5KCAnLnBvcG92ZXJfYm90dG9tLnBvcG92ZXJfY2xpY2snLCB7XHJcblx0XHRjb250ZW50KCByZWZlcmVuY2UgKXtcclxuXHRcdFx0dmFyIHBvcG92ZXJfdGl0bGUgPSByZWZlcmVuY2UuZ2V0QXR0cmlidXRlKCAnZGF0YS1vcmlnaW5hbC10aXRsZScgKTtcclxuXHRcdFx0dmFyIHBvcG92ZXJfY29udGVudCA9IHJlZmVyZW5jZS5nZXRBdHRyaWJ1dGUoICdkYXRhLWNvbnRlbnQnICk7XHJcblx0XHRcdHJldHVybiAnPGRpdiBjbGFzcz1cInBvcG92ZXIgcG9wb3Zlcl90aXBweVwiPidcclxuXHRcdFx0XHQrICc8ZGl2IGNsYXNzPVwicG9wb3Zlci1jbG9zZVwiPjxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMClcIiBvbmNsaWNrPVwiamF2YXNjcmlwdDp0aGlzLnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudC5fdGlwcHkuaGlkZSgpO1wiID4mdGltZXM7PC9hPjwvZGl2PidcclxuXHRcdFx0XHQrIHBvcG92ZXJfY29udGVudFxyXG5cdFx0XHRcdCsgJzwvZGl2Pic7XHJcblx0XHR9LFxyXG5cdFx0YWxsb3dIVE1MICAgICAgICA6IHRydWUsXHJcblx0XHR0cmlnZ2VyICAgICAgICAgIDogJ21hbnVhbCcsXHJcblx0XHRpbnRlcmFjdGl2ZSAgICAgIDogdHJ1ZSxcclxuXHRcdGhpZGVPbkNsaWNrICAgICAgOiBmYWxzZSxcclxuXHRcdGludGVyYWN0aXZlQm9yZGVyOiAxMCxcclxuXHRcdG1heFdpZHRoICAgICAgICAgOiA1NTAsXHJcblx0XHR0aGVtZSAgICAgICAgICAgIDogJ3dwYmMtdGlwcHktcG9wb3ZlcicsXHJcblx0XHRwbGFjZW1lbnQgICAgICAgIDogJ2JvdHRvbS1zdGFydCcsXHJcblx0XHR0b3VjaCAgICAgICAgICAgIDogWydob2xkJywgNTAwXSxcclxuXHR9ICk7XHJcblx0alF1ZXJ5KCAnLnBvcG92ZXJfYm90dG9tLnBvcG92ZXJfY2xpY2snICkub24oICdjbGljaycsIGZ1bmN0aW9uICgpe1xyXG5cdFx0aWYgKCB0aGlzLl90
3411aXBweS5zdGF0ZS5pc1Zpc2libGUgKXtcclxuXHRcdFx0dGhpcy5fdGlwcHkuaGlkZSgpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5fdGlwcHkuc2hvdygpO1xyXG5cdFx0fVxyXG5cdH0gKTtcclxuXHR3cGJjX2RlZmluZV9oaWRlX3RpcHB5X29uX3Njcm9sbCgpO1xyXG59XHJcblxyXG5cclxuXHJcbmZ1bmN0aW9uIHdwYmNfZGVmaW5lX2hpZGVfdGlwcHlfb25fc2Nyb2xsKCl7XHJcblx0alF1ZXJ5KCAnLmZsZXhfdGxfX3Njcm9sbGluZ19zZWN0aW9uMiwuZmxleF90bF9fc2Nyb2xsaW5nX3NlY3Rpb25zJyApLm9uKCAnc2Nyb2xsJywgZnVuY3Rpb24gKCBldmVudCApe1xyXG5cdFx0aWYgKCAnZnVuY3Rpb24nID09PSB0eXBlb2YgKHdwYmNfdGlwcHkpICl7XHJcblx0XHRcdHdwYmNfdGlwcHkuaGlkZUFsbCgpO1xyXG5cdFx0fVxyXG5cdH0gKTtcclxufVxyXG4iXSwibWFwcGluZ3MiOiI7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBQUEsVUFBQUMsY0FBQTtFQUVBLElBQUFDLEtBQUEsQ0FBQUMsT0FBQSxDQUFBRixjQUFBO0lBQ0FBLGNBQUEsR0FBQUEsY0FBQSxDQUFBRyxJQUFBO0VBQ0E7RUFFQSx1QkFBQUgsY0FBQTtJQUNBQSxjQUFBLEdBQUFBLGNBQUEsQ0FBQUksSUFBQTtFQUNBO0VBRUEsT0FBQUosY0FBQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBQUssY0FBQUMsVUFBQSxFQUFBQyxLQUFBO0VBQ0EsU0FBQUMsQ0FBQSxNQUFBQyxDQUFBLEdBQUFILFVBQUEsQ0FBQUksTUFBQSxFQUFBRixDQUFBLEdBQUFDLENBQUEsRUFBQUQsQ0FBQTtJQUNBLElBQUFGLFVBQUEsQ0FBQUUsQ0FBQSxLQUFBRCxLQUFBO01BQ0E7SUFDQTtFQUNBO0VBQ0E7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
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.