PageSourceSearch

https://www.ismonnet.edu.it/jmedu/wp-content/plugins/booking/_dist/all/_out/wpbc_all.js?ver=10.14.9

js ismonnet.edu.it collected 2026-10-08 09:19:16 UTC 498,613 bytes, 3,789 lines download raw bytes

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