add serve as dev dependency
[apps/outliner/.git] / public / assets / bundle.js
1 /******/ (() => { // webpackBootstrap
2 /******/        var __webpack_modules__ = ({
3
4 /***/ "./node_modules/keyboardjs/dist/keyboard.js":
5 /*!**************************************************!*\
6   !*** ./node_modules/keyboardjs/dist/keyboard.js ***!
7   \**************************************************/
8 /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
9
10 (function (global, factory) {
11    true ? module.exports = factory() :
12   0;
13 }(this, (function () { 'use strict';
14
15   function _typeof(obj) {
16     "@babel/helpers - typeof";
17
18     if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
19       _typeof = function (obj) {
20         return typeof obj;
21       };
22     } else {
23       _typeof = function (obj) {
24         return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
25       };
26     }
27
28     return _typeof(obj);
29   }
30
31   function _classCallCheck(instance, Constructor) {
32     if (!(instance instanceof Constructor)) {
33       throw new TypeError("Cannot call a class as a function");
34     }
35   }
36
37   function _defineProperties(target, props) {
38     for (var i = 0; i < props.length; i++) {
39       var descriptor = props[i];
40       descriptor.enumerable = descriptor.enumerable || false;
41       descriptor.configurable = true;
42       if ("value" in descriptor) descriptor.writable = true;
43       Object.defineProperty(target, descriptor.key, descriptor);
44     }
45   }
46
47   function _createClass(Constructor, protoProps, staticProps) {
48     if (protoProps) _defineProperties(Constructor.prototype, protoProps);
49     if (staticProps) _defineProperties(Constructor, staticProps);
50     return Constructor;
51   }
52
53   function _toConsumableArray(arr) {
54     return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
55   }
56
57   function _arrayWithoutHoles(arr) {
58     if (Array.isArray(arr)) return _arrayLikeToArray(arr);
59   }
60
61   function _iterableToArray(iter) {
62     if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
63   }
64
65   function _unsupportedIterableToArray(o, minLen) {
66     if (!o) return;
67     if (typeof o === "string") return _arrayLikeToArray(o, minLen);
68     var n = Object.prototype.toString.call(o).slice(8, -1);
69     if (n === "Object" && o.constructor) n = o.constructor.name;
70     if (n === "Map" || n === "Set") return Array.from(o);
71     if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
72   }
73
74   function _arrayLikeToArray(arr, len) {
75     if (len == null || len > arr.length) len = arr.length;
76
77     for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
78
79     return arr2;
80   }
81
82   function _nonIterableSpread() {
83     throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
84   }
85
86   var KeyCombo = /*#__PURE__*/function () {
87     function KeyCombo(keyComboStr) {
88       _classCallCheck(this, KeyCombo);
89
90       this.sourceStr = keyComboStr;
91       this.subCombos = KeyCombo.parseComboStr(keyComboStr);
92       this.keyNames = this.subCombos.reduce(function (memo, nextSubCombo) {
93         return memo.concat(nextSubCombo);
94       }, []);
95     }
96
97     _createClass(KeyCombo, [{
98       key: "check",
99       value: function check(pressedKeyNames) {
100         var startingKeyNameIndex = 0;
101
102         for (var i = 0; i < this.subCombos.length; i += 1) {
103           startingKeyNameIndex = this._checkSubCombo(this.subCombos[i], startingKeyNameIndex, pressedKeyNames);
104
105           if (startingKeyNameIndex === -1) {
106             return false;
107           }
108         }
109
110         return true;
111       }
112     }, {
113       key: "isEqual",
114       value: function isEqual(otherKeyCombo) {
115         if (!otherKeyCombo || typeof otherKeyCombo !== 'string' && _typeof(otherKeyCombo) !== 'object') {
116           return false;
117         }
118
119         if (typeof otherKeyCombo === 'string') {
120           otherKeyCombo = new KeyCombo(otherKeyCombo);
121         }
122
123         if (this.subCombos.length !== otherKeyCombo.subCombos.length) {
124           return false;
125         }
126
127         for (var i = 0; i < this.subCombos.length; i += 1) {
128           if (this.subCombos[i].length !== otherKeyCombo.subCombos[i].length) {
129             return false;
130           }
131         }
132
133         for (var _i = 0; _i < this.subCombos.length; _i += 1) {
134           var subCombo = this.subCombos[_i];
135
136           var otherSubCombo = otherKeyCombo.subCombos[_i].slice(0);
137
138           for (var j = 0; j < subCombo.length; j += 1) {
139             var keyName = subCombo[j];
140             var index = otherSubCombo.indexOf(keyName);
141
142             if (index > -1) {
143               otherSubCombo.splice(index, 1);
144             }
145           }
146
147           if (otherSubCombo.length !== 0) {
148             return false;
149           }
150         }
151
152         return true;
153       }
154     }, {
155       key: "_checkSubCombo",
156       value: function _checkSubCombo(subCombo, startingKeyNameIndex, pressedKeyNames) {
157         subCombo = subCombo.slice(0);
158         pressedKeyNames = pressedKeyNames.slice(startingKeyNameIndex);
159         var endIndex = startingKeyNameIndex;
160
161         for (var i = 0; i < subCombo.length; i += 1) {
162           var keyName = subCombo[i];
163
164           if (keyName[0] === '\\') {
165             var escapedKeyName = keyName.slice(1);
166
167             if (escapedKeyName === KeyCombo.comboDeliminator || escapedKeyName === KeyCombo.keyDeliminator) {
168               keyName = escapedKeyName;
169             }
170           }
171
172           var index = pressedKeyNames.indexOf(keyName);
173
174           if (index > -1) {
175             subCombo.splice(i, 1);
176             i -= 1;
177
178             if (index > endIndex) {
179               endIndex = index;
180             }
181
182             if (subCombo.length === 0) {
183               return endIndex;
184             }
185           }
186         }
187
188         return -1;
189       }
190     }]);
191
192     return KeyCombo;
193   }();
194   KeyCombo.comboDeliminator = '>';
195   KeyCombo.keyDeliminator = '+';
196
197   KeyCombo.parseComboStr = function (keyComboStr) {
198     var subComboStrs = KeyCombo._splitStr(keyComboStr, KeyCombo.comboDeliminator);
199
200     var combo = [];
201
202     for (var i = 0; i < subComboStrs.length; i += 1) {
203       combo.push(KeyCombo._splitStr(subComboStrs[i], KeyCombo.keyDeliminator));
204     }
205
206     return combo;
207   };
208
209   KeyCombo._splitStr = function (str, deliminator) {
210     var s = str;
211     var d = deliminator;
212     var c = '';
213     var ca = [];
214
215     for (var ci = 0; ci < s.length; ci += 1) {
216       if (ci > 0 && s[ci] === d && s[ci - 1] !== '\\') {
217         ca.push(c.trim());
218         c = '';
219         ci += 1;
220       }
221
222       c += s[ci];
223     }
224
225     if (c) {
226       ca.push(c.trim());
227     }
228
229     return ca;
230   };
231
232   var Locale = /*#__PURE__*/function () {
233     function Locale(name) {
234       _classCallCheck(this, Locale);
235
236       this.localeName = name;
237       this.activeTargetKeys = [];
238       this.pressedKeys = [];
239       this._appliedMacros = [];
240       this._keyMap = {};
241       this._killKeyCodes = [];
242       this._macros = [];
243     }
244
245     _createClass(Locale, [{
246       key: "bindKeyCode",
247       value: function bindKeyCode(keyCode, keyNames) {
248         if (typeof keyNames === 'string') {
249           keyNames = [keyNames];
250         }
251
252         this._keyMap[keyCode] = keyNames;
253       }
254     }, {
255       key: "bindMacro",
256       value: function bindMacro(keyComboStr, keyNames) {
257         if (typeof keyNames === 'string') {
258           keyNames = [keyNames];
259         }
260
261         var handler = null;
262
263         if (typeof keyNames === 'function') {
264           handler = keyNames;
265           keyNames = null;
266         }
267
268         var macro = {
269           keyCombo: new KeyCombo(keyComboStr),
270           keyNames: keyNames,
271           handler: handler
272         };
273
274         this._macros.push(macro);
275       }
276     }, {
277       key: "getKeyCodes",
278       value: function getKeyCodes(keyName) {
279         var keyCodes = [];
280
281         for (var keyCode in this._keyMap) {
282           var index = this._keyMap[keyCode].indexOf(keyName);
283
284           if (index > -1) {
285             keyCodes.push(keyCode | 0);
286           }
287         }
288
289         return keyCodes;
290       }
291     }, {
292       key: "getKeyNames",
293       value: function getKeyNames(keyCode) {
294         return this._keyMap[keyCode] || [];
295       }
296     }, {
297       key: "setKillKey",
298       value: function setKillKey(keyCode) {
299         if (typeof keyCode === 'string') {
300           var keyCodes = this.getKeyCodes(keyCode);
301
302           for (var i = 0; i < keyCodes.length; i += 1) {
303             this.setKillKey(keyCodes[i]);
304           }
305
306           return;
307         }
308
309         this._killKeyCodes.push(keyCode);
310       }
311     }, {
312       key: "pressKey",
313       value: function pressKey(keyCode) {
314         if (typeof keyCode === 'string') {
315           var keyCodes = this.getKeyCodes(keyCode);
316
317           for (var i = 0; i < keyCodes.length; i += 1) {
318             this.pressKey(keyCodes[i]);
319           }
320
321           return;
322         }
323
324         this.activeTargetKeys.length = 0;
325         var keyNames = this.getKeyNames(keyCode);
326
327         for (var _i = 0; _i < keyNames.length; _i += 1) {
328           this.activeTargetKeys.push(keyNames[_i]);
329
330           if (this.pressedKeys.indexOf(keyNames[_i]) === -1) {
331             this.pressedKeys.push(keyNames[_i]);
332           }
333         }
334
335         this._applyMacros();
336       }
337     }, {
338       key: "releaseKey",
339       value: function releaseKey(keyCode) {
340         if (typeof keyCode === 'string') {
341           var keyCodes = this.getKeyCodes(keyCode);
342
343           for (var i = 0; i < keyCodes.length; i += 1) {
344             this.releaseKey(keyCodes[i]);
345           }
346         } else {
347           var keyNames = this.getKeyNames(keyCode);
348
349           var killKeyCodeIndex = this._killKeyCodes.indexOf(keyCode);
350
351           if (killKeyCodeIndex !== -1) {
352             this.pressedKeys.length = 0;
353           } else {
354             for (var _i2 = 0; _i2 < keyNames.length; _i2 += 1) {
355               var index = this.pressedKeys.indexOf(keyNames[_i2]);
356
357               if (index > -1) {
358                 this.pressedKeys.splice(index, 1);
359               }
360             }
361           }
362
363           this.activeTargetKeys.length = 0;
364
365           this._clearMacros();
366         }
367       }
368     }, {
369       key: "_applyMacros",
370       value: function _applyMacros() {
371         var macros = this._macros.slice(0);
372
373         for (var i = 0; i < macros.length; i += 1) {
374           var macro = macros[i];
375
376           if (macro.keyCombo.check(this.pressedKeys)) {
377             if (macro.handler) {
378               macro.keyNames = macro.handler(this.pressedKeys);
379             }
380
381             for (var j = 0; j < macro.keyNames.length; j += 1) {
382               if (this.pressedKeys.indexOf(macro.keyNames[j]) === -1) {
383                 this.pressedKeys.push(macro.keyNames[j]);
384               }
385             }
386
387             this._appliedMacros.push(macro);
388           }
389         }
390       }
391     }, {
392       key: "_clearMacros",
393       value: function _clearMacros() {
394         for (var i = 0; i < this._appliedMacros.length; i += 1) {
395           var macro = this._appliedMacros[i];
396
397           if (!macro.keyCombo.check(this.pressedKeys)) {
398             for (var j = 0; j < macro.keyNames.length; j += 1) {
399               var index = this.pressedKeys.indexOf(macro.keyNames[j]);
400
401               if (index > -1) {
402                 this.pressedKeys.splice(index, 1);
403               }
404             }
405
406             if (macro.handler) {
407               macro.keyNames = null;
408             }
409
410             this._appliedMacros.splice(i, 1);
411
412             i -= 1;
413           }
414         }
415       }
416     }]);
417
418     return Locale;
419   }();
420
421   var Keyboard = /*#__PURE__*/function () {
422     function Keyboard(targetWindow, targetElement, targetPlatform, targetUserAgent) {
423       _classCallCheck(this, Keyboard);
424
425       this._locale = null;
426       this._currentContext = '';
427       this._contexts = {};
428       this._listeners = [];
429       this._appliedListeners = [];
430       this._locales = {};
431       this._targetElement = null;
432       this._targetWindow = null;
433       this._targetPlatform = '';
434       this._targetUserAgent = '';
435       this._isModernBrowser = false;
436       this._targetKeyDownBinding = null;
437       this._targetKeyUpBinding = null;
438       this._targetResetBinding = null;
439       this._paused = false;
440       this._contexts.global = {
441         listeners: this._listeners,
442         targetWindow: targetWindow,
443         targetElement: targetElement,
444         targetPlatform: targetPlatform,
445         targetUserAgent: targetUserAgent
446       };
447       this.setContext('global');
448     }
449
450     _createClass(Keyboard, [{
451       key: "setLocale",
452       value: function setLocale(localeName, localeBuilder) {
453         var locale = null;
454
455         if (typeof localeName === 'string') {
456           if (localeBuilder) {
457             locale = new Locale(localeName);
458             localeBuilder(locale, this._targetPlatform, this._targetUserAgent);
459           } else {
460             locale = this._locales[localeName] || null;
461           }
462         } else {
463           locale = localeName;
464           localeName = locale._localeName;
465         }
466
467         this._locale = locale;
468         this._locales[localeName] = locale;
469
470         if (locale) {
471           this._locale.pressedKeys = locale.pressedKeys;
472         }
473
474         return this;
475       }
476     }, {
477       key: "getLocale",
478       value: function getLocale(localName) {
479         localName || (localName = this._locale.localeName);
480         return this._locales[localName] || null;
481       }
482     }, {
483       key: "bind",
484       value: function bind(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault) {
485         if (keyComboStr === null || typeof keyComboStr === 'function') {
486           preventRepeatByDefault = releaseHandler;
487           releaseHandler = pressHandler;
488           pressHandler = keyComboStr;
489           keyComboStr = null;
490         }
491
492         if (keyComboStr && _typeof(keyComboStr) === 'object' && typeof keyComboStr.length === 'number') {
493           for (var i = 0; i < keyComboStr.length; i += 1) {
494             this.bind(keyComboStr[i], pressHandler, releaseHandler);
495           }
496
497           return this;
498         }
499
500         this._listeners.push({
501           keyCombo: keyComboStr ? new KeyCombo(keyComboStr) : null,
502           pressHandler: pressHandler || null,
503           releaseHandler: releaseHandler || null,
504           preventRepeat: false,
505           preventRepeatByDefault: preventRepeatByDefault || false,
506           executingHandler: false
507         });
508
509         return this;
510       }
511     }, {
512       key: "addListener",
513       value: function addListener(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault) {
514         return this.bind(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault);
515       }
516     }, {
517       key: "on",
518       value: function on(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault) {
519         return this.bind(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault);
520       }
521     }, {
522       key: "bindPress",
523       value: function bindPress(keyComboStr, pressHandler, preventRepeatByDefault) {
524         return this.bind(keyComboStr, pressHandler, null, preventRepeatByDefault);
525       }
526     }, {
527       key: "bindRelease",
528       value: function bindRelease(keyComboStr, releaseHandler) {
529         return this.bind(keyComboStr, null, releaseHandler, preventRepeatByDefault);
530       }
531     }, {
532       key: "unbind",
533       value: function unbind(keyComboStr, pressHandler, releaseHandler) {
534         if (keyComboStr === null || typeof keyComboStr === 'function') {
535           releaseHandler = pressHandler;
536           pressHandler = keyComboStr;
537           keyComboStr = null;
538         }
539
540         if (keyComboStr && _typeof(keyComboStr) === 'object' && typeof keyComboStr.length === 'number') {
541           for (var i = 0; i < keyComboStr.length; i += 1) {
542             this.unbind(keyComboStr[i], pressHandler, releaseHandler);
543           }
544
545           return this;
546         }
547
548         for (var _i = 0; _i < this._listeners.length; _i += 1) {
549           var listener = this._listeners[_i];
550           var comboMatches = !keyComboStr && !listener.keyCombo || listener.keyCombo && listener.keyCombo.isEqual(keyComboStr);
551           var pressHandlerMatches = !pressHandler && !releaseHandler || !pressHandler && !listener.pressHandler || pressHandler === listener.pressHandler;
552           var releaseHandlerMatches = !pressHandler && !releaseHandler || !releaseHandler && !listener.releaseHandler || releaseHandler === listener.releaseHandler;
553
554           if (comboMatches && pressHandlerMatches && releaseHandlerMatches) {
555             this._listeners.splice(_i, 1);
556
557             _i -= 1;
558           }
559         }
560
561         return this;
562       }
563     }, {
564       key: "removeListener",
565       value: function removeListener(keyComboStr, pressHandler, releaseHandler) {
566         return this.unbind(keyComboStr, pressHandler, releaseHandler);
567       }
568     }, {
569       key: "off",
570       value: function off(keyComboStr, pressHandler, releaseHandler) {
571         return this.unbind(keyComboStr, pressHandler, releaseHandler);
572       }
573     }, {
574       key: "setContext",
575       value: function setContext(contextName) {
576         if (this._locale) {
577           this.releaseAllKeys();
578         }
579
580         if (!this._contexts[contextName]) {
581           var globalContext = this._contexts.global;
582           this._contexts[contextName] = {
583             listeners: [],
584             targetWindow: globalContext.targetWindow,
585             targetElement: globalContext.targetElement,
586             targetPlatform: globalContext.targetPlatform,
587             targetUserAgent: globalContext.targetUserAgent
588           };
589         }
590
591         var context = this._contexts[contextName];
592         this._currentContext = contextName;
593         this._listeners = context.listeners;
594         this.stop();
595         this.watch(context.targetWindow, context.targetElement, context.targetPlatform, context.targetUserAgent);
596         return this;
597       }
598     }, {
599       key: "getContext",
600       value: function getContext() {
601         return this._currentContext;
602       }
603     }, {
604       key: "withContext",
605       value: function withContext(contextName, callback) {
606         var previousContextName = this.getContext();
607         this.setContext(contextName);
608         callback();
609         this.setContext(previousContextName);
610         return this;
611       }
612     }, {
613       key: "watch",
614       value: function watch(targetWindow, targetElement, targetPlatform, targetUserAgent) {
615         var _this = this;
616
617         this.stop();
618         var win = typeof globalThis !== 'undefined' ? globalThis : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof window !== 'undefined' ? window : {};
619
620         if (!targetWindow) {
621           if (!win.addEventListener && !win.attachEvent) {
622             // This was added so when using things like JSDOM watch can be used to configure watch
623             // for the global namespace manually.
624             if (this._currentContext === 'global') {
625               return;
626             }
627
628             throw new Error('Cannot find window functions addEventListener or attachEvent.');
629           }
630
631           targetWindow = win;
632         } // Handle element bindings where a target window is not passed
633
634
635         if (typeof targetWindow.nodeType === 'number') {
636           targetUserAgent = targetPlatform;
637           targetPlatform = targetElement;
638           targetElement = targetWindow;
639           targetWindow = win;
640         }
641
642         if (!targetWindow.addEventListener && !targetWindow.attachEvent) {
643           throw new Error('Cannot find addEventListener or attachEvent methods on targetWindow.');
644         }
645
646         this._isModernBrowser = !!targetWindow.addEventListener;
647         var userAgent = targetWindow.navigator && targetWindow.navigator.userAgent || '';
648         var platform = targetWindow.navigator && targetWindow.navigator.platform || '';
649         targetElement && targetElement !== null || (targetElement = targetWindow.document);
650         targetPlatform && targetPlatform !== null || (targetPlatform = platform);
651         targetUserAgent && targetUserAgent !== null || (targetUserAgent = userAgent);
652
653         this._targetKeyDownBinding = function (event) {
654           _this.pressKey(event.keyCode, event);
655
656           _this._handleCommandBug(event, platform);
657         };
658
659         this._targetKeyUpBinding = function (event) {
660           _this.releaseKey(event.keyCode, event);
661         };
662
663         this._targetResetBinding = function (event) {
664           _this.releaseAllKeys(event);
665         };
666
667         this._bindEvent(targetElement, 'keydown', this._targetKeyDownBinding);
668
669         this._bindEvent(targetElement, 'keyup', this._targetKeyUpBinding);
670
671         this._bindEvent(targetWindow, 'focus', this._targetResetBinding);
672
673         this._bindEvent(targetWindow, 'blur', this._targetResetBinding);
674
675         this._targetElement = targetElement;
676         this._targetWindow = targetWindow;
677         this._targetPlatform = targetPlatform;
678         this._targetUserAgent = targetUserAgent;
679         var currentContext = this._contexts[this._currentContext];
680         currentContext.targetWindow = this._targetWindow;
681         currentContext.targetElement = this._targetElement;
682         currentContext.targetPlatform = this._targetPlatform;
683         currentContext.targetUserAgent = this._targetUserAgent;
684         return this;
685       }
686     }, {
687       key: "stop",
688       value: function stop() {
689         if (!this._targetElement || !this._targetWindow) {
690           return;
691         }
692
693         this._unbindEvent(this._targetElement, 'keydown', this._targetKeyDownBinding);
694
695         this._unbindEvent(this._targetElement, 'keyup', this._targetKeyUpBinding);
696
697         this._unbindEvent(this._targetWindow, 'focus', this._targetResetBinding);
698
699         this._unbindEvent(this._targetWindow, 'blur', this._targetResetBinding);
700
701         this._targetWindow = null;
702         this._targetElement = null;
703         return this;
704       }
705     }, {
706       key: "pressKey",
707       value: function pressKey(keyCode, event) {
708         if (this._paused) {
709           return this;
710         }
711
712         if (!this._locale) {
713           throw new Error('Locale not set');
714         }
715
716         this._locale.pressKey(keyCode);
717
718         this._applyBindings(event);
719
720         return this;
721       }
722     }, {
723       key: "releaseKey",
724       value: function releaseKey(keyCode, event) {
725         if (this._paused) {
726           return this;
727         }
728
729         if (!this._locale) {
730           throw new Error('Locale not set');
731         }
732
733         this._locale.releaseKey(keyCode);
734
735         this._clearBindings(event);
736
737         return this;
738       }
739     }, {
740       key: "releaseAllKeys",
741       value: function releaseAllKeys(event) {
742         if (this._paused) {
743           return this;
744         }
745
746         if (!this._locale) {
747           throw new Error('Locale not set');
748         }
749
750         this._locale.pressedKeys.length = 0;
751
752         this._clearBindings(event);
753
754         return this;
755       }
756     }, {
757       key: "pause",
758       value: function pause() {
759         if (this._paused) {
760           return this;
761         }
762
763         if (this._locale) {
764           this.releaseAllKeys();
765         }
766
767         this._paused = true;
768         return this;
769       }
770     }, {
771       key: "resume",
772       value: function resume() {
773         this._paused = false;
774         return this;
775       }
776     }, {
777       key: "reset",
778       value: function reset() {
779         this.releaseAllKeys();
780         this._listeners.length = 0;
781         return this;
782       }
783     }, {
784       key: "_bindEvent",
785       value: function _bindEvent(targetElement, eventName, handler) {
786         return this._isModernBrowser ? targetElement.addEventListener(eventName, handler, false) : targetElement.attachEvent('on' + eventName, handler);
787       }
788     }, {
789       key: "_unbindEvent",
790       value: function _unbindEvent(targetElement, eventName, handler) {
791         return this._isModernBrowser ? targetElement.removeEventListener(eventName, handler, false) : targetElement.detachEvent('on' + eventName, handler);
792       }
793     }, {
794       key: "_getGroupedListeners",
795       value: function _getGroupedListeners() {
796         var listenerGroups = [];
797         var listenerGroupMap = [];
798         var listeners = this._listeners;
799
800         if (this._currentContext !== 'global') {
801           listeners = [].concat(_toConsumableArray(listeners), _toConsumableArray(this._contexts.global.listeners));
802         }
803
804         listeners.sort(function (a, b) {
805           return (b.keyCombo ? b.keyCombo.keyNames.length : 0) - (a.keyCombo ? a.keyCombo.keyNames.length : 0);
806         }).forEach(function (l) {
807           var mapIndex = -1;
808
809           for (var i = 0; i < listenerGroupMap.length; i += 1) {
810             if (listenerGroupMap[i] === null && l.keyCombo === null || listenerGroupMap[i] !== null && listenerGroupMap[i].isEqual(l.keyCombo)) {
811               mapIndex = i;
812             }
813           }
814
815           if (mapIndex === -1) {
816             mapIndex = listenerGroupMap.length;
817             listenerGroupMap.push(l.keyCombo);
818           }
819
820           if (!listenerGroups[mapIndex]) {
821             listenerGroups[mapIndex] = [];
822           }
823
824           listenerGroups[mapIndex].push(l);
825         });
826         return listenerGroups;
827       }
828     }, {
829       key: "_applyBindings",
830       value: function _applyBindings(event) {
831         var _this2 = this;
832
833         var preventRepeat = false;
834         event || (event = {});
835
836         event.preventRepeat = function () {
837           preventRepeat = true;
838         };
839
840         event.pressedKeys = this._locale.pressedKeys.slice(0);
841         var activeTargetKeys = this._locale.activeTargetKeys;
842
843         var pressedKeys = this._locale.pressedKeys.slice(0);
844
845         var listenerGroups = this._getGroupedListeners();
846
847         var _loop = function _loop(i) {
848           var listeners = listenerGroups[i];
849           var keyCombo = listeners[0].keyCombo;
850
851           if (keyCombo === null || keyCombo.check(pressedKeys) && activeTargetKeys.some(function (k) {
852             return keyCombo.keyNames.includes(k);
853           })) {
854             for (var j = 0; j < listeners.length; j += 1) {
855               var listener = listeners[j];
856
857               if (!listener.executingHandler && listener.pressHandler && !listener.preventRepeat) {
858                 listener.executingHandler = true;
859                 listener.pressHandler.call(_this2, event);
860                 listener.executingHandler = false;
861
862                 if (preventRepeat || listener.preventRepeatByDefault) {
863                   listener.preventRepeat = true;
864                   preventRepeat = false;
865                 }
866               }
867
868               if (_this2._appliedListeners.indexOf(listener) === -1) {
869                 _this2._appliedListeners.push(listener);
870               }
871             }
872
873             if (keyCombo) {
874               for (var _j = 0; _j < keyCombo.keyNames.length; _j += 1) {
875                 var index = pressedKeys.indexOf(keyCombo.keyNames[_j]);
876
877                 if (index !== -1) {
878                   pressedKeys.splice(index, 1);
879                   _j -= 1;
880                 }
881               }
882             }
883           }
884         };
885
886         for (var i = 0; i < listenerGroups.length; i += 1) {
887           _loop(i);
888         }
889       }
890     }, {
891       key: "_clearBindings",
892       value: function _clearBindings(event) {
893         event || (event = {});
894         event.pressedKeys = this._locale.pressedKeys.slice(0);
895
896         for (var i = 0; i < this._appliedListeners.length; i += 1) {
897           var listener = this._appliedListeners[i];
898           var keyCombo = listener.keyCombo;
899
900           if (keyCombo === null || !keyCombo.check(this._locale.pressedKeys)) {
901             listener.preventRepeat = false;
902
903             if (keyCombo !== null || event.pressedKeys.length === 0) {
904               this._appliedListeners.splice(i, 1);
905
906               i -= 1;
907             }
908
909             if (!listener.executingHandler && listener.releaseHandler) {
910               listener.executingHandler = true;
911               listener.releaseHandler.call(this, event);
912               listener.executingHandler = false;
913             }
914           }
915         }
916       }
917     }, {
918       key: "_handleCommandBug",
919       value: function _handleCommandBug(event, platform) {
920         // On Mac when the command key is kept pressed, keyup is not triggered for any other key.
921         // In this case force a keyup for non-modifier keys directly after the keypress.
922         var modifierKeys = ["shift", "ctrl", "alt", "capslock", "tab", "command"];
923
924         if (platform.match("Mac") && this._locale.pressedKeys.includes("command") && !modifierKeys.includes(this._locale.getKeyNames(event.keyCode)[0])) {
925           this._targetKeyUpBinding(event);
926         }
927       }
928     }]);
929
930     return Keyboard;
931   }();
932
933   function us(locale, platform, userAgent) {
934     // general
935     locale.bindKeyCode(3, ['cancel']);
936     locale.bindKeyCode(8, ['backspace']);
937     locale.bindKeyCode(9, ['tab']);
938     locale.bindKeyCode(12, ['clear']);
939     locale.bindKeyCode(13, ['enter']);
940     locale.bindKeyCode(16, ['shift']);
941     locale.bindKeyCode(17, ['ctrl']);
942     locale.bindKeyCode(18, ['alt', 'menu']);
943     locale.bindKeyCode(19, ['pause', 'break']);
944     locale.bindKeyCode(20, ['capslock']);
945     locale.bindKeyCode(27, ['escape', 'esc']);
946     locale.bindKeyCode(32, ['space', 'spacebar']);
947     locale.bindKeyCode(33, ['pageup']);
948     locale.bindKeyCode(34, ['pagedown']);
949     locale.bindKeyCode(35, ['end']);
950     locale.bindKeyCode(36, ['home']);
951     locale.bindKeyCode(37, ['left']);
952     locale.bindKeyCode(38, ['up']);
953     locale.bindKeyCode(39, ['right']);
954     locale.bindKeyCode(40, ['down']);
955     locale.bindKeyCode(41, ['select']);
956     locale.bindKeyCode(42, ['printscreen']);
957     locale.bindKeyCode(43, ['execute']);
958     locale.bindKeyCode(44, ['snapshot']);
959     locale.bindKeyCode(45, ['insert', 'ins']);
960     locale.bindKeyCode(46, ['delete', 'del']);
961     locale.bindKeyCode(47, ['help']);
962     locale.bindKeyCode(145, ['scrolllock', 'scroll']);
963     locale.bindKeyCode(188, ['comma', ',']);
964     locale.bindKeyCode(190, ['period', '.']);
965     locale.bindKeyCode(191, ['slash', 'forwardslash', '/']);
966     locale.bindKeyCode(192, ['graveaccent', '`']);
967     locale.bindKeyCode(219, ['openbracket', '[']);
968     locale.bindKeyCode(220, ['backslash', '\\']);
969     locale.bindKeyCode(221, ['closebracket', ']']);
970     locale.bindKeyCode(222, ['apostrophe', '\'']); // 0-9
971
972     locale.bindKeyCode(48, ['zero', '0']);
973     locale.bindKeyCode(49, ['one', '1']);
974     locale.bindKeyCode(50, ['two', '2']);
975     locale.bindKeyCode(51, ['three', '3']);
976     locale.bindKeyCode(52, ['four', '4']);
977     locale.bindKeyCode(53, ['five', '5']);
978     locale.bindKeyCode(54, ['six', '6']);
979     locale.bindKeyCode(55, ['seven', '7']);
980     locale.bindKeyCode(56, ['eight', '8']);
981     locale.bindKeyCode(57, ['nine', '9']); // numpad
982
983     locale.bindKeyCode(96, ['numzero', 'num0']);
984     locale.bindKeyCode(97, ['numone', 'num1']);
985     locale.bindKeyCode(98, ['numtwo', 'num2']);
986     locale.bindKeyCode(99, ['numthree', 'num3']);
987     locale.bindKeyCode(100, ['numfour', 'num4']);
988     locale.bindKeyCode(101, ['numfive', 'num5']);
989     locale.bindKeyCode(102, ['numsix', 'num6']);
990     locale.bindKeyCode(103, ['numseven', 'num7']);
991     locale.bindKeyCode(104, ['numeight', 'num8']);
992     locale.bindKeyCode(105, ['numnine', 'num9']);
993     locale.bindKeyCode(106, ['nummultiply', 'num*']);
994     locale.bindKeyCode(107, ['numadd', 'num+']);
995     locale.bindKeyCode(108, ['numenter']);
996     locale.bindKeyCode(109, ['numsubtract', 'num-']);
997     locale.bindKeyCode(110, ['numdecimal', 'num.']);
998     locale.bindKeyCode(111, ['numdivide', 'num/']);
999     locale.bindKeyCode(144, ['numlock', 'num']); // function keys
1000
1001     locale.bindKeyCode(112, ['f1']);
1002     locale.bindKeyCode(113, ['f2']);
1003     locale.bindKeyCode(114, ['f3']);
1004     locale.bindKeyCode(115, ['f4']);
1005     locale.bindKeyCode(116, ['f5']);
1006     locale.bindKeyCode(117, ['f6']);
1007     locale.bindKeyCode(118, ['f7']);
1008     locale.bindKeyCode(119, ['f8']);
1009     locale.bindKeyCode(120, ['f9']);
1010     locale.bindKeyCode(121, ['f10']);
1011     locale.bindKeyCode(122, ['f11']);
1012     locale.bindKeyCode(123, ['f12']);
1013     locale.bindKeyCode(124, ['f13']);
1014     locale.bindKeyCode(125, ['f14']);
1015     locale.bindKeyCode(126, ['f15']);
1016     locale.bindKeyCode(127, ['f16']);
1017     locale.bindKeyCode(128, ['f17']);
1018     locale.bindKeyCode(129, ['f18']);
1019     locale.bindKeyCode(130, ['f19']);
1020     locale.bindKeyCode(131, ['f20']);
1021     locale.bindKeyCode(132, ['f21']);
1022     locale.bindKeyCode(133, ['f22']);
1023     locale.bindKeyCode(134, ['f23']);
1024     locale.bindKeyCode(135, ['f24']); // secondary key symbols
1025
1026     locale.bindMacro('shift + `', ['tilde', '~']);
1027     locale.bindMacro('shift + 1', ['exclamation', 'exclamationpoint', '!']);
1028     locale.bindMacro('shift + 2', ['at', '@']);
1029     locale.bindMacro('shift + 3', ['number', '#']);
1030     locale.bindMacro('shift + 4', ['dollar', 'dollars', 'dollarsign', '$']);
1031     locale.bindMacro('shift + 5', ['percent', '%']);
1032     locale.bindMacro('shift + 6', ['caret', '^']);
1033     locale.bindMacro('shift + 7', ['ampersand', 'and', '&']);
1034     locale.bindMacro('shift + 8', ['asterisk', '*']);
1035     locale.bindMacro('shift + 9', ['openparen', '(']);
1036     locale.bindMacro('shift + 0', ['closeparen', ')']);
1037     locale.bindMacro('shift + -', ['underscore', '_']);
1038     locale.bindMacro('shift + =', ['plus', '+']);
1039     locale.bindMacro('shift + [', ['opencurlybrace', 'opencurlybracket', '{']);
1040     locale.bindMacro('shift + ]', ['closecurlybrace', 'closecurlybracket', '}']);
1041     locale.bindMacro('shift + \\', ['verticalbar', '|']);
1042     locale.bindMacro('shift + ;', ['colon', ':']);
1043     locale.bindMacro('shift + \'', ['quotationmark', '\'']);
1044     locale.bindMacro('shift + !,', ['openanglebracket', '<']);
1045     locale.bindMacro('shift + .', ['closeanglebracket', '>']);
1046     locale.bindMacro('shift + /', ['questionmark', '?']);
1047
1048     if (platform.match('Mac')) {
1049       locale.bindMacro('command', ['mod', 'modifier']);
1050     } else {
1051       locale.bindMacro('ctrl', ['mod', 'modifier']);
1052     } //a-z and A-Z
1053
1054
1055     for (var keyCode = 65; keyCode <= 90; keyCode += 1) {
1056       var keyName = String.fromCharCode(keyCode + 32);
1057       var capitalKeyName = String.fromCharCode(keyCode);
1058       locale.bindKeyCode(keyCode, keyName);
1059       locale.bindMacro('shift + ' + keyName, capitalKeyName);
1060       locale.bindMacro('capslock + ' + keyName, capitalKeyName);
1061     } // browser caveats
1062
1063
1064     var semicolonKeyCode = userAgent.match('Firefox') ? 59 : 186;
1065     var dashKeyCode = userAgent.match('Firefox') ? 173 : 189;
1066     var equalKeyCode = userAgent.match('Firefox') ? 61 : 187;
1067     var leftCommandKeyCode;
1068     var rightCommandKeyCode;
1069
1070     if (platform.match('Mac') && (userAgent.match('Safari') || userAgent.match('Chrome'))) {
1071       leftCommandKeyCode = 91;
1072       rightCommandKeyCode = 93;
1073     } else if (platform.match('Mac') && userAgent.match('Opera')) {
1074       leftCommandKeyCode = 17;
1075       rightCommandKeyCode = 17;
1076     } else if (platform.match('Mac') && userAgent.match('Firefox')) {
1077       leftCommandKeyCode = 224;
1078       rightCommandKeyCode = 224;
1079     }
1080
1081     locale.bindKeyCode(semicolonKeyCode, ['semicolon', ';']);
1082     locale.bindKeyCode(dashKeyCode, ['dash', '-']);
1083     locale.bindKeyCode(equalKeyCode, ['equal', 'equalsign', '=']);
1084     locale.bindKeyCode(leftCommandKeyCode, ['command', 'windows', 'win', 'super', 'leftcommand', 'leftwindows', 'leftwin', 'leftsuper']);
1085     locale.bindKeyCode(rightCommandKeyCode, ['command', 'windows', 'win', 'super', 'rightcommand', 'rightwindows', 'rightwin', 'rightsuper']); // kill keys
1086
1087     locale.setKillKey('command');
1088   }
1089
1090   var keyboard = new Keyboard();
1091   keyboard.setLocale('us', us);
1092   keyboard.Keyboard = Keyboard;
1093   keyboard.Locale = Locale;
1094   keyboard.KeyCombo = KeyCombo;
1095
1096   return keyboard;
1097
1098 })));
1099 //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Ym9hcmQuanMiLCJzb3VyY2VzIjpbIi4uL2xpYi9rZXktY29tYm8uanMiLCIuLi9saWIvbG9jYWxlLmpzIiwiLi4vbGliL2tleWJvYXJkLmpzIiwiLi4vbG9jYWxlcy91cy5qcyIsIi4uL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlxuZXhwb3J0IGNsYXNzIEtleUNvbWJvIHtcbiAgY29uc3RydWN0b3Ioa2V5Q29tYm9TdHIpIHtcbiAgICB0aGlzLnNvdXJjZVN0ciA9IGtleUNvbWJvU3RyO1xuICAgIHRoaXMuc3ViQ29tYm9zID0gS2V5Q29tYm8ucGFyc2VDb21ib1N0cihrZXlDb21ib1N0cik7XG4gICAgdGhpcy5rZXlOYW1lcyAgPSB0aGlzLnN1YkNvbWJvcy5yZWR1Y2UoKG1lbW8sIG5leHRTdWJDb21ibykgPT5cbiAgICAgIG1lbW8uY29uY2F0KG5leHRTdWJDb21ibyksIFtdKTtcbiAgfVxuXG4gIGNoZWNrKHByZXNzZWRLZXlOYW1lcykge1xuICAgIGxldCBzdGFydGluZ0tleU5hbWVJbmRleCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgc3RhcnRpbmdLZXlOYW1lSW5kZXggPSB0aGlzLl9jaGVja1N1YkNvbWJvKFxuICAgICAgICB0aGlzLnN1YkNvbWJvc1tpXSxcbiAgICAgICAgc3RhcnRpbmdLZXlOYW1lSW5kZXgsXG4gICAgICAgIHByZXNzZWRLZXlOYW1lc1xuICAgICAgKTtcbiAgICAgIGlmIChzdGFydGluZ0tleU5hbWVJbmRleCA9PT0gLTEpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIGlzRXF1YWwob3RoZXJLZXlDb21ibykge1xuICAgIGlmIChcbiAgICAgICFvdGhlcktleUNvbWJvIHx8XG4gICAgICB0eXBlb2Ygb3RoZXJLZXlDb21ibyAhPT0gJ3N0cmluZycgJiZcbiAgICAgIHR5cGVvZiBvdGhlcktleUNvbWJvICE9PSAnb2JqZWN0J1xuICAgICkgeyByZXR1cm4gZmFsc2U7IH1cblxuICAgIGlmICh0eXBlb2Ygb3RoZXJLZXlDb21ibyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG90aGVyS2V5Q29tYm8gPSBuZXcgS2V5Q29tYm8ob3RoZXJLZXlDb21ibyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3ViQ29tYm9zLmxlbmd0aCAhPT0gb3RoZXJLZXlDb21iby5zdWJDb21ib3MubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zdWJDb21ib3MubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGlmICh0aGlzLnN1YkNvbWJvc1tpXS5sZW5ndGggIT09IG90aGVyS2V5Q29tYm8uc3ViQ29tYm9zW2ldLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3Qgc3ViQ29tYm8gICAgICA9IHRoaXMuc3ViQ29tYm9zW2ldO1xuICAgICAgY29uc3Qgb3RoZXJTdWJDb21ibyA9IG90aGVyS2V5Q29tYm8uc3ViQ29tYm9zW2ldLnNsaWNlKDApO1xuXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHN1YkNvbWJvLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIGNvbnN0IGtleU5hbWUgPSBzdWJDb21ib1tqXTtcbiAgICAgICAgY29uc3QgaW5kZXggICA9IG90aGVyU3ViQ29tYm8uaW5kZXhPZihrZXlOYW1lKTtcblxuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgIG90aGVyU3ViQ29tYm8uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG90aGVyU3ViQ29tYm8ubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICBfY2hlY2tTdWJDb21ibyhzdWJDb21ibywgc3RhcnRpbmdLZXlOYW1lSW5kZXgsIHByZXNzZWRLZXlOYW1lcykge1xuICAgIHN1YkNvbWJvID0gc3ViQ29tYm8uc2xpY2UoMCk7XG4gICAgcHJlc3NlZEtleU5hbWVzID0gcHJlc3NlZEtleU5hbWVzLnNsaWNlKHN0YXJ0aW5nS2V5TmFtZUluZGV4KTtcblxuICAgIGxldCBlbmRJbmRleCA9IHN0YXJ0aW5nS2V5TmFtZUluZGV4O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3ViQ29tYm8ubGVuZ3RoOyBpICs9IDEpIHtcblxuICAgICAgbGV0IGtleU5hbWUgPSBzdWJDb21ib1tpXTtcbiAgICAgIGlmIChrZXlOYW1lWzBdID09PSAnXFxcXCcpIHtcbiAgICAgICAgY29uc3QgZXNjYXBlZEtleU5hbWUgPSBrZXlOYW1lLnNsaWNlKDEpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZXNjYXBlZEtleU5hbWUgPT09IEtleUNvbWJvLmNvbWJvRGVsaW1pbmF0b3IgfHxcbiAgICAgICAgICBlc2NhcGVkS2V5TmFtZSA9PT0gS2V5Q29tYm8ua2V5RGVsaW1pbmF0b3JcbiAgICAgICAgKSB7XG4gICAgICAgICAga2V5TmFtZSA9IGVzY2FwZWRLZXlOYW1lO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGluZGV4ID0gcHJlc3NlZEtleU5hbWVzLmluZGV4T2Yoa2V5TmFtZSk7XG4gICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICBzdWJDb21iby5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGkgLT0gMTtcbiAgICAgICAgaWYgKGluZGV4ID4gZW5kSW5kZXgpIHtcbiAgICAgICAgICBlbmRJbmRleCA9IGluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdWJDb21iby5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gZW5kSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9O1xufVxuXG5LZXlDb21iby5jb21ib0RlbGltaW5hdG9yID0gJz4nO1xuS2V5Q29tYm8ua2V5RGVsaW1pbmF0b3IgICA9ICcrJztcblxuS2V5Q29tYm8ucGFyc2VDb21ib1N0ciA9IGZ1bmN0aW9uKGtleUNvbWJvU3RyKSB7XG4gIGNvbnN0IHN1YkNvbWJvU3RycyA9IEtleUNvbWJvLl9zcGxpdFN0cihrZXlDb21ib1N0ciwgS2V5Q29tYm8uY29tYm9EZWxpbWluYXRvcik7XG4gIGNvbnN0IGNvbWJvICAgICAgICA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwIDsgaSA8IHN1YkNvbWJvU3Rycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGNvbWJvLnB1c2goS2V5Q29tYm8uX3NwbGl0U3RyKHN1YkNvbWJvU3Ryc1tpXSwgS2V5Q29tYm8ua2V5RGVsaW1pbmF0b3IpKTtcbiAgfVxuICByZXR1cm4gY29tYm87XG59XG5cbktleUNvbWJvLl9zcGxpdFN0ciA9IGZ1bmN0aW9uKHN0ciwgZGVsaW1pbmF0b3IpIHtcbiAgY29uc3QgcyAgPSBzdHI7XG4gIGNvbnN0IGQgID0gZGVsaW1pbmF0b3I7XG4gIGxldCBjICA9ICcnO1xuICBjb25zdCBjYSA9IFtdO1xuXG4gIGZvciAobGV0IGNpID0gMDsgY2kgPCBzLmxlbmd0aDsgY2kgKz0gMSkge1xuICAgIGlmIChjaSA+IDAgJiYgc1tjaV0gPT09IGQgJiYgc1tjaSAtIDFdICE9PSAnXFxcXCcpIHtcbiAgICAgIGNhLnB1c2goYy50cmltKCkpO1xuICAgICAgYyA9ICcnO1xuICAgICAgY2kgKz0gMTtcbiAgICB9XG4gICAgYyArPSBzW2NpXTtcbiAgfVxuICBpZiAoYykgeyBjYS5wdXNoKGMudHJpbSgpKTsgfVxuXG4gIHJldHVybiBjYTtcbn07XG4iLCJpbXBvcnQgeyBLZXlDb21ibyB9IGZyb20gJy4va2V5LWNvbWJvJztcblxuXG5leHBvcnQgY2xhc3MgTG9jYWxlIHtcbiAgY29uc3RydWN0b3IobmFtZSkge1xuICAgIHRoaXMubG9jYWxlTmFtZSAgICAgICAgICA9IG5hbWU7XG4gICAgdGhpcy5hY3RpdmVUYXJnZXRLZXlzID0gW107XG4gICAgdGhpcy5wcmVzc2VkS2V5cyAgICAgICAgID0gW107XG4gICAgdGhpcy5fYXBwbGllZE1hY3JvcyAgICAgID0gW107XG4gICAgdGhpcy5fa2V5TWFwICAgICAgICAgICAgID0ge307XG4gICAgdGhpcy5fa2lsbEtleUNvZGVzICAgICAgID0gW107XG4gICAgdGhpcy5fbWFjcm9zICAgICAgICAgICAgID0gW107XG4gIH1cblxuICBiaW5kS2V5Q29kZShrZXlDb2RlLCBrZXlOYW1lcykge1xuICAgIGlmICh0eXBlb2Yga2V5TmFtZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICBrZXlOYW1lcyA9IFtrZXlOYW1lc107XG4gICAgfVxuXG4gICAgdGhpcy5fa2V5TWFwW2tleUNvZGVdID0ga2V5TmFtZXM7XG4gIH07XG5cbiAgYmluZE1hY3JvKGtleUNvbWJvU3RyLCBrZXlOYW1lcykge1xuICAgIGlmICh0eXBlb2Yga2V5TmFtZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICBrZXlOYW1lcyA9IFsga2V5TmFtZXMgXTtcbiAgICB9XG5cbiAgICBsZXQgaGFuZGxlciA9IG51bGw7XG4gICAgaWYgKHR5cGVvZiBrZXlOYW1lcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaGFuZGxlciA9IGtleU5hbWVzO1xuICAgICAga2V5TmFtZXMgPSBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IG1hY3JvID0ge1xuICAgICAga2V5Q29tYm8gOiBuZXcgS2V5Q29tYm8oa2V5Q29tYm9TdHIpLFxuICAgICAga2V5TmFtZXMgOiBrZXlOYW1lcyxcbiAgICAgIGhhbmRsZXIgIDogaGFuZGxlclxuICAgIH07XG5cbiAgICB0aGlzLl9tYWNyb3MucHVzaChtYWNybyk7XG4gIH07XG5cbiAgZ2V0S2V5Q29kZXMoa2V5TmFtZSkge1xuICAgIGNvbnN0IGtleUNvZGVzID0gW107XG4gICAgZm9yIChjb25zdCBrZXlDb2RlIGluIHRoaXMuX2tleU1hcCkge1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9rZXlNYXBba2V5Q29kZV0uaW5kZXhPZihrZXlOYW1lKTtcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7IGtleUNvZGVzLnB1c2goa2V5Q29kZXwwKTsgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5Q29kZXM7XG4gIH07XG5cbiAgZ2V0S2V5TmFtZXMoa2V5Q29kZSkge1xuICAgIHJldHVybiB0aGlzLl9rZXlNYXBba2V5Q29kZV0gfHwgW107XG4gIH07XG5cbiAgc2V0S2lsbEtleShrZXlDb2RlKSB7XG4gICAgaWYgKHR5cGVvZiBrZXlDb2RlID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3Qga2V5Q29kZXMgPSB0aGlzLmdldEtleUNvZGVzKGtleUNvZGUpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlDb2Rlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICB0aGlzLnNldEtpbGxLZXkoa2V5Q29kZXNbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2tpbGxLZXlDb2Rlcy5wdXNoKGtleUNvZGUpO1xuICB9O1xuXG4gIHByZXNzS2V5KGtleUNvZGUpIHtcbiAgICBpZiAodHlwZW9mIGtleUNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBrZXlDb2RlcyA9IHRoaXMuZ2V0S2V5Q29kZXMoa2V5Q29kZSk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleUNvZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHRoaXMucHJlc3NLZXkoa2V5Q29kZXNbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYWN0aXZlVGFyZ2V0S2V5cy5sZW5ndGggPSAwO1xuICAgIGNvbnN0IGtleU5hbWVzID0gdGhpcy5nZXRLZXlOYW1lcyhrZXlDb2RlKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleU5hbWVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICB0aGlzLmFjdGl2ZVRhcmdldEtleXMucHVzaChrZXlOYW1lc1tpXSk7XG4gICAgICBpZiAodGhpcy5wcmVzc2VkS2V5cy5pbmRleE9mKGtleU5hbWVzW2ldKSA9PT0gLTEpIHtcbiAgICAgICAgdGhpcy5wcmVzc2VkS2V5cy5wdXNoKGtleU5hbWVzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9hcHBseU1hY3JvcygpO1xuICB9O1xuXG4gIHJlbGVhc2VLZXkoa2V5Q29kZSkge1xuICAgIGlmICh0eXBlb2Yga2V5Q29kZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IGtleUNvZGVzID0gdGhpcy5nZXRLZXlDb2RlcyhrZXlDb2RlKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5Q29kZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgdGhpcy5yZWxlYXNlS2V5KGtleUNvZGVzW2ldKTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBrZXlOYW1lcyAgICAgICAgID0gdGhpcy5nZXRLZXlOYW1lcyhrZXlDb2RlKTtcbiAgICAgIGNvbnN0IGtpbGxLZXlDb2RlSW5kZXggPSB0aGlzLl9raWxsS2V5Q29kZXMuaW5kZXhPZihrZXlDb2RlKTtcblxuICAgICAgaWYgKGtpbGxLZXlDb2RlSW5kZXggIT09IC0xKSB7XG4gICAgICAgIHRoaXMucHJlc3NlZEtleXMubGVuZ3RoID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5TmFtZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihrZXlOYW1lc1tpXSk7XG4gICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucHJlc3NlZEtleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5hY3RpdmVUYXJnZXRLZXlzLmxlbmd0aCA9IDA7XG4gICAgICB0aGlzLl9jbGVhck1hY3JvcygpO1xuICAgIH1cbiAgfTtcblxuICBfYXBwbHlNYWNyb3MoKSB7XG4gICAgY29uc3QgbWFjcm9zID0gdGhpcy5fbWFjcm9zLnNsaWNlKDApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWFjcm9zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBtYWNybyA9IG1hY3Jvc1tpXTtcbiAgICAgIGlmIChtYWNyby5rZXlDb21iby5jaGVjayh0aGlzLnByZXNzZWRLZXlzKSkge1xuICAgICAgICBpZiAobWFjcm8uaGFuZGxlcikge1xuICAgICAgICAgIG1hY3JvLmtleU5hbWVzID0gbWFjcm8uaGFuZGxlcih0aGlzLnByZXNzZWRLZXlzKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG1hY3JvLmtleU5hbWVzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihtYWNyby5rZXlOYW1lc1tqXSkgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnByZXNzZWRLZXlzLnB1c2gobWFjcm8ua2V5TmFtZXNbal0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hcHBsaWVkTWFjcm9zLnB1c2gobWFjcm8pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBfY2xlYXJNYWNyb3MoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hcHBsaWVkTWFjcm9zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBtYWNybyA9IHRoaXMuX2FwcGxpZWRNYWNyb3NbaV07XG4gICAgICBpZiAoIW1hY3JvLmtleUNvbWJvLmNoZWNrKHRoaXMucHJlc3NlZEtleXMpKSB7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbWFjcm8ua2V5TmFtZXMubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihtYWNyby5rZXlOYW1lc1tqXSk7XG4gICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucHJlc3NlZEtleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1hY3JvLmhhbmRsZXIpIHtcbiAgICAgICAgICBtYWNyby5rZXlOYW1lcyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYXBwbGllZE1hY3Jvcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGkgLT0gMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCB7IExvY2FsZSB9IGZyb20gJy4vbG9jYWxlJztcbmltcG9ydCB7IEtleUNvbWJvIH0gZnJvbSAnLi9rZXktY29tYm8nO1xuXG5cbmV4cG9ydCBjbGFzcyBLZXlib2FyZCB7XG4gIGNvbnN0cnVjdG9yKHRhcmdldFdpbmRvdywgdGFyZ2V0RWxlbWVudCwgdGFyZ2V0UGxhdGZvcm0sIHRhcmdldFVzZXJBZ2VudCkge1xuICAgIHRoaXMuX2xvY2FsZSAgICAgICAgICAgICAgID0gbnVsbDtcbiAgICB0aGlzLl9jdXJyZW50Q29udGV4dCAgICAgICA9ICcnO1xuICAgIHRoaXMuX2NvbnRleHRzICAgICAgICAgICAgID0ge307XG4gICAgdGhpcy5fbGlzdGVuZXJzICAgICAgICAgICAgPSBbXTtcbiAgICB0aGlzLl9hcHBsaWVkTGlzdGVuZXJzICAgICA9IFtdO1xuICAgIHRoaXMuX2xvY2FsZXMgICAgICAgICAgICAgID0ge307XG4gICAgdGhpcy5fdGFyZ2V0RWxlbWVudCAgICAgICAgPSBudWxsO1xuICAgIHRoaXMuX3RhcmdldFdpbmRvdyAgICAgICAgID0gbnVsbDtcbiAgICB0aGlzLl90YXJnZXRQbGF0Zm9ybSAgICAgICA9ICcnO1xuICAgIHRoaXMuX3RhcmdldFVzZXJBZ2VudCAgICAgID0gJyc7XG4gICAgdGhpcy5faXNNb2Rlcm5Ccm93c2VyICAgICAgPSBmYWxzZTtcbiAgICB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyA9IG51bGw7XG4gICAgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nICAgPSBudWxsO1xuICAgIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyAgID0gbnVsbDtcbiAgICB0aGlzLl9wYXVzZWQgICAgICAgICAgICAgICA9IGZhbHNlO1xuXG4gICAgdGhpcy5fY29udGV4dHMuZ2xvYmFsID0ge1xuICAgICAgbGlzdGVuZXJzOiB0aGlzLl9saXN0ZW5lcnMsXG4gICAgICB0YXJnZXRXaW5kb3csXG4gICAgICB0YXJnZXRFbGVtZW50LFxuICAgICAgdGFyZ2V0UGxhdGZvcm0sXG4gICAgICB0YXJnZXRVc2VyQWdlbnRcbiAgICB9O1xuXG4gICAgdGhpcy5zZXRDb250ZXh0KCdnbG9iYWwnKTtcbiAgfVxuXG4gIHNldExvY2FsZShsb2NhbGVOYW1lLCBsb2NhbGVCdWlsZGVyKSB7XG4gICAgbGV0IGxvY2FsZSA9IG51bGw7XG4gICAgaWYgKHR5cGVvZiBsb2NhbGVOYW1lID09PSAnc3RyaW5nJykge1xuXG4gICAgICBpZiAobG9jYWxlQnVpbGRlcikge1xuICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKGxvY2FsZU5hbWUpO1xuICAgICAgICBsb2NhbGVCdWlsZGVyKGxvY2FsZSwgdGhpcy5fdGFyZ2V0UGxhdGZvcm0sIHRoaXMuX3RhcmdldFVzZXJBZ2VudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2NhbGUgPSB0aGlzLl9sb2NhbGVzW2xvY2FsZU5hbWVdIHx8IG51bGw7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvY2FsZSAgICAgPSBsb2NhbGVOYW1lO1xuICAgICAgbG9jYWxlTmFtZSA9IGxvY2FsZS5fbG9jYWxlTmFtZTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2NhbGUgICAgICAgICAgICAgID0gbG9jYWxlO1xuICAgIHRoaXMuX2xvY2FsZXNbbG9jYWxlTmFtZV0gPSBsb2NhbGU7XG4gICAgaWYgKGxvY2FsZSkge1xuICAgICAgdGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzID0gbG9jYWxlLnByZXNzZWRLZXlzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZ2V0TG9jYWxlKGxvY2FsTmFtZSkge1xuICAgIGxvY2FsTmFtZSB8fCAobG9jYWxOYW1lID0gdGhpcy5fbG9jYWxlLmxvY2FsZU5hbWUpO1xuICAgIHJldHVybiB0aGlzLl9sb2NhbGVzW2xvY2FsTmFtZV0gfHwgbnVsbDtcbiAgfVxuXG4gIGJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICBpZiAoa2V5Q29tYm9TdHIgPT09IG51bGwgfHwgdHlwZW9mIGtleUNvbWJvU3RyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0ID0gcmVsZWFzZUhhbmRsZXI7XG4gICAgICByZWxlYXNlSGFuZGxlciAgICAgICAgID0gcHJlc3NIYW5kbGVyO1xuICAgICAgcHJlc3NIYW5kbGVyICAgICAgICAgICA9IGtleUNvbWJvU3RyO1xuICAgICAga2V5Q29tYm9TdHIgICAgICAgICAgICA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAga2V5Q29tYm9TdHIgJiZcbiAgICAgIHR5cGVvZiBrZXlDb21ib1N0ciA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHR5cGVvZiBrZXlDb21ib1N0ci5sZW5ndGggPT09ICdudW1iZXInXG4gICAgKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleUNvbWJvU3RyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHRoaXMuYmluZChrZXlDb21ib1N0cltpXSwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLl9saXN0ZW5lcnMucHVzaCh7XG4gICAgICBrZXlDb21ibyAgICAgICAgICAgICAgOiBrZXlDb21ib1N0ciA/IG5ldyBLZXlDb21ibyhrZXlDb21ib1N0cikgOiBudWxsLFxuICAgICAgcHJlc3NIYW5kbGVyICAgICAgICAgIDogcHJlc3NIYW5kbGVyICAgICAgICAgICB8fCBudWxsLFxuICAgICAgcmVsZWFzZUhhbmRsZXIgICAgICAgIDogcmVsZWFzZUhhbmRsZXIgICAgICAgICB8fCBudWxsLFxuICAgICAgcHJldmVudFJlcGVhdCAgICAgICAgIDogZmFsc2UsXG4gICAgICBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0OiBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0IHx8IGZhbHNlLFxuICAgICAgZXhlY3V0aW5nSGFuZGxlciAgICAgIDogZmFsc2VcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgYWRkTGlzdGVuZXIoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KTtcbiAgfVxuXG4gIG9uKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KSB7XG4gICAgcmV0dXJuIHRoaXMuYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCk7XG4gIH1cblxuICBiaW5kUHJlc3Moa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgIHJldHVybiB0aGlzLmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgbnVsbCwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCk7XG4gIH1cblxuICBiaW5kUmVsZWFzZShrZXlDb21ib1N0ciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBudWxsLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCk7XG4gIH1cblxuICB1bmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICBpZiAoa2V5Q29tYm9TdHIgPT09IG51bGwgfHwgdHlwZW9mIGtleUNvbWJvU3RyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZWxlYXNlSGFuZGxlciA9IHByZXNzSGFuZGxlcjtcbiAgICAgIHByZXNzSGFuZGxlciAgID0ga2V5Q29tYm9TdHI7XG4gICAgICBrZXlDb21ib1N0ciA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAga2V5Q29tYm9TdHIgJiZcbiAgICAgIHR5cGVvZiBrZXlDb21ib1N0ciA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHR5cGVvZiBrZXlDb21ib1N0ci5sZW5ndGggPT09ICdudW1iZXInXG4gICAgKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleUNvbWJvU3RyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHRoaXMudW5iaW5kKGtleUNvbWJvU3RyW2ldLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBsaXN0ZW5lciA9IHRoaXMuX2xpc3RlbmVyc1tpXTtcblxuICAgICAgY29uc3QgY29tYm9NYXRjaGVzICAgICAgICAgID0gIWtleUNvbWJvU3RyICYmICFsaXN0ZW5lci5rZXlDb21ibyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmtleUNvbWJvICYmIGxpc3RlbmVyLmtleUNvbWJvLmlzRXF1YWwoa2V5Q29tYm9TdHIpO1xuICAgICAgY29uc3QgcHJlc3NIYW5kbGVyTWF0Y2hlcyAgID0gIXByZXNzSGFuZGxlciAmJiAhcmVsZWFzZUhhbmRsZXIgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhcHJlc3NIYW5kbGVyICYmICFsaXN0ZW5lci5wcmVzc0hhbmRsZXIgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVzc0hhbmRsZXIgPT09IGxpc3RlbmVyLnByZXNzSGFuZGxlcjtcbiAgICAgIGNvbnN0IHJlbGVhc2VIYW5kbGVyTWF0Y2hlcyA9ICFwcmVzc0hhbmRsZXIgJiYgIXJlbGVhc2VIYW5kbGVyIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXJlbGVhc2VIYW5kbGVyICYmICFsaXN0ZW5lci5yZWxlYXNlSGFuZGxlciB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbGVhc2VIYW5kbGVyID09PSBsaXN0ZW5lci5yZWxlYXNlSGFuZGxlcjtcblxuICAgICAgaWYgKGNvbWJvTWF0Y2hlcyAmJiBwcmVzc0hhbmRsZXJNYXRjaGVzICYmIHJlbGVhc2VIYW5kbGVyTWF0Y2hlcykge1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICBpIC09IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICByZW1vdmVMaXN0ZW5lcihrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcikge1xuICAgIHJldHVybiB0aGlzLnVuYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcik7XG4gIH1cblxuICBvZmYoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICByZXR1cm4gdGhpcy51bmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpO1xuICB9XG5cbiAgc2V0Q29udGV4dChjb250ZXh0TmFtZSkge1xuICAgIGlmKHRoaXMuX2xvY2FsZSkgeyB0aGlzLnJlbGVhc2VBbGxLZXlzKCk7IH1cblxuICAgIGlmICghdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdKSB7XG4gICAgICBjb25zdCBnbG9iYWxDb250ZXh0ID0gdGhpcy5fY29udGV4dHMuZ2xvYmFsO1xuICAgICAgdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdID0ge1xuICAgICAgICBsaXN0ZW5lcnMgICAgICA6IFtdLFxuICAgICAgICB0YXJnZXRXaW5kb3cgICA6IGdsb2JhbENvbnRleHQudGFyZ2V0V2luZG93LFxuICAgICAgICB0YXJnZXRFbGVtZW50ICA6IGdsb2JhbENvbnRleHQudGFyZ2V0RWxlbWVudCxcbiAgICAgICAgdGFyZ2V0UGxhdGZvcm0gOiBnbG9iYWxDb250ZXh0LnRhcmdldFBsYXRmb3JtLFxuICAgICAgICB0YXJnZXRVc2VyQWdlbnQ6IGdsb2JhbENvbnRleHQudGFyZ2V0VXNlckFnZW50XG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRleHQgICAgICAgID0gdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdO1xuICAgIHRoaXMuX2N1cnJlbnRDb250ZXh0ID0gY29udGV4dE5hbWU7XG4gICAgdGhpcy5fbGlzdGVuZXJzICAgICAgPSBjb250ZXh0Lmxpc3RlbmVycztcblxuICAgIHRoaXMuc3RvcCgpO1xuICAgIHRoaXMud2F0Y2goXG4gICAgICBjb250ZXh0LnRhcmdldFdpbmRvdyxcbiAgICAgIGNvbnRleHQudGFyZ2V0RWxlbWVudCxcbiAgICAgIGNvbnRleHQudGFyZ2V0UGxhdGZvcm0sXG4gICAgICBjb250ZXh0LnRhcmdldFVzZXJBZ2VudFxuICAgICk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldENvbnRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRDb250ZXh0O1xuICB9XG5cbiAgd2l0aENvbnRleHQoY29udGV4dE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgcHJldmlvdXNDb250ZXh0TmFtZSA9IHRoaXMuZ2V0Q29udGV4dCgpO1xuICAgIHRoaXMuc2V0Q29udGV4dChjb250ZXh0TmFtZSk7XG5cbiAgICBjYWxsYmFjaygpO1xuXG4gICAgdGhpcy5zZXRDb250ZXh0KHByZXZpb3VzQ29udGV4dE5hbWUpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB3YXRjaCh0YXJnZXRXaW5kb3csIHRhcmdldEVsZW1lbnQsIHRhcmdldFBsYXRmb3JtLCB0YXJnZXRVc2VyQWdlbnQpIHtcbiAgICB0aGlzLnN0b3AoKTtcblxuICAgIGNvbnN0IHdpbiA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOlxuICAgICAgICAgICAgICAgIHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDpcbiAgICAgICAgICAgICAgICB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6XG4gICAgICAgICAgICAgICAge307XG5cbiAgICBpZiAoIXRhcmdldFdpbmRvdykge1xuICAgICAgaWYgKCF3aW4uYWRkRXZlbnRMaXN0ZW5lciAmJiAhd2luLmF0dGFjaEV2ZW50KSB7XG4gICAgICAgIC8vIFRoaXMgd2FzIGFkZGVkIHNvIHdoZW4gdXNpbmcgdGhpbmdzIGxpa2UgSlNET00gd2F0Y2ggY2FuIGJlIHVzZWQgdG8gY29uZmlndXJlIHdhdGNoXG4gICAgICAgIC8vIGZvciB0aGUgZ2xvYmFsIG5hbWVzcGFjZSBtYW51YWxseS5cbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDb250ZXh0ID09PSAnZ2xvYmFsJykge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgd2luZG93IGZ1bmN0aW9ucyBhZGRFdmVudExpc3RlbmVyIG9yIGF0dGFjaEV2ZW50LicpO1xuICAgICAgfVxuICAgICAgdGFyZ2V0V2luZG93ID0gd2luO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBlbGVtZW50IGJpbmRpbmdzIHdoZXJlIGEgdGFyZ2V0IHdpbmRvdyBpcyBub3QgcGFzc2VkXG4gICAgaWYgKHR5cGVvZiB0YXJnZXRXaW5kb3cubm9kZVR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICB0YXJnZXRVc2VyQWdlbnQgPSB0YXJnZXRQbGF0Zm9ybTtcbiAgICAgIHRhcmdldFBsYXRmb3JtICA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICB0YXJnZXRFbGVtZW50ICAgPSB0YXJnZXRXaW5kb3c7XG4gICAgICB0YXJnZXRXaW5kb3cgICAgPSB3aW47XG4gICAgfVxuXG4gICAgaWYgKCF0YXJnZXRXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lciAmJiAhdGFyZ2V0V2luZG93LmF0dGFjaEV2ZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIGFkZEV2ZW50TGlzdGVuZXIgb3IgYXR0YWNoRXZlbnQgbWV0aG9kcyBvbiB0YXJnZXRXaW5kb3cuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5faXNNb2Rlcm5Ccm93c2VyID0gISF0YXJnZXRXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcjtcblxuICAgIGNvbnN0IHVzZXJBZ2VudCA9IHRhcmdldFdpbmRvdy5uYXZpZ2F0b3IgJiYgdGFyZ2V0V2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQgfHwgJyc7XG4gICAgY29uc3QgcGxhdGZvcm0gID0gdGFyZ2V0V2luZG93Lm5hdmlnYXRvciAmJiB0YXJnZXRXaW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtICB8fCAnJztcblxuICAgIHRhcmdldEVsZW1lbnQgICAmJiB0YXJnZXRFbGVtZW50ICAgIT09IG51bGwgfHwgKHRhcmdldEVsZW1lbnQgICA9IHRhcmdldFdpbmRvdy5kb2N1bWVudCk7XG4gICAgdGFyZ2V0UGxhdGZvcm0gICYmIHRhcmdldFBsYXRmb3JtICAhPT0gbnVsbCB8fCAodGFyZ2V0UGxhdGZvcm0gID0gcGxhdGZvcm0pO1xuICAgIHRhcmdldFVzZXJBZ2VudCAmJiB0YXJnZXRVc2VyQWdlbnQgIT09IG51bGwgfHwgKHRhcmdldFVzZXJBZ2VudCA9IHVzZXJBZ2VudCk7XG5cbiAgICB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyA9IChldmVudCkgPT4ge1xuICAgICAgdGhpcy5wcmVzc0tleShldmVudC5rZXlDb2RlLCBldmVudCk7XG4gICAgICB0aGlzLl9oYW5kbGVDb21tYW5kQnVnKGV2ZW50LCBwbGF0Zm9ybSk7XG4gICAgfTtcbiAgICB0aGlzLl90YXJnZXRLZXlVcEJpbmRpbmcgPSAoZXZlbnQpID0+IHtcbiAgICAgIHRoaXMucmVsZWFzZUtleShldmVudC5rZXlDb2RlLCBldmVudCk7XG4gICAgfTtcbiAgICB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcgPSAoZXZlbnQpID0+IHtcbiAgICAgIHRoaXMucmVsZWFzZUFsbEtleXMoZXZlbnQpO1xuICAgIH07XG5cbiAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgJ2tleWRvd24nLCB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyk7XG4gICAgdGhpcy5fYmluZEV2ZW50KHRhcmdldEVsZW1lbnQsICdrZXl1cCcsICAgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nKTtcbiAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0V2luZG93LCAgJ2ZvY3VzJywgICB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcpO1xuICAgIHRoaXMuX2JpbmRFdmVudCh0YXJnZXRXaW5kb3csICAnYmx1cicsICAgIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyk7XG5cbiAgICB0aGlzLl90YXJnZXRFbGVtZW50ICAgPSB0YXJnZXRFbGVtZW50O1xuICAgIHRoaXMuX3RhcmdldFdpbmRvdyAgICA9IHRhcmdldFdpbmRvdztcbiAgICB0aGlzLl90YXJnZXRQbGF0Zm9ybSAgPSB0YXJnZXRQbGF0Zm9ybTtcbiAgICB0aGlzLl90YXJnZXRVc2VyQWdlbnQgPSB0YXJnZXRVc2VyQWdlbnQ7XG5cbiAgICBjb25zdCBjdXJyZW50Q29udGV4dCAgICAgICAgICAgPSB0aGlzLl9jb250ZXh0c1t0aGlzLl9jdXJyZW50Q29udGV4dF07XG4gICAgY3VycmVudENvbnRleHQudGFyZ2V0V2luZG93ICAgID0gdGhpcy5fdGFyZ2V0V2luZG93O1xuICAgIGN1cnJlbnRDb250ZXh0LnRhcmdldEVsZW1lbnQgICA9IHRoaXMuX3RhcmdldEVsZW1lbnQ7XG4gICAgY3VycmVudENvbnRleHQudGFyZ2V0UGxhdGZvcm0gID0gdGhpcy5fdGFyZ2V0UGxhdGZvcm07XG4gICAgY3VycmVudENvbnRleHQudGFyZ2V0VXNlckFnZW50ID0gdGhpcy5fdGFyZ2V0VXNlckFnZW50O1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdG9wKCkge1xuICAgIGlmICghdGhpcy5fdGFyZ2V0RWxlbWVudCB8fCAhdGhpcy5fdGFyZ2V0V2luZG93KSB7IHJldHVybjsgfVxuXG4gICAgdGhpcy5fdW5iaW5kRXZlbnQodGhpcy5fdGFyZ2V0RWxlbWVudCwgJ2tleWRvd24nLCB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyk7XG4gICAgdGhpcy5fdW5iaW5kRXZlbnQodGhpcy5fdGFyZ2V0RWxlbWVudCwgJ2tleXVwJywgICB0aGlzLl90YXJnZXRLZXlVcEJpbmRpbmcpO1xuICAgIHRoaXMuX3VuYmluZEV2ZW50KHRoaXMuX3RhcmdldFdpbmRvdywgICdmb2N1cycsICAgdGhpcy5fdGFyZ2V0UmVzZXRCaW5kaW5nKTtcbiAgICB0aGlzLl91bmJpbmRFdmVudCh0aGlzLl90YXJnZXRXaW5kb3csICAnYmx1cicsICAgIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyk7XG5cbiAgICB0aGlzLl90YXJnZXRXaW5kb3cgID0gbnVsbDtcbiAgICB0aGlzLl90YXJnZXRFbGVtZW50ID0gbnVsbDtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHJlc3NLZXkoa2V5Q29kZSwgZXZlbnQpIHtcbiAgICBpZiAodGhpcy5fcGF1c2VkKSB7IHJldHVybiB0aGlzOyB9XG4gICAgaWYgKCF0aGlzLl9sb2NhbGUpIHsgdGhyb3cgbmV3IEVycm9yKCdMb2NhbGUgbm90IHNldCcpOyB9XG5cbiAgICB0aGlzLl9sb2NhbGUucHJlc3NLZXkoa2V5Q29kZSk7XG4gICAgdGhpcy5fYXBwbHlCaW5kaW5ncyhldmVudCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHJlbGVhc2VLZXkoa2V5Q29kZSwgZXZlbnQpIHtcbiAgICBpZiAodGhpcy5fcGF1c2VkKSB7IHJldHVybiB0aGlzOyB9XG4gICAgaWYgKCF0aGlzLl9sb2NhbGUpIHsgdGhyb3cgbmV3IEVycm9yKCdMb2NhbGUgbm90IHNldCcpOyB9XG5cbiAgICB0aGlzLl9sb2NhbGUucmVsZWFzZUtleShrZXlDb2RlKTtcbiAgICB0aGlzLl9jbGVhckJpbmRpbmdzKGV2ZW50KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmVsZWFzZUFsbEtleXMoZXZlbnQpIHtcbiAgICBpZiAodGhpcy5fcGF1c2VkKSB7IHJldHVybiB0aGlzOyB9XG4gICAgaWYgKCF0aGlzLl9sb2NhbGUpIHsgdGhyb3cgbmV3IEVycm9yKCdMb2NhbGUgbm90IHNldCcpOyB9XG5cbiAgICB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMubGVuZ3RoID0gMDtcbiAgICB0aGlzLl9jbGVhckJpbmRpbmdzKGV2ZW50KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcGF1c2UoKSB7XG4gICAgaWYgKHRoaXMuX3BhdXNlZCkgeyByZXR1cm4gdGhpczsgfVxuICAgIGlmICh0aGlzLl9sb2NhbGUpIHsgdGhpcy5yZWxlYXNlQWxsS2V5cygpOyB9XG4gICAgdGhpcy5fcGF1c2VkID0gdHJ1ZTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmVzdW1lKCkge1xuICAgIHRoaXMuX3BhdXNlZCA9IGZhbHNlO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLnJlbGVhc2VBbGxLZXlzKCk7XG4gICAgdGhpcy5fbGlzdGVuZXJzLmxlbmd0aCA9IDA7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIF9iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzTW9kZXJuQnJvd3NlciA/XG4gICAgICB0YXJnZXRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSkgOlxuICAgICAgdGFyZ2V0RWxlbWVudC5hdHRhY2hFdmVudCgnb24nICsgZXZlbnROYW1lLCBoYW5kbGVyKTtcbiAgfVxuXG4gIF91bmJpbmRFdmVudCh0YXJnZXRFbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICByZXR1cm4gdGhpcy5faXNNb2Rlcm5Ccm93c2VyID9cbiAgICAgIHRhcmdldEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGhhbmRsZXIsIGZhbHNlKSA6XG4gICAgICB0YXJnZXRFbGVtZW50LmRldGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWUsIGhhbmRsZXIpO1xuICB9XG5cbiAgX2dldEdyb3VwZWRMaXN0ZW5lcnMoKSB7XG4gICAgY29uc3QgbGlzdGVuZXJHcm91cHMgICA9IFtdO1xuICAgIGNvbnN0IGxpc3RlbmVyR3JvdXBNYXAgPSBbXTtcblxuICAgIGxldCBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XG4gICAgaWYgKHRoaXMuX2N1cnJlbnRDb250ZXh0ICE9PSAnZ2xvYmFsJykge1xuICAgICAgbGlzdGVuZXJzID0gWy4uLmxpc3RlbmVycywgLi4udGhpcy5fY29udGV4dHMuZ2xvYmFsLmxpc3RlbmVyc107XG4gICAgfVxuXG4gICAgbGlzdGVuZXJzLnNvcnQoXG4gICAgICAoYSwgYikgPT5cbiAgICAgICAgKGIua2V5Q29tYm8gPyBiLmtleUNvbWJvLmtleU5hbWVzLmxlbmd0aCA6IDApIC1cbiAgICAgICAgKGEua2V5Q29tYm8gPyBhLmtleUNvbWJvLmtleU5hbWVzLmxlbmd0aCA6IDApXG4gICAgKS5mb3JFYWNoKChsKSA9PiB7XG4gICAgICBsZXQgbWFwSW5kZXggPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdGVuZXJHcm91cE1hcC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAobGlzdGVuZXJHcm91cE1hcFtpXSA9PT0gbnVsbCAmJiBsLmtleUNvbWJvID09PSBudWxsIHx8XG4gICAgICAgICAgICBsaXN0ZW5lckdyb3VwTWFwW2ldICE9PSBudWxsICYmIGxpc3RlbmVyR3JvdXBNYXBbaV0uaXNFcXVhbChsLmtleUNvbWJvKSkge1xuICAgICAgICAgIG1hcEluZGV4ID0gaTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1hcEluZGV4ID09PSAtMSkge1xuICAgICAgICBtYXBJbmRleCA9IGxpc3RlbmVyR3JvdXBNYXAubGVuZ3RoO1xuICAgICAgICBsaXN0ZW5lckdyb3VwTWFwLnB1c2gobC5rZXlDb21ibyk7XG4gICAgICB9XG4gICAgICBpZiAoIWxpc3RlbmVyR3JvdXBzW21hcEluZGV4XSkge1xuICAgICAgICBsaXN0ZW5lckdyb3Vwc1ttYXBJbmRleF0gPSBbXTtcbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyR3JvdXBzW21hcEluZGV4XS5wdXNoKGwpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGxpc3RlbmVyR3JvdXBzO1xuICB9XG5cbiAgX2FwcGx5QmluZGluZ3MoZXZlbnQpIHtcbiAgICBsZXQgcHJldmVudFJlcGVhdCA9IGZhbHNlO1xuXG4gICAgZXZlbnQgfHwgKGV2ZW50ID0ge30pO1xuICAgIGV2ZW50LnByZXZlbnRSZXBlYXQgPSAoKSA9PiB7IHByZXZlbnRSZXBlYXQgPSB0cnVlOyB9O1xuICAgIGV2ZW50LnByZXNzZWRLZXlzICAgPSB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMuc2xpY2UoMCk7XG5cbiAgICBjb25zdCBhY3RpdmVUYXJnZXRLZXlzID0gdGhpcy5fbG9jYWxlLmFjdGl2ZVRhcmdldEtleXM7XG4gICAgY29uc3QgcHJlc3NlZEtleXMgICAgICA9IHRoaXMuX2xvY2FsZS5wcmVzc2VkS2V5cy5zbGljZSgwKTtcbiAgICBjb25zdCBsaXN0ZW5lckdyb3VwcyAgID0gdGhpcy5fZ2V0R3JvdXBlZExpc3RlbmVycygpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lckdyb3Vwcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3QgbGlzdGVuZXJzID0gbGlzdGVuZXJHcm91cHNbaV07XG4gICAgICBjb25zdCBrZXlDb21ibyAgPSBsaXN0ZW5lcnNbMF0ua2V5Q29tYm87XG5cbiAgICAgIGlmIChcbiAgICAgICAga2V5Q29tYm8gPT09IG51bGwgfHxcbiAgICAgICAga2V5Q29tYm8uY2hlY2socHJlc3NlZEtleXMpICYmXG4gICAgICAgIGFjdGl2ZVRhcmdldEtleXMuc29tZShrID0+IGtleUNvbWJvLmtleU5hbWVzLmluY2x1ZGVzKGspKVxuICAgICAgKSB7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGlzdGVuZXJzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgbGV0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2pdO1xuXG4gICAgICAgICAgaWYgKCFsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyICYmIGxpc3RlbmVyLnByZXNzSGFuZGxlciAmJiAhbGlzdGVuZXIucHJldmVudFJlcGVhdCkge1xuICAgICAgICAgICAgbGlzdGVuZXIuZXhlY3V0aW5nSGFuZGxlciA9IHRydWU7XG4gICAgICAgICAgICBsaXN0ZW5lci5wcmVzc0hhbmRsZXIuY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICAgICAgICBsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmIChwcmV2ZW50UmVwZWF0IHx8IGxpc3RlbmVyLnByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICAgICAgICAgICAgbGlzdGVuZXIucHJldmVudFJlcGVhdCA9IHRydWU7XG4gICAgICAgICAgICAgIHByZXZlbnRSZXBlYXQgICAgICAgICAgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGhpcy5fYXBwbGllZExpc3RlbmVycy5pbmRleE9mKGxpc3RlbmVyKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FwcGxpZWRMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGtleUNvbWJvKSB7XG4gICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBrZXlDb21iby5rZXlOYW1lcy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBwcmVzc2VkS2V5cy5pbmRleE9mKGtleUNvbWJvLmtleU5hbWVzW2pdKTtcbiAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgcHJlc3NlZEtleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgaiAtPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9jbGVhckJpbmRpbmdzKGV2ZW50KSB7XG4gICAgZXZlbnQgfHwgKGV2ZW50ID0ge30pO1xuICAgIGV2ZW50LnByZXNzZWRLZXlzID0gdGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzLnNsaWNlKDApO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hcHBsaWVkTGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBsaXN0ZW5lciA9IHRoaXMuX2FwcGxpZWRMaXN0ZW5lcnNbaV07XG4gICAgICBjb25zdCBrZXlDb21ibyA9IGxpc3RlbmVyLmtleUNvbWJvO1xuICAgICAgaWYgKGtleUNvbWJvID09PSBudWxsIHx8ICFrZXlDb21iby5jaGVjayh0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMpKSB7XG4gICAgICAgIGxpc3RlbmVyLnByZXZlbnRSZXBlYXQgPSBmYWxzZTtcbiAgICAgICAgaWYgKGtleUNvbWJvICE9PSBudWxsIHx8IGV2ZW50LnByZXNzZWRLZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2FwcGxpZWRMaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgJiYgbGlzdGVuZXIucmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgICBsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyID0gdHJ1ZTtcbiAgICAgICAgICBsaXN0ZW5lci5yZWxlYXNlSGFuZGxlci5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICBsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfaGFuZGxlQ29tbWFuZEJ1ZyhldmVudCwgcGxhdGZvcm0pIHtcbiAgICAvLyBPbiBNYWMgd2hlbiB0aGUgY29tbWFuZCBrZXkgaXMga2VwdCBwcmVzc2VkLCBrZXl1cCBpcyBub3QgdHJpZ2dlcmVkIGZvciBhbnkgb3RoZXIga2V5LlxuICAgIC8vIEluIHRoaXMgY2FzZSBmb3JjZSBhIGtleXVwIGZvciBub24tbW9kaWZpZXIga2V5cyBkaXJlY3RseSBhZnRlciB0aGUga2V5cHJlc3MuXG4gICAgY29uc3QgbW9kaWZpZXJLZXlzID0gW1wic2hpZnRcIiwgXCJjdHJsXCIsIFwiYWx0XCIsIFwiY2Fwc2xvY2tcIiwgXCJ0YWJcIiwgXCJjb21tYW5kXCJdO1xuICAgIGlmIChwbGF0Zm9ybS5tYXRjaChcIk1hY1wiKSAmJiB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMuaW5jbHVkZXMoXCJjb21tYW5kXCIpICYmXG4gICAgICAgICFtb2RpZmllcktleXMuaW5jbHVkZXModGhpcy5fbG9jYWxlLmdldEtleU5hbWVzKGV2ZW50LmtleUNvZGUpWzBdKSkge1xuICAgICAgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nKGV2ZW50KTtcbiAgICB9XG4gIH1cbn1cbiIsIlxuZXhwb3J0IGZ1bmN0aW9uIHVzKGxvY2FsZSwgcGxhdGZvcm0sIHVzZXJBZ2VudCkge1xuXG4gIC8vIGdlbmVyYWxcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDMsICAgWydjYW5jZWwnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg4LCAgIFsnYmFja3NwYWNlJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoOSwgICBbJ3RhYiddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyLCAgWydjbGVhciddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzLCAgWydlbnRlciddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDE2LCAgWydzaGlmdCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDE3LCAgWydjdHJsJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTgsICBbJ2FsdCcsICdtZW51J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTksICBbJ3BhdXNlJywgJ2JyZWFrJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMjAsICBbJ2NhcHNsb2NrJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMjcsICBbJ2VzY2FwZScsICdlc2MnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgzMiwgIFsnc3BhY2UnLCAnc3BhY2ViYXInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgzMywgIFsncGFnZXVwJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMzQsICBbJ3BhZ2Vkb3duJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMzUsICBbJ2VuZCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDM2LCAgWydob21lJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMzcsICBbJ2xlZnQnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgzOCwgIFsndXAnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgzOSwgIFsncmlnaHQnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg0MCwgIFsnZG93biddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQxLCAgWydzZWxlY3QnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg0MiwgIFsncHJpbnRzY3JlZW4nXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg0MywgIFsnZXhlY3V0ZSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ0LCAgWydzbmFwc2hvdCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ1LCAgWydpbnNlcnQnLCAnaW5zJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNDYsICBbJ2RlbGV0ZScsICdkZWwnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg0NywgIFsnaGVscCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDE0NSwgWydzY3JvbGxsb2NrJywgJ3Njcm9sbCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDE4OCwgWydjb21tYScsICcsJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTkwLCBbJ3BlcmlvZCcsICcuJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTkxLCBbJ3NsYXNoJywgJ2ZvcndhcmRzbGFzaCcsICcvJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTkyLCBbJ2dyYXZlYWNjZW50JywgJ2AnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgyMTksIFsnb3BlbmJyYWNrZXQnLCAnWyddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDIyMCwgWydiYWNrc2xhc2gnLCAnXFxcXCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDIyMSwgWydjbG9zZWJyYWNrZXQnLCAnXSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDIyMiwgWydhcG9zdHJvcGhlJywgJ1xcJyddKTtcblxuICAvLyAwLTlcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ4LCBbJ3plcm8nLCAnMCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ5LCBbJ29uZScsICcxJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTAsIFsndHdvJywgJzInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg1MSwgWyd0aHJlZScsICczJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTIsIFsnZm91cicsICc0J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTMsIFsnZml2ZScsICc1J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTQsIFsnc2l4JywgJzYnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg1NSwgWydzZXZlbicsICc3J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTYsIFsnZWlnaHQnLCAnOCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDU3LCBbJ25pbmUnLCAnOSddKTtcblxuICAvLyBudW1wYWRcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDk2LCBbJ251bXplcm8nLCAnbnVtMCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDk3LCBbJ251bW9uZScsICdudW0xJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoOTgsIFsnbnVtdHdvJywgJ251bTInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg5OSwgWydudW10aHJlZScsICdudW0zJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTAwLCBbJ251bWZvdXInLCAnbnVtNCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwMSwgWydudW1maXZlJywgJ251bTUnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDIsIFsnbnVtc2l4JywgJ251bTYnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDMsIFsnbnVtc2V2ZW4nLCAnbnVtNyddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwNCwgWydudW1laWdodCcsICdudW04J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTA1LCBbJ251bW5pbmUnLCAnbnVtOSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwNiwgWydudW1tdWx0aXBseScsICdudW0qJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTA3LCBbJ251bWFkZCcsICdudW0rJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTA4LCBbJ251bWVudGVyJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTA5LCBbJ251bXN1YnRyYWN0JywgJ251bS0nXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTAsIFsnbnVtZGVjaW1hbCcsICdudW0uJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTExLCBbJ251bWRpdmlkZScsICdudW0vJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTQ0LCBbJ251bWxvY2snLCAnbnVtJ10pO1xuXG4gIC8vIGZ1bmN0aW9uIGtleXNcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExMiwgWydmMSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExMywgWydmMiddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNCwgWydmMyddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNSwgWydmNCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNiwgWydmNSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNywgWydmNiddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExOCwgWydmNyddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExOSwgWydmOCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMCwgWydmOSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMSwgWydmMTAnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMjIsIFsnZjExJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTIzLCBbJ2YxMiddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNCwgWydmMTMnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMjUsIFsnZjE0J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTI2LCBbJ2YxNSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNywgWydmMTYnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMjgsIFsnZjE3J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTI5LCBbJ2YxOCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMCwgWydmMTknXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMzEsIFsnZjIwJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTMyLCBbJ2YyMSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMywgWydmMjInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMzQsIFsnZjIzJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTM1LCBbJ2YyNCddKTtcblxuICAvLyBzZWNvbmRhcnkga2V5IHN5bWJvbHNcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyBgJywgWyd0aWxkZScsICd+J10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDEnLCBbJ2V4Y2xhbWF0aW9uJywgJ2V4Y2xhbWF0aW9ucG9pbnQnLCAnISddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAyJywgWydhdCcsICdAJ10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDMnLCBbJ251bWJlcicsICcjJ10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDQnLCBbJ2RvbGxhcicsICdkb2xsYXJzJywgJ2RvbGxhcnNpZ24nLCAnJCddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA1JywgWydwZXJjZW50JywgJyUnXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgNicsIFsnY2FyZXQnLCAnXiddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA3JywgWydhbXBlcnNhbmQnLCAnYW5kJywgJyYnXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgOCcsIFsnYXN0ZXJpc2snLCAnKiddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA5JywgWydvcGVucGFyZW4nLCAnKCddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAwJywgWydjbG9zZXBhcmVuJywgJyknXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgLScsIFsndW5kZXJzY29yZScsICdfJ10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArID0nLCBbJ3BsdXMnLCAnKyddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyBbJywgWydvcGVuY3VybHlicmFjZScsICdvcGVuY3VybHlicmFja2V0JywgJ3snXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgXScsIFsnY2xvc2VjdXJseWJyYWNlJywgJ2Nsb3NlY3VybHlicmFja2V0JywgJ30nXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgXFxcXCcsIFsndmVydGljYWxiYXInLCAnfCddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA7JywgWydjb2xvbicsICc6J10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIFxcJycsIFsncXVvdGF0aW9ubWFyaycsICdcXCcnXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgISwnLCBbJ29wZW5hbmdsZWJyYWNrZXQnLCAnPCddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAuJywgWydjbG9zZWFuZ2xlYnJhY2tldCcsICc+J10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIC8nLCBbJ3F1ZXN0aW9ubWFyaycsICc/J10pO1xuXG4gIGlmIChwbGF0Zm9ybS5tYXRjaCgnTWFjJykpIHtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdjb21tYW5kJywgWydtb2QnLCAnbW9kaWZpZXInXSk7XG4gIH0gZWxzZSB7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnY3RybCcsIFsnbW9kJywgJ21vZGlmaWVyJ10pO1xuICB9XG5cbiAgLy9hLXogYW5kIEEtWlxuICBmb3IgKGxldCBrZXlDb2RlID0gNjU7IGtleUNvZGUgPD0gOTA7IGtleUNvZGUgKz0gMSkge1xuICAgIHZhciBrZXlOYW1lID0gU3RyaW5nLmZyb21DaGFyQ29kZShrZXlDb2RlICsgMzIpO1xuICAgIHZhciBjYXBpdGFsS2V5TmFtZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoa2V5Q29kZSk7XG4gIFx0bG9jYWxlLmJpbmRLZXlDb2RlKGtleUNvZGUsIGtleU5hbWUpO1xuICBcdGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgJyArIGtleU5hbWUsIGNhcGl0YWxLZXlOYW1lKTtcbiAgXHRsb2NhbGUuYmluZE1hY3JvKCdjYXBzbG9jayArICcgKyBrZXlOYW1lLCBjYXBpdGFsS2V5TmFtZSk7XG4gIH1cblxuICAvLyBicm93c2VyIGNhdmVhdHNcbiAgY29uc3Qgc2VtaWNvbG9uS2V5Q29kZSA9IHVzZXJBZ2VudC5tYXRjaCgnRmlyZWZveCcpID8gNTkgIDogMTg2O1xuICBjb25zdCBkYXNoS2V5Q29kZSAgICAgID0gdXNlckFnZW50Lm1hdGNoKCdGaXJlZm94JykgPyAxNzMgOiAxODk7XG4gIGNvbnN0IGVxdWFsS2V5Q29kZSAgICAgPSB1c2VyQWdlbnQubWF0Y2goJ0ZpcmVmb3gnKSA/IDYxICA6IDE4NztcbiAgbGV0IGxlZnRDb21tYW5kS2V5Q29kZTtcbiAgbGV0IHJpZ2h0Q29tbWFuZEtleUNvZGU7XG4gIGlmIChwbGF0Zm9ybS5tYXRjaCgnTWFjJykgJiYgKHVzZXJBZ2VudC5tYXRjaCgnU2FmYXJpJykgfHwgdXNlckFnZW50Lm1hdGNoKCdDaHJvbWUnKSkpIHtcbiAgICBsZWZ0Q29tbWFuZEtleUNvZGUgID0gOTE7XG4gICAgcmlnaHRDb21tYW5kS2V5Q29kZSA9IDkzO1xuICB9IGVsc2UgaWYocGxhdGZvcm0ubWF0Y2goJ01hYycpICYmIHVzZXJBZ2VudC5tYXRjaCgnT3BlcmEnKSkge1xuICAgIGxlZnRDb21tYW5kS2V5Q29kZSAgPSAxNztcbiAgICByaWdodENvbW1hbmRLZXlDb2RlID0gMTc7XG4gIH0gZWxzZSBpZihwbGF0Zm9ybS5tYXRjaCgnTWFjJykgJiYgdXNlckFnZW50Lm1hdGNoKCdGaXJlZm94JykpIHtcbiAgICBsZWZ0Q29tbWFuZEtleUNvZGUgID0gMjI0O1xuICAgIHJpZ2h0Q29tbWFuZEtleUNvZGUgPSAyMjQ7XG4gIH1cbiAgbG9jYWxlLmJpbmRLZXlDb2RlKHNlbWljb2xvbktleUNvZGUsICAgIFsnc2VtaWNvbG9uJywgJzsnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZShkYXNoS2V5Q29kZSwgICAgICAgICBbJ2Rhc2gnLCAnLSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKGVxdWFsS2V5Q29kZSwgICAgICAgIFsnZXF1YWwnLCAnZXF1YWxzaWduJywgJz0nXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZShsZWZ0Q29tbWFuZEtleUNvZGUsICBbJ2NvbW1hbmQnLCAnd2luZG93cycsICd3aW4nLCAnc3VwZXInLCAnbGVmdGNvbW1hbmQnLCAnbGVmdHdpbmRvd3MnLCAnbGVmdHdpbicsICdsZWZ0c3VwZXInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZShyaWdodENvbW1hbmRLZXlDb2RlLCBbJ2NvbW1hbmQnLCAnd2luZG93cycsICd3aW4nLCAnc3VwZXInLCAncmlnaHRjb21tYW5kJywgJ3JpZ2h0d2luZG93cycsICdyaWdodHdpbicsICdyaWdodHN1cGVyJ10pO1xuXG4gIC8vIGtpbGwga2V5c1xuICBsb2NhbGUuc2V0S2lsbEtleSgnY29tbWFuZCcpO1xufTtcbiIsImltcG9ydCB7IEtleWJvYXJkIH0gZnJvbSAnLi9saWIva2V5Ym9hcmQnO1xuaW1wb3J0IHsgTG9jYWxlIH0gZnJvbSAnLi9saWIvbG9jYWxlJztcbmltcG9ydCB7IEtleUNvbWJvIH0gZnJvbSAnLi9saWIva2V5LWNvbWJvJztcbmltcG9ydCB7IHVzIH0gZnJvbSAnLi9sb2NhbGVzL3VzJztcblxuY29uc3Qga2V5Ym9hcmQgPSBuZXcgS2V5Ym9hcmQoKTtcblxua2V5Ym9hcmQuc2V0TG9jYWxlKCd1cycsIHVzKTtcblxua2V5Ym9hcmQuS2V5Ym9hcmQgPSBLZXlib2FyZDtcbmtleWJvYXJkLkxvY2FsZSA9IExvY2FsZTtcbmtleWJvYXJkLktleUNvbWJvID0gS2V5Q29tYm87XG5cbmV4cG9ydCBkZWZhdWx0IGtleWJvYXJkO1xuIl0sIm5hbWVzIjpbIktleUNvbWJvIiwia2V5Q29tYm9TdHIiLCJzb3VyY2VTdHIiLCJzdWJDb21ib3MiLCJwYXJzZUNvbWJvU3RyIiwia2V5TmFtZXMiLCJyZWR1Y2UiLCJtZW1vIiwibmV4dFN1YkNvbWJvIiwiY29uY2F0IiwicHJlc3NlZEtleU5hbWVzIiwic3RhcnRpbmdLZXlOYW1lSW5kZXgiLCJpIiwibGVuZ3RoIiwiX2NoZWNrU3ViQ29tYm8iLCJvdGhlcktleUNvbWJvIiwic3ViQ29tYm8iLCJvdGhlclN1YkNvbWJvIiwic2xpY2UiLCJqIiwia2V5TmFtZSIsImluZGV4IiwiaW5kZXhPZiIsInNwbGljZSIsImVuZEluZGV4IiwiZXNjYXBlZEtleU5hbWUiLCJjb21ib0RlbGltaW5hdG9yIiwia2V5RGVsaW1pbmF0b3IiLCJzdWJDb21ib1N0cnMiLCJfc3BsaXRTdHIiLCJjb21ibyIsInB1c2giLCJzdHIiLCJkZWxpbWluYXRvciIsInMiLCJkIiwiYyIsImNhIiwiY2kiLCJ0cmltIiwiTG9jYWxlIiwibmFtZSIsImxvY2FsZU5hbWUiLCJhY3RpdmVUYXJnZXRLZXlzIiwicHJlc3NlZEtleXMiLCJfYXBwbGllZE1hY3JvcyIsIl9rZXlNYXAiLCJfa2lsbEtleUNvZGVzIiwiX21hY3JvcyIsImtleUNvZGUiLCJoYW5kbGVyIiwibWFjcm8iLCJrZXlDb21ibyIsImtleUNvZGVzIiwiZ2V0S2V5Q29kZXMiLCJzZXRLaWxsS2V5IiwicHJlc3NLZXkiLCJnZXRLZXlOYW1lcyIsIl9hcHBseU1hY3JvcyIsInJlbGVhc2VLZXkiLCJraWxsS2V5Q29kZUluZGV4IiwiX2NsZWFyTWFjcm9zIiwibWFjcm9zIiwiY2hlY2siLCJLZXlib2FyZCIsInRhcmdldFdpbmRvdyIsInRhcmdldEVsZW1lbnQiLCJ0YXJnZXRQbGF0Zm9ybSIsInRhcmdldFVzZXJBZ2VudCIsIl9sb2NhbGUiLCJfY3VycmVudENvbnRleHQiLCJfY29udGV4dHMiLCJfbGlzdGVuZXJzIiwiX2FwcGxpZWRMaXN0ZW5lcnMiLCJfbG9jYWxlcyIsIl90YXJnZXRFbGVtZW50IiwiX3RhcmdldFdpbmRvdyIsIl90YXJnZXRQbGF0Zm9ybSIsIl90YXJnZXRVc2VyQWdlbnQiLCJfaXNNb2Rlcm5Ccm93c2VyIiwiX3RhcmdldEtleURvd25CaW5kaW5nIiwiX3RhcmdldEtleVVwQmluZGluZyIsIl90YXJnZXRSZXNldEJpbmRpbmciLCJfcGF1c2VkIiwiZ2xvYmFsIiwibGlzdGVuZXJzIiwic2V0Q29udGV4dCIsImxvY2FsZUJ1aWxkZXIiLCJsb2NhbGUiLCJfbG9jYWxlTmFtZSIsImxvY2FsTmFtZSIsInByZXNzSGFuZGxlciIsInJlbGVhc2VIYW5kbGVyIiwicHJldmVudFJlcGVhdEJ5RGVmYXVsdCIsImJpbmQiLCJwcmV2ZW50UmVwZWF0IiwiZXhlY3V0aW5nSGFuZGxlciIsInVuYmluZCIsImxpc3RlbmVyIiwiY29tYm9NYXRjaGVzIiwiaXNFcXVhbCIsInByZXNzSGFuZGxlck1hdGNoZXMiLCJyZWxlYXNlSGFuZGxlck1hdGNoZXMiLCJjb250ZXh0TmFtZSIsInJlbGVhc2VBbGxLZXlzIiwiZ2xvYmFsQ29udGV4dCIsImNvbnRleHQiLCJzdG9wIiwid2F0Y2giLCJjYWxsYmFjayIsInByZXZpb3VzQ29udGV4dE5hbWUiLCJnZXRDb250ZXh0Iiwid2luIiwiZ2xvYmFsVGhpcyIsIndpbmRvdyIsImFkZEV2ZW50TGlzdGVuZXIiLCJhdHRhY2hFdmVudCIsIkVycm9yIiwibm9kZVR5cGUiLCJ1c2VyQWdlbnQiLCJuYXZpZ2F0b3IiLCJwbGF0Zm9ybSIsImRvY3VtZW50IiwiZXZlbnQiLCJfaGFuZGxlQ29tbWFuZEJ1ZyIsIl9iaW5kRXZlbnQiLCJjdXJyZW50Q29udGV4dCIsIl91bmJpbmRFdmVudCIsIl9hcHBseUJpbmRpbmdzIiwiX2NsZWFyQmluZGluZ3MiLCJldmVudE5hbWUiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiZGV0YWNoRXZlbnQiLCJsaXN0ZW5lckdyb3VwcyIsImxpc3RlbmVyR3JvdXBNYXAiLCJzb3J0IiwiYSIsImIiLCJmb3JFYWNoIiwibCIsIm1hcEluZGV4IiwiX2dldEdyb3VwZWRMaXN0ZW5lcnMiLCJzb21lIiwiayIsImluY2x1ZGVzIiwiY2FsbCIsIm1vZGlmaWVyS2V5cyIsIm1hdGNoIiwidXMiLCJiaW5kS2V5Q29kZSIsImJpbmRNYWNybyIsIlN0cmluZyIsImZyb21DaGFyQ29kZSIsImNhcGl0YWxLZXlOYW1lIiwic2VtaWNvbG9uS2V5Q29kZSIsImRhc2hLZXlDb2RlIiwiZXF1YWxLZXlDb2RlIiwibGVmdENvbW1hbmRLZXlDb2RlIiwicmlnaHRDb21tYW5kS2V5Q29kZSIsImtleWJvYXJkIiwic2V0TG9jYWxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztNQUNhQSxRQUFiO0VBQ0Usb0JBQVlDLFdBQVosRUFBeUI7RUFBQTs7RUFDdkIsU0FBS0MsU0FBTCxHQUFpQkQsV0FBakI7RUFDQSxTQUFLRSxTQUFMLEdBQWlCSCxRQUFRLENBQUNJLGFBQVQsQ0FBdUJILFdBQXZCLENBQWpCO0VBQ0EsU0FBS0ksUUFBTCxHQUFpQixLQUFLRixTQUFMLENBQWVHLE1BQWYsQ0FBc0IsVUFBQ0MsSUFBRCxFQUFPQyxZQUFQO0VBQUEsYUFDckNELElBQUksQ0FBQ0UsTUFBTCxDQUFZRCxZQUFaLENBRHFDO0VBQUEsS0FBdEIsRUFDWSxFQURaLENBQWpCO0VBRUQ7O0VBTkg7RUFBQTtFQUFBLDBCQVFRRSxlQVJSLEVBUXlCO0VB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
1100
1101
1102 /***/ }),
1103
1104 /***/ "./node_modules/lodash/lodash.js":
1105 /*!***************************************!*\
1106   !*** ./node_modules/lodash/lodash.js ***!
1107   \***************************************/
1108 /***/ (function(module, exports, __webpack_require__) {
1109
1110 /* module decorator */ module = __webpack_require__.nmd(module);
1111 var __WEBPACK_AMD_DEFINE_RESULT__;/**
1112  * @license
1113  * Lodash <https://lodash.com/>
1114  * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
1115  * Released under MIT license <https://lodash.com/license>
1116  * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
1117  * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
1118  */
1119 ;(function() {
1120
1121   /** Used as a safe reference for `undefined` in pre-ES5 environments. */
1122   var undefined;
1123
1124   /** Used as the semantic version number. */
1125   var VERSION = '4.17.21';
1126
1127   /** Used as the size to enable large array optimizations. */
1128   var LARGE_ARRAY_SIZE = 200;
1129
1130   /** Error message constants. */
1131   var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
1132       FUNC_ERROR_TEXT = 'Expected a function',
1133       INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`';
1134
1135   /** Used to stand-in for `undefined` hash values. */
1136   var HASH_UNDEFINED = '__lodash_hash_undefined__';
1137
1138   /** Used as the maximum memoize cache size. */
1139   var MAX_MEMOIZE_SIZE = 500;
1140
1141   /** Used as the internal argument placeholder. */
1142   var PLACEHOLDER = '__lodash_placeholder__';
1143
1144   /** Used to compose bitmasks for cloning. */
1145   var CLONE_DEEP_FLAG = 1,
1146       CLONE_FLAT_FLAG = 2,
1147       CLONE_SYMBOLS_FLAG = 4;
1148
1149   /** Used to compose bitmasks for value comparisons. */
1150   var COMPARE_PARTIAL_FLAG = 1,
1151       COMPARE_UNORDERED_FLAG = 2;
1152
1153   /** Used to compose bitmasks for function metadata. */
1154   var WRAP_BIND_FLAG = 1,
1155       WRAP_BIND_KEY_FLAG = 2,
1156       WRAP_CURRY_BOUND_FLAG = 4,
1157       WRAP_CURRY_FLAG = 8,
1158       WRAP_CURRY_RIGHT_FLAG = 16,
1159       WRAP_PARTIAL_FLAG = 32,
1160       WRAP_PARTIAL_RIGHT_FLAG = 64,
1161       WRAP_ARY_FLAG = 128,
1162       WRAP_REARG_FLAG = 256,
1163       WRAP_FLIP_FLAG = 512;
1164
1165   /** Used as default options for `_.truncate`. */
1166   var DEFAULT_TRUNC_LENGTH = 30,
1167       DEFAULT_TRUNC_OMISSION = '...';
1168
1169   /** Used to detect hot functions by number of calls within a span of milliseconds. */
1170   var HOT_COUNT = 800,
1171       HOT_SPAN = 16;
1172
1173   /** Used to indicate the type of lazy iteratees. */
1174   var LAZY_FILTER_FLAG = 1,
1175       LAZY_MAP_FLAG = 2,
1176       LAZY_WHILE_FLAG = 3;
1177
1178   /** Used as references for various `Number` constants. */
1179   var INFINITY = 1 / 0,
1180       MAX_SAFE_INTEGER = 9007199254740991,
1181       MAX_INTEGER = 1.7976931348623157e+308,
1182       NAN = 0 / 0;
1183
1184   /** Used as references for the maximum length and index of an array. */
1185   var MAX_ARRAY_LENGTH = 4294967295,
1186       MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
1187       HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
1188
1189   /** Used to associate wrap methods with their bit flags. */
1190   var wrapFlags = [
1191     ['ary', WRAP_ARY_FLAG],
1192     ['bind', WRAP_BIND_FLAG],
1193     ['bindKey', WRAP_BIND_KEY_FLAG],
1194     ['curry', WRAP_CURRY_FLAG],
1195     ['curryRight', WRAP_CURRY_RIGHT_FLAG],
1196     ['flip', WRAP_FLIP_FLAG],
1197     ['partial', WRAP_PARTIAL_FLAG],
1198     ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
1199     ['rearg', WRAP_REARG_FLAG]
1200   ];
1201
1202   /** `Object#toString` result references. */
1203   var argsTag = '[object Arguments]',
1204       arrayTag = '[object Array]',
1205       asyncTag = '[object AsyncFunction]',
1206       boolTag = '[object Boolean]',
1207       dateTag = '[object Date]',
1208       domExcTag = '[object DOMException]',
1209       errorTag = '[object Error]',
1210       funcTag = '[object Function]',
1211       genTag = '[object GeneratorFunction]',
1212       mapTag = '[object Map]',
1213       numberTag = '[object Number]',
1214       nullTag = '[object Null]',
1215       objectTag = '[object Object]',
1216       promiseTag = '[object Promise]',
1217       proxyTag = '[object Proxy]',
1218       regexpTag = '[object RegExp]',
1219       setTag = '[object Set]',
1220       stringTag = '[object String]',
1221       symbolTag = '[object Symbol]',
1222       undefinedTag = '[object Undefined]',
1223       weakMapTag = '[object WeakMap]',
1224       weakSetTag = '[object WeakSet]';
1225
1226   var arrayBufferTag = '[object ArrayBuffer]',
1227       dataViewTag = '[object DataView]',
1228       float32Tag = '[object Float32Array]',
1229       float64Tag = '[object Float64Array]',
1230       int8Tag = '[object Int8Array]',
1231       int16Tag = '[object Int16Array]',
1232       int32Tag = '[object Int32Array]',
1233       uint8Tag = '[object Uint8Array]',
1234       uint8ClampedTag = '[object Uint8ClampedArray]',
1235       uint16Tag = '[object Uint16Array]',
1236       uint32Tag = '[object Uint32Array]';
1237
1238   /** Used to match empty string literals in compiled template source. */
1239   var reEmptyStringLeading = /\b__p \+= '';/g,
1240       reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
1241       reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
1242
1243   /** Used to match HTML entities and HTML characters. */
1244   var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
1245       reUnescapedHtml = /[&<>"']/g,
1246       reHasEscapedHtml = RegExp(reEscapedHtml.source),
1247       reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
1248
1249   /** Used to match template delimiters. */
1250   var reEscape = /<%-([\s\S]+?)%>/g,
1251       reEvaluate = /<%([\s\S]+?)%>/g,
1252       reInterpolate = /<%=([\s\S]+?)%>/g;
1253
1254   /** Used to match property names within property paths. */
1255   var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
1256       reIsPlainProp = /^\w*$/,
1257       rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
1258
1259   /**
1260    * Used to match `RegExp`
1261    * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
1262    */
1263   var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
1264       reHasRegExpChar = RegExp(reRegExpChar.source);
1265
1266   /** Used to match leading whitespace. */
1267   var reTrimStart = /^\s+/;
1268
1269   /** Used to match a single whitespace character. */
1270   var reWhitespace = /\s/;
1271
1272   /** Used to match wrap detail comments. */
1273   var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
1274       reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
1275       reSplitDetails = /,? & /;
1276
1277   /** Used to match words composed of alphanumeric characters. */
1278   var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
1279
1280   /**
1281    * Used to validate the `validate` option in `_.template` variable.
1282    *
1283    * Forbids characters which could potentially change the meaning of the function argument definition:
1284    * - "()," (modification of function parameters)
1285    * - "=" (default value)
1286    * - "[]{}" (destructuring of function parameters)
1287    * - "/" (beginning of a comment)
1288    * - whitespace
1289    */
1290   var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
1291
1292   /** Used to match backslashes in property paths. */
1293   var reEscapeChar = /\\(\\)?/g;
1294
1295   /**
1296    * Used to match
1297    * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
1298    */
1299   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
1300
1301   /** Used to match `RegExp` flags from their coerced string values. */
1302   var reFlags = /\w*$/;
1303
1304   /** Used to detect bad signed hexadecimal string values. */
1305   var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
1306
1307   /** Used to detect binary string values. */
1308   var reIsBinary = /^0b[01]+$/i;
1309
1310   /** Used to detect host constructors (Safari). */
1311   var reIsHostCtor = /^\[object .+?Constructor\]$/;
1312
1313   /** Used to detect octal string values. */
1314   var reIsOctal = /^0o[0-7]+$/i;
1315
1316   /** Used to detect unsigned integer values. */
1317   var reIsUint = /^(?:0|[1-9]\d*)$/;
1318
1319   /** Used to match Latin Unicode letters (excluding mathematical operators). */
1320   var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
1321
1322   /** Used to ensure capturing order of template delimiters. */
1323   var reNoMatch = /($^)/;
1324
1325   /** Used to match unescaped characters in compiled string literals. */
1326   var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
1327
1328   /** Used to compose unicode character classes. */
1329   var rsAstralRange = '\\ud800-\\udfff',
1330       rsComboMarksRange = '\\u0300-\\u036f',
1331       reComboHalfMarksRange = '\\ufe20-\\ufe2f',
1332       rsComboSymbolsRange = '\\u20d0-\\u20ff',
1333       rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
1334       rsDingbatRange = '\\u2700-\\u27bf',
1335       rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
1336       rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
1337       rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
1338       rsPunctuationRange = '\\u2000-\\u206f',
1339       rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
1340       rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
1341       rsVarRange = '\\ufe0e\\ufe0f',
1342       rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
1343
1344   /** Used to compose unicode capture groups. */
1345   var rsApos = "['\u2019]",
1346       rsAstral = '[' + rsAstralRange + ']',
1347       rsBreak = '[' + rsBreakRange + ']',
1348       rsCombo = '[' + rsComboRange + ']',
1349       rsDigits = '\\d+',
1350       rsDingbat = '[' + rsDingbatRange + ']',
1351       rsLower = '[' + rsLowerRange + ']',
1352       rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
1353       rsFitz = '\\ud83c[\\udffb-\\udfff]',
1354       rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
1355       rsNonAstral = '[^' + rsAstralRange + ']',
1356       rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
1357       rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
1358       rsUpper = '[' + rsUpperRange + ']',
1359       rsZWJ = '\\u200d';
1360
1361   /** Used to compose unicode regexes. */
1362   var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
1363       rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
1364       rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
1365       rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
1366       reOptMod = rsModifier + '?',
1367       rsOptVar = '[' + rsVarRange + ']?',
1368       rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
1369       rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
1370       rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
1371       rsSeq = rsOptVar + reOptMod + rsOptJoin,
1372       rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
1373       rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
1374
1375   /** Used to match apostrophes. */
1376   var reApos = RegExp(rsApos, 'g');
1377
1378   /**
1379    * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
1380    * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
1381    */
1382   var reComboMark = RegExp(rsCombo, 'g');
1383
1384   /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
1385   var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
1386
1387   /** Used to match complex or compound words. */
1388   var reUnicodeWord = RegExp([
1389     rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
1390     rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
1391     rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
1392     rsUpper + '+' + rsOptContrUpper,
1393     rsOrdUpper,
1394     rsOrdLower,
1395     rsDigits,
1396     rsEmoji
1397   ].join('|'), 'g');
1398
1399   /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
1400   var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
1401
1402   /** Used to detect strings that need a more robust regexp to match words. */
1403   var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
1404
1405   /** Used to assign default `context` object properties. */
1406   var contextProps = [
1407     'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
1408     'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
1409     'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
1410     'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
1411     '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
1412   ];
1413
1414   /** Used to make template sourceURLs easier to identify. */
1415   var templateCounter = -1;
1416
1417   /** Used to identify `toStringTag` values of typed arrays. */
1418   var typedArrayTags = {};
1419   typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
1420   typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
1421   typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
1422   typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
1423   typedArrayTags[uint32Tag] = true;
1424   typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
1425   typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
1426   typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
1427   typedArrayTags[errorTag] = typedArrayTags[funcTag] =
1428   typedArrayTags[mapTag] = typedArrayTags[numberTag] =
1429   typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
1430   typedArrayTags[setTag] = typedArrayTags[stringTag] =
1431   typedArrayTags[weakMapTag] = false;
1432
1433   /** Used to identify `toStringTag` values supported by `_.clone`. */
1434   var cloneableTags = {};
1435   cloneableTags[argsTag] = cloneableTags[arrayTag] =
1436   cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
1437   cloneableTags[boolTag] = cloneableTags[dateTag] =
1438   cloneableTags[float32Tag] = cloneableTags[float64Tag] =
1439   cloneableTags[int8Tag] = cloneableTags[int16Tag] =
1440   cloneableTags[int32Tag] = cloneableTags[mapTag] =
1441   cloneableTags[numberTag] = cloneableTags[objectTag] =
1442   cloneableTags[regexpTag] = cloneableTags[setTag] =
1443   cloneableTags[stringTag] = cloneableTags[symbolTag] =
1444   cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
1445   cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
1446   cloneableTags[errorTag] = cloneableTags[funcTag] =
1447   cloneableTags[weakMapTag] = false;
1448
1449   /** Used to map Latin Unicode letters to basic Latin letters. */
1450   var deburredLetters = {
1451     // Latin-1 Supplement block.
1452     '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
1453     '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
1454     '\xc7': 'C',  '\xe7': 'c',
1455     '\xd0': 'D',  '\xf0': 'd',
1456     '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
1457     '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
1458     '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
1459     '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
1460     '\xd1': 'N',  '\xf1': 'n',
1461     '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
1462     '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
1463     '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
1464     '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
1465     '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
1466     '\xc6': 'Ae', '\xe6': 'ae',
1467     '\xde': 'Th', '\xfe': 'th',
1468     '\xdf': 'ss',
1469     // Latin Extended-A block.
1470     '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
1471     '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
1472     '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
1473     '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
1474     '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
1475     '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
1476     '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
1477     '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
1478     '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
1479     '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
1480     '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
1481     '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
1482     '\u0134': 'J',  '\u0135': 'j',
1483     '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
1484     '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
1485     '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
1486     '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
1487     '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
1488     '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
1489     '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
1490     '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
1491     '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
1492     '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
1493     '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
1494     '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
1495     '\u0163': 't',  '\u0165': 't', '\u0167': 't',
1496     '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
1497     '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
1498     '\u0174': 'W',  '\u0175': 'w',
1499     '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
1500     '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
1501     '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
1502     '\u0132': 'IJ', '\u0133': 'ij',
1503     '\u0152': 'Oe', '\u0153': 'oe',
1504     '\u0149': "'n", '\u017f': 's'
1505   };
1506
1507   /** Used to map characters to HTML entities. */
1508   var htmlEscapes = {
1509     '&': '&amp;',
1510     '<': '&lt;',
1511     '>': '&gt;',
1512     '"': '&quot;',
1513     "'": '&#39;'
1514   };
1515
1516   /** Used to map HTML entities to characters. */
1517   var htmlUnescapes = {
1518     '&amp;': '&',
1519     '&lt;': '<',
1520     '&gt;': '>',
1521     '&quot;': '"',
1522     '&#39;': "'"
1523   };
1524
1525   /** Used to escape characters for inclusion in compiled string literals. */
1526   var stringEscapes = {
1527     '\\': '\\',
1528     "'": "'",
1529     '\n': 'n',
1530     '\r': 'r',
1531     '\u2028': 'u2028',
1532     '\u2029': 'u2029'
1533   };
1534
1535   /** Built-in method references without a dependency on `root`. */
1536   var freeParseFloat = parseFloat,
1537       freeParseInt = parseInt;
1538
1539   /** Detect free variable `global` from Node.js. */
1540   var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g;
1541
1542   /** Detect free variable `self`. */
1543   var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
1544
1545   /** Used as a reference to the global object. */
1546   var root = freeGlobal || freeSelf || Function('return this')();
1547
1548   /** Detect free variable `exports`. */
1549   var freeExports =  true && exports && !exports.nodeType && exports;
1550
1551   /** Detect free variable `module`. */
1552   var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
1553
1554   /** Detect the popular CommonJS extension `module.exports`. */
1555   var moduleExports = freeModule && freeModule.exports === freeExports;
1556
1557   /** Detect free variable `process` from Node.js. */
1558   var freeProcess = moduleExports && freeGlobal.process;
1559
1560   /** Used to access faster Node.js helpers. */
1561   var nodeUtil = (function() {
1562     try {
1563       // Use `util.types` for Node.js 10+.
1564       var types = freeModule && freeModule.require && freeModule.require('util').types;
1565
1566       if (types) {
1567         return types;
1568       }
1569
1570       // Legacy `process.binding('util')` for Node.js < 10.
1571       return freeProcess && freeProcess.binding && freeProcess.binding('util');
1572     } catch (e) {}
1573   }());
1574
1575   /* Node.js helper references. */
1576   var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
1577       nodeIsDate = nodeUtil && nodeUtil.isDate,
1578       nodeIsMap = nodeUtil && nodeUtil.isMap,
1579       nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
1580       nodeIsSet = nodeUtil && nodeUtil.isSet,
1581       nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
1582
1583   /*--------------------------------------------------------------------------*/
1584
1585   /**
1586    * A faster alternative to `Function#apply`, this function invokes `func`
1587    * with the `this` binding of `thisArg` and the arguments of `args`.
1588    *
1589    * @private
1590    * @param {Function} func The function to invoke.
1591    * @param {*} thisArg The `this` binding of `func`.
1592    * @param {Array} args The arguments to invoke `func` with.
1593    * @returns {*} Returns the result of `func`.
1594    */
1595   function apply(func, thisArg, args) {
1596     switch (args.length) {
1597       case 0: return func.call(thisArg);
1598       case 1: return func.call(thisArg, args[0]);
1599       case 2: return func.call(thisArg, args[0], args[1]);
1600       case 3: return func.call(thisArg, args[0], args[1], args[2]);
1601     }
1602     return func.apply(thisArg, args);
1603   }
1604
1605   /**
1606    * A specialized version of `baseAggregator` for arrays.
1607    *
1608    * @private
1609    * @param {Array} [array] The array to iterate over.
1610    * @param {Function} setter The function to set `accumulator` values.
1611    * @param {Function} iteratee The iteratee to transform keys.
1612    * @param {Object} accumulator The initial aggregated object.
1613    * @returns {Function} Returns `accumulator`.
1614    */
1615   function arrayAggregator(array, setter, iteratee, accumulator) {
1616     var index = -1,
1617         length = array == null ? 0 : array.length;
1618
1619     while (++index < length) {
1620       var value = array[index];
1621       setter(accumulator, value, iteratee(value), array);
1622     }
1623     return accumulator;
1624   }
1625
1626   /**
1627    * A specialized version of `_.forEach` for arrays without support for
1628    * iteratee shorthands.
1629    *
1630    * @private
1631    * @param {Array} [array] The array to iterate over.
1632    * @param {Function} iteratee The function invoked per iteration.
1633    * @returns {Array} Returns `array`.
1634    */
1635   function arrayEach(array, iteratee) {
1636     var index = -1,
1637         length = array == null ? 0 : array.length;
1638
1639     while (++index < length) {
1640       if (iteratee(array[index], index, array) === false) {
1641         break;
1642       }
1643     }
1644     return array;
1645   }
1646
1647   /**
1648    * A specialized version of `_.forEachRight` for arrays without support for
1649    * iteratee shorthands.
1650    *
1651    * @private
1652    * @param {Array} [array] The array to iterate over.
1653    * @param {Function} iteratee The function invoked per iteration.
1654    * @returns {Array} Returns `array`.
1655    */
1656   function arrayEachRight(array, iteratee) {
1657     var length = array == null ? 0 : array.length;
1658
1659     while (length--) {
1660       if (iteratee(array[length], length, array) === false) {
1661         break;
1662       }
1663     }
1664     return array;
1665   }
1666
1667   /**
1668    * A specialized version of `_.every` for arrays without support for
1669    * iteratee shorthands.
1670    *
1671    * @private
1672    * @param {Array} [array] The array to iterate over.
1673    * @param {Function} predicate The function invoked per iteration.
1674    * @returns {boolean} Returns `true` if all elements pass the predicate check,
1675    *  else `false`.
1676    */
1677   function arrayEvery(array, predicate) {
1678     var index = -1,
1679         length = array == null ? 0 : array.length;
1680
1681     while (++index < length) {
1682       if (!predicate(array[index], index, array)) {
1683         return false;
1684       }
1685     }
1686     return true;
1687   }
1688
1689   /**
1690    * A specialized version of `_.filter` for arrays without support for
1691    * iteratee shorthands.
1692    *
1693    * @private
1694    * @param {Array} [array] The array to iterate over.
1695    * @param {Function} predicate The function invoked per iteration.
1696    * @returns {Array} Returns the new filtered array.
1697    */
1698   function arrayFilter(array, predicate) {
1699     var index = -1,
1700         length = array == null ? 0 : array.length,
1701         resIndex = 0,
1702         result = [];
1703
1704     while (++index < length) {
1705       var value = array[index];
1706       if (predicate(value, index, array)) {
1707         result[resIndex++] = value;
1708       }
1709     }
1710     return result;
1711   }
1712
1713   /**
1714    * A specialized version of `_.includes` for arrays without support for
1715    * specifying an index to search from.
1716    *
1717    * @private
1718    * @param {Array} [array] The array to inspect.
1719    * @param {*} target The value to search for.
1720    * @returns {boolean} Returns `true` if `target` is found, else `false`.
1721    */
1722   function arrayIncludes(array, value) {
1723     var length = array == null ? 0 : array.length;
1724     return !!length && baseIndexOf(array, value, 0) > -1;
1725   }
1726
1727   /**
1728    * This function is like `arrayIncludes` except that it accepts a comparator.
1729    *
1730    * @private
1731    * @param {Array} [array] The array to inspect.
1732    * @param {*} target The value to search for.
1733    * @param {Function} comparator The comparator invoked per element.
1734    * @returns {boolean} Returns `true` if `target` is found, else `false`.
1735    */
1736   function arrayIncludesWith(array, value, comparator) {
1737     var index = -1,
1738         length = array == null ? 0 : array.length;
1739
1740     while (++index < length) {
1741       if (comparator(value, array[index])) {
1742         return true;
1743       }
1744     }
1745     return false;
1746   }
1747
1748   /**
1749    * A specialized version of `_.map` for arrays without support for iteratee
1750    * shorthands.
1751    *
1752    * @private
1753    * @param {Array} [array] The array to iterate over.
1754    * @param {Function} iteratee The function invoked per iteration.
1755    * @returns {Array} Returns the new mapped array.
1756    */
1757   function arrayMap(array, iteratee) {
1758     var index = -1,
1759         length = array == null ? 0 : array.length,
1760         result = Array(length);
1761
1762     while (++index < length) {
1763       result[index] = iteratee(array[index], index, array);
1764     }
1765     return result;
1766   }
1767
1768   /**
1769    * Appends the elements of `values` to `array`.
1770    *
1771    * @private
1772    * @param {Array} array The array to modify.
1773    * @param {Array} values The values to append.
1774    * @returns {Array} Returns `array`.
1775    */
1776   function arrayPush(array, values) {
1777     var index = -1,
1778         length = values.length,
1779         offset = array.length;
1780
1781     while (++index < length) {
1782       array[offset + index] = values[index];
1783     }
1784     return array;
1785   }
1786
1787   /**
1788    * A specialized version of `_.reduce` for arrays without support for
1789    * iteratee shorthands.
1790    *
1791    * @private
1792    * @param {Array} [array] The array to iterate over.
1793    * @param {Function} iteratee The function invoked per iteration.
1794    * @param {*} [accumulator] The initial value.
1795    * @param {boolean} [initAccum] Specify using the first element of `array` as
1796    *  the initial value.
1797    * @returns {*} Returns the accumulated value.
1798    */
1799   function arrayReduce(array, iteratee, accumulator, initAccum) {
1800     var index = -1,
1801         length = array == null ? 0 : array.length;
1802
1803     if (initAccum && length) {
1804       accumulator = array[++index];
1805     }
1806     while (++index < length) {
1807       accumulator = iteratee(accumulator, array[index], index, array);
1808     }
1809     return accumulator;
1810   }
1811
1812   /**
1813    * A specialized version of `_.reduceRight` for arrays without support for
1814    * iteratee shorthands.
1815    *
1816    * @private
1817    * @param {Array} [array] The array to iterate over.
1818    * @param {Function} iteratee The function invoked per iteration.
1819    * @param {*} [accumulator] The initial value.
1820    * @param {boolean} [initAccum] Specify using the last element of `array` as
1821    *  the initial value.
1822    * @returns {*} Returns the accumulated value.
1823    */
1824   function arrayReduceRight(array, iteratee, accumulator, initAccum) {
1825     var length = array == null ? 0 : array.length;
1826     if (initAccum && length) {
1827       accumulator = array[--length];
1828     }
1829     while (length--) {
1830       accumulator = iteratee(accumulator, array[length], length, array);
1831     }
1832     return accumulator;
1833   }
1834
1835   /**
1836    * A specialized version of `_.some` for arrays without support for iteratee
1837    * shorthands.
1838    *
1839    * @private
1840    * @param {Array} [array] The array to iterate over.
1841    * @param {Function} predicate The function invoked per iteration.
1842    * @returns {boolean} Returns `true` if any element passes the predicate check,
1843    *  else `false`.
1844    */
1845   function arraySome(array, predicate) {
1846     var index = -1,
1847         length = array == null ? 0 : array.length;
1848
1849     while (++index < length) {
1850       if (predicate(array[index], index, array)) {
1851         return true;
1852       }
1853     }
1854     return false;
1855   }
1856
1857   /**
1858    * Gets the size of an ASCII `string`.
1859    *
1860    * @private
1861    * @param {string} string The string inspect.
1862    * @returns {number} Returns the string size.
1863    */
1864   var asciiSize = baseProperty('length');
1865
1866   /**
1867    * Converts an ASCII `string` to an array.
1868    *
1869    * @private
1870    * @param {string} string The string to convert.
1871    * @returns {Array} Returns the converted array.
1872    */
1873   function asciiToArray(string) {
1874     return string.split('');
1875   }
1876
1877   /**
1878    * Splits an ASCII `string` into an array of its words.
1879    *
1880    * @private
1881    * @param {string} The string to inspect.
1882    * @returns {Array} Returns the words of `string`.
1883    */
1884   function asciiWords(string) {
1885     return string.match(reAsciiWord) || [];
1886   }
1887
1888   /**
1889    * The base implementation of methods like `_.findKey` and `_.findLastKey`,
1890    * without support for iteratee shorthands, which iterates over `collection`
1891    * using `eachFunc`.
1892    *
1893    * @private
1894    * @param {Array|Object} collection The collection to inspect.
1895    * @param {Function} predicate The function invoked per iteration.
1896    * @param {Function} eachFunc The function to iterate over `collection`.
1897    * @returns {*} Returns the found element or its key, else `undefined`.
1898    */
1899   function baseFindKey(collection, predicate, eachFunc) {
1900     var result;
1901     eachFunc(collection, function(value, key, collection) {
1902       if (predicate(value, key, collection)) {
1903         result = key;
1904         return false;
1905       }
1906     });
1907     return result;
1908   }
1909
1910   /**
1911    * The base implementation of `_.findIndex` and `_.findLastIndex` without
1912    * support for iteratee shorthands.
1913    *
1914    * @private
1915    * @param {Array} array The array to inspect.
1916    * @param {Function} predicate The function invoked per iteration.
1917    * @param {number} fromIndex The index to search from.
1918    * @param {boolean} [fromRight] Specify iterating from right to left.
1919    * @returns {number} Returns the index of the matched value, else `-1`.
1920    */
1921   function baseFindIndex(array, predicate, fromIndex, fromRight) {
1922     var length = array.length,
1923         index = fromIndex + (fromRight ? 1 : -1);
1924
1925     while ((fromRight ? index-- : ++index < length)) {
1926       if (predicate(array[index], index, array)) {
1927         return index;
1928       }
1929     }
1930     return -1;
1931   }
1932
1933   /**
1934    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
1935    *
1936    * @private
1937    * @param {Array} array The array to inspect.
1938    * @param {*} value The value to search for.
1939    * @param {number} fromIndex The index to search from.
1940    * @returns {number} Returns the index of the matched value, else `-1`.
1941    */
1942   function baseIndexOf(array, value, fromIndex) {
1943     return value === value
1944       ? strictIndexOf(array, value, fromIndex)
1945       : baseFindIndex(array, baseIsNaN, fromIndex);
1946   }
1947
1948   /**
1949    * This function is like `baseIndexOf` except that it accepts a comparator.
1950    *
1951    * @private
1952    * @param {Array} array The array to inspect.
1953    * @param {*} value The value to search for.
1954    * @param {number} fromIndex The index to search from.
1955    * @param {Function} comparator The comparator invoked per element.
1956    * @returns {number} Returns the index of the matched value, else `-1`.
1957    */
1958   function baseIndexOfWith(array, value, fromIndex, comparator) {
1959     var index = fromIndex - 1,
1960         length = array.length;
1961
1962     while (++index < length) {
1963       if (comparator(array[index], value)) {
1964         return index;
1965       }
1966     }
1967     return -1;
1968   }
1969
1970   /**
1971    * The base implementation of `_.isNaN` without support for number objects.
1972    *
1973    * @private
1974    * @param {*} value The value to check.
1975    * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
1976    */
1977   function baseIsNaN(value) {
1978     return value !== value;
1979   }
1980
1981   /**
1982    * The base implementation of `_.mean` and `_.meanBy` without support for
1983    * iteratee shorthands.
1984    *
1985    * @private
1986    * @param {Array} array The array to iterate over.
1987    * @param {Function} iteratee The function invoked per iteration.
1988    * @returns {number} Returns the mean.
1989    */
1990   function baseMean(array, iteratee) {
1991     var length = array == null ? 0 : array.length;
1992     return length ? (baseSum(array, iteratee) / length) : NAN;
1993   }
1994
1995   /**
1996    * The base implementation of `_.property` without support for deep paths.
1997    *
1998    * @private
1999    * @param {string} key The key of the property to get.
2000    * @returns {Function} Returns the new accessor function.
2001    */
2002   function baseProperty(key) {
2003     return function(object) {
2004       return object == null ? undefined : object[key];
2005     };
2006   }
2007
2008   /**
2009    * The base implementation of `_.propertyOf` without support for deep paths.
2010    *
2011    * @private
2012    * @param {Object} object The object to query.
2013    * @returns {Function} Returns the new accessor function.
2014    */
2015   function basePropertyOf(object) {
2016     return function(key) {
2017       return object == null ? undefined : object[key];
2018     };
2019   }
2020
2021   /**
2022    * The base implementation of `_.reduce` and `_.reduceRight`, without support
2023    * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
2024    *
2025    * @private
2026    * @param {Array|Object} collection The collection to iterate over.
2027    * @param {Function} iteratee The function invoked per iteration.
2028    * @param {*} accumulator The initial value.
2029    * @param {boolean} initAccum Specify using the first or last element of
2030    *  `collection` as the initial value.
2031    * @param {Function} eachFunc The function to iterate over `collection`.
2032    * @returns {*} Returns the accumulated value.
2033    */
2034   function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
2035     eachFunc(collection, function(value, index, collection) {
2036       accumulator = initAccum
2037         ? (initAccum = false, value)
2038         : iteratee(accumulator, value, index, collection);
2039     });
2040     return accumulator;
2041   }
2042
2043   /**
2044    * The base implementation of `_.sortBy` which uses `comparer` to define the
2045    * sort order of `array` and replaces criteria objects with their corresponding
2046    * values.
2047    *
2048    * @private
2049    * @param {Array} array The array to sort.
2050    * @param {Function} comparer The function to define sort order.
2051    * @returns {Array} Returns `array`.
2052    */
2053   function baseSortBy(array, comparer) {
2054     var length = array.length;
2055
2056     array.sort(comparer);
2057     while (length--) {
2058       array[length] = array[length].value;
2059     }
2060     return array;
2061   }
2062
2063   /**
2064    * The base implementation of `_.sum` and `_.sumBy` without support for
2065    * iteratee shorthands.
2066    *
2067    * @private
2068    * @param {Array} array The array to iterate over.
2069    * @param {Function} iteratee The function invoked per iteration.
2070    * @returns {number} Returns the sum.
2071    */
2072   function baseSum(array, iteratee) {
2073     var result,
2074         index = -1,
2075         length = array.length;
2076
2077     while (++index < length) {
2078       var current = iteratee(array[index]);
2079       if (current !== undefined) {
2080         result = result === undefined ? current : (result + current);
2081       }
2082     }
2083     return result;
2084   }
2085
2086   /**
2087    * The base implementation of `_.times` without support for iteratee shorthands
2088    * or max array length checks.
2089    *
2090    * @private
2091    * @param {number} n The number of times to invoke `iteratee`.
2092    * @param {Function} iteratee The function invoked per iteration.
2093    * @returns {Array} Returns the array of results.
2094    */
2095   function baseTimes(n, iteratee) {
2096     var index = -1,
2097         result = Array(n);
2098
2099     while (++index < n) {
2100       result[index] = iteratee(index);
2101     }
2102     return result;
2103   }
2104
2105   /**
2106    * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
2107    * of key-value pairs for `object` corresponding to the property names of `props`.
2108    *
2109    * @private
2110    * @param {Object} object The object to query.
2111    * @param {Array} props The property names to get values for.
2112    * @returns {Object} Returns the key-value pairs.
2113    */
2114   function baseToPairs(object, props) {
2115     return arrayMap(props, function(key) {
2116       return [key, object[key]];
2117     });
2118   }
2119
2120   /**
2121    * The base implementation of `_.trim`.
2122    *
2123    * @private
2124    * @param {string} string The string to trim.
2125    * @returns {string} Returns the trimmed string.
2126    */
2127   function baseTrim(string) {
2128     return string
2129       ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
2130       : string;
2131   }
2132
2133   /**
2134    * The base implementation of `_.unary` without support for storing metadata.
2135    *
2136    * @private
2137    * @param {Function} func The function to cap arguments for.
2138    * @returns {Function} Returns the new capped function.
2139    */
2140   function baseUnary(func) {
2141     return function(value) {
2142       return func(value);
2143     };
2144   }
2145
2146   /**
2147    * The base implementation of `_.values` and `_.valuesIn` which creates an
2148    * array of `object` property values corresponding to the property names
2149    * of `props`.
2150    *
2151    * @private
2152    * @param {Object} object The object to query.
2153    * @param {Array} props The property names to get values for.
2154    * @returns {Object} Returns the array of property values.
2155    */
2156   function baseValues(object, props) {
2157     return arrayMap(props, function(key) {
2158       return object[key];
2159     });
2160   }
2161
2162   /**
2163    * Checks if a `cache` value for `key` exists.
2164    *
2165    * @private
2166    * @param {Object} cache The cache to query.
2167    * @param {string} key The key of the entry to check.
2168    * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2169    */
2170   function cacheHas(cache, key) {
2171     return cache.has(key);
2172   }
2173
2174   /**
2175    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
2176    * that is not found in the character symbols.
2177    *
2178    * @private
2179    * @param {Array} strSymbols The string symbols to inspect.
2180    * @param {Array} chrSymbols The character symbols to find.
2181    * @returns {number} Returns the index of the first unmatched string symbol.
2182    */
2183   function charsStartIndex(strSymbols, chrSymbols) {
2184     var index = -1,
2185         length = strSymbols.length;
2186
2187     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
2188     return index;
2189   }
2190
2191   /**
2192    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
2193    * that is not found in the character symbols.
2194    *
2195    * @private
2196    * @param {Array} strSymbols The string symbols to inspect.
2197    * @param {Array} chrSymbols The character symbols to find.
2198    * @returns {number} Returns the index of the last unmatched string symbol.
2199    */
2200   function charsEndIndex(strSymbols, chrSymbols) {
2201     var index = strSymbols.length;
2202
2203     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
2204     return index;
2205   }
2206
2207   /**
2208    * Gets the number of `placeholder` occurrences in `array`.
2209    *
2210    * @private
2211    * @param {Array} array The array to inspect.
2212    * @param {*} placeholder The placeholder to search for.
2213    * @returns {number} Returns the placeholder count.
2214    */
2215   function countHolders(array, placeholder) {
2216     var length = array.length,
2217         result = 0;
2218
2219     while (length--) {
2220       if (array[length] === placeholder) {
2221         ++result;
2222       }
2223     }
2224     return result;
2225   }
2226
2227   /**
2228    * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
2229    * letters to basic Latin letters.
2230    *
2231    * @private
2232    * @param {string} letter The matched letter to deburr.
2233    * @returns {string} Returns the deburred letter.
2234    */
2235   var deburrLetter = basePropertyOf(deburredLetters);
2236
2237   /**
2238    * Used by `_.escape` to convert characters to HTML entities.
2239    *
2240    * @private
2241    * @param {string} chr The matched character to escape.
2242    * @returns {string} Returns the escaped character.
2243    */
2244   var escapeHtmlChar = basePropertyOf(htmlEscapes);
2245
2246   /**
2247    * Used by `_.template` to escape characters for inclusion in compiled string literals.
2248    *
2249    * @private
2250    * @param {string} chr The matched character to escape.
2251    * @returns {string} Returns the escaped character.
2252    */
2253   function escapeStringChar(chr) {
2254     return '\\' + stringEscapes[chr];
2255   }
2256
2257   /**
2258    * Gets the value at `key` of `object`.
2259    *
2260    * @private
2261    * @param {Object} [object] The object to query.
2262    * @param {string} key The key of the property to get.
2263    * @returns {*} Returns the property value.
2264    */
2265   function getValue(object, key) {
2266     return object == null ? undefined : object[key];
2267   }
2268
2269   /**
2270    * Checks if `string` contains Unicode symbols.
2271    *
2272    * @private
2273    * @param {string} string The string to inspect.
2274    * @returns {boolean} Returns `true` if a symbol is found, else `false`.
2275    */
2276   function hasUnicode(string) {
2277     return reHasUnicode.test(string);
2278   }
2279
2280   /**
2281    * Checks if `string` contains a word composed of Unicode symbols.
2282    *
2283    * @private
2284    * @param {string} string The string to inspect.
2285    * @returns {boolean} Returns `true` if a word is found, else `false`.
2286    */
2287   function hasUnicodeWord(string) {
2288     return reHasUnicodeWord.test(string);
2289   }
2290
2291   /**
2292    * Converts `iterator` to an array.
2293    *
2294    * @private
2295    * @param {Object} iterator The iterator to convert.
2296    * @returns {Array} Returns the converted array.
2297    */
2298   function iteratorToArray(iterator) {
2299     var data,
2300         result = [];
2301
2302     while (!(data = iterator.next()).done) {
2303       result.push(data.value);
2304     }
2305     return result;
2306   }
2307
2308   /**
2309    * Converts `map` to its key-value pairs.
2310    *
2311    * @private
2312    * @param {Object} map The map to convert.
2313    * @returns {Array} Returns the key-value pairs.
2314    */
2315   function mapToArray(map) {
2316     var index = -1,
2317         result = Array(map.size);
2318
2319     map.forEach(function(value, key) {
2320       result[++index] = [key, value];
2321     });
2322     return result;
2323   }
2324
2325   /**
2326    * Creates a unary function that invokes `func` with its argument transformed.
2327    *
2328    * @private
2329    * @param {Function} func The function to wrap.
2330    * @param {Function} transform The argument transform.
2331    * @returns {Function} Returns the new function.
2332    */
2333   function overArg(func, transform) {
2334     return function(arg) {
2335       return func(transform(arg));
2336     };
2337   }
2338
2339   /**
2340    * Replaces all `placeholder` elements in `array` with an internal placeholder
2341    * and returns an array of their indexes.
2342    *
2343    * @private
2344    * @param {Array} array The array to modify.
2345    * @param {*} placeholder The placeholder to replace.
2346    * @returns {Array} Returns the new array of placeholder indexes.
2347    */
2348   function replaceHolders(array, placeholder) {
2349     var index = -1,
2350         length = array.length,
2351         resIndex = 0,
2352         result = [];
2353
2354     while (++index < length) {
2355       var value = array[index];
2356       if (value === placeholder || value === PLACEHOLDER) {
2357         array[index] = PLACEHOLDER;
2358         result[resIndex++] = index;
2359       }
2360     }
2361     return result;
2362   }
2363
2364   /**
2365    * Converts `set` to an array of its values.
2366    *
2367    * @private
2368    * @param {Object} set The set to convert.
2369    * @returns {Array} Returns the values.
2370    */
2371   function setToArray(set) {
2372     var index = -1,
2373         result = Array(set.size);
2374
2375     set.forEach(function(value) {
2376       result[++index] = value;
2377     });
2378     return result;
2379   }
2380
2381   /**
2382    * Converts `set` to its value-value pairs.
2383    *
2384    * @private
2385    * @param {Object} set The set to convert.
2386    * @returns {Array} Returns the value-value pairs.
2387    */
2388   function setToPairs(set) {
2389     var index = -1,
2390         result = Array(set.size);
2391
2392     set.forEach(function(value) {
2393       result[++index] = [value, value];
2394     });
2395     return result;
2396   }
2397
2398   /**
2399    * A specialized version of `_.indexOf` which performs strict equality
2400    * comparisons of values, i.e. `===`.
2401    *
2402    * @private
2403    * @param {Array} array The array to inspect.
2404    * @param {*} value The value to search for.
2405    * @param {number} fromIndex The index to search from.
2406    * @returns {number} Returns the index of the matched value, else `-1`.
2407    */
2408   function strictIndexOf(array, value, fromIndex) {
2409     var index = fromIndex - 1,
2410         length = array.length;
2411
2412     while (++index < length) {
2413       if (array[index] === value) {
2414         return index;
2415       }
2416     }
2417     return -1;
2418   }
2419
2420   /**
2421    * A specialized version of `_.lastIndexOf` which performs strict equality
2422    * comparisons of values, i.e. `===`.
2423    *
2424    * @private
2425    * @param {Array} array The array to inspect.
2426    * @param {*} value The value to search for.
2427    * @param {number} fromIndex The index to search from.
2428    * @returns {number} Returns the index of the matched value, else `-1`.
2429    */
2430   function strictLastIndexOf(array, value, fromIndex) {
2431     var index = fromIndex + 1;
2432     while (index--) {
2433       if (array[index] === value) {
2434         return index;
2435       }
2436     }
2437     return index;
2438   }
2439
2440   /**
2441    * Gets the number of symbols in `string`.
2442    *
2443    * @private
2444    * @param {string} string The string to inspect.
2445    * @returns {number} Returns the string size.
2446    */
2447   function stringSize(string) {
2448     return hasUnicode(string)
2449       ? unicodeSize(string)
2450       : asciiSize(string);
2451   }
2452
2453   /**
2454    * Converts `string` to an array.
2455    *
2456    * @private
2457    * @param {string} string The string to convert.
2458    * @returns {Array} Returns the converted array.
2459    */
2460   function stringToArray(string) {
2461     return hasUnicode(string)
2462       ? unicodeToArray(string)
2463       : asciiToArray(string);
2464   }
2465
2466   /**
2467    * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
2468    * character of `string`.
2469    *
2470    * @private
2471    * @param {string} string The string to inspect.
2472    * @returns {number} Returns the index of the last non-whitespace character.
2473    */
2474   function trimmedEndIndex(string) {
2475     var index = string.length;
2476
2477     while (index-- && reWhitespace.test(string.charAt(index))) {}
2478     return index;
2479   }
2480
2481   /**
2482    * Used by `_.unescape` to convert HTML entities to characters.
2483    *
2484    * @private
2485    * @param {string} chr The matched character to unescape.
2486    * @returns {string} Returns the unescaped character.
2487    */
2488   var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
2489
2490   /**
2491    * Gets the size of a Unicode `string`.
2492    *
2493    * @private
2494    * @param {string} string The string inspect.
2495    * @returns {number} Returns the string size.
2496    */
2497   function unicodeSize(string) {
2498     var result = reUnicode.lastIndex = 0;
2499     while (reUnicode.test(string)) {
2500       ++result;
2501     }
2502     return result;
2503   }
2504
2505   /**
2506    * Converts a Unicode `string` to an array.
2507    *
2508    * @private
2509    * @param {string} string The string to convert.
2510    * @returns {Array} Returns the converted array.
2511    */
2512   function unicodeToArray(string) {
2513     return string.match(reUnicode) || [];
2514   }
2515
2516   /**
2517    * Splits a Unicode `string` into an array of its words.
2518    *
2519    * @private
2520    * @param {string} The string to inspect.
2521    * @returns {Array} Returns the words of `string`.
2522    */
2523   function unicodeWords(string) {
2524     return string.match(reUnicodeWord) || [];
2525   }
2526
2527   /*--------------------------------------------------------------------------*/
2528
2529   /**
2530    * Create a new pristine `lodash` function using the `context` object.
2531    *
2532    * @static
2533    * @memberOf _
2534    * @since 1.1.0
2535    * @category Util
2536    * @param {Object} [context=root] The context object.
2537    * @returns {Function} Returns a new `lodash` function.
2538    * @example
2539    *
2540    * _.mixin({ 'foo': _.constant('foo') });
2541    *
2542    * var lodash = _.runInContext();
2543    * lodash.mixin({ 'bar': lodash.constant('bar') });
2544    *
2545    * _.isFunction(_.foo);
2546    * // => true
2547    * _.isFunction(_.bar);
2548    * // => false
2549    *
2550    * lodash.isFunction(lodash.foo);
2551    * // => false
2552    * lodash.isFunction(lodash.bar);
2553    * // => true
2554    *
2555    * // Create a suped-up `defer` in Node.js.
2556    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
2557    */
2558   var runInContext = (function runInContext(context) {
2559     context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
2560
2561     /** Built-in constructor references. */
2562     var Array = context.Array,
2563         Date = context.Date,
2564         Error = context.Error,
2565         Function = context.Function,
2566         Math = context.Math,
2567         Object = context.Object,
2568         RegExp = context.RegExp,
2569         String = context.String,
2570         TypeError = context.TypeError;
2571
2572     /** Used for built-in method references. */
2573     var arrayProto = Array.prototype,
2574         funcProto = Function.prototype,
2575         objectProto = Object.prototype;
2576
2577     /** Used to detect overreaching core-js shims. */
2578     var coreJsData = context['__core-js_shared__'];
2579
2580     /** Used to resolve the decompiled source of functions. */
2581     var funcToString = funcProto.toString;
2582
2583     /** Used to check objects for own properties. */
2584     var hasOwnProperty = objectProto.hasOwnProperty;
2585
2586     /** Used to generate unique IDs. */
2587     var idCounter = 0;
2588
2589     /** Used to detect methods masquerading as native. */
2590     var maskSrcKey = (function() {
2591       var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
2592       return uid ? ('Symbol(src)_1.' + uid) : '';
2593     }());
2594
2595     /**
2596      * Used to resolve the
2597      * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
2598      * of values.
2599      */
2600     var nativeObjectToString = objectProto.toString;
2601
2602     /** Used to infer the `Object` constructor. */
2603     var objectCtorString = funcToString.call(Object);
2604
2605     /** Used to restore the original `_` reference in `_.noConflict`. */
2606     var oldDash = root._;
2607
2608     /** Used to detect if a method is native. */
2609     var reIsNative = RegExp('^' +
2610       funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
2611       .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
2612     );
2613
2614     /** Built-in value references. */
2615     var Buffer = moduleExports ? context.Buffer : undefined,
2616         Symbol = context.Symbol,
2617         Uint8Array = context.Uint8Array,
2618         allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
2619         getPrototype = overArg(Object.getPrototypeOf, Object),
2620         objectCreate = Object.create,
2621         propertyIsEnumerable = objectProto.propertyIsEnumerable,
2622         splice = arrayProto.splice,
2623         spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
2624         symIterator = Symbol ? Symbol.iterator : undefined,
2625         symToStringTag = Symbol ? Symbol.toStringTag : undefined;
2626
2627     var defineProperty = (function() {
2628       try {
2629         var func = getNative(Object, 'defineProperty');
2630         func({}, '', {});
2631         return func;
2632       } catch (e) {}
2633     }());
2634
2635     /** Mocked built-ins. */
2636     var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
2637         ctxNow = Date && Date.now !== root.Date.now && Date.now,
2638         ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
2639
2640     /* Built-in method references for those with the same name as other `lodash` methods. */
2641     var nativeCeil = Math.ceil,
2642         nativeFloor = Math.floor,
2643         nativeGetSymbols = Object.getOwnPropertySymbols,
2644         nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
2645         nativeIsFinite = context.isFinite,
2646         nativeJoin = arrayProto.join,
2647         nativeKeys = overArg(Object.keys, Object),
2648         nativeMax = Math.max,
2649         nativeMin = Math.min,
2650         nativeNow = Date.now,
2651         nativeParseInt = context.parseInt,
2652         nativeRandom = Math.random,
2653         nativeReverse = arrayProto.reverse;
2654
2655     /* Built-in method references that are verified to be native. */
2656     var DataView = getNative(context, 'DataView'),
2657         Map = getNative(context, 'Map'),
2658         Promise = getNative(context, 'Promise'),
2659         Set = getNative(context, 'Set'),
2660         WeakMap = getNative(context, 'WeakMap'),
2661         nativeCreate = getNative(Object, 'create');
2662
2663     /** Used to store function metadata. */
2664     var metaMap = WeakMap && new WeakMap;
2665
2666     /** Used to lookup unminified function names. */
2667     var realNames = {};
2668
2669     /** Used to detect maps, sets, and weakmaps. */
2670     var dataViewCtorString = toSource(DataView),
2671         mapCtorString = toSource(Map),
2672         promiseCtorString = toSource(Promise),
2673         setCtorString = toSource(Set),
2674         weakMapCtorString = toSource(WeakMap);
2675
2676     /** Used to convert symbols to primitives and strings. */
2677     var symbolProto = Symbol ? Symbol.prototype : undefined,
2678         symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
2679         symbolToString = symbolProto ? symbolProto.toString : undefined;
2680
2681     /*------------------------------------------------------------------------*/
2682
2683     /**
2684      * Creates a `lodash` object which wraps `value` to enable implicit method
2685      * chain sequences. Methods that operate on and return arrays, collections,
2686      * and functions can be chained together. Methods that retrieve a single value
2687      * or may return a primitive value will automatically end the chain sequence
2688      * and return the unwrapped value. Otherwise, the value must be unwrapped
2689      * with `_#value`.
2690      *
2691      * Explicit chain sequences, which must be unwrapped with `_#value`, may be
2692      * enabled using `_.chain`.
2693      *
2694      * The execution of chained methods is lazy, that is, it's deferred until
2695      * `_#value` is implicitly or explicitly called.
2696      *
2697      * Lazy evaluation allows several methods to support shortcut fusion.
2698      * Shortcut fusion is an optimization to merge iteratee calls; this avoids
2699      * the creation of intermediate arrays and can greatly reduce the number of
2700      * iteratee executions. Sections of a chain sequence qualify for shortcut
2701      * fusion if the section is applied to an array and iteratees accept only
2702      * one argument. The heuristic for whether a section qualifies for shortcut
2703      * fusion is subject to change.
2704      *
2705      * Chaining is supported in custom builds as long as the `_#value` method is
2706      * directly or indirectly included in the build.
2707      *
2708      * In addition to lodash methods, wrappers have `Array` and `String` methods.
2709      *
2710      * The wrapper `Array` methods are:
2711      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
2712      *
2713      * The wrapper `String` methods are:
2714      * `replace` and `split`
2715      *
2716      * The wrapper methods that support shortcut fusion are:
2717      * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
2718      * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
2719      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
2720      *
2721      * The chainable wrapper methods are:
2722      * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
2723      * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
2724      * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
2725      * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
2726      * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
2727      * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
2728      * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
2729      * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
2730      * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
2731      * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
2732      * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
2733      * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
2734      * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
2735      * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
2736      * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
2737      * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
2738      * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
2739      * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
2740      * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
2741      * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
2742      * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
2743      * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
2744      * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
2745      * `zipObject`, `zipObjectDeep`, and `zipWith`
2746      *
2747      * The wrapper methods that are **not** chainable by default are:
2748      * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
2749      * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
2750      * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
2751      * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
2752      * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
2753      * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
2754      * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
2755      * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
2756      * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
2757      * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
2758      * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
2759      * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
2760      * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
2761      * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
2762      * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
2763      * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
2764      * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
2765      * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
2766      * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
2767      * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
2768      * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
2769      * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
2770      * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
2771      * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
2772      * `upperFirst`, `value`, and `words`
2773      *
2774      * @name _
2775      * @constructor
2776      * @category Seq
2777      * @param {*} value The value to wrap in a `lodash` instance.
2778      * @returns {Object} Returns the new `lodash` wrapper instance.
2779      * @example
2780      *
2781      * function square(n) {
2782      *   return n * n;
2783      * }
2784      *
2785      * var wrapped = _([1, 2, 3]);
2786      *
2787      * // Returns an unwrapped value.
2788      * wrapped.reduce(_.add);
2789      * // => 6
2790      *
2791      * // Returns a wrapped value.
2792      * var squares = wrapped.map(square);
2793      *
2794      * _.isArray(squares);
2795      * // => false
2796      *
2797      * _.isArray(squares.value());
2798      * // => true
2799      */
2800     function lodash(value) {
2801       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
2802         if (value instanceof LodashWrapper) {
2803           return value;
2804         }
2805         if (hasOwnProperty.call(value, '__wrapped__')) {
2806           return wrapperClone(value);
2807         }
2808       }
2809       return new LodashWrapper(value);
2810     }
2811
2812     /**
2813      * The base implementation of `_.create` without support for assigning
2814      * properties to the created object.
2815      *
2816      * @private
2817      * @param {Object} proto The object to inherit from.
2818      * @returns {Object} Returns the new object.
2819      */
2820     var baseCreate = (function() {
2821       function object() {}
2822       return function(proto) {
2823         if (!isObject(proto)) {
2824           return {};
2825         }
2826         if (objectCreate) {
2827           return objectCreate(proto);
2828         }
2829         object.prototype = proto;
2830         var result = new object;
2831         object.prototype = undefined;
2832         return result;
2833       };
2834     }());
2835
2836     /**
2837      * The function whose prototype chain sequence wrappers inherit from.
2838      *
2839      * @private
2840      */
2841     function baseLodash() {
2842       // No operation performed.
2843     }
2844
2845     /**
2846      * The base constructor for creating `lodash` wrapper objects.
2847      *
2848      * @private
2849      * @param {*} value The value to wrap.
2850      * @param {boolean} [chainAll] Enable explicit method chain sequences.
2851      */
2852     function LodashWrapper(value, chainAll) {
2853       this.__wrapped__ = value;
2854       this.__actions__ = [];
2855       this.__chain__ = !!chainAll;
2856       this.__index__ = 0;
2857       this.__values__ = undefined;
2858     }
2859
2860     /**
2861      * By default, the template delimiters used by lodash are like those in
2862      * embedded Ruby (ERB) as well as ES2015 template strings. Change the
2863      * following template settings to use alternative delimiters.
2864      *
2865      * @static
2866      * @memberOf _
2867      * @type {Object}
2868      */
2869     lodash.templateSettings = {
2870
2871       /**
2872        * Used to detect `data` property values to be HTML-escaped.
2873        *
2874        * @memberOf _.templateSettings
2875        * @type {RegExp}
2876        */
2877       'escape': reEscape,
2878
2879       /**
2880        * Used to detect code to be evaluated.
2881        *
2882        * @memberOf _.templateSettings
2883        * @type {RegExp}
2884        */
2885       'evaluate': reEvaluate,
2886
2887       /**
2888        * Used to detect `data` property values to inject.
2889        *
2890        * @memberOf _.templateSettings
2891        * @type {RegExp}
2892        */
2893       'interpolate': reInterpolate,
2894
2895       /**
2896        * Used to reference the data object in the template text.
2897        *
2898        * @memberOf _.templateSettings
2899        * @type {string}
2900        */
2901       'variable': '',
2902
2903       /**
2904        * Used to import variables into the compiled template.
2905        *
2906        * @memberOf _.templateSettings
2907        * @type {Object}
2908        */
2909       'imports': {
2910
2911         /**
2912          * A reference to the `lodash` function.
2913          *
2914          * @memberOf _.templateSettings.imports
2915          * @type {Function}
2916          */
2917         '_': lodash
2918       }
2919     };
2920
2921     // Ensure wrappers are instances of `baseLodash`.
2922     lodash.prototype = baseLodash.prototype;
2923     lodash.prototype.constructor = lodash;
2924
2925     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
2926     LodashWrapper.prototype.constructor = LodashWrapper;
2927
2928     /*------------------------------------------------------------------------*/
2929
2930     /**
2931      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
2932      *
2933      * @private
2934      * @constructor
2935      * @param {*} value The value to wrap.
2936      */
2937     function LazyWrapper(value) {
2938       this.__wrapped__ = value;
2939       this.__actions__ = [];
2940       this.__dir__ = 1;
2941       this.__filtered__ = false;
2942       this.__iteratees__ = [];
2943       this.__takeCount__ = MAX_ARRAY_LENGTH;
2944       this.__views__ = [];
2945     }
2946
2947     /**
2948      * Creates a clone of the lazy wrapper object.
2949      *
2950      * @private
2951      * @name clone
2952      * @memberOf LazyWrapper
2953      * @returns {Object} Returns the cloned `LazyWrapper` object.
2954      */
2955     function lazyClone() {
2956       var result = new LazyWrapper(this.__wrapped__);
2957       result.__actions__ = copyArray(this.__actions__);
2958       result.__dir__ = this.__dir__;
2959       result.__filtered__ = this.__filtered__;
2960       result.__iteratees__ = copyArray(this.__iteratees__);
2961       result.__takeCount__ = this.__takeCount__;
2962       result.__views__ = copyArray(this.__views__);
2963       return result;
2964     }
2965
2966     /**
2967      * Reverses the direction of lazy iteration.
2968      *
2969      * @private
2970      * @name reverse
2971      * @memberOf LazyWrapper
2972      * @returns {Object} Returns the new reversed `LazyWrapper` object.
2973      */
2974     function lazyReverse() {
2975       if (this.__filtered__) {
2976         var result = new LazyWrapper(this);
2977         result.__dir__ = -1;
2978         result.__filtered__ = true;
2979       } else {
2980         result = this.clone();
2981         result.__dir__ *= -1;
2982       }
2983       return result;
2984     }
2985
2986     /**
2987      * Extracts the unwrapped value from its lazy wrapper.
2988      *
2989      * @private
2990      * @name value
2991      * @memberOf LazyWrapper
2992      * @returns {*} Returns the unwrapped value.
2993      */
2994     function lazyValue() {
2995       var array = this.__wrapped__.value(),
2996           dir = this.__dir__,
2997           isArr = isArray(array),
2998           isRight = dir < 0,
2999           arrLength = isArr ? array.length : 0,
3000           view = getView(0, arrLength, this.__views__),
3001           start = view.start,
3002           end = view.end,
3003           length = end - start,
3004           index = isRight ? end : (start - 1),
3005           iteratees = this.__iteratees__,
3006           iterLength = iteratees.length,
3007           resIndex = 0,
3008           takeCount = nativeMin(length, this.__takeCount__);
3009
3010       if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
3011         return baseWrapperValue(array, this.__actions__);
3012       }
3013       var result = [];
3014
3015       outer:
3016       while (length-- && resIndex < takeCount) {
3017         index += dir;
3018
3019         var iterIndex = -1,
3020             value = array[index];
3021
3022         while (++iterIndex < iterLength) {
3023           var data = iteratees[iterIndex],
3024               iteratee = data.iteratee,
3025               type = data.type,
3026               computed = iteratee(value);
3027
3028           if (type == LAZY_MAP_FLAG) {
3029             value = computed;
3030           } else if (!computed) {
3031             if (type == LAZY_FILTER_FLAG) {
3032               continue outer;
3033             } else {
3034               break outer;
3035             }
3036           }
3037         }
3038         result[resIndex++] = value;
3039       }
3040       return result;
3041     }
3042
3043     // Ensure `LazyWrapper` is an instance of `baseLodash`.
3044     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
3045     LazyWrapper.prototype.constructor = LazyWrapper;
3046
3047     /*------------------------------------------------------------------------*/
3048
3049     /**
3050      * Creates a hash object.
3051      *
3052      * @private
3053      * @constructor
3054      * @param {Array} [entries] The key-value pairs to cache.
3055      */
3056     function Hash(entries) {
3057       var index = -1,
3058           length = entries == null ? 0 : entries.length;
3059
3060       this.clear();
3061       while (++index < length) {
3062         var entry = entries[index];
3063         this.set(entry[0], entry[1]);
3064       }
3065     }
3066
3067     /**
3068      * Removes all key-value entries from the hash.
3069      *
3070      * @private
3071      * @name clear
3072      * @memberOf Hash
3073      */
3074     function hashClear() {
3075       this.__data__ = nativeCreate ? nativeCreate(null) : {};
3076       this.size = 0;
3077     }
3078
3079     /**
3080      * Removes `key` and its value from the hash.
3081      *
3082      * @private
3083      * @name delete
3084      * @memberOf Hash
3085      * @param {Object} hash The hash to modify.
3086      * @param {string} key The key of the value to remove.
3087      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3088      */
3089     function hashDelete(key) {
3090       var result = this.has(key) && delete this.__data__[key];
3091       this.size -= result ? 1 : 0;
3092       return result;
3093     }
3094
3095     /**
3096      * Gets the hash value for `key`.
3097      *
3098      * @private
3099      * @name get
3100      * @memberOf Hash
3101      * @param {string} key The key of the value to get.
3102      * @returns {*} Returns the entry value.
3103      */
3104     function hashGet(key) {
3105       var data = this.__data__;
3106       if (nativeCreate) {
3107         var result = data[key];
3108         return result === HASH_UNDEFINED ? undefined : result;
3109       }
3110       return hasOwnProperty.call(data, key) ? data[key] : undefined;
3111     }
3112
3113     /**
3114      * Checks if a hash value for `key` exists.
3115      *
3116      * @private
3117      * @name has
3118      * @memberOf Hash
3119      * @param {string} key The key of the entry to check.
3120      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3121      */
3122     function hashHas(key) {
3123       var data = this.__data__;
3124       return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
3125     }
3126
3127     /**
3128      * Sets the hash `key` to `value`.
3129      *
3130      * @private
3131      * @name set
3132      * @memberOf Hash
3133      * @param {string} key The key of the value to set.
3134      * @param {*} value The value to set.
3135      * @returns {Object} Returns the hash instance.
3136      */
3137     function hashSet(key, value) {
3138       var data = this.__data__;
3139       this.size += this.has(key) ? 0 : 1;
3140       data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
3141       return this;
3142     }
3143
3144     // Add methods to `Hash`.
3145     Hash.prototype.clear = hashClear;
3146     Hash.prototype['delete'] = hashDelete;
3147     Hash.prototype.get = hashGet;
3148     Hash.prototype.has = hashHas;
3149     Hash.prototype.set = hashSet;
3150
3151     /*------------------------------------------------------------------------*/
3152
3153     /**
3154      * Creates an list cache object.
3155      *
3156      * @private
3157      * @constructor
3158      * @param {Array} [entries] The key-value pairs to cache.
3159      */
3160     function ListCache(entries) {
3161       var index = -1,
3162           length = entries == null ? 0 : entries.length;
3163
3164       this.clear();
3165       while (++index < length) {
3166         var entry = entries[index];
3167         this.set(entry[0], entry[1]);
3168       }
3169     }
3170
3171     /**
3172      * Removes all key-value entries from the list cache.
3173      *
3174      * @private
3175      * @name clear
3176      * @memberOf ListCache
3177      */
3178     function listCacheClear() {
3179       this.__data__ = [];
3180       this.size = 0;
3181     }
3182
3183     /**
3184      * Removes `key` and its value from the list cache.
3185      *
3186      * @private
3187      * @name delete
3188      * @memberOf ListCache
3189      * @param {string} key The key of the value to remove.
3190      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3191      */
3192     function listCacheDelete(key) {
3193       var data = this.__data__,
3194           index = assocIndexOf(data, key);
3195
3196       if (index < 0) {
3197         return false;
3198       }
3199       var lastIndex = data.length - 1;
3200       if (index == lastIndex) {
3201         data.pop();
3202       } else {
3203         splice.call(data, index, 1);
3204       }
3205       --this.size;
3206       return true;
3207     }
3208
3209     /**
3210      * Gets the list cache value for `key`.
3211      *
3212      * @private
3213      * @name get
3214      * @memberOf ListCache
3215      * @param {string} key The key of the value to get.
3216      * @returns {*} Returns the entry value.
3217      */
3218     function listCacheGet(key) {
3219       var data = this.__data__,
3220           index = assocIndexOf(data, key);
3221
3222       return index < 0 ? undefined : data[index][1];
3223     }
3224
3225     /**
3226      * Checks if a list cache value for `key` exists.
3227      *
3228      * @private
3229      * @name has
3230      * @memberOf ListCache
3231      * @param {string} key The key of the entry to check.
3232      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3233      */
3234     function listCacheHas(key) {
3235       return assocIndexOf(this.__data__, key) > -1;
3236     }
3237
3238     /**
3239      * Sets the list cache `key` to `value`.
3240      *
3241      * @private
3242      * @name set
3243      * @memberOf ListCache
3244      * @param {string} key The key of the value to set.
3245      * @param {*} value The value to set.
3246      * @returns {Object} Returns the list cache instance.
3247      */
3248     function listCacheSet(key, value) {
3249       var data = this.__data__,
3250           index = assocIndexOf(data, key);
3251
3252       if (index < 0) {
3253         ++this.size;
3254         data.push([key, value]);
3255       } else {
3256         data[index][1] = value;
3257       }
3258       return this;
3259     }
3260
3261     // Add methods to `ListCache`.
3262     ListCache.prototype.clear = listCacheClear;
3263     ListCache.prototype['delete'] = listCacheDelete;
3264     ListCache.prototype.get = listCacheGet;
3265     ListCache.prototype.has = listCacheHas;
3266     ListCache.prototype.set = listCacheSet;
3267
3268     /*------------------------------------------------------------------------*/
3269
3270     /**
3271      * Creates a map cache object to store key-value pairs.
3272      *
3273      * @private
3274      * @constructor
3275      * @param {Array} [entries] The key-value pairs to cache.
3276      */
3277     function MapCache(entries) {
3278       var index = -1,
3279           length = entries == null ? 0 : entries.length;
3280
3281       this.clear();
3282       while (++index < length) {
3283         var entry = entries[index];
3284         this.set(entry[0], entry[1]);
3285       }
3286     }
3287
3288     /**
3289      * Removes all key-value entries from the map.
3290      *
3291      * @private
3292      * @name clear
3293      * @memberOf MapCache
3294      */
3295     function mapCacheClear() {
3296       this.size = 0;
3297       this.__data__ = {
3298         'hash': new Hash,
3299         'map': new (Map || ListCache),
3300         'string': new Hash
3301       };
3302     }
3303
3304     /**
3305      * Removes `key` and its value from the map.
3306      *
3307      * @private
3308      * @name delete
3309      * @memberOf MapCache
3310      * @param {string} key The key of the value to remove.
3311      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3312      */
3313     function mapCacheDelete(key) {
3314       var result = getMapData(this, key)['delete'](key);
3315       this.size -= result ? 1 : 0;
3316       return result;
3317     }
3318
3319     /**
3320      * Gets the map value for `key`.
3321      *
3322      * @private
3323      * @name get
3324      * @memberOf MapCache
3325      * @param {string} key The key of the value to get.
3326      * @returns {*} Returns the entry value.
3327      */
3328     function mapCacheGet(key) {
3329       return getMapData(this, key).get(key);
3330     }
3331
3332     /**
3333      * Checks if a map value for `key` exists.
3334      *
3335      * @private
3336      * @name has
3337      * @memberOf MapCache
3338      * @param {string} key The key of the entry to check.
3339      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3340      */
3341     function mapCacheHas(key) {
3342       return getMapData(this, key).has(key);
3343     }
3344
3345     /**
3346      * Sets the map `key` to `value`.
3347      *
3348      * @private
3349      * @name set
3350      * @memberOf MapCache
3351      * @param {string} key The key of the value to set.
3352      * @param {*} value The value to set.
3353      * @returns {Object} Returns the map cache instance.
3354      */
3355     function mapCacheSet(key, value) {
3356       var data = getMapData(this, key),
3357           size = data.size;
3358
3359       data.set(key, value);
3360       this.size += data.size == size ? 0 : 1;
3361       return this;
3362     }
3363
3364     // Add methods to `MapCache`.
3365     MapCache.prototype.clear = mapCacheClear;
3366     MapCache.prototype['delete'] = mapCacheDelete;
3367     MapCache.prototype.get = mapCacheGet;
3368     MapCache.prototype.has = mapCacheHas;
3369     MapCache.prototype.set = mapCacheSet;
3370
3371     /*------------------------------------------------------------------------*/
3372
3373     /**
3374      *
3375      * Creates an array cache object to store unique values.
3376      *
3377      * @private
3378      * @constructor
3379      * @param {Array} [values] The values to cache.
3380      */
3381     function SetCache(values) {
3382       var index = -1,
3383           length = values == null ? 0 : values.length;
3384
3385       this.__data__ = new MapCache;
3386       while (++index < length) {
3387         this.add(values[index]);
3388       }
3389     }
3390
3391     /**
3392      * Adds `value` to the array cache.
3393      *
3394      * @private
3395      * @name add
3396      * @memberOf SetCache
3397      * @alias push
3398      * @param {*} value The value to cache.
3399      * @returns {Object} Returns the cache instance.
3400      */
3401     function setCacheAdd(value) {
3402       this.__data__.set(value, HASH_UNDEFINED);
3403       return this;
3404     }
3405
3406     /**
3407      * Checks if `value` is in the array cache.
3408      *
3409      * @private
3410      * @name has
3411      * @memberOf SetCache
3412      * @param {*} value The value to search for.
3413      * @returns {number} Returns `true` if `value` is found, else `false`.
3414      */
3415     function setCacheHas(value) {
3416       return this.__data__.has(value);
3417     }
3418
3419     // Add methods to `SetCache`.
3420     SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
3421     SetCache.prototype.has = setCacheHas;
3422
3423     /*------------------------------------------------------------------------*/
3424
3425     /**
3426      * Creates a stack cache object to store key-value pairs.
3427      *
3428      * @private
3429      * @constructor
3430      * @param {Array} [entries] The key-value pairs to cache.
3431      */
3432     function Stack(entries) {
3433       var data = this.__data__ = new ListCache(entries);
3434       this.size = data.size;
3435     }
3436
3437     /**
3438      * Removes all key-value entries from the stack.
3439      *
3440      * @private
3441      * @name clear
3442      * @memberOf Stack
3443      */
3444     function stackClear() {
3445       this.__data__ = new ListCache;
3446       this.size = 0;
3447     }
3448
3449     /**
3450      * Removes `key` and its value from the stack.
3451      *
3452      * @private
3453      * @name delete
3454      * @memberOf Stack
3455      * @param {string} key The key of the value to remove.
3456      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3457      */
3458     function stackDelete(key) {
3459       var data = this.__data__,
3460           result = data['delete'](key);
3461
3462       this.size = data.size;
3463       return result;
3464     }
3465
3466     /**
3467      * Gets the stack value for `key`.
3468      *
3469      * @private
3470      * @name get
3471      * @memberOf Stack
3472      * @param {string} key The key of the value to get.
3473      * @returns {*} Returns the entry value.
3474      */
3475     function stackGet(key) {
3476       return this.__data__.get(key);
3477     }
3478
3479     /**
3480      * Checks if a stack value for `key` exists.
3481      *
3482      * @private
3483      * @name has
3484      * @memberOf Stack
3485      * @param {string} key The key of the entry to check.
3486      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3487      */
3488     function stackHas(key) {
3489       return this.__data__.has(key);
3490     }
3491
3492     /**
3493      * Sets the stack `key` to `value`.
3494      *
3495      * @private
3496      * @name set
3497      * @memberOf Stack
3498      * @param {string} key The key of the value to set.
3499      * @param {*} value The value to set.
3500      * @returns {Object} Returns the stack cache instance.
3501      */
3502     function stackSet(key, value) {
3503       var data = this.__data__;
3504       if (data instanceof ListCache) {
3505         var pairs = data.__data__;
3506         if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
3507           pairs.push([key, value]);
3508           this.size = ++data.size;
3509           return this;
3510         }
3511         data = this.__data__ = new MapCache(pairs);
3512       }
3513       data.set(key, value);
3514       this.size = data.size;
3515       return this;
3516     }
3517
3518     // Add methods to `Stack`.
3519     Stack.prototype.clear = stackClear;
3520     Stack.prototype['delete'] = stackDelete;
3521     Stack.prototype.get = stackGet;
3522     Stack.prototype.has = stackHas;
3523     Stack.prototype.set = stackSet;
3524
3525     /*------------------------------------------------------------------------*/
3526
3527     /**
3528      * Creates an array of the enumerable property names of the array-like `value`.
3529      *
3530      * @private
3531      * @param {*} value The value to query.
3532      * @param {boolean} inherited Specify returning inherited property names.
3533      * @returns {Array} Returns the array of property names.
3534      */
3535     function arrayLikeKeys(value, inherited) {
3536       var isArr = isArray(value),
3537           isArg = !isArr && isArguments(value),
3538           isBuff = !isArr && !isArg && isBuffer(value),
3539           isType = !isArr && !isArg && !isBuff && isTypedArray(value),
3540           skipIndexes = isArr || isArg || isBuff || isType,
3541           result = skipIndexes ? baseTimes(value.length, String) : [],
3542           length = result.length;
3543
3544       for (var key in value) {
3545         if ((inherited || hasOwnProperty.call(value, key)) &&
3546             !(skipIndexes && (
3547                // Safari 9 has enumerable `arguments.length` in strict mode.
3548                key == 'length' ||
3549                // Node.js 0.10 has enumerable non-index properties on buffers.
3550                (isBuff && (key == 'offset' || key == 'parent')) ||
3551                // PhantomJS 2 has enumerable non-index properties on typed arrays.
3552                (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
3553                // Skip index properties.
3554                isIndex(key, length)
3555             ))) {
3556           result.push(key);
3557         }
3558       }
3559       return result;
3560     }
3561
3562     /**
3563      * A specialized version of `_.sample` for arrays.
3564      *
3565      * @private
3566      * @param {Array} array The array to sample.
3567      * @returns {*} Returns the random element.
3568      */
3569     function arraySample(array) {
3570       var length = array.length;
3571       return length ? array[baseRandom(0, length - 1)] : undefined;
3572     }
3573
3574     /**
3575      * A specialized version of `_.sampleSize` for arrays.
3576      *
3577      * @private
3578      * @param {Array} array The array to sample.
3579      * @param {number} n The number of elements to sample.
3580      * @returns {Array} Returns the random elements.
3581      */
3582     function arraySampleSize(array, n) {
3583       return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
3584     }
3585
3586     /**
3587      * A specialized version of `_.shuffle` for arrays.
3588      *
3589      * @private
3590      * @param {Array} array The array to shuffle.
3591      * @returns {Array} Returns the new shuffled array.
3592      */
3593     function arrayShuffle(array) {
3594       return shuffleSelf(copyArray(array));
3595     }
3596
3597     /**
3598      * This function is like `assignValue` except that it doesn't assign
3599      * `undefined` values.
3600      *
3601      * @private
3602      * @param {Object} object The object to modify.
3603      * @param {string} key The key of the property to assign.
3604      * @param {*} value The value to assign.
3605      */
3606     function assignMergeValue(object, key, value) {
3607       if ((value !== undefined && !eq(object[key], value)) ||
3608           (value === undefined && !(key in object))) {
3609         baseAssignValue(object, key, value);
3610       }
3611     }
3612
3613     /**
3614      * Assigns `value` to `key` of `object` if the existing value is not equivalent
3615      * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
3616      * for equality comparisons.
3617      *
3618      * @private
3619      * @param {Object} object The object to modify.
3620      * @param {string} key The key of the property to assign.
3621      * @param {*} value The value to assign.
3622      */
3623     function assignValue(object, key, value) {
3624       var objValue = object[key];
3625       if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
3626           (value === undefined && !(key in object))) {
3627         baseAssignValue(object, key, value);
3628       }
3629     }
3630
3631     /**
3632      * Gets the index at which the `key` is found in `array` of key-value pairs.
3633      *
3634      * @private
3635      * @param {Array} array The array to inspect.
3636      * @param {*} key The key to search for.
3637      * @returns {number} Returns the index of the matched value, else `-1`.
3638      */
3639     function assocIndexOf(array, key) {
3640       var length = array.length;
3641       while (length--) {
3642         if (eq(array[length][0], key)) {
3643           return length;
3644         }
3645       }
3646       return -1;
3647     }
3648
3649     /**
3650      * Aggregates elements of `collection` on `accumulator` with keys transformed
3651      * by `iteratee` and values set by `setter`.
3652      *
3653      * @private
3654      * @param {Array|Object} collection The collection to iterate over.
3655      * @param {Function} setter The function to set `accumulator` values.
3656      * @param {Function} iteratee The iteratee to transform keys.
3657      * @param {Object} accumulator The initial aggregated object.
3658      * @returns {Function} Returns `accumulator`.
3659      */
3660     function baseAggregator(collection, setter, iteratee, accumulator) {
3661       baseEach(collection, function(value, key, collection) {
3662         setter(accumulator, value, iteratee(value), collection);
3663       });
3664       return accumulator;
3665     }
3666
3667     /**
3668      * The base implementation of `_.assign` without support for multiple sources
3669      * or `customizer` functions.
3670      *
3671      * @private
3672      * @param {Object} object The destination object.
3673      * @param {Object} source The source object.
3674      * @returns {Object} Returns `object`.
3675      */
3676     function baseAssign(object, source) {
3677       return object && copyObject(source, keys(source), object);
3678     }
3679
3680     /**
3681      * The base implementation of `_.assignIn` without support for multiple sources
3682      * or `customizer` functions.
3683      *
3684      * @private
3685      * @param {Object} object The destination object.
3686      * @param {Object} source The source object.
3687      * @returns {Object} Returns `object`.
3688      */
3689     function baseAssignIn(object, source) {
3690       return object && copyObject(source, keysIn(source), object);
3691     }
3692
3693     /**
3694      * The base implementation of `assignValue` and `assignMergeValue` without
3695      * value checks.
3696      *
3697      * @private
3698      * @param {Object} object The object to modify.
3699      * @param {string} key The key of the property to assign.
3700      * @param {*} value The value to assign.
3701      */
3702     function baseAssignValue(object, key, value) {
3703       if (key == '__proto__' && defineProperty) {
3704         defineProperty(object, key, {
3705           'configurable': true,
3706           'enumerable': true,
3707           'value': value,
3708           'writable': true
3709         });
3710       } else {
3711         object[key] = value;
3712       }
3713     }
3714
3715     /**
3716      * The base implementation of `_.at` without support for individual paths.
3717      *
3718      * @private
3719      * @param {Object} object The object to iterate over.
3720      * @param {string[]} paths The property paths to pick.
3721      * @returns {Array} Returns the picked elements.
3722      */
3723     function baseAt(object, paths) {
3724       var index = -1,
3725           length = paths.length,
3726           result = Array(length),
3727           skip = object == null;
3728
3729       while (++index < length) {
3730         result[index] = skip ? undefined : get(object, paths[index]);
3731       }
3732       return result;
3733     }
3734
3735     /**
3736      * The base implementation of `_.clamp` which doesn't coerce arguments.
3737      *
3738      * @private
3739      * @param {number} number The number to clamp.
3740      * @param {number} [lower] The lower bound.
3741      * @param {number} upper The upper bound.
3742      * @returns {number} Returns the clamped number.
3743      */
3744     function baseClamp(number, lower, upper) {
3745       if (number === number) {
3746         if (upper !== undefined) {
3747           number = number <= upper ? number : upper;
3748         }
3749         if (lower !== undefined) {
3750           number = number >= lower ? number : lower;
3751         }
3752       }
3753       return number;
3754     }
3755
3756     /**
3757      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
3758      * traversed objects.
3759      *
3760      * @private
3761      * @param {*} value The value to clone.
3762      * @param {boolean} bitmask The bitmask flags.
3763      *  1 - Deep clone
3764      *  2 - Flatten inherited properties
3765      *  4 - Clone symbols
3766      * @param {Function} [customizer] The function to customize cloning.
3767      * @param {string} [key] The key of `value`.
3768      * @param {Object} [object] The parent object of `value`.
3769      * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
3770      * @returns {*} Returns the cloned value.
3771      */
3772     function baseClone(value, bitmask, customizer, key, object, stack) {
3773       var result,
3774           isDeep = bitmask & CLONE_DEEP_FLAG,
3775           isFlat = bitmask & CLONE_FLAT_FLAG,
3776           isFull = bitmask & CLONE_SYMBOLS_FLAG;
3777
3778       if (customizer) {
3779         result = object ? customizer(value, key, object, stack) : customizer(value);
3780       }
3781       if (result !== undefined) {
3782         return result;
3783       }
3784       if (!isObject(value)) {
3785         return value;
3786       }
3787       var isArr = isArray(value);
3788       if (isArr) {
3789         result = initCloneArray(value);
3790         if (!isDeep) {
3791           return copyArray(value, result);
3792         }
3793       } else {
3794         var tag = getTag(value),
3795             isFunc = tag == funcTag || tag == genTag;
3796
3797         if (isBuffer(value)) {
3798           return cloneBuffer(value, isDeep);
3799         }
3800         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
3801           result = (isFlat || isFunc) ? {} : initCloneObject(value);
3802           if (!isDeep) {
3803             return isFlat
3804               ? copySymbolsIn(value, baseAssignIn(result, value))
3805               : copySymbols(value, baseAssign(result, value));
3806           }
3807         } else {
3808           if (!cloneableTags[tag]) {
3809             return object ? value : {};
3810           }
3811           result = initCloneByTag(value, tag, isDeep);
3812         }
3813       }
3814       // Check for circular references and return its corresponding clone.
3815       stack || (stack = new Stack);
3816       var stacked = stack.get(value);
3817       if (stacked) {
3818         return stacked;
3819       }
3820       stack.set(value, result);
3821
3822       if (isSet(value)) {
3823         value.forEach(function(subValue) {
3824           result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
3825         });
3826       } else if (isMap(value)) {
3827         value.forEach(function(subValue, key) {
3828           result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
3829         });
3830       }
3831
3832       var keysFunc = isFull
3833         ? (isFlat ? getAllKeysIn : getAllKeys)
3834         : (isFlat ? keysIn : keys);
3835
3836       var props = isArr ? undefined : keysFunc(value);
3837       arrayEach(props || value, function(subValue, key) {
3838         if (props) {
3839           key = subValue;
3840           subValue = value[key];
3841         }
3842         // Recursively populate clone (susceptible to call stack limits).
3843         assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
3844       });
3845       return result;
3846     }
3847
3848     /**
3849      * The base implementation of `_.conforms` which doesn't clone `source`.
3850      *
3851      * @private
3852      * @param {Object} source The object of property predicates to conform to.
3853      * @returns {Function} Returns the new spec function.
3854      */
3855     function baseConforms(source) {
3856       var props = keys(source);
3857       return function(object) {
3858         return baseConformsTo(object, source, props);
3859       };
3860     }
3861
3862     /**
3863      * The base implementation of `_.conformsTo` which accepts `props` to check.
3864      *
3865      * @private
3866      * @param {Object} object The object to inspect.
3867      * @param {Object} source The object of property predicates to conform to.
3868      * @returns {boolean} Returns `true` if `object` conforms, else `false`.
3869      */
3870     function baseConformsTo(object, source, props) {
3871       var length = props.length;
3872       if (object == null) {
3873         return !length;
3874       }
3875       object = Object(object);
3876       while (length--) {
3877         var key = props[length],
3878             predicate = source[key],
3879             value = object[key];
3880
3881         if ((value === undefined && !(key in object)) || !predicate(value)) {
3882           return false;
3883         }
3884       }
3885       return true;
3886     }
3887
3888     /**
3889      * The base implementation of `_.delay` and `_.defer` which accepts `args`
3890      * to provide to `func`.
3891      *
3892      * @private
3893      * @param {Function} func The function to delay.
3894      * @param {number} wait The number of milliseconds to delay invocation.
3895      * @param {Array} args The arguments to provide to `func`.
3896      * @returns {number|Object} Returns the timer id or timeout object.
3897      */
3898     function baseDelay(func, wait, args) {
3899       if (typeof func != 'function') {
3900         throw new TypeError(FUNC_ERROR_TEXT);
3901       }
3902       return setTimeout(function() { func.apply(undefined, args); }, wait);
3903     }
3904
3905     /**
3906      * The base implementation of methods like `_.difference` without support
3907      * for excluding multiple arrays or iteratee shorthands.
3908      *
3909      * @private
3910      * @param {Array} array The array to inspect.
3911      * @param {Array} values The values to exclude.
3912      * @param {Function} [iteratee] The iteratee invoked per element.
3913      * @param {Function} [comparator] The comparator invoked per element.
3914      * @returns {Array} Returns the new array of filtered values.
3915      */
3916     function baseDifference(array, values, iteratee, comparator) {
3917       var index = -1,
3918           includes = arrayIncludes,
3919           isCommon = true,
3920           length = array.length,
3921           result = [],
3922           valuesLength = values.length;
3923
3924       if (!length) {
3925         return result;
3926       }
3927       if (iteratee) {
3928         values = arrayMap(values, baseUnary(iteratee));
3929       }
3930       if (comparator) {
3931         includes = arrayIncludesWith;
3932         isCommon = false;
3933       }
3934       else if (values.length >= LARGE_ARRAY_SIZE) {
3935         includes = cacheHas;
3936         isCommon = false;
3937         values = new SetCache(values);
3938       }
3939       outer:
3940       while (++index < length) {
3941         var value = array[index],
3942             computed = iteratee == null ? value : iteratee(value);
3943
3944         value = (comparator || value !== 0) ? value : 0;
3945         if (isCommon && computed === computed) {
3946           var valuesIndex = valuesLength;
3947           while (valuesIndex--) {
3948             if (values[valuesIndex] === computed) {
3949               continue outer;
3950             }
3951           }
3952           result.push(value);
3953         }
3954         else if (!includes(values, computed, comparator)) {
3955           result.push(value);
3956         }
3957       }
3958       return result;
3959     }
3960
3961     /**
3962      * The base implementation of `_.forEach` without support for iteratee shorthands.
3963      *
3964      * @private
3965      * @param {Array|Object} collection The collection to iterate over.
3966      * @param {Function} iteratee The function invoked per iteration.
3967      * @returns {Array|Object} Returns `collection`.
3968      */
3969     var baseEach = createBaseEach(baseForOwn);
3970
3971     /**
3972      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
3973      *
3974      * @private
3975      * @param {Array|Object} collection The collection to iterate over.
3976      * @param {Function} iteratee The function invoked per iteration.
3977      * @returns {Array|Object} Returns `collection`.
3978      */
3979     var baseEachRight = createBaseEach(baseForOwnRight, true);
3980
3981     /**
3982      * The base implementation of `_.every` without support for iteratee shorthands.
3983      *
3984      * @private
3985      * @param {Array|Object} collection The collection to iterate over.
3986      * @param {Function} predicate The function invoked per iteration.
3987      * @returns {boolean} Returns `true` if all elements pass the predicate check,
3988      *  else `false`
3989      */
3990     function baseEvery(collection, predicate) {
3991       var result = true;
3992       baseEach(collection, function(value, index, collection) {
3993         result = !!predicate(value, index, collection);
3994         return result;
3995       });
3996       return result;
3997     }
3998
3999     /**
4000      * The base implementation of methods like `_.max` and `_.min` which accepts a
4001      * `comparator` to determine the extremum value.
4002      *
4003      * @private
4004      * @param {Array} array The array to iterate over.
4005      * @param {Function} iteratee The iteratee invoked per iteration.
4006      * @param {Function} comparator The comparator used to compare values.
4007      * @returns {*} Returns the extremum value.
4008      */
4009     function baseExtremum(array, iteratee, comparator) {
4010       var index = -1,
4011           length = array.length;
4012
4013       while (++index < length) {
4014         var value = array[index],
4015             current = iteratee(value);
4016
4017         if (current != null && (computed === undefined
4018               ? (current === current && !isSymbol(current))
4019               : comparator(current, computed)
4020             )) {
4021           var computed = current,
4022               result = value;
4023         }
4024       }
4025       return result;
4026     }
4027
4028     /**
4029      * The base implementation of `_.fill` without an iteratee call guard.
4030      *
4031      * @private
4032      * @param {Array} array The array to fill.
4033      * @param {*} value The value to fill `array` with.
4034      * @param {number} [start=0] The start position.
4035      * @param {number} [end=array.length] The end position.
4036      * @returns {Array} Returns `array`.
4037      */
4038     function baseFill(array, value, start, end) {
4039       var length = array.length;
4040
4041       start = toInteger(start);
4042       if (start < 0) {
4043         start = -start > length ? 0 : (length + start);
4044       }
4045       end = (end === undefined || end > length) ? length : toInteger(end);
4046       if (end < 0) {
4047         end += length;
4048       }
4049       end = start > end ? 0 : toLength(end);
4050       while (start < end) {
4051         array[start++] = value;
4052       }
4053       return array;
4054     }
4055
4056     /**
4057      * The base implementation of `_.filter` without support for iteratee shorthands.
4058      *
4059      * @private
4060      * @param {Array|Object} collection The collection to iterate over.
4061      * @param {Function} predicate The function invoked per iteration.
4062      * @returns {Array} Returns the new filtered array.
4063      */
4064     function baseFilter(collection, predicate) {
4065       var result = [];
4066       baseEach(collection, function(value, index, collection) {
4067         if (predicate(value, index, collection)) {
4068           result.push(value);
4069         }
4070       });
4071       return result;
4072     }
4073
4074     /**
4075      * The base implementation of `_.flatten` with support for restricting flattening.
4076      *
4077      * @private
4078      * @param {Array} array The array to flatten.
4079      * @param {number} depth The maximum recursion depth.
4080      * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
4081      * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
4082      * @param {Array} [result=[]] The initial result value.
4083      * @returns {Array} Returns the new flattened array.
4084      */
4085     function baseFlatten(array, depth, predicate, isStrict, result) {
4086       var index = -1,
4087           length = array.length;
4088
4089       predicate || (predicate = isFlattenable);
4090       result || (result = []);
4091
4092       while (++index < length) {
4093         var value = array[index];
4094         if (depth > 0 && predicate(value)) {
4095           if (depth > 1) {
4096             // Recursively flatten arrays (susceptible to call stack limits).
4097             baseFlatten(value, depth - 1, predicate, isStrict, result);
4098           } else {
4099             arrayPush(result, value);
4100           }
4101         } else if (!isStrict) {
4102           result[result.length] = value;
4103         }
4104       }
4105       return result;
4106     }
4107
4108     /**
4109      * The base implementation of `baseForOwn` which iterates over `object`
4110      * properties returned by `keysFunc` and invokes `iteratee` for each property.
4111      * Iteratee functions may exit iteration early by explicitly returning `false`.
4112      *
4113      * @private
4114      * @param {Object} object The object to iterate over.
4115      * @param {Function} iteratee The function invoked per iteration.
4116      * @param {Function} keysFunc The function to get the keys of `object`.
4117      * @returns {Object} Returns `object`.
4118      */
4119     var baseFor = createBaseFor();
4120
4121     /**
4122      * This function is like `baseFor` except that it iterates over properties
4123      * in the opposite order.
4124      *
4125      * @private
4126      * @param {Object} object The object to iterate over.
4127      * @param {Function} iteratee The function invoked per iteration.
4128      * @param {Function} keysFunc The function to get the keys of `object`.
4129      * @returns {Object} Returns `object`.
4130      */
4131     var baseForRight = createBaseFor(true);
4132
4133     /**
4134      * The base implementation of `_.forOwn` without support for iteratee shorthands.
4135      *
4136      * @private
4137      * @param {Object} object The object to iterate over.
4138      * @param {Function} iteratee The function invoked per iteration.
4139      * @returns {Object} Returns `object`.
4140      */
4141     function baseForOwn(object, iteratee) {
4142       return object && baseFor(object, iteratee, keys);
4143     }
4144
4145     /**
4146      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
4147      *
4148      * @private
4149      * @param {Object} object The object to iterate over.
4150      * @param {Function} iteratee The function invoked per iteration.
4151      * @returns {Object} Returns `object`.
4152      */
4153     function baseForOwnRight(object, iteratee) {
4154       return object && baseForRight(object, iteratee, keys);
4155     }
4156
4157     /**
4158      * The base implementation of `_.functions` which creates an array of
4159      * `object` function property names filtered from `props`.
4160      *
4161      * @private
4162      * @param {Object} object The object to inspect.
4163      * @param {Array} props The property names to filter.
4164      * @returns {Array} Returns the function names.
4165      */
4166     function baseFunctions(object, props) {
4167       return arrayFilter(props, function(key) {
4168         return isFunction(object[key]);
4169       });
4170     }
4171
4172     /**
4173      * The base implementation of `_.get` without support for default values.
4174      *
4175      * @private
4176      * @param {Object} object The object to query.
4177      * @param {Array|string} path The path of the property to get.
4178      * @returns {*} Returns the resolved value.
4179      */
4180     function baseGet(object, path) {
4181       path = castPath(path, object);
4182
4183       var index = 0,
4184           length = path.length;
4185
4186       while (object != null && index < length) {
4187         object = object[toKey(path[index++])];
4188       }
4189       return (index && index == length) ? object : undefined;
4190     }
4191
4192     /**
4193      * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
4194      * `keysFunc` and `symbolsFunc` to get the enumerable property names and
4195      * symbols of `object`.
4196      *
4197      * @private
4198      * @param {Object} object The object to query.
4199      * @param {Function} keysFunc The function to get the keys of `object`.
4200      * @param {Function} symbolsFunc The function to get the symbols of `object`.
4201      * @returns {Array} Returns the array of property names and symbols.
4202      */
4203     function baseGetAllKeys(object, keysFunc, symbolsFunc) {
4204       var result = keysFunc(object);
4205       return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
4206     }
4207
4208     /**
4209      * The base implementation of `getTag` without fallbacks for buggy environments.
4210      *
4211      * @private
4212      * @param {*} value The value to query.
4213      * @returns {string} Returns the `toStringTag`.
4214      */
4215     function baseGetTag(value) {
4216       if (value == null) {
4217         return value === undefined ? undefinedTag : nullTag;
4218       }
4219       return (symToStringTag && symToStringTag in Object(value))
4220         ? getRawTag(value)
4221         : objectToString(value);
4222     }
4223
4224     /**
4225      * The base implementation of `_.gt` which doesn't coerce arguments.
4226      *
4227      * @private
4228      * @param {*} value The value to compare.
4229      * @param {*} other The other value to compare.
4230      * @returns {boolean} Returns `true` if `value` is greater than `other`,
4231      *  else `false`.
4232      */
4233     function baseGt(value, other) {
4234       return value > other;
4235     }
4236
4237     /**
4238      * The base implementation of `_.has` without support for deep paths.
4239      *
4240      * @private
4241      * @param {Object} [object] The object to query.
4242      * @param {Array|string} key The key to check.
4243      * @returns {boolean} Returns `true` if `key` exists, else `false`.
4244      */
4245     function baseHas(object, key) {
4246       return object != null && hasOwnProperty.call(object, key);
4247     }
4248
4249     /**
4250      * The base implementation of `_.hasIn` without support for deep paths.
4251      *
4252      * @private
4253      * @param {Object} [object] The object to query.
4254      * @param {Array|string} key The key to check.
4255      * @returns {boolean} Returns `true` if `key` exists, else `false`.
4256      */
4257     function baseHasIn(object, key) {
4258       return object != null && key in Object(object);
4259     }
4260
4261     /**
4262      * The base implementation of `_.inRange` which doesn't coerce arguments.
4263      *
4264      * @private
4265      * @param {number} number The number to check.
4266      * @param {number} start The start of the range.
4267      * @param {number} end The end of the range.
4268      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
4269      */
4270     function baseInRange(number, start, end) {
4271       return number >= nativeMin(start, end) && number < nativeMax(start, end);
4272     }
4273
4274     /**
4275      * The base implementation of methods like `_.intersection`, without support
4276      * for iteratee shorthands, that accepts an array of arrays to inspect.
4277      *
4278      * @private
4279      * @param {Array} arrays The arrays to inspect.
4280      * @param {Function} [iteratee] The iteratee invoked per element.
4281      * @param {Function} [comparator] The comparator invoked per element.
4282      * @returns {Array} Returns the new array of shared values.
4283      */
4284     function baseIntersection(arrays, iteratee, comparator) {
4285       var includes = comparator ? arrayIncludesWith : arrayIncludes,
4286           length = arrays[0].length,
4287           othLength = arrays.length,
4288           othIndex = othLength,
4289           caches = Array(othLength),
4290           maxLength = Infinity,
4291           result = [];
4292
4293       while (othIndex--) {
4294         var array = arrays[othIndex];
4295         if (othIndex && iteratee) {
4296           array = arrayMap(array, baseUnary(iteratee));
4297         }
4298         maxLength = nativeMin(array.length, maxLength);
4299         caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
4300           ? new SetCache(othIndex && array)
4301           : undefined;
4302       }
4303       array = arrays[0];
4304
4305       var index = -1,
4306           seen = caches[0];
4307
4308       outer:
4309       while (++index < length && result.length < maxLength) {
4310         var value = array[index],
4311             computed = iteratee ? iteratee(value) : value;
4312
4313         value = (comparator || value !== 0) ? value : 0;
4314         if (!(seen
4315               ? cacheHas(seen, computed)
4316               : includes(result, computed, comparator)
4317             )) {
4318           othIndex = othLength;
4319           while (--othIndex) {
4320             var cache = caches[othIndex];
4321             if (!(cache
4322                   ? cacheHas(cache, computed)
4323                   : includes(arrays[othIndex], computed, comparator))
4324                 ) {
4325               continue outer;
4326             }
4327           }
4328           if (seen) {
4329             seen.push(computed);
4330           }
4331           result.push(value);
4332         }
4333       }
4334       return result;
4335     }
4336
4337     /**
4338      * The base implementation of `_.invert` and `_.invertBy` which inverts
4339      * `object` with values transformed by `iteratee` and set by `setter`.
4340      *
4341      * @private
4342      * @param {Object} object The object to iterate over.
4343      * @param {Function} setter The function to set `accumulator` values.
4344      * @param {Function} iteratee The iteratee to transform values.
4345      * @param {Object} accumulator The initial inverted object.
4346      * @returns {Function} Returns `accumulator`.
4347      */
4348     function baseInverter(object, setter, iteratee, accumulator) {
4349       baseForOwn(object, function(value, key, object) {
4350         setter(accumulator, iteratee(value), key, object);
4351       });
4352       return accumulator;
4353     }
4354
4355     /**
4356      * The base implementation of `_.invoke` without support for individual
4357      * method arguments.
4358      *
4359      * @private
4360      * @param {Object} object The object to query.
4361      * @param {Array|string} path The path of the method to invoke.
4362      * @param {Array} args The arguments to invoke the method with.
4363      * @returns {*} Returns the result of the invoked method.
4364      */
4365     function baseInvoke(object, path, args) {
4366       path = castPath(path, object);
4367       object = parent(object, path);
4368       var func = object == null ? object : object[toKey(last(path))];
4369       return func == null ? undefined : apply(func, object, args);
4370     }
4371
4372     /**
4373      * The base implementation of `_.isArguments`.
4374      *
4375      * @private
4376      * @param {*} value The value to check.
4377      * @returns {boolean} Returns `true` if `value` is an `arguments` object,
4378      */
4379     function baseIsArguments(value) {
4380       return isObjectLike(value) && baseGetTag(value) == argsTag;
4381     }
4382
4383     /**
4384      * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
4385      *
4386      * @private
4387      * @param {*} value The value to check.
4388      * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
4389      */
4390     function baseIsArrayBuffer(value) {
4391       return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
4392     }
4393
4394     /**
4395      * The base implementation of `_.isDate` without Node.js optimizations.
4396      *
4397      * @private
4398      * @param {*} value The value to check.
4399      * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
4400      */
4401     function baseIsDate(value) {
4402       return isObjectLike(value) && baseGetTag(value) == dateTag;
4403     }
4404
4405     /**
4406      * The base implementation of `_.isEqual` which supports partial comparisons
4407      * and tracks traversed objects.
4408      *
4409      * @private
4410      * @param {*} value The value to compare.
4411      * @param {*} other The other value to compare.
4412      * @param {boolean} bitmask The bitmask flags.
4413      *  1 - Unordered comparison
4414      *  2 - Partial comparison
4415      * @param {Function} [customizer] The function to customize comparisons.
4416      * @param {Object} [stack] Tracks traversed `value` and `other` objects.
4417      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
4418      */
4419     function baseIsEqual(value, other, bitmask, customizer, stack) {
4420       if (value === other) {
4421         return true;
4422       }
4423       if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
4424         return value !== value && other !== other;
4425       }
4426       return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
4427     }
4428
4429     /**
4430      * A specialized version of `baseIsEqual` for arrays and objects which performs
4431      * deep comparisons and tracks traversed objects enabling objects with circular
4432      * references to be compared.
4433      *
4434      * @private
4435      * @param {Object} object The object to compare.
4436      * @param {Object} other The other object to compare.
4437      * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
4438      * @param {Function} customizer The function to customize comparisons.
4439      * @param {Function} equalFunc The function to determine equivalents of values.
4440      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
4441      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4442      */
4443     function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
4444       var objIsArr = isArray(object),
4445           othIsArr = isArray(other),
4446           objTag = objIsArr ? arrayTag : getTag(object),
4447           othTag = othIsArr ? arrayTag : getTag(other);
4448
4449       objTag = objTag == argsTag ? objectTag : objTag;
4450       othTag = othTag == argsTag ? objectTag : othTag;
4451
4452       var objIsObj = objTag == objectTag,
4453           othIsObj = othTag == objectTag,
4454           isSameTag = objTag == othTag;
4455
4456       if (isSameTag && isBuffer(object)) {
4457         if (!isBuffer(other)) {
4458           return false;
4459         }
4460         objIsArr = true;
4461         objIsObj = false;
4462       }
4463       if (isSameTag && !objIsObj) {
4464         stack || (stack = new Stack);
4465         return (objIsArr || isTypedArray(object))
4466           ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
4467           : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
4468       }
4469       if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
4470         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
4471             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
4472
4473         if (objIsWrapped || othIsWrapped) {
4474           var objUnwrapped = objIsWrapped ? object.value() : object,
4475               othUnwrapped = othIsWrapped ? other.value() : other;
4476
4477           stack || (stack = new Stack);
4478           return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
4479         }
4480       }
4481       if (!isSameTag) {
4482         return false;
4483       }
4484       stack || (stack = new Stack);
4485       return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
4486     }
4487
4488     /**
4489      * The base implementation of `_.isMap` without Node.js optimizations.
4490      *
4491      * @private
4492      * @param {*} value The value to check.
4493      * @returns {boolean} Returns `true` if `value` is a map, else `false`.
4494      */
4495     function baseIsMap(value) {
4496       return isObjectLike(value) && getTag(value) == mapTag;
4497     }
4498
4499     /**
4500      * The base implementation of `_.isMatch` without support for iteratee shorthands.
4501      *
4502      * @private
4503      * @param {Object} object The object to inspect.
4504      * @param {Object} source The object of property values to match.
4505      * @param {Array} matchData The property names, values, and compare flags to match.
4506      * @param {Function} [customizer] The function to customize comparisons.
4507      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
4508      */
4509     function baseIsMatch(object, source, matchData, customizer) {
4510       var index = matchData.length,
4511           length = index,
4512           noCustomizer = !customizer;
4513
4514       if (object == null) {
4515         return !length;
4516       }
4517       object = Object(object);
4518       while (index--) {
4519         var data = matchData[index];
4520         if ((noCustomizer && data[2])
4521               ? data[1] !== object[data[0]]
4522               : !(data[0] in object)
4523             ) {
4524           return false;
4525         }
4526       }
4527       while (++index < length) {
4528         data = matchData[index];
4529         var key = data[0],
4530             objValue = object[key],
4531             srcValue = data[1];
4532
4533         if (noCustomizer && data[2]) {
4534           if (objValue === undefined && !(key in object)) {
4535             return false;
4536           }
4537         } else {
4538           var stack = new Stack;
4539           if (customizer) {
4540             var result = customizer(objValue, srcValue, key, object, source, stack);
4541           }
4542           if (!(result === undefined
4543                 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
4544                 : result
4545               )) {
4546             return false;
4547           }
4548         }
4549       }
4550       return true;
4551     }
4552
4553     /**
4554      * The base implementation of `_.isNative` without bad shim checks.
4555      *
4556      * @private
4557      * @param {*} value The value to check.
4558      * @returns {boolean} Returns `true` if `value` is a native function,
4559      *  else `false`.
4560      */
4561     function baseIsNative(value) {
4562       if (!isObject(value) || isMasked(value)) {
4563         return false;
4564       }
4565       var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
4566       return pattern.test(toSource(value));
4567     }
4568
4569     /**
4570      * The base implementation of `_.isRegExp` without Node.js optimizations.
4571      *
4572      * @private
4573      * @param {*} value The value to check.
4574      * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
4575      */
4576     function baseIsRegExp(value) {
4577       return isObjectLike(value) && baseGetTag(value) == regexpTag;
4578     }
4579
4580     /**
4581      * The base implementation of `_.isSet` without Node.js optimizations.
4582      *
4583      * @private
4584      * @param {*} value The value to check.
4585      * @returns {boolean} Returns `true` if `value` is a set, else `false`.
4586      */
4587     function baseIsSet(value) {
4588       return isObjectLike(value) && getTag(value) == setTag;
4589     }
4590
4591     /**
4592      * The base implementation of `_.isTypedArray` without Node.js optimizations.
4593      *
4594      * @private
4595      * @param {*} value The value to check.
4596      * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
4597      */
4598     function baseIsTypedArray(value) {
4599       return isObjectLike(value) &&
4600         isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
4601     }
4602
4603     /**
4604      * The base implementation of `_.iteratee`.
4605      *
4606      * @private
4607      * @param {*} [value=_.identity] The value to convert to an iteratee.
4608      * @returns {Function} Returns the iteratee.
4609      */
4610     function baseIteratee(value) {
4611       // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
4612       // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
4613       if (typeof value == 'function') {
4614         return value;
4615       }
4616       if (value == null) {
4617         return identity;
4618       }
4619       if (typeof value == 'object') {
4620         return isArray(value)
4621           ? baseMatchesProperty(value[0], value[1])
4622           : baseMatches(value);
4623       }
4624       return property(value);
4625     }
4626
4627     /**
4628      * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
4629      *
4630      * @private
4631      * @param {Object} object The object to query.
4632      * @returns {Array} Returns the array of property names.
4633      */
4634     function baseKeys(object) {
4635       if (!isPrototype(object)) {
4636         return nativeKeys(object);
4637       }
4638       var result = [];
4639       for (var key in Object(object)) {
4640         if (hasOwnProperty.call(object, key) && key != 'constructor') {
4641           result.push(key);
4642         }
4643       }
4644       return result;
4645     }
4646
4647     /**
4648      * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
4649      *
4650      * @private
4651      * @param {Object} object The object to query.
4652      * @returns {Array} Returns the array of property names.
4653      */
4654     function baseKeysIn(object) {
4655       if (!isObject(object)) {
4656         return nativeKeysIn(object);
4657       }
4658       var isProto = isPrototype(object),
4659           result = [];
4660
4661       for (var key in object) {
4662         if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
4663           result.push(key);
4664         }
4665       }
4666       return result;
4667     }
4668
4669     /**
4670      * The base implementation of `_.lt` which doesn't coerce arguments.
4671      *
4672      * @private
4673      * @param {*} value The value to compare.
4674      * @param {*} other The other value to compare.
4675      * @returns {boolean} Returns `true` if `value` is less than `other`,
4676      *  else `false`.
4677      */
4678     function baseLt(value, other) {
4679       return value < other;
4680     }
4681
4682     /**
4683      * The base implementation of `_.map` without support for iteratee shorthands.
4684      *
4685      * @private
4686      * @param {Array|Object} collection The collection to iterate over.
4687      * @param {Function} iteratee The function invoked per iteration.
4688      * @returns {Array} Returns the new mapped array.
4689      */
4690     function baseMap(collection, iteratee) {
4691       var index = -1,
4692           result = isArrayLike(collection) ? Array(collection.length) : [];
4693
4694       baseEach(collection, function(value, key, collection) {
4695         result[++index] = iteratee(value, key, collection);
4696       });
4697       return result;
4698     }
4699
4700     /**
4701      * The base implementation of `_.matches` which doesn't clone `source`.
4702      *
4703      * @private
4704      * @param {Object} source The object of property values to match.
4705      * @returns {Function} Returns the new spec function.
4706      */
4707     function baseMatches(source) {
4708       var matchData = getMatchData(source);
4709       if (matchData.length == 1 && matchData[0][2]) {
4710         return matchesStrictComparable(matchData[0][0], matchData[0][1]);
4711       }
4712       return function(object) {
4713         return object === source || baseIsMatch(object, source, matchData);
4714       };
4715     }
4716
4717     /**
4718      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
4719      *
4720      * @private
4721      * @param {string} path The path of the property to get.
4722      * @param {*} srcValue The value to match.
4723      * @returns {Function} Returns the new spec function.
4724      */
4725     function baseMatchesProperty(path, srcValue) {
4726       if (isKey(path) && isStrictComparable(srcValue)) {
4727         return matchesStrictComparable(toKey(path), srcValue);
4728       }
4729       return function(object) {
4730         var objValue = get(object, path);
4731         return (objValue === undefined && objValue === srcValue)
4732           ? hasIn(object, path)
4733           : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
4734       };
4735     }
4736
4737     /**
4738      * The base implementation of `_.merge` without support for multiple sources.
4739      *
4740      * @private
4741      * @param {Object} object The destination object.
4742      * @param {Object} source The source object.
4743      * @param {number} srcIndex The index of `source`.
4744      * @param {Function} [customizer] The function to customize merged values.
4745      * @param {Object} [stack] Tracks traversed source values and their merged
4746      *  counterparts.
4747      */
4748     function baseMerge(object, source, srcIndex, customizer, stack) {
4749       if (object === source) {
4750         return;
4751       }
4752       baseFor(source, function(srcValue, key) {
4753         stack || (stack = new Stack);
4754         if (isObject(srcValue)) {
4755           baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
4756         }
4757         else {
4758           var newValue = customizer
4759             ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
4760             : undefined;
4761
4762           if (newValue === undefined) {
4763             newValue = srcValue;
4764           }
4765           assignMergeValue(object, key, newValue);
4766         }
4767       }, keysIn);
4768     }
4769
4770     /**
4771      * A specialized version of `baseMerge` for arrays and objects which performs
4772      * deep merges and tracks traversed objects enabling objects with circular
4773      * references to be merged.
4774      *
4775      * @private
4776      * @param {Object} object The destination object.
4777      * @param {Object} source The source object.
4778      * @param {string} key The key of the value to merge.
4779      * @param {number} srcIndex The index of `source`.
4780      * @param {Function} mergeFunc The function to merge values.
4781      * @param {Function} [customizer] The function to customize assigned values.
4782      * @param {Object} [stack] Tracks traversed source values and their merged
4783      *  counterparts.
4784      */
4785     function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
4786       var objValue = safeGet(object, key),
4787           srcValue = safeGet(source, key),
4788           stacked = stack.get(srcValue);
4789
4790       if (stacked) {
4791         assignMergeValue(object, key, stacked);
4792         return;
4793       }
4794       var newValue = customizer
4795         ? customizer(objValue, srcValue, (key + ''), object, source, stack)
4796         : undefined;
4797
4798       var isCommon = newValue === undefined;
4799
4800       if (isCommon) {
4801         var isArr = isArray(srcValue),
4802             isBuff = !isArr && isBuffer(srcValue),
4803             isTyped = !isArr && !isBuff && isTypedArray(srcValue);
4804
4805         newValue = srcValue;
4806         if (isArr || isBuff || isTyped) {
4807           if (isArray(objValue)) {
4808             newValue = objValue;
4809           }
4810           else if (isArrayLikeObject(objValue)) {
4811             newValue = copyArray(objValue);
4812           }
4813           else if (isBuff) {
4814             isCommon = false;
4815             newValue = cloneBuffer(srcValue, true);
4816           }
4817           else if (isTyped) {
4818             isCommon = false;
4819             newValue = cloneTypedArray(srcValue, true);
4820           }
4821           else {
4822             newValue = [];
4823           }
4824         }
4825         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
4826           newValue = objValue;
4827           if (isArguments(objValue)) {
4828             newValue = toPlainObject(objValue);
4829           }
4830           else if (!isObject(objValue) || isFunction(objValue)) {
4831             newValue = initCloneObject(srcValue);
4832           }
4833         }
4834         else {
4835           isCommon = false;
4836         }
4837       }
4838       if (isCommon) {
4839         // Recursively merge objects and arrays (susceptible to call stack limits).
4840         stack.set(srcValue, newValue);
4841         mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
4842         stack['delete'](srcValue);
4843       }
4844       assignMergeValue(object, key, newValue);
4845     }
4846
4847     /**
4848      * The base implementation of `_.nth` which doesn't coerce arguments.
4849      *
4850      * @private
4851      * @param {Array} array The array to query.
4852      * @param {number} n The index of the element to return.
4853      * @returns {*} Returns the nth element of `array`.
4854      */
4855     function baseNth(array, n) {
4856       var length = array.length;
4857       if (!length) {
4858         return;
4859       }
4860       n += n < 0 ? length : 0;
4861       return isIndex(n, length) ? array[n] : undefined;
4862     }
4863
4864     /**
4865      * The base implementation of `_.orderBy` without param guards.
4866      *
4867      * @private
4868      * @param {Array|Object} collection The collection to iterate over.
4869      * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
4870      * @param {string[]} orders The sort orders of `iteratees`.
4871      * @returns {Array} Returns the new sorted array.
4872      */
4873     function baseOrderBy(collection, iteratees, orders) {
4874       if (iteratees.length) {
4875         iteratees = arrayMap(iteratees, function(iteratee) {
4876           if (isArray(iteratee)) {
4877             return function(value) {
4878               return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
4879             }
4880           }
4881           return iteratee;
4882         });
4883       } else {
4884         iteratees = [identity];
4885       }
4886
4887       var index = -1;
4888       iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
4889
4890       var result = baseMap(collection, function(value, key, collection) {
4891         var criteria = arrayMap(iteratees, function(iteratee) {
4892           return iteratee(value);
4893         });
4894         return { 'criteria': criteria, 'index': ++index, 'value': value };
4895       });
4896
4897       return baseSortBy(result, function(object, other) {
4898         return compareMultiple(object, other, orders);
4899       });
4900     }
4901
4902     /**
4903      * The base implementation of `_.pick` without support for individual
4904      * property identifiers.
4905      *
4906      * @private
4907      * @param {Object} object The source object.
4908      * @param {string[]} paths The property paths to pick.
4909      * @returns {Object} Returns the new object.
4910      */
4911     function basePick(object, paths) {
4912       return basePickBy(object, paths, function(value, path) {
4913         return hasIn(object, path);
4914       });
4915     }
4916
4917     /**
4918      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
4919      *
4920      * @private
4921      * @param {Object} object The source object.
4922      * @param {string[]} paths The property paths to pick.
4923      * @param {Function} predicate The function invoked per property.
4924      * @returns {Object} Returns the new object.
4925      */
4926     function basePickBy(object, paths, predicate) {
4927       var index = -1,
4928           length = paths.length,
4929           result = {};
4930
4931       while (++index < length) {
4932         var path = paths[index],
4933             value = baseGet(object, path);
4934
4935         if (predicate(value, path)) {
4936           baseSet(result, castPath(path, object), value);
4937         }
4938       }
4939       return result;
4940     }
4941
4942     /**
4943      * A specialized version of `baseProperty` which supports deep paths.
4944      *
4945      * @private
4946      * @param {Array|string} path The path of the property to get.
4947      * @returns {Function} Returns the new accessor function.
4948      */
4949     function basePropertyDeep(path) {
4950       return function(object) {
4951         return baseGet(object, path);
4952       };
4953     }
4954
4955     /**
4956      * The base implementation of `_.pullAllBy` without support for iteratee
4957      * shorthands.
4958      *
4959      * @private
4960      * @param {Array} array The array to modify.
4961      * @param {Array} values The values to remove.
4962      * @param {Function} [iteratee] The iteratee invoked per element.
4963      * @param {Function} [comparator] The comparator invoked per element.
4964      * @returns {Array} Returns `array`.
4965      */
4966     function basePullAll(array, values, iteratee, comparator) {
4967       var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
4968           index = -1,
4969           length = values.length,
4970           seen = array;
4971
4972       if (array === values) {
4973         values = copyArray(values);
4974       }
4975       if (iteratee) {
4976         seen = arrayMap(array, baseUnary(iteratee));
4977       }
4978       while (++index < length) {
4979         var fromIndex = 0,
4980             value = values[index],
4981             computed = iteratee ? iteratee(value) : value;
4982
4983         while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
4984           if (seen !== array) {
4985             splice.call(seen, fromIndex, 1);
4986           }
4987           splice.call(array, fromIndex, 1);
4988         }
4989       }
4990       return array;
4991     }
4992
4993     /**
4994      * The base implementation of `_.pullAt` without support for individual
4995      * indexes or capturing the removed elements.
4996      *
4997      * @private
4998      * @param {Array} array The array to modify.
4999      * @param {number[]} indexes The indexes of elements to remove.
5000      * @returns {Array} Returns `array`.
5001      */
5002     function basePullAt(array, indexes) {
5003       var length = array ? indexes.length : 0,
5004           lastIndex = length - 1;
5005
5006       while (length--) {
5007         var index = indexes[length];
5008         if (length == lastIndex || index !== previous) {
5009           var previous = index;
5010           if (isIndex(index)) {
5011             splice.call(array, index, 1);
5012           } else {
5013             baseUnset(array, index);
5014           }
5015         }
5016       }
5017       return array;
5018     }
5019
5020     /**
5021      * The base implementation of `_.random` without support for returning
5022      * floating-point numbers.
5023      *
5024      * @private
5025      * @param {number} lower The lower bound.
5026      * @param {number} upper The upper bound.
5027      * @returns {number} Returns the random number.
5028      */
5029     function baseRandom(lower, upper) {
5030       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
5031     }
5032
5033     /**
5034      * The base implementation of `_.range` and `_.rangeRight` which doesn't
5035      * coerce arguments.
5036      *
5037      * @private
5038      * @param {number} start The start of the range.
5039      * @param {number} end The end of the range.
5040      * @param {number} step The value to increment or decrement by.
5041      * @param {boolean} [fromRight] Specify iterating from right to left.
5042      * @returns {Array} Returns the range of numbers.
5043      */
5044     function baseRange(start, end, step, fromRight) {
5045       var index = -1,
5046           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
5047           result = Array(length);
5048
5049       while (length--) {
5050         result[fromRight ? length : ++index] = start;
5051         start += step;
5052       }
5053       return result;
5054     }
5055
5056     /**
5057      * The base implementation of `_.repeat` which doesn't coerce arguments.
5058      *
5059      * @private
5060      * @param {string} string The string to repeat.
5061      * @param {number} n The number of times to repeat the string.
5062      * @returns {string} Returns the repeated string.
5063      */
5064     function baseRepeat(string, n) {
5065       var result = '';
5066       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
5067         return result;
5068       }
5069       // Leverage the exponentiation by squaring algorithm for a faster repeat.
5070       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
5071       do {
5072         if (n % 2) {
5073           result += string;
5074         }
5075         n = nativeFloor(n / 2);
5076         if (n) {
5077           string += string;
5078         }
5079       } while (n);
5080
5081       return result;
5082     }
5083
5084     /**
5085      * The base implementation of `_.rest` which doesn't validate or coerce arguments.
5086      *
5087      * @private
5088      * @param {Function} func The function to apply a rest parameter to.
5089      * @param {number} [start=func.length-1] The start position of the rest parameter.
5090      * @returns {Function} Returns the new function.
5091      */
5092     function baseRest(func, start) {
5093       return setToString(overRest(func, start, identity), func + '');
5094     }
5095
5096     /**
5097      * The base implementation of `_.sample`.
5098      *
5099      * @private
5100      * @param {Array|Object} collection The collection to sample.
5101      * @returns {*} Returns the random element.
5102      */
5103     function baseSample(collection) {
5104       return arraySample(values(collection));
5105     }
5106
5107     /**
5108      * The base implementation of `_.sampleSize` without param guards.
5109      *
5110      * @private
5111      * @param {Array|Object} collection The collection to sample.
5112      * @param {number} n The number of elements to sample.
5113      * @returns {Array} Returns the random elements.
5114      */
5115     function baseSampleSize(collection, n) {
5116       var array = values(collection);
5117       return shuffleSelf(array, baseClamp(n, 0, array.length));
5118     }
5119
5120     /**
5121      * The base implementation of `_.set`.
5122      *
5123      * @private
5124      * @param {Object} object The object to modify.
5125      * @param {Array|string} path The path of the property to set.
5126      * @param {*} value The value to set.
5127      * @param {Function} [customizer] The function to customize path creation.
5128      * @returns {Object} Returns `object`.
5129      */
5130     function baseSet(object, path, value, customizer) {
5131       if (!isObject(object)) {
5132         return object;
5133       }
5134       path = castPath(path, object);
5135
5136       var index = -1,
5137           length = path.length,
5138           lastIndex = length - 1,
5139           nested = object;
5140
5141       while (nested != null && ++index < length) {
5142         var key = toKey(path[index]),
5143             newValue = value;
5144
5145         if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
5146           return object;
5147         }
5148
5149         if (index != lastIndex) {
5150           var objValue = nested[key];
5151           newValue = customizer ? customizer(objValue, key, nested) : undefined;
5152           if (newValue === undefined) {
5153             newValue = isObject(objValue)
5154               ? objValue
5155               : (isIndex(path[index + 1]) ? [] : {});
5156           }
5157         }
5158         assignValue(nested, key, newValue);
5159         nested = nested[key];
5160       }
5161       return object;
5162     }
5163
5164     /**
5165      * The base implementation of `setData` without support for hot loop shorting.
5166      *
5167      * @private
5168      * @param {Function} func The function to associate metadata with.
5169      * @param {*} data The metadata.
5170      * @returns {Function} Returns `func`.
5171      */
5172     var baseSetData = !metaMap ? identity : function(func, data) {
5173       metaMap.set(func, data);
5174       return func;
5175     };
5176
5177     /**
5178      * The base implementation of `setToString` without support for hot loop shorting.
5179      *
5180      * @private
5181      * @param {Function} func The function to modify.
5182      * @param {Function} string The `toString` result.
5183      * @returns {Function} Returns `func`.
5184      */
5185     var baseSetToString = !defineProperty ? identity : function(func, string) {
5186       return defineProperty(func, 'toString', {
5187         'configurable': true,
5188         'enumerable': false,
5189         'value': constant(string),
5190         'writable': true
5191       });
5192     };
5193
5194     /**
5195      * The base implementation of `_.shuffle`.
5196      *
5197      * @private
5198      * @param {Array|Object} collection The collection to shuffle.
5199      * @returns {Array} Returns the new shuffled array.
5200      */
5201     function baseShuffle(collection) {
5202       return shuffleSelf(values(collection));
5203     }
5204
5205     /**
5206      * The base implementation of `_.slice` without an iteratee call guard.
5207      *
5208      * @private
5209      * @param {Array} array The array to slice.
5210      * @param {number} [start=0] The start position.
5211      * @param {number} [end=array.length] The end position.
5212      * @returns {Array} Returns the slice of `array`.
5213      */
5214     function baseSlice(array, start, end) {
5215       var index = -1,
5216           length = array.length;
5217
5218       if (start < 0) {
5219         start = -start > length ? 0 : (length + start);
5220       }
5221       end = end > length ? length : end;
5222       if (end < 0) {
5223         end += length;
5224       }
5225       length = start > end ? 0 : ((end - start) >>> 0);
5226       start >>>= 0;
5227
5228       var result = Array(length);
5229       while (++index < length) {
5230         result[index] = array[index + start];
5231       }
5232       return result;
5233     }
5234
5235     /**
5236      * The base implementation of `_.some` without support for iteratee shorthands.
5237      *
5238      * @private
5239      * @param {Array|Object} collection The collection to iterate over.
5240      * @param {Function} predicate The function invoked per iteration.
5241      * @returns {boolean} Returns `true` if any element passes the predicate check,
5242      *  else `false`.
5243      */
5244     function baseSome(collection, predicate) {
5245       var result;
5246
5247       baseEach(collection, function(value, index, collection) {
5248         result = predicate(value, index, collection);
5249         return !result;
5250       });
5251       return !!result;
5252     }
5253
5254     /**
5255      * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
5256      * performs a binary search of `array` to determine the index at which `value`
5257      * should be inserted into `array` in order to maintain its sort order.
5258      *
5259      * @private
5260      * @param {Array} array The sorted array to inspect.
5261      * @param {*} value The value to evaluate.
5262      * @param {boolean} [retHighest] Specify returning the highest qualified index.
5263      * @returns {number} Returns the index at which `value` should be inserted
5264      *  into `array`.
5265      */
5266     function baseSortedIndex(array, value, retHighest) {
5267       var low = 0,
5268           high = array == null ? low : array.length;
5269
5270       if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
5271         while (low < high) {
5272           var mid = (low + high) >>> 1,
5273               computed = array[mid];
5274
5275           if (computed !== null && !isSymbol(computed) &&
5276               (retHighest ? (computed <= value) : (computed < value))) {
5277             low = mid + 1;
5278           } else {
5279             high = mid;
5280           }
5281         }
5282         return high;
5283       }
5284       return baseSortedIndexBy(array, value, identity, retHighest);
5285     }
5286
5287     /**
5288      * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
5289      * which invokes `iteratee` for `value` and each element of `array` to compute
5290      * their sort ranking. The iteratee is invoked with one argument; (value).
5291      *
5292      * @private
5293      * @param {Array} array The sorted array to inspect.
5294      * @param {*} value The value to evaluate.
5295      * @param {Function} iteratee The iteratee invoked per element.
5296      * @param {boolean} [retHighest] Specify returning the highest qualified index.
5297      * @returns {number} Returns the index at which `value` should be inserted
5298      *  into `array`.
5299      */
5300     function baseSortedIndexBy(array, value, iteratee, retHighest) {
5301       var low = 0,
5302           high = array == null ? 0 : array.length;
5303       if (high === 0) {
5304         return 0;
5305       }
5306
5307       value = iteratee(value);
5308       var valIsNaN = value !== value,
5309           valIsNull = value === null,
5310           valIsSymbol = isSymbol(value),
5311           valIsUndefined = value === undefined;
5312
5313       while (low < high) {
5314         var mid = nativeFloor((low + high) / 2),
5315             computed = iteratee(array[mid]),
5316             othIsDefined = computed !== undefined,
5317             othIsNull = computed === null,
5318             othIsReflexive = computed === computed,
5319             othIsSymbol = isSymbol(computed);
5320
5321         if (valIsNaN) {
5322           var setLow = retHighest || othIsReflexive;
5323         } else if (valIsUndefined) {
5324           setLow = othIsReflexive && (retHighest || othIsDefined);
5325         } else if (valIsNull) {
5326           setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
5327         } else if (valIsSymbol) {
5328           setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
5329         } else if (othIsNull || othIsSymbol) {
5330           setLow = false;
5331         } else {
5332           setLow = retHighest ? (computed <= value) : (computed < value);
5333         }
5334         if (setLow) {
5335           low = mid + 1;
5336         } else {
5337           high = mid;
5338         }
5339       }
5340       return nativeMin(high, MAX_ARRAY_INDEX);
5341     }
5342
5343     /**
5344      * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
5345      * support for iteratee shorthands.
5346      *
5347      * @private
5348      * @param {Array} array The array to inspect.
5349      * @param {Function} [iteratee] The iteratee invoked per element.
5350      * @returns {Array} Returns the new duplicate free array.
5351      */
5352     function baseSortedUniq(array, iteratee) {
5353       var index = -1,
5354           length = array.length,
5355           resIndex = 0,
5356           result = [];
5357
5358       while (++index < length) {
5359         var value = array[index],
5360             computed = iteratee ? iteratee(value) : value;
5361
5362         if (!index || !eq(computed, seen)) {
5363           var seen = computed;
5364           result[resIndex++] = value === 0 ? 0 : value;
5365         }
5366       }
5367       return result;
5368     }
5369
5370     /**
5371      * The base implementation of `_.toNumber` which doesn't ensure correct
5372      * conversions of binary, hexadecimal, or octal string values.
5373      *
5374      * @private
5375      * @param {*} value The value to process.
5376      * @returns {number} Returns the number.
5377      */
5378     function baseToNumber(value) {
5379       if (typeof value == 'number') {
5380         return value;
5381       }
5382       if (isSymbol(value)) {
5383         return NAN;
5384       }
5385       return +value;
5386     }
5387
5388     /**
5389      * The base implementation of `_.toString` which doesn't convert nullish
5390      * values to empty strings.
5391      *
5392      * @private
5393      * @param {*} value The value to process.
5394      * @returns {string} Returns the string.
5395      */
5396     function baseToString(value) {
5397       // Exit early for strings to avoid a performance hit in some environments.
5398       if (typeof value == 'string') {
5399         return value;
5400       }
5401       if (isArray(value)) {
5402         // Recursively convert values (susceptible to call stack limits).
5403         return arrayMap(value, baseToString) + '';
5404       }
5405       if (isSymbol(value)) {
5406         return symbolToString ? symbolToString.call(value) : '';
5407       }
5408       var result = (value + '');
5409       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
5410     }
5411
5412     /**
5413      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
5414      *
5415      * @private
5416      * @param {Array} array The array to inspect.
5417      * @param {Function} [iteratee] The iteratee invoked per element.
5418      * @param {Function} [comparator] The comparator invoked per element.
5419      * @returns {Array} Returns the new duplicate free array.
5420      */
5421     function baseUniq(array, iteratee, comparator) {
5422       var index = -1,
5423           includes = arrayIncludes,
5424           length = array.length,
5425           isCommon = true,
5426           result = [],
5427           seen = result;
5428
5429       if (comparator) {
5430         isCommon = false;
5431         includes = arrayIncludesWith;
5432       }
5433       else if (length >= LARGE_ARRAY_SIZE) {
5434         var set = iteratee ? null : createSet(array);
5435         if (set) {
5436           return setToArray(set);
5437         }
5438         isCommon = false;
5439         includes = cacheHas;
5440         seen = new SetCache;
5441       }
5442       else {
5443         seen = iteratee ? [] : result;
5444       }
5445       outer:
5446       while (++index < length) {
5447         var value = array[index],
5448             computed = iteratee ? iteratee(value) : value;
5449
5450         value = (comparator || value !== 0) ? value : 0;
5451         if (isCommon && computed === computed) {
5452           var seenIndex = seen.length;
5453           while (seenIndex--) {
5454             if (seen[seenIndex] === computed) {
5455               continue outer;
5456             }
5457           }
5458           if (iteratee) {
5459             seen.push(computed);
5460           }
5461           result.push(value);
5462         }
5463         else if (!includes(seen, computed, comparator)) {
5464           if (seen !== result) {
5465             seen.push(computed);
5466           }
5467           result.push(value);
5468         }
5469       }
5470       return result;
5471     }
5472
5473     /**
5474      * The base implementation of `_.unset`.
5475      *
5476      * @private
5477      * @param {Object} object The object to modify.
5478      * @param {Array|string} path The property path to unset.
5479      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
5480      */
5481     function baseUnset(object, path) {
5482       path = castPath(path, object);
5483       object = parent(object, path);
5484       return object == null || delete object[toKey(last(path))];
5485     }
5486
5487     /**
5488      * The base implementation of `_.update`.
5489      *
5490      * @private
5491      * @param {Object} object The object to modify.
5492      * @param {Array|string} path The path of the property to update.
5493      * @param {Function} updater The function to produce the updated value.
5494      * @param {Function} [customizer] The function to customize path creation.
5495      * @returns {Object} Returns `object`.
5496      */
5497     function baseUpdate(object, path, updater, customizer) {
5498       return baseSet(object, path, updater(baseGet(object, path)), customizer);
5499     }
5500
5501     /**
5502      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
5503      * without support for iteratee shorthands.
5504      *
5505      * @private
5506      * @param {Array} array The array to query.
5507      * @param {Function} predicate The function invoked per iteration.
5508      * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
5509      * @param {boolean} [fromRight] Specify iterating from right to left.
5510      * @returns {Array} Returns the slice of `array`.
5511      */
5512     function baseWhile(array, predicate, isDrop, fromRight) {
5513       var length = array.length,
5514           index = fromRight ? length : -1;
5515
5516       while ((fromRight ? index-- : ++index < length) &&
5517         predicate(array[index], index, array)) {}
5518
5519       return isDrop
5520         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
5521         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
5522     }
5523
5524     /**
5525      * The base implementation of `wrapperValue` which returns the result of
5526      * performing a sequence of actions on the unwrapped `value`, where each
5527      * successive action is supplied the return value of the previous.
5528      *
5529      * @private
5530      * @param {*} value The unwrapped value.
5531      * @param {Array} actions Actions to perform to resolve the unwrapped value.
5532      * @returns {*} Returns the resolved value.
5533      */
5534     function baseWrapperValue(value, actions) {
5535       var result = value;
5536       if (result instanceof LazyWrapper) {
5537         result = result.value();
5538       }
5539       return arrayReduce(actions, function(result, action) {
5540         return action.func.apply(action.thisArg, arrayPush([result], action.args));
5541       }, result);
5542     }
5543
5544     /**
5545      * The base implementation of methods like `_.xor`, without support for
5546      * iteratee shorthands, that accepts an array of arrays to inspect.
5547      *
5548      * @private
5549      * @param {Array} arrays The arrays to inspect.
5550      * @param {Function} [iteratee] The iteratee invoked per element.
5551      * @param {Function} [comparator] The comparator invoked per element.
5552      * @returns {Array} Returns the new array of values.
5553      */
5554     function baseXor(arrays, iteratee, comparator) {
5555       var length = arrays.length;
5556       if (length < 2) {
5557         return length ? baseUniq(arrays[0]) : [];
5558       }
5559       var index = -1,
5560           result = Array(length);
5561
5562       while (++index < length) {
5563         var array = arrays[index],
5564             othIndex = -1;
5565
5566         while (++othIndex < length) {
5567           if (othIndex != index) {
5568             result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
5569           }
5570         }
5571       }
5572       return baseUniq(baseFlatten(result, 1), iteratee, comparator);
5573     }
5574
5575     /**
5576      * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
5577      *
5578      * @private
5579      * @param {Array} props The property identifiers.
5580      * @param {Array} values The property values.
5581      * @param {Function} assignFunc The function to assign values.
5582      * @returns {Object} Returns the new object.
5583      */
5584     function baseZipObject(props, values, assignFunc) {
5585       var index = -1,
5586           length = props.length,
5587           valsLength = values.length,
5588           result = {};
5589
5590       while (++index < length) {
5591         var value = index < valsLength ? values[index] : undefined;
5592         assignFunc(result, props[index], value);
5593       }
5594       return result;
5595     }
5596
5597     /**
5598      * Casts `value` to an empty array if it's not an array like object.
5599      *
5600      * @private
5601      * @param {*} value The value to inspect.
5602      * @returns {Array|Object} Returns the cast array-like object.
5603      */
5604     function castArrayLikeObject(value) {
5605       return isArrayLikeObject(value) ? value : [];
5606     }
5607
5608     /**
5609      * Casts `value` to `identity` if it's not a function.
5610      *
5611      * @private
5612      * @param {*} value The value to inspect.
5613      * @returns {Function} Returns cast function.
5614      */
5615     function castFunction(value) {
5616       return typeof value == 'function' ? value : identity;
5617     }
5618
5619     /**
5620      * Casts `value` to a path array if it's not one.
5621      *
5622      * @private
5623      * @param {*} value The value to inspect.
5624      * @param {Object} [object] The object to query keys on.
5625      * @returns {Array} Returns the cast property path array.
5626      */
5627     function castPath(value, object) {
5628       if (isArray(value)) {
5629         return value;
5630       }
5631       return isKey(value, object) ? [value] : stringToPath(toString(value));
5632     }
5633
5634     /**
5635      * A `baseRest` alias which can be replaced with `identity` by module
5636      * replacement plugins.
5637      *
5638      * @private
5639      * @type {Function}
5640      * @param {Function} func The function to apply a rest parameter to.
5641      * @returns {Function} Returns the new function.
5642      */
5643     var castRest = baseRest;
5644
5645     /**
5646      * Casts `array` to a slice if it's needed.
5647      *
5648      * @private
5649      * @param {Array} array The array to inspect.
5650      * @param {number} start The start position.
5651      * @param {number} [end=array.length] The end position.
5652      * @returns {Array} Returns the cast slice.
5653      */
5654     function castSlice(array, start, end) {
5655       var length = array.length;
5656       end = end === undefined ? length : end;
5657       return (!start && end >= length) ? array : baseSlice(array, start, end);
5658     }
5659
5660     /**
5661      * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
5662      *
5663      * @private
5664      * @param {number|Object} id The timer id or timeout object of the timer to clear.
5665      */
5666     var clearTimeout = ctxClearTimeout || function(id) {
5667       return root.clearTimeout(id);
5668     };
5669
5670     /**
5671      * Creates a clone of  `buffer`.
5672      *
5673      * @private
5674      * @param {Buffer} buffer The buffer to clone.
5675      * @param {boolean} [isDeep] Specify a deep clone.
5676      * @returns {Buffer} Returns the cloned buffer.
5677      */
5678     function cloneBuffer(buffer, isDeep) {
5679       if (isDeep) {
5680         return buffer.slice();
5681       }
5682       var length = buffer.length,
5683           result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
5684
5685       buffer.copy(result);
5686       return result;
5687     }
5688
5689     /**
5690      * Creates a clone of `arrayBuffer`.
5691      *
5692      * @private
5693      * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
5694      * @returns {ArrayBuffer} Returns the cloned array buffer.
5695      */
5696     function cloneArrayBuffer(arrayBuffer) {
5697       var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
5698       new Uint8Array(result).set(new Uint8Array(arrayBuffer));
5699       return result;
5700     }
5701
5702     /**
5703      * Creates a clone of `dataView`.
5704      *
5705      * @private
5706      * @param {Object} dataView The data view to clone.
5707      * @param {boolean} [isDeep] Specify a deep clone.
5708      * @returns {Object} Returns the cloned data view.
5709      */
5710     function cloneDataView(dataView, isDeep) {
5711       var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
5712       return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
5713     }
5714
5715     /**
5716      * Creates a clone of `regexp`.
5717      *
5718      * @private
5719      * @param {Object} regexp The regexp to clone.
5720      * @returns {Object} Returns the cloned regexp.
5721      */
5722     function cloneRegExp(regexp) {
5723       var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
5724       result.lastIndex = regexp.lastIndex;
5725       return result;
5726     }
5727
5728     /**
5729      * Creates a clone of the `symbol` object.
5730      *
5731      * @private
5732      * @param {Object} symbol The symbol object to clone.
5733      * @returns {Object} Returns the cloned symbol object.
5734      */
5735     function cloneSymbol(symbol) {
5736       return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
5737     }
5738
5739     /**
5740      * Creates a clone of `typedArray`.
5741      *
5742      * @private
5743      * @param {Object} typedArray The typed array to clone.
5744      * @param {boolean} [isDeep] Specify a deep clone.
5745      * @returns {Object} Returns the cloned typed array.
5746      */
5747     function cloneTypedArray(typedArray, isDeep) {
5748       var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
5749       return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
5750     }
5751
5752     /**
5753      * Compares values to sort them in ascending order.
5754      *
5755      * @private
5756      * @param {*} value The value to compare.
5757      * @param {*} other The other value to compare.
5758      * @returns {number} Returns the sort order indicator for `value`.
5759      */
5760     function compareAscending(value, other) {
5761       if (value !== other) {
5762         var valIsDefined = value !== undefined,
5763             valIsNull = value === null,
5764             valIsReflexive = value === value,
5765             valIsSymbol = isSymbol(value);
5766
5767         var othIsDefined = other !== undefined,
5768             othIsNull = other === null,
5769             othIsReflexive = other === other,
5770             othIsSymbol = isSymbol(other);
5771
5772         if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
5773             (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
5774             (valIsNull && othIsDefined && othIsReflexive) ||
5775             (!valIsDefined && othIsReflexive) ||
5776             !valIsReflexive) {
5777           return 1;
5778         }
5779         if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
5780             (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
5781             (othIsNull && valIsDefined && valIsReflexive) ||
5782             (!othIsDefined && valIsReflexive) ||
5783             !othIsReflexive) {
5784           return -1;
5785         }
5786       }
5787       return 0;
5788     }
5789
5790     /**
5791      * Used by `_.orderBy` to compare multiple properties of a value to another
5792      * and stable sort them.
5793      *
5794      * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
5795      * specify an order of "desc" for descending or "asc" for ascending sort order
5796      * of corresponding values.
5797      *
5798      * @private
5799      * @param {Object} object The object to compare.
5800      * @param {Object} other The other object to compare.
5801      * @param {boolean[]|string[]} orders The order to sort by for each property.
5802      * @returns {number} Returns the sort order indicator for `object`.
5803      */
5804     function compareMultiple(object, other, orders) {
5805       var index = -1,
5806           objCriteria = object.criteria,
5807           othCriteria = other.criteria,
5808           length = objCriteria.length,
5809           ordersLength = orders.length;
5810
5811       while (++index < length) {
5812         var result = compareAscending(objCriteria[index], othCriteria[index]);
5813         if (result) {
5814           if (index >= ordersLength) {
5815             return result;
5816           }
5817           var order = orders[index];
5818           return result * (order == 'desc' ? -1 : 1);
5819         }
5820       }
5821       // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
5822       // that causes it, under certain circumstances, to provide the same value for
5823       // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
5824       // for more details.
5825       //
5826       // This also ensures a stable sort in V8 and other engines.
5827       // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
5828       return object.index - other.index;
5829     }
5830
5831     /**
5832      * Creates an array that is the composition of partially applied arguments,
5833      * placeholders, and provided arguments into a single array of arguments.
5834      *
5835      * @private
5836      * @param {Array} args The provided arguments.
5837      * @param {Array} partials The arguments to prepend to those provided.
5838      * @param {Array} holders The `partials` placeholder indexes.
5839      * @params {boolean} [isCurried] Specify composing for a curried function.
5840      * @returns {Array} Returns the new array of composed arguments.
5841      */
5842     function composeArgs(args, partials, holders, isCurried) {
5843       var argsIndex = -1,
5844           argsLength = args.length,
5845           holdersLength = holders.length,
5846           leftIndex = -1,
5847           leftLength = partials.length,
5848           rangeLength = nativeMax(argsLength - holdersLength, 0),
5849           result = Array(leftLength + rangeLength),
5850           isUncurried = !isCurried;
5851
5852       while (++leftIndex < leftLength) {
5853         result[leftIndex] = partials[leftIndex];
5854       }
5855       while (++argsIndex < holdersLength) {
5856         if (isUncurried || argsIndex < argsLength) {
5857           result[holders[argsIndex]] = args[argsIndex];
5858         }
5859       }
5860       while (rangeLength--) {
5861         result[leftIndex++] = args[argsIndex++];
5862       }
5863       return result;
5864     }
5865
5866     /**
5867      * This function is like `composeArgs` except that the arguments composition
5868      * is tailored for `_.partialRight`.
5869      *
5870      * @private
5871      * @param {Array} args The provided arguments.
5872      * @param {Array} partials The arguments to append to those provided.
5873      * @param {Array} holders The `partials` placeholder indexes.
5874      * @params {boolean} [isCurried] Specify composing for a curried function.
5875      * @returns {Array} Returns the new array of composed arguments.
5876      */
5877     function composeArgsRight(args, partials, holders, isCurried) {
5878       var argsIndex = -1,
5879           argsLength = args.length,
5880           holdersIndex = -1,
5881           holdersLength = holders.length,
5882           rightIndex = -1,
5883           rightLength = partials.length,
5884           rangeLength = nativeMax(argsLength - holdersLength, 0),
5885           result = Array(rangeLength + rightLength),
5886           isUncurried = !isCurried;
5887
5888       while (++argsIndex < rangeLength) {
5889         result[argsIndex] = args[argsIndex];
5890       }
5891       var offset = argsIndex;
5892       while (++rightIndex < rightLength) {
5893         result[offset + rightIndex] = partials[rightIndex];
5894       }
5895       while (++holdersIndex < holdersLength) {
5896         if (isUncurried || argsIndex < argsLength) {
5897           result[offset + holders[holdersIndex]] = args[argsIndex++];
5898         }
5899       }
5900       return result;
5901     }
5902
5903     /**
5904      * Copies the values of `source` to `array`.
5905      *
5906      * @private
5907      * @param {Array} source The array to copy values from.
5908      * @param {Array} [array=[]] The array to copy values to.
5909      * @returns {Array} Returns `array`.
5910      */
5911     function copyArray(source, array) {
5912       var index = -1,
5913           length = source.length;
5914
5915       array || (array = Array(length));
5916       while (++index < length) {
5917         array[index] = source[index];
5918       }
5919       return array;
5920     }
5921
5922     /**
5923      * Copies properties of `source` to `object`.
5924      *
5925      * @private
5926      * @param {Object} source The object to copy properties from.
5927      * @param {Array} props The property identifiers to copy.
5928      * @param {Object} [object={}] The object to copy properties to.
5929      * @param {Function} [customizer] The function to customize copied values.
5930      * @returns {Object} Returns `object`.
5931      */
5932     function copyObject(source, props, object, customizer) {
5933       var isNew = !object;
5934       object || (object = {});
5935
5936       var index = -1,
5937           length = props.length;
5938
5939       while (++index < length) {
5940         var key = props[index];
5941
5942         var newValue = customizer
5943           ? customizer(object[key], source[key], key, object, source)
5944           : undefined;
5945
5946         if (newValue === undefined) {
5947           newValue = source[key];
5948         }
5949         if (isNew) {
5950           baseAssignValue(object, key, newValue);
5951         } else {
5952           assignValue(object, key, newValue);
5953         }
5954       }
5955       return object;
5956     }
5957
5958     /**
5959      * Copies own symbols of `source` to `object`.
5960      *
5961      * @private
5962      * @param {Object} source The object to copy symbols from.
5963      * @param {Object} [object={}] The object to copy symbols to.
5964      * @returns {Object} Returns `object`.
5965      */
5966     function copySymbols(source, object) {
5967       return copyObject(source, getSymbols(source), object);
5968     }
5969
5970     /**
5971      * Copies own and inherited symbols of `source` to `object`.
5972      *
5973      * @private
5974      * @param {Object} source The object to copy symbols from.
5975      * @param {Object} [object={}] The object to copy symbols to.
5976      * @returns {Object} Returns `object`.
5977      */
5978     function copySymbolsIn(source, object) {
5979       return copyObject(source, getSymbolsIn(source), object);
5980     }
5981
5982     /**
5983      * Creates a function like `_.groupBy`.
5984      *
5985      * @private
5986      * @param {Function} setter The function to set accumulator values.
5987      * @param {Function} [initializer] The accumulator object initializer.
5988      * @returns {Function} Returns the new aggregator function.
5989      */
5990     function createAggregator(setter, initializer) {
5991       return function(collection, iteratee) {
5992         var func = isArray(collection) ? arrayAggregator : baseAggregator,
5993             accumulator = initializer ? initializer() : {};
5994
5995         return func(collection, setter, getIteratee(iteratee, 2), accumulator);
5996       };
5997     }
5998
5999     /**
6000      * Creates a function like `_.assign`.
6001      *
6002      * @private
6003      * @param {Function} assigner The function to assign values.
6004      * @returns {Function} Returns the new assigner function.
6005      */
6006     function createAssigner(assigner) {
6007       return baseRest(function(object, sources) {
6008         var index = -1,
6009             length = sources.length,
6010             customizer = length > 1 ? sources[length - 1] : undefined,
6011             guard = length > 2 ? sources[2] : undefined;
6012
6013         customizer = (assigner.length > 3 && typeof customizer == 'function')
6014           ? (length--, customizer)
6015           : undefined;
6016
6017         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
6018           customizer = length < 3 ? undefined : customizer;
6019           length = 1;
6020         }
6021         object = Object(object);
6022         while (++index < length) {
6023           var source = sources[index];
6024           if (source) {
6025             assigner(object, source, index, customizer);
6026           }
6027         }
6028         return object;
6029       });
6030     }
6031
6032     /**
6033      * Creates a `baseEach` or `baseEachRight` function.
6034      *
6035      * @private
6036      * @param {Function} eachFunc The function to iterate over a collection.
6037      * @param {boolean} [fromRight] Specify iterating from right to left.
6038      * @returns {Function} Returns the new base function.
6039      */
6040     function createBaseEach(eachFunc, fromRight) {
6041       return function(collection, iteratee) {
6042         if (collection == null) {
6043           return collection;
6044         }
6045         if (!isArrayLike(collection)) {
6046           return eachFunc(collection, iteratee);
6047         }
6048         var length = collection.length,
6049             index = fromRight ? length : -1,
6050             iterable = Object(collection);
6051
6052         while ((fromRight ? index-- : ++index < length)) {
6053           if (iteratee(iterable[index], index, iterable) === false) {
6054             break;
6055           }
6056         }
6057         return collection;
6058       };
6059     }
6060
6061     /**
6062      * Creates a base function for methods like `_.forIn` and `_.forOwn`.
6063      *
6064      * @private
6065      * @param {boolean} [fromRight] Specify iterating from right to left.
6066      * @returns {Function} Returns the new base function.
6067      */
6068     function createBaseFor(fromRight) {
6069       return function(object, iteratee, keysFunc) {
6070         var index = -1,
6071             iterable = Object(object),
6072             props = keysFunc(object),
6073             length = props.length;
6074
6075         while (length--) {
6076           var key = props[fromRight ? length : ++index];
6077           if (iteratee(iterable[key], key, iterable) === false) {
6078             break;
6079           }
6080         }
6081         return object;
6082       };
6083     }
6084
6085     /**
6086      * Creates a function that wraps `func` to invoke it with the optional `this`
6087      * binding of `thisArg`.
6088      *
6089      * @private
6090      * @param {Function} func The function to wrap.
6091      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6092      * @param {*} [thisArg] The `this` binding of `func`.
6093      * @returns {Function} Returns the new wrapped function.
6094      */
6095     function createBind(func, bitmask, thisArg) {
6096       var isBind = bitmask & WRAP_BIND_FLAG,
6097           Ctor = createCtor(func);
6098
6099       function wrapper() {
6100         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
6101         return fn.apply(isBind ? thisArg : this, arguments);
6102       }
6103       return wrapper;
6104     }
6105
6106     /**
6107      * Creates a function like `_.lowerFirst`.
6108      *
6109      * @private
6110      * @param {string} methodName The name of the `String` case method to use.
6111      * @returns {Function} Returns the new case function.
6112      */
6113     function createCaseFirst(methodName) {
6114       return function(string) {
6115         string = toString(string);
6116
6117         var strSymbols = hasUnicode(string)
6118           ? stringToArray(string)
6119           : undefined;
6120
6121         var chr = strSymbols
6122           ? strSymbols[0]
6123           : string.charAt(0);
6124
6125         var trailing = strSymbols
6126           ? castSlice(strSymbols, 1).join('')
6127           : string.slice(1);
6128
6129         return chr[methodName]() + trailing;
6130       };
6131     }
6132
6133     /**
6134      * Creates a function like `_.camelCase`.
6135      *
6136      * @private
6137      * @param {Function} callback The function to combine each word.
6138      * @returns {Function} Returns the new compounder function.
6139      */
6140     function createCompounder(callback) {
6141       return function(string) {
6142         return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
6143       };
6144     }
6145
6146     /**
6147      * Creates a function that produces an instance of `Ctor` regardless of
6148      * whether it was invoked as part of a `new` expression or by `call` or `apply`.
6149      *
6150      * @private
6151      * @param {Function} Ctor The constructor to wrap.
6152      * @returns {Function} Returns the new wrapped function.
6153      */
6154     function createCtor(Ctor) {
6155       return function() {
6156         // Use a `switch` statement to work with class constructors. See
6157         // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
6158         // for more details.
6159         var args = arguments;
6160         switch (args.length) {
6161           case 0: return new Ctor;
6162           case 1: return new Ctor(args[0]);
6163           case 2: return new Ctor(args[0], args[1]);
6164           case 3: return new Ctor(args[0], args[1], args[2]);
6165           case 4: return new Ctor(args[0], args[1], args[2], args[3]);
6166           case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
6167           case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
6168           case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
6169         }
6170         var thisBinding = baseCreate(Ctor.prototype),
6171             result = Ctor.apply(thisBinding, args);
6172
6173         // Mimic the constructor's `return` behavior.
6174         // See https://es5.github.io/#x13.2.2 for more details.
6175         return isObject(result) ? result : thisBinding;
6176       };
6177     }
6178
6179     /**
6180      * Creates a function that wraps `func` to enable currying.
6181      *
6182      * @private
6183      * @param {Function} func The function to wrap.
6184      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6185      * @param {number} arity The arity of `func`.
6186      * @returns {Function} Returns the new wrapped function.
6187      */
6188     function createCurry(func, bitmask, arity) {
6189       var Ctor = createCtor(func);
6190
6191       function wrapper() {
6192         var length = arguments.length,
6193             args = Array(length),
6194             index = length,
6195             placeholder = getHolder(wrapper);
6196
6197         while (index--) {
6198           args[index] = arguments[index];
6199         }
6200         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
6201           ? []
6202           : replaceHolders(args, placeholder);
6203
6204         length -= holders.length;
6205         if (length < arity) {
6206           return createRecurry(
6207             func, bitmask, createHybrid, wrapper.placeholder, undefined,
6208             args, holders, undefined, undefined, arity - length);
6209         }
6210         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
6211         return apply(fn, this, args);
6212       }
6213       return wrapper;
6214     }
6215
6216     /**
6217      * Creates a `_.find` or `_.findLast` function.
6218      *
6219      * @private
6220      * @param {Function} findIndexFunc The function to find the collection index.
6221      * @returns {Function} Returns the new find function.
6222      */
6223     function createFind(findIndexFunc) {
6224       return function(collection, predicate, fromIndex) {
6225         var iterable = Object(collection);
6226         if (!isArrayLike(collection)) {
6227           var iteratee = getIteratee(predicate, 3);
6228           collection = keys(collection);
6229           predicate = function(key) { return iteratee(iterable[key], key, iterable); };
6230         }
6231         var index = findIndexFunc(collection, predicate, fromIndex);
6232         return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
6233       };
6234     }
6235
6236     /**
6237      * Creates a `_.flow` or `_.flowRight` function.
6238      *
6239      * @private
6240      * @param {boolean} [fromRight] Specify iterating from right to left.
6241      * @returns {Function} Returns the new flow function.
6242      */
6243     function createFlow(fromRight) {
6244       return flatRest(function(funcs) {
6245         var length = funcs.length,
6246             index = length,
6247             prereq = LodashWrapper.prototype.thru;
6248
6249         if (fromRight) {
6250           funcs.reverse();
6251         }
6252         while (index--) {
6253           var func = funcs[index];
6254           if (typeof func != 'function') {
6255             throw new TypeError(FUNC_ERROR_TEXT);
6256           }
6257           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
6258             var wrapper = new LodashWrapper([], true);
6259           }
6260         }
6261         index = wrapper ? index : length;
6262         while (++index < length) {
6263           func = funcs[index];
6264
6265           var funcName = getFuncName(func),
6266               data = funcName == 'wrapper' ? getData(func) : undefined;
6267
6268           if (data && isLaziable(data[0]) &&
6269                 data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
6270                 !data[4].length && data[9] == 1
6271               ) {
6272             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
6273           } else {
6274             wrapper = (func.length == 1 && isLaziable(func))
6275               ? wrapper[funcName]()
6276               : wrapper.thru(func);
6277           }
6278         }
6279         return function() {
6280           var args = arguments,
6281               value = args[0];
6282
6283           if (wrapper && args.length == 1 && isArray(value)) {
6284             return wrapper.plant(value).value();
6285           }
6286           var index = 0,
6287               result = length ? funcs[index].apply(this, args) : value;
6288
6289           while (++index < length) {
6290             result = funcs[index].call(this, result);
6291           }
6292           return result;
6293         };
6294       });
6295     }
6296
6297     /**
6298      * Creates a function that wraps `func` to invoke it with optional `this`
6299      * binding of `thisArg`, partial application, and currying.
6300      *
6301      * @private
6302      * @param {Function|string} func The function or method name to wrap.
6303      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6304      * @param {*} [thisArg] The `this` binding of `func`.
6305      * @param {Array} [partials] The arguments to prepend to those provided to
6306      *  the new function.
6307      * @param {Array} [holders] The `partials` placeholder indexes.
6308      * @param {Array} [partialsRight] The arguments to append to those provided
6309      *  to the new function.
6310      * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
6311      * @param {Array} [argPos] The argument positions of the new function.
6312      * @param {number} [ary] The arity cap of `func`.
6313      * @param {number} [arity] The arity of `func`.
6314      * @returns {Function} Returns the new wrapped function.
6315      */
6316     function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
6317       var isAry = bitmask & WRAP_ARY_FLAG,
6318           isBind = bitmask & WRAP_BIND_FLAG,
6319           isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
6320           isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
6321           isFlip = bitmask & WRAP_FLIP_FLAG,
6322           Ctor = isBindKey ? undefined : createCtor(func);
6323
6324       function wrapper() {
6325         var length = arguments.length,
6326             args = Array(length),
6327             index = length;
6328
6329         while (index--) {
6330           args[index] = arguments[index];
6331         }
6332         if (isCurried) {
6333           var placeholder = getHolder(wrapper),
6334               holdersCount = countHolders(args, placeholder);
6335         }
6336         if (partials) {
6337           args = composeArgs(args, partials, holders, isCurried);
6338         }
6339         if (partialsRight) {
6340           args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
6341         }
6342         length -= holdersCount;
6343         if (isCurried && length < arity) {
6344           var newHolders = replaceHolders(args, placeholder);
6345           return createRecurry(
6346             func, bitmask, createHybrid, wrapper.placeholder, thisArg,
6347             args, newHolders, argPos, ary, arity - length
6348           );
6349         }
6350         var thisBinding = isBind ? thisArg : this,
6351             fn = isBindKey ? thisBinding[func] : func;
6352
6353         length = args.length;
6354         if (argPos) {
6355           args = reorder(args, argPos);
6356         } else if (isFlip && length > 1) {
6357           args.reverse();
6358         }
6359         if (isAry && ary < length) {
6360           args.length = ary;
6361         }
6362         if (this && this !== root && this instanceof wrapper) {
6363           fn = Ctor || createCtor(fn);
6364         }
6365         return fn.apply(thisBinding, args);
6366       }
6367       return wrapper;
6368     }
6369
6370     /**
6371      * Creates a function like `_.invertBy`.
6372      *
6373      * @private
6374      * @param {Function} setter The function to set accumulator values.
6375      * @param {Function} toIteratee The function to resolve iteratees.
6376      * @returns {Function} Returns the new inverter function.
6377      */
6378     function createInverter(setter, toIteratee) {
6379       return function(object, iteratee) {
6380         return baseInverter(object, setter, toIteratee(iteratee), {});
6381       };
6382     }
6383
6384     /**
6385      * Creates a function that performs a mathematical operation on two values.
6386      *
6387      * @private
6388      * @param {Function} operator The function to perform the operation.
6389      * @param {number} [defaultValue] The value used for `undefined` arguments.
6390      * @returns {Function} Returns the new mathematical operation function.
6391      */
6392     function createMathOperation(operator, defaultValue) {
6393       return function(value, other) {
6394         var result;
6395         if (value === undefined && other === undefined) {
6396           return defaultValue;
6397         }
6398         if (value !== undefined) {
6399           result = value;
6400         }
6401         if (other !== undefined) {
6402           if (result === undefined) {
6403             return other;
6404           }
6405           if (typeof value == 'string' || typeof other == 'string') {
6406             value = baseToString(value);
6407             other = baseToString(other);
6408           } else {
6409             value = baseToNumber(value);
6410             other = baseToNumber(other);
6411           }
6412           result = operator(value, other);
6413         }
6414         return result;
6415       };
6416     }
6417
6418     /**
6419      * Creates a function like `_.over`.
6420      *
6421      * @private
6422      * @param {Function} arrayFunc The function to iterate over iteratees.
6423      * @returns {Function} Returns the new over function.
6424      */
6425     function createOver(arrayFunc) {
6426       return flatRest(function(iteratees) {
6427         iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
6428         return baseRest(function(args) {
6429           var thisArg = this;
6430           return arrayFunc(iteratees, function(iteratee) {
6431             return apply(iteratee, thisArg, args);
6432           });
6433         });
6434       });
6435     }
6436
6437     /**
6438      * Creates the padding for `string` based on `length`. The `chars` string
6439      * is truncated if the number of characters exceeds `length`.
6440      *
6441      * @private
6442      * @param {number} length The padding length.
6443      * @param {string} [chars=' '] The string used as padding.
6444      * @returns {string} Returns the padding for `string`.
6445      */
6446     function createPadding(length, chars) {
6447       chars = chars === undefined ? ' ' : baseToString(chars);
6448
6449       var charsLength = chars.length;
6450       if (charsLength < 2) {
6451         return charsLength ? baseRepeat(chars, length) : chars;
6452       }
6453       var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
6454       return hasUnicode(chars)
6455         ? castSlice(stringToArray(result), 0, length).join('')
6456         : result.slice(0, length);
6457     }
6458
6459     /**
6460      * Creates a function that wraps `func` to invoke it with the `this` binding
6461      * of `thisArg` and `partials` prepended to the arguments it receives.
6462      *
6463      * @private
6464      * @param {Function} func The function to wrap.
6465      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6466      * @param {*} thisArg The `this` binding of `func`.
6467      * @param {Array} partials The arguments to prepend to those provided to
6468      *  the new function.
6469      * @returns {Function} Returns the new wrapped function.
6470      */
6471     function createPartial(func, bitmask, thisArg, partials) {
6472       var isBind = bitmask & WRAP_BIND_FLAG,
6473           Ctor = createCtor(func);
6474
6475       function wrapper() {
6476         var argsIndex = -1,
6477             argsLength = arguments.length,
6478             leftIndex = -1,
6479             leftLength = partials.length,
6480             args = Array(leftLength + argsLength),
6481             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
6482
6483         while (++leftIndex < leftLength) {
6484           args[leftIndex] = partials[leftIndex];
6485         }
6486         while (argsLength--) {
6487           args[leftIndex++] = arguments[++argsIndex];
6488         }
6489         return apply(fn, isBind ? thisArg : this, args);
6490       }
6491       return wrapper;
6492     }
6493
6494     /**
6495      * Creates a `_.range` or `_.rangeRight` function.
6496      *
6497      * @private
6498      * @param {boolean} [fromRight] Specify iterating from right to left.
6499      * @returns {Function} Returns the new range function.
6500      */
6501     function createRange(fromRight) {
6502       return function(start, end, step) {
6503         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
6504           end = step = undefined;
6505         }
6506         // Ensure the sign of `-0` is preserved.
6507         start = toFinite(start);
6508         if (end === undefined) {
6509           end = start;
6510           start = 0;
6511         } else {
6512           end = toFinite(end);
6513         }
6514         step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
6515         return baseRange(start, end, step, fromRight);
6516       };
6517     }
6518
6519     /**
6520      * Creates a function that performs a relational operation on two values.
6521      *
6522      * @private
6523      * @param {Function} operator The function to perform the operation.
6524      * @returns {Function} Returns the new relational operation function.
6525      */
6526     function createRelationalOperation(operator) {
6527       return function(value, other) {
6528         if (!(typeof value == 'string' && typeof other == 'string')) {
6529           value = toNumber(value);
6530           other = toNumber(other);
6531         }
6532         return operator(value, other);
6533       };
6534     }
6535
6536     /**
6537      * Creates a function that wraps `func` to continue currying.
6538      *
6539      * @private
6540      * @param {Function} func The function to wrap.
6541      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6542      * @param {Function} wrapFunc The function to create the `func` wrapper.
6543      * @param {*} placeholder The placeholder value.
6544      * @param {*} [thisArg] The `this` binding of `func`.
6545      * @param {Array} [partials] The arguments to prepend to those provided to
6546      *  the new function.
6547      * @param {Array} [holders] The `partials` placeholder indexes.
6548      * @param {Array} [argPos] The argument positions of the new function.
6549      * @param {number} [ary] The arity cap of `func`.
6550      * @param {number} [arity] The arity of `func`.
6551      * @returns {Function} Returns the new wrapped function.
6552      */
6553     function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
6554       var isCurry = bitmask & WRAP_CURRY_FLAG,
6555           newHolders = isCurry ? holders : undefined,
6556           newHoldersRight = isCurry ? undefined : holders,
6557           newPartials = isCurry ? partials : undefined,
6558           newPartialsRight = isCurry ? undefined : partials;
6559
6560       bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
6561       bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
6562
6563       if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
6564         bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
6565       }
6566       var newData = [
6567         func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
6568         newHoldersRight, argPos, ary, arity
6569       ];
6570
6571       var result = wrapFunc.apply(undefined, newData);
6572       if (isLaziable(func)) {
6573         setData(result, newData);
6574       }
6575       result.placeholder = placeholder;
6576       return setWrapToString(result, func, bitmask);
6577     }
6578
6579     /**
6580      * Creates a function like `_.round`.
6581      *
6582      * @private
6583      * @param {string} methodName The name of the `Math` method to use when rounding.
6584      * @returns {Function} Returns the new round function.
6585      */
6586     function createRound(methodName) {
6587       var func = Math[methodName];
6588       return function(number, precision) {
6589         number = toNumber(number);
6590         precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
6591         if (precision && nativeIsFinite(number)) {
6592           // Shift with exponential notation to avoid floating-point issues.
6593           // See [MDN](https://mdn.io/round#Examples) for more details.
6594           var pair = (toString(number) + 'e').split('e'),
6595               value = func(pair[0] + 'e' + (+pair[1] + precision));
6596
6597           pair = (toString(value) + 'e').split('e');
6598           return +(pair[0] + 'e' + (+pair[1] - precision));
6599         }
6600         return func(number);
6601       };
6602     }
6603
6604     /**
6605      * Creates a set object of `values`.
6606      *
6607      * @private
6608      * @param {Array} values The values to add to the set.
6609      * @returns {Object} Returns the new set.
6610      */
6611     var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
6612       return new Set(values);
6613     };
6614
6615     /**
6616      * Creates a `_.toPairs` or `_.toPairsIn` function.
6617      *
6618      * @private
6619      * @param {Function} keysFunc The function to get the keys of a given object.
6620      * @returns {Function} Returns the new pairs function.
6621      */
6622     function createToPairs(keysFunc) {
6623       return function(object) {
6624         var tag = getTag(object);
6625         if (tag == mapTag) {
6626           return mapToArray(object);
6627         }
6628         if (tag == setTag) {
6629           return setToPairs(object);
6630         }
6631         return baseToPairs(object, keysFunc(object));
6632       };
6633     }
6634
6635     /**
6636      * Creates a function that either curries or invokes `func` with optional
6637      * `this` binding and partially applied arguments.
6638      *
6639      * @private
6640      * @param {Function|string} func The function or method name to wrap.
6641      * @param {number} bitmask The bitmask flags.
6642      *    1 - `_.bind`
6643      *    2 - `_.bindKey`
6644      *    4 - `_.curry` or `_.curryRight` of a bound function
6645      *    8 - `_.curry`
6646      *   16 - `_.curryRight`
6647      *   32 - `_.partial`
6648      *   64 - `_.partialRight`
6649      *  128 - `_.rearg`
6650      *  256 - `_.ary`
6651      *  512 - `_.flip`
6652      * @param {*} [thisArg] The `this` binding of `func`.
6653      * @param {Array} [partials] The arguments to be partially applied.
6654      * @param {Array} [holders] The `partials` placeholder indexes.
6655      * @param {Array} [argPos] The argument positions of the new function.
6656      * @param {number} [ary] The arity cap of `func`.
6657      * @param {number} [arity] The arity of `func`.
6658      * @returns {Function} Returns the new wrapped function.
6659      */
6660     function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
6661       var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
6662       if (!isBindKey && typeof func != 'function') {
6663         throw new TypeError(FUNC_ERROR_TEXT);
6664       }
6665       var length = partials ? partials.length : 0;
6666       if (!length) {
6667         bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
6668         partials = holders = undefined;
6669       }
6670       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
6671       arity = arity === undefined ? arity : toInteger(arity);
6672       length -= holders ? holders.length : 0;
6673
6674       if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
6675         var partialsRight = partials,
6676             holdersRight = holders;
6677
6678         partials = holders = undefined;
6679       }
6680       var data = isBindKey ? undefined : getData(func);
6681
6682       var newData = [
6683         func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
6684         argPos, ary, arity
6685       ];
6686
6687       if (data) {
6688         mergeData(newData, data);
6689       }
6690       func = newData[0];
6691       bitmask = newData[1];
6692       thisArg = newData[2];
6693       partials = newData[3];
6694       holders = newData[4];
6695       arity = newData[9] = newData[9] === undefined
6696         ? (isBindKey ? 0 : func.length)
6697         : nativeMax(newData[9] - length, 0);
6698
6699       if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
6700         bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
6701       }
6702       if (!bitmask || bitmask == WRAP_BIND_FLAG) {
6703         var result = createBind(func, bitmask, thisArg);
6704       } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
6705         result = createCurry(func, bitmask, arity);
6706       } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
6707         result = createPartial(func, bitmask, thisArg, partials);
6708       } else {
6709         result = createHybrid.apply(undefined, newData);
6710       }
6711       var setter = data ? baseSetData : setData;
6712       return setWrapToString(setter(result, newData), func, bitmask);
6713     }
6714
6715     /**
6716      * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
6717      * of source objects to the destination object for all destination properties
6718      * that resolve to `undefined`.
6719      *
6720      * @private
6721      * @param {*} objValue The destination value.
6722      * @param {*} srcValue The source value.
6723      * @param {string} key The key of the property to assign.
6724      * @param {Object} object The parent object of `objValue`.
6725      * @returns {*} Returns the value to assign.
6726      */
6727     function customDefaultsAssignIn(objValue, srcValue, key, object) {
6728       if (objValue === undefined ||
6729           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
6730         return srcValue;
6731       }
6732       return objValue;
6733     }
6734
6735     /**
6736      * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
6737      * objects into destination objects that are passed thru.
6738      *
6739      * @private
6740      * @param {*} objValue The destination value.
6741      * @param {*} srcValue The source value.
6742      * @param {string} key The key of the property to merge.
6743      * @param {Object} object The parent object of `objValue`.
6744      * @param {Object} source The parent object of `srcValue`.
6745      * @param {Object} [stack] Tracks traversed source values and their merged
6746      *  counterparts.
6747      * @returns {*} Returns the value to assign.
6748      */
6749     function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
6750       if (isObject(objValue) && isObject(srcValue)) {
6751         // Recursively merge objects and arrays (susceptible to call stack limits).
6752         stack.set(srcValue, objValue);
6753         baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
6754         stack['delete'](srcValue);
6755       }
6756       return objValue;
6757     }
6758
6759     /**
6760      * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
6761      * objects.
6762      *
6763      * @private
6764      * @param {*} value The value to inspect.
6765      * @param {string} key The key of the property to inspect.
6766      * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
6767      */
6768     function customOmitClone(value) {
6769       return isPlainObject(value) ? undefined : value;
6770     }
6771
6772     /**
6773      * A specialized version of `baseIsEqualDeep` for arrays with support for
6774      * partial deep comparisons.
6775      *
6776      * @private
6777      * @param {Array} array The array to compare.
6778      * @param {Array} other The other array to compare.
6779      * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
6780      * @param {Function} customizer The function to customize comparisons.
6781      * @param {Function} equalFunc The function to determine equivalents of values.
6782      * @param {Object} stack Tracks traversed `array` and `other` objects.
6783      * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
6784      */
6785     function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
6786       var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
6787           arrLength = array.length,
6788           othLength = other.length;
6789
6790       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
6791         return false;
6792       }
6793       // Check that cyclic values are equal.
6794       var arrStacked = stack.get(array);
6795       var othStacked = stack.get(other);
6796       if (arrStacked && othStacked) {
6797         return arrStacked == other && othStacked == array;
6798       }
6799       var index = -1,
6800           result = true,
6801           seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
6802
6803       stack.set(array, other);
6804       stack.set(other, array);
6805
6806       // Ignore non-index properties.
6807       while (++index < arrLength) {
6808         var arrValue = array[index],
6809             othValue = other[index];
6810
6811         if (customizer) {
6812           var compared = isPartial
6813             ? customizer(othValue, arrValue, index, other, array, stack)
6814             : customizer(arrValue, othValue, index, array, other, stack);
6815         }
6816         if (compared !== undefined) {
6817           if (compared) {
6818             continue;
6819           }
6820           result = false;
6821           break;
6822         }
6823         // Recursively compare arrays (susceptible to call stack limits).
6824         if (seen) {
6825           if (!arraySome(other, function(othValue, othIndex) {
6826                 if (!cacheHas(seen, othIndex) &&
6827                     (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
6828                   return seen.push(othIndex);
6829                 }
6830               })) {
6831             result = false;
6832             break;
6833           }
6834         } else if (!(
6835               arrValue === othValue ||
6836                 equalFunc(arrValue, othValue, bitmask, customizer, stack)
6837             )) {
6838           result = false;
6839           break;
6840         }
6841       }
6842       stack['delete'](array);
6843       stack['delete'](other);
6844       return result;
6845     }
6846
6847     /**
6848      * A specialized version of `baseIsEqualDeep` for comparing objects of
6849      * the same `toStringTag`.
6850      *
6851      * **Note:** This function only supports comparing values with tags of
6852      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
6853      *
6854      * @private
6855      * @param {Object} object The object to compare.
6856      * @param {Object} other The other object to compare.
6857      * @param {string} tag The `toStringTag` of the objects to compare.
6858      * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
6859      * @param {Function} customizer The function to customize comparisons.
6860      * @param {Function} equalFunc The function to determine equivalents of values.
6861      * @param {Object} stack Tracks traversed `object` and `other` objects.
6862      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
6863      */
6864     function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
6865       switch (tag) {
6866         case dataViewTag:
6867           if ((object.byteLength != other.byteLength) ||
6868               (object.byteOffset != other.byteOffset)) {
6869             return false;
6870           }
6871           object = object.buffer;
6872           other = other.buffer;
6873
6874         case arrayBufferTag:
6875           if ((object.byteLength != other.byteLength) ||
6876               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
6877             return false;
6878           }
6879           return true;
6880
6881         case boolTag:
6882         case dateTag:
6883         case numberTag:
6884           // Coerce booleans to `1` or `0` and dates to milliseconds.
6885           // Invalid dates are coerced to `NaN`.
6886           return eq(+object, +other);
6887
6888         case errorTag:
6889           return object.name == other.name && object.message == other.message;
6890
6891         case regexpTag:
6892         case stringTag:
6893           // Coerce regexes to strings and treat strings, primitives and objects,
6894           // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
6895           // for more details.
6896           return object == (other + '');
6897
6898         case mapTag:
6899           var convert = mapToArray;
6900
6901         case setTag:
6902           var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
6903           convert || (convert = setToArray);
6904
6905           if (object.size != other.size && !isPartial) {
6906             return false;
6907           }
6908           // Assume cyclic values are equal.
6909           var stacked = stack.get(object);
6910           if (stacked) {
6911             return stacked == other;
6912           }
6913           bitmask |= COMPARE_UNORDERED_FLAG;
6914
6915           // Recursively compare objects (susceptible to call stack limits).
6916           stack.set(object, other);
6917           var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
6918           stack['delete'](object);
6919           return result;
6920
6921         case symbolTag:
6922           if (symbolValueOf) {
6923             return symbolValueOf.call(object) == symbolValueOf.call(other);
6924           }
6925       }
6926       return false;
6927     }
6928
6929     /**
6930      * A specialized version of `baseIsEqualDeep` for objects with support for
6931      * partial deep comparisons.
6932      *
6933      * @private
6934      * @param {Object} object The object to compare.
6935      * @param {Object} other The other object to compare.
6936      * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
6937      * @param {Function} customizer The function to customize comparisons.
6938      * @param {Function} equalFunc The function to determine equivalents of values.
6939      * @param {Object} stack Tracks traversed `object` and `other` objects.
6940      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
6941      */
6942     function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
6943       var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
6944           objProps = getAllKeys(object),
6945           objLength = objProps.length,
6946           othProps = getAllKeys(other),
6947           othLength = othProps.length;
6948
6949       if (objLength != othLength && !isPartial) {
6950         return false;
6951       }
6952       var index = objLength;
6953       while (index--) {
6954         var key = objProps[index];
6955         if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
6956           return false;
6957         }
6958       }
6959       // Check that cyclic values are equal.
6960       var objStacked = stack.get(object);
6961       var othStacked = stack.get(other);
6962       if (objStacked && othStacked) {
6963         return objStacked == other && othStacked == object;
6964       }
6965       var result = true;
6966       stack.set(object, other);
6967       stack.set(other, object);
6968
6969       var skipCtor = isPartial;
6970       while (++index < objLength) {
6971         key = objProps[index];
6972         var objValue = object[key],
6973             othValue = other[key];
6974
6975         if (customizer) {
6976           var compared = isPartial
6977             ? customizer(othValue, objValue, key, other, object, stack)
6978             : customizer(objValue, othValue, key, object, other, stack);
6979         }
6980         // Recursively compare objects (susceptible to call stack limits).
6981         if (!(compared === undefined
6982               ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
6983               : compared
6984             )) {
6985           result = false;
6986           break;
6987         }
6988         skipCtor || (skipCtor = key == 'constructor');
6989       }
6990       if (result && !skipCtor) {
6991         var objCtor = object.constructor,
6992             othCtor = other.constructor;
6993
6994         // Non `Object` object instances with different constructors are not equal.
6995         if (objCtor != othCtor &&
6996             ('constructor' in object && 'constructor' in other) &&
6997             !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
6998               typeof othCtor == 'function' && othCtor instanceof othCtor)) {
6999           result = false;
7000         }
7001       }
7002       stack['delete'](object);
7003       stack['delete'](other);
7004       return result;
7005     }
7006
7007     /**
7008      * A specialized version of `baseRest` which flattens the rest array.
7009      *
7010      * @private
7011      * @param {Function} func The function to apply a rest parameter to.
7012      * @returns {Function} Returns the new function.
7013      */
7014     function flatRest(func) {
7015       return setToString(overRest(func, undefined, flatten), func + '');
7016     }
7017
7018     /**
7019      * Creates an array of own enumerable property names and symbols of `object`.
7020      *
7021      * @private
7022      * @param {Object} object The object to query.
7023      * @returns {Array} Returns the array of property names and symbols.
7024      */
7025     function getAllKeys(object) {
7026       return baseGetAllKeys(object, keys, getSymbols);
7027     }
7028
7029     /**
7030      * Creates an array of own and inherited enumerable property names and
7031      * symbols of `object`.
7032      *
7033      * @private
7034      * @param {Object} object The object to query.
7035      * @returns {Array} Returns the array of property names and symbols.
7036      */
7037     function getAllKeysIn(object) {
7038       return baseGetAllKeys(object, keysIn, getSymbolsIn);
7039     }
7040
7041     /**
7042      * Gets metadata for `func`.
7043      *
7044      * @private
7045      * @param {Function} func The function to query.
7046      * @returns {*} Returns the metadata for `func`.
7047      */
7048     var getData = !metaMap ? noop : function(func) {
7049       return metaMap.get(func);
7050     };
7051
7052     /**
7053      * Gets the name of `func`.
7054      *
7055      * @private
7056      * @param {Function} func The function to query.
7057      * @returns {string} Returns the function name.
7058      */
7059     function getFuncName(func) {
7060       var result = (func.name + ''),
7061           array = realNames[result],
7062           length = hasOwnProperty.call(realNames, result) ? array.length : 0;
7063
7064       while (length--) {
7065         var data = array[length],
7066             otherFunc = data.func;
7067         if (otherFunc == null || otherFunc == func) {
7068           return data.name;
7069         }
7070       }
7071       return result;
7072     }
7073
7074     /**
7075      * Gets the argument placeholder value for `func`.
7076      *
7077      * @private
7078      * @param {Function} func The function to inspect.
7079      * @returns {*} Returns the placeholder value.
7080      */
7081     function getHolder(func) {
7082       var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
7083       return object.placeholder;
7084     }
7085
7086     /**
7087      * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
7088      * this function returns the custom method, otherwise it returns `baseIteratee`.
7089      * If arguments are provided, the chosen function is invoked with them and
7090      * its result is returned.
7091      *
7092      * @private
7093      * @param {*} [value] The value to convert to an iteratee.
7094      * @param {number} [arity] The arity of the created iteratee.
7095      * @returns {Function} Returns the chosen function or its result.
7096      */
7097     function getIteratee() {
7098       var result = lodash.iteratee || iteratee;
7099       result = result === iteratee ? baseIteratee : result;
7100       return arguments.length ? result(arguments[0], arguments[1]) : result;
7101     }
7102
7103     /**
7104      * Gets the data for `map`.
7105      *
7106      * @private
7107      * @param {Object} map The map to query.
7108      * @param {string} key The reference key.
7109      * @returns {*} Returns the map data.
7110      */
7111     function getMapData(map, key) {
7112       var data = map.__data__;
7113       return isKeyable(key)
7114         ? data[typeof key == 'string' ? 'string' : 'hash']
7115         : data.map;
7116     }
7117
7118     /**
7119      * Gets the property names, values, and compare flags of `object`.
7120      *
7121      * @private
7122      * @param {Object} object The object to query.
7123      * @returns {Array} Returns the match data of `object`.
7124      */
7125     function getMatchData(object) {
7126       var result = keys(object),
7127           length = result.length;
7128
7129       while (length--) {
7130         var key = result[length],
7131             value = object[key];
7132
7133         result[length] = [key, value, isStrictComparable(value)];
7134       }
7135       return result;
7136     }
7137
7138     /**
7139      * Gets the native function at `key` of `object`.
7140      *
7141      * @private
7142      * @param {Object} object The object to query.
7143      * @param {string} key The key of the method to get.
7144      * @returns {*} Returns the function if it's native, else `undefined`.
7145      */
7146     function getNative(object, key) {
7147       var value = getValue(object, key);
7148       return baseIsNative(value) ? value : undefined;
7149     }
7150
7151     /**
7152      * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
7153      *
7154      * @private
7155      * @param {*} value The value to query.
7156      * @returns {string} Returns the raw `toStringTag`.
7157      */
7158     function getRawTag(value) {
7159       var isOwn = hasOwnProperty.call(value, symToStringTag),
7160           tag = value[symToStringTag];
7161
7162       try {
7163         value[symToStringTag] = undefined;
7164         var unmasked = true;
7165       } catch (e) {}
7166
7167       var result = nativeObjectToString.call(value);
7168       if (unmasked) {
7169         if (isOwn) {
7170           value[symToStringTag] = tag;
7171         } else {
7172           delete value[symToStringTag];
7173         }
7174       }
7175       return result;
7176     }
7177
7178     /**
7179      * Creates an array of the own enumerable symbols of `object`.
7180      *
7181      * @private
7182      * @param {Object} object The object to query.
7183      * @returns {Array} Returns the array of symbols.
7184      */
7185     var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
7186       if (object == null) {
7187         return [];
7188       }
7189       object = Object(object);
7190       return arrayFilter(nativeGetSymbols(object), function(symbol) {
7191         return propertyIsEnumerable.call(object, symbol);
7192       });
7193     };
7194
7195     /**
7196      * Creates an array of the own and inherited enumerable symbols of `object`.
7197      *
7198      * @private
7199      * @param {Object} object The object to query.
7200      * @returns {Array} Returns the array of symbols.
7201      */
7202     var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
7203       var result = [];
7204       while (object) {
7205         arrayPush(result, getSymbols(object));
7206         object = getPrototype(object);
7207       }
7208       return result;
7209     };
7210
7211     /**
7212      * Gets the `toStringTag` of `value`.
7213      *
7214      * @private
7215      * @param {*} value The value to query.
7216      * @returns {string} Returns the `toStringTag`.
7217      */
7218     var getTag = baseGetTag;
7219
7220     // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
7221     if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
7222         (Map && getTag(new Map) != mapTag) ||
7223         (Promise && getTag(Promise.resolve()) != promiseTag) ||
7224         (Set && getTag(new Set) != setTag) ||
7225         (WeakMap && getTag(new WeakMap) != weakMapTag)) {
7226       getTag = function(value) {
7227         var result = baseGetTag(value),
7228             Ctor = result == objectTag ? value.constructor : undefined,
7229             ctorString = Ctor ? toSource(Ctor) : '';
7230
7231         if (ctorString) {
7232           switch (ctorString) {
7233             case dataViewCtorString: return dataViewTag;
7234             case mapCtorString: return mapTag;
7235             case promiseCtorString: return promiseTag;
7236             case setCtorString: return setTag;
7237             case weakMapCtorString: return weakMapTag;
7238           }
7239         }
7240         return result;
7241       };
7242     }
7243
7244     /**
7245      * Gets the view, applying any `transforms` to the `start` and `end` positions.
7246      *
7247      * @private
7248      * @param {number} start The start of the view.
7249      * @param {number} end The end of the view.
7250      * @param {Array} transforms The transformations to apply to the view.
7251      * @returns {Object} Returns an object containing the `start` and `end`
7252      *  positions of the view.
7253      */
7254     function getView(start, end, transforms) {
7255       var index = -1,
7256           length = transforms.length;
7257
7258       while (++index < length) {
7259         var data = transforms[index],
7260             size = data.size;
7261
7262         switch (data.type) {
7263           case 'drop':      start += size; break;
7264           case 'dropRight': end -= size; break;
7265           case 'take':      end = nativeMin(end, start + size); break;
7266           case 'takeRight': start = nativeMax(start, end - size); break;
7267         }
7268       }
7269       return { 'start': start, 'end': end };
7270     }
7271
7272     /**
7273      * Extracts wrapper details from the `source` body comment.
7274      *
7275      * @private
7276      * @param {string} source The source to inspect.
7277      * @returns {Array} Returns the wrapper details.
7278      */
7279     function getWrapDetails(source) {
7280       var match = source.match(reWrapDetails);
7281       return match ? match[1].split(reSplitDetails) : [];
7282     }
7283
7284     /**
7285      * Checks if `path` exists on `object`.
7286      *
7287      * @private
7288      * @param {Object} object The object to query.
7289      * @param {Array|string} path The path to check.
7290      * @param {Function} hasFunc The function to check properties.
7291      * @returns {boolean} Returns `true` if `path` exists, else `false`.
7292      */
7293     function hasPath(object, path, hasFunc) {
7294       path = castPath(path, object);
7295
7296       var index = -1,
7297           length = path.length,
7298           result = false;
7299
7300       while (++index < length) {
7301         var key = toKey(path[index]);
7302         if (!(result = object != null && hasFunc(object, key))) {
7303           break;
7304         }
7305         object = object[key];
7306       }
7307       if (result || ++index != length) {
7308         return result;
7309       }
7310       length = object == null ? 0 : object.length;
7311       return !!length && isLength(length) && isIndex(key, length) &&
7312         (isArray(object) || isArguments(object));
7313     }
7314
7315     /**
7316      * Initializes an array clone.
7317      *
7318      * @private
7319      * @param {Array} array The array to clone.
7320      * @returns {Array} Returns the initialized clone.
7321      */
7322     function initCloneArray(array) {
7323       var length = array.length,
7324           result = new array.constructor(length);
7325
7326       // Add properties assigned by `RegExp#exec`.
7327       if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
7328         result.index = array.index;
7329         result.input = array.input;
7330       }
7331       return result;
7332     }
7333
7334     /**
7335      * Initializes an object clone.
7336      *
7337      * @private
7338      * @param {Object} object The object to clone.
7339      * @returns {Object} Returns the initialized clone.
7340      */
7341     function initCloneObject(object) {
7342       return (typeof object.constructor == 'function' && !isPrototype(object))
7343         ? baseCreate(getPrototype(object))
7344         : {};
7345     }
7346
7347     /**
7348      * Initializes an object clone based on its `toStringTag`.
7349      *
7350      * **Note:** This function only supports cloning values with tags of
7351      * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
7352      *
7353      * @private
7354      * @param {Object} object The object to clone.
7355      * @param {string} tag The `toStringTag` of the object to clone.
7356      * @param {boolean} [isDeep] Specify a deep clone.
7357      * @returns {Object} Returns the initialized clone.
7358      */
7359     function initCloneByTag(object, tag, isDeep) {
7360       var Ctor = object.constructor;
7361       switch (tag) {
7362         case arrayBufferTag:
7363           return cloneArrayBuffer(object);
7364
7365         case boolTag:
7366         case dateTag:
7367           return new Ctor(+object);
7368
7369         case dataViewTag:
7370           return cloneDataView(object, isDeep);
7371
7372         case float32Tag: case float64Tag:
7373         case int8Tag: case int16Tag: case int32Tag:
7374         case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
7375           return cloneTypedArray(object, isDeep);
7376
7377         case mapTag:
7378           return new Ctor;
7379
7380         case numberTag:
7381         case stringTag:
7382           return new Ctor(object);
7383
7384         case regexpTag:
7385           return cloneRegExp(object);
7386
7387         case setTag:
7388           return new Ctor;
7389
7390         case symbolTag:
7391           return cloneSymbol(object);
7392       }
7393     }
7394
7395     /**
7396      * Inserts wrapper `details` in a comment at the top of the `source` body.
7397      *
7398      * @private
7399      * @param {string} source The source to modify.
7400      * @returns {Array} details The details to insert.
7401      * @returns {string} Returns the modified source.
7402      */
7403     function insertWrapDetails(source, details) {
7404       var length = details.length;
7405       if (!length) {
7406         return source;
7407       }
7408       var lastIndex = length - 1;
7409       details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
7410       details = details.join(length > 2 ? ', ' : ' ');
7411       return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
7412     }
7413
7414     /**
7415      * Checks if `value` is a flattenable `arguments` object or array.
7416      *
7417      * @private
7418      * @param {*} value The value to check.
7419      * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
7420      */
7421     function isFlattenable(value) {
7422       return isArray(value) || isArguments(value) ||
7423         !!(spreadableSymbol && value && value[spreadableSymbol]);
7424     }
7425
7426     /**
7427      * Checks if `value` is a valid array-like index.
7428      *
7429      * @private
7430      * @param {*} value The value to check.
7431      * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
7432      * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
7433      */
7434     function isIndex(value, length) {
7435       var type = typeof value;
7436       length = length == null ? MAX_SAFE_INTEGER : length;
7437
7438       return !!length &&
7439         (type == 'number' ||
7440           (type != 'symbol' && reIsUint.test(value))) &&
7441             (value > -1 && value % 1 == 0 && value < length);
7442     }
7443
7444     /**
7445      * Checks if the given arguments are from an iteratee call.
7446      *
7447      * @private
7448      * @param {*} value The potential iteratee value argument.
7449      * @param {*} index The potential iteratee index or key argument.
7450      * @param {*} object The potential iteratee object argument.
7451      * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
7452      *  else `false`.
7453      */
7454     function isIterateeCall(value, index, object) {
7455       if (!isObject(object)) {
7456         return false;
7457       }
7458       var type = typeof index;
7459       if (type == 'number'
7460             ? (isArrayLike(object) && isIndex(index, object.length))
7461             : (type == 'string' && index in object)
7462           ) {
7463         return eq(object[index], value);
7464       }
7465       return false;
7466     }
7467
7468     /**
7469      * Checks if `value` is a property name and not a property path.
7470      *
7471      * @private
7472      * @param {*} value The value to check.
7473      * @param {Object} [object] The object to query keys on.
7474      * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
7475      */
7476     function isKey(value, object) {
7477       if (isArray(value)) {
7478         return false;
7479       }
7480       var type = typeof value;
7481       if (type == 'number' || type == 'symbol' || type == 'boolean' ||
7482           value == null || isSymbol(value)) {
7483         return true;
7484       }
7485       return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
7486         (object != null && value in Object(object));
7487     }
7488
7489     /**
7490      * Checks if `value` is suitable for use as unique object key.
7491      *
7492      * @private
7493      * @param {*} value The value to check.
7494      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
7495      */
7496     function isKeyable(value) {
7497       var type = typeof value;
7498       return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
7499         ? (value !== '__proto__')
7500         : (value === null);
7501     }
7502
7503     /**
7504      * Checks if `func` has a lazy counterpart.
7505      *
7506      * @private
7507      * @param {Function} func The function to check.
7508      * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
7509      *  else `false`.
7510      */
7511     function isLaziable(func) {
7512       var funcName = getFuncName(func),
7513           other = lodash[funcName];
7514
7515       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
7516         return false;
7517       }
7518       if (func === other) {
7519         return true;
7520       }
7521       var data = getData(other);
7522       return !!data && func === data[0];
7523     }
7524
7525     /**
7526      * Checks if `func` has its source masked.
7527      *
7528      * @private
7529      * @param {Function} func The function to check.
7530      * @returns {boolean} Returns `true` if `func` is masked, else `false`.
7531      */
7532     function isMasked(func) {
7533       return !!maskSrcKey && (maskSrcKey in func);
7534     }
7535
7536     /**
7537      * Checks if `func` is capable of being masked.
7538      *
7539      * @private
7540      * @param {*} value The value to check.
7541      * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
7542      */
7543     var isMaskable = coreJsData ? isFunction : stubFalse;
7544
7545     /**
7546      * Checks if `value` is likely a prototype object.
7547      *
7548      * @private
7549      * @param {*} value The value to check.
7550      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
7551      */
7552     function isPrototype(value) {
7553       var Ctor = value && value.constructor,
7554           proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
7555
7556       return value === proto;
7557     }
7558
7559     /**
7560      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
7561      *
7562      * @private
7563      * @param {*} value The value to check.
7564      * @returns {boolean} Returns `true` if `value` if suitable for strict
7565      *  equality comparisons, else `false`.
7566      */
7567     function isStrictComparable(value) {
7568       return value === value && !isObject(value);
7569     }
7570
7571     /**
7572      * A specialized version of `matchesProperty` for source values suitable
7573      * for strict equality comparisons, i.e. `===`.
7574      *
7575      * @private
7576      * @param {string} key The key of the property to get.
7577      * @param {*} srcValue The value to match.
7578      * @returns {Function} Returns the new spec function.
7579      */
7580     function matchesStrictComparable(key, srcValue) {
7581       return function(object) {
7582         if (object == null) {
7583           return false;
7584         }
7585         return object[key] === srcValue &&
7586           (srcValue !== undefined || (key in Object(object)));
7587       };
7588     }
7589
7590     /**
7591      * A specialized version of `_.memoize` which clears the memoized function's
7592      * cache when it exceeds `MAX_MEMOIZE_SIZE`.
7593      *
7594      * @private
7595      * @param {Function} func The function to have its output memoized.
7596      * @returns {Function} Returns the new memoized function.
7597      */
7598     function memoizeCapped(func) {
7599       var result = memoize(func, function(key) {
7600         if (cache.size === MAX_MEMOIZE_SIZE) {
7601           cache.clear();
7602         }
7603         return key;
7604       });
7605
7606       var cache = result.cache;
7607       return result;
7608     }
7609
7610     /**
7611      * Merges the function metadata of `source` into `data`.
7612      *
7613      * Merging metadata reduces the number of wrappers used to invoke a function.
7614      * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
7615      * may be applied regardless of execution order. Methods like `_.ary` and
7616      * `_.rearg` modify function arguments, making the order in which they are
7617      * executed important, preventing the merging of metadata. However, we make
7618      * an exception for a safe combined case where curried functions have `_.ary`
7619      * and or `_.rearg` applied.
7620      *
7621      * @private
7622      * @param {Array} data The destination metadata.
7623      * @param {Array} source The source metadata.
7624      * @returns {Array} Returns `data`.
7625      */
7626     function mergeData(data, source) {
7627       var bitmask = data[1],
7628           srcBitmask = source[1],
7629           newBitmask = bitmask | srcBitmask,
7630           isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
7631
7632       var isCombo =
7633         ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
7634         ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
7635         ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
7636
7637       // Exit early if metadata can't be merged.
7638       if (!(isCommon || isCombo)) {
7639         return data;
7640       }
7641       // Use source `thisArg` if available.
7642       if (srcBitmask & WRAP_BIND_FLAG) {
7643         data[2] = source[2];
7644         // Set when currying a bound function.
7645         newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
7646       }
7647       // Compose partial arguments.
7648       var value = source[3];
7649       if (value) {
7650         var partials = data[3];
7651         data[3] = partials ? composeArgs(partials, value, source[4]) : value;
7652         data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
7653       }
7654       // Compose partial right arguments.
7655       value = source[5];
7656       if (value) {
7657         partials = data[5];
7658         data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
7659         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
7660       }
7661       // Use source `argPos` if available.
7662       value = source[7];
7663       if (value) {
7664         data[7] = value;
7665       }
7666       // Use source `ary` if it's smaller.
7667       if (srcBitmask & WRAP_ARY_FLAG) {
7668         data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
7669       }
7670       // Use source `arity` if one is not provided.
7671       if (data[9] == null) {
7672         data[9] = source[9];
7673       }
7674       // Use source `func` and merge bitmasks.
7675       data[0] = source[0];
7676       data[1] = newBitmask;
7677
7678       return data;
7679     }
7680
7681     /**
7682      * This function is like
7683      * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
7684      * except that it includes inherited enumerable properties.
7685      *
7686      * @private
7687      * @param {Object} object The object to query.
7688      * @returns {Array} Returns the array of property names.
7689      */
7690     function nativeKeysIn(object) {
7691       var result = [];
7692       if (object != null) {
7693         for (var key in Object(object)) {
7694           result.push(key);
7695         }
7696       }
7697       return result;
7698     }
7699
7700     /**
7701      * Converts `value` to a string using `Object.prototype.toString`.
7702      *
7703      * @private
7704      * @param {*} value The value to convert.
7705      * @returns {string} Returns the converted string.
7706      */
7707     function objectToString(value) {
7708       return nativeObjectToString.call(value);
7709     }
7710
7711     /**
7712      * A specialized version of `baseRest` which transforms the rest array.
7713      *
7714      * @private
7715      * @param {Function} func The function to apply a rest parameter to.
7716      * @param {number} [start=func.length-1] The start position of the rest parameter.
7717      * @param {Function} transform The rest array transform.
7718      * @returns {Function} Returns the new function.
7719      */
7720     function overRest(func, start, transform) {
7721       start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
7722       return function() {
7723         var args = arguments,
7724             index = -1,
7725             length = nativeMax(args.length - start, 0),
7726             array = Array(length);
7727
7728         while (++index < length) {
7729           array[index] = args[start + index];
7730         }
7731         index = -1;
7732         var otherArgs = Array(start + 1);
7733         while (++index < start) {
7734           otherArgs[index] = args[index];
7735         }
7736         otherArgs[start] = transform(array);
7737         return apply(func, this, otherArgs);
7738       };
7739     }
7740
7741     /**
7742      * Gets the parent value at `path` of `object`.
7743      *
7744      * @private
7745      * @param {Object} object The object to query.
7746      * @param {Array} path The path to get the parent value of.
7747      * @returns {*} Returns the parent value.
7748      */
7749     function parent(object, path) {
7750       return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
7751     }
7752
7753     /**
7754      * Reorder `array` according to the specified indexes where the element at
7755      * the first index is assigned as the first element, the element at
7756      * the second index is assigned as the second element, and so on.
7757      *
7758      * @private
7759      * @param {Array} array The array to reorder.
7760      * @param {Array} indexes The arranged array indexes.
7761      * @returns {Array} Returns `array`.
7762      */
7763     function reorder(array, indexes) {
7764       var arrLength = array.length,
7765           length = nativeMin(indexes.length, arrLength),
7766           oldArray = copyArray(array);
7767
7768       while (length--) {
7769         var index = indexes[length];
7770         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
7771       }
7772       return array;
7773     }
7774
7775     /**
7776      * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
7777      *
7778      * @private
7779      * @param {Object} object The object to query.
7780      * @param {string} key The key of the property to get.
7781      * @returns {*} Returns the property value.
7782      */
7783     function safeGet(object, key) {
7784       if (key === 'constructor' && typeof object[key] === 'function') {
7785         return;
7786       }
7787
7788       if (key == '__proto__') {
7789         return;
7790       }
7791
7792       return object[key];
7793     }
7794
7795     /**
7796      * Sets metadata for `func`.
7797      *
7798      * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
7799      * period of time, it will trip its breaker and transition to an identity
7800      * function to avoid garbage collection pauses in V8. See
7801      * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
7802      * for more details.
7803      *
7804      * @private
7805      * @param {Function} func The function to associate metadata with.
7806      * @param {*} data The metadata.
7807      * @returns {Function} Returns `func`.
7808      */
7809     var setData = shortOut(baseSetData);
7810
7811     /**
7812      * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
7813      *
7814      * @private
7815      * @param {Function} func The function to delay.
7816      * @param {number} wait The number of milliseconds to delay invocation.
7817      * @returns {number|Object} Returns the timer id or timeout object.
7818      */
7819     var setTimeout = ctxSetTimeout || function(func, wait) {
7820       return root.setTimeout(func, wait);
7821     };
7822
7823     /**
7824      * Sets the `toString` method of `func` to return `string`.
7825      *
7826      * @private
7827      * @param {Function} func The function to modify.
7828      * @param {Function} string The `toString` result.
7829      * @returns {Function} Returns `func`.
7830      */
7831     var setToString = shortOut(baseSetToString);
7832
7833     /**
7834      * Sets the `toString` method of `wrapper` to mimic the source of `reference`
7835      * with wrapper details in a comment at the top of the source body.
7836      *
7837      * @private
7838      * @param {Function} wrapper The function to modify.
7839      * @param {Function} reference The reference function.
7840      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
7841      * @returns {Function} Returns `wrapper`.
7842      */
7843     function setWrapToString(wrapper, reference, bitmask) {
7844       var source = (reference + '');
7845       return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
7846     }
7847
7848     /**
7849      * Creates a function that'll short out and invoke `identity` instead
7850      * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
7851      * milliseconds.
7852      *
7853      * @private
7854      * @param {Function} func The function to restrict.
7855      * @returns {Function} Returns the new shortable function.
7856      */
7857     function shortOut(func) {
7858       var count = 0,
7859           lastCalled = 0;
7860
7861       return function() {
7862         var stamp = nativeNow(),
7863             remaining = HOT_SPAN - (stamp - lastCalled);
7864
7865         lastCalled = stamp;
7866         if (remaining > 0) {
7867           if (++count >= HOT_COUNT) {
7868             return arguments[0];
7869           }
7870         } else {
7871           count = 0;
7872         }
7873         return func.apply(undefined, arguments);
7874       };
7875     }
7876
7877     /**
7878      * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
7879      *
7880      * @private
7881      * @param {Array} array The array to shuffle.
7882      * @param {number} [size=array.length] The size of `array`.
7883      * @returns {Array} Returns `array`.
7884      */
7885     function shuffleSelf(array, size) {
7886       var index = -1,
7887           length = array.length,
7888           lastIndex = length - 1;
7889
7890       size = size === undefined ? length : size;
7891       while (++index < size) {
7892         var rand = baseRandom(index, lastIndex),
7893             value = array[rand];
7894
7895         array[rand] = array[index];
7896         array[index] = value;
7897       }
7898       array.length = size;
7899       return array;
7900     }
7901
7902     /**
7903      * Converts `string` to a property path array.
7904      *
7905      * @private
7906      * @param {string} string The string to convert.
7907      * @returns {Array} Returns the property path array.
7908      */
7909     var stringToPath = memoizeCapped(function(string) {
7910       var result = [];
7911       if (string.charCodeAt(0) === 46 /* . */) {
7912         result.push('');
7913       }
7914       string.replace(rePropName, function(match, number, quote, subString) {
7915         result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
7916       });
7917       return result;
7918     });
7919
7920     /**
7921      * Converts `value` to a string key if it's not a string or symbol.
7922      *
7923      * @private
7924      * @param {*} value The value to inspect.
7925      * @returns {string|symbol} Returns the key.
7926      */
7927     function toKey(value) {
7928       if (typeof value == 'string' || isSymbol(value)) {
7929         return value;
7930       }
7931       var result = (value + '');
7932       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
7933     }
7934
7935     /**
7936      * Converts `func` to its source code.
7937      *
7938      * @private
7939      * @param {Function} func The function to convert.
7940      * @returns {string} Returns the source code.
7941      */
7942     function toSource(func) {
7943       if (func != null) {
7944         try {
7945           return funcToString.call(func);
7946         } catch (e) {}
7947         try {
7948           return (func + '');
7949         } catch (e) {}
7950       }
7951       return '';
7952     }
7953
7954     /**
7955      * Updates wrapper `details` based on `bitmask` flags.
7956      *
7957      * @private
7958      * @returns {Array} details The details to modify.
7959      * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
7960      * @returns {Array} Returns `details`.
7961      */
7962     function updateWrapDetails(details, bitmask) {
7963       arrayEach(wrapFlags, function(pair) {
7964         var value = '_.' + pair[0];
7965         if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
7966           details.push(value);
7967         }
7968       });
7969       return details.sort();
7970     }
7971
7972     /**
7973      * Creates a clone of `wrapper`.
7974      *
7975      * @private
7976      * @param {Object} wrapper The wrapper to clone.
7977      * @returns {Object} Returns the cloned wrapper.
7978      */
7979     function wrapperClone(wrapper) {
7980       if (wrapper instanceof LazyWrapper) {
7981         return wrapper.clone();
7982       }
7983       var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
7984       result.__actions__ = copyArray(wrapper.__actions__);
7985       result.__index__  = wrapper.__index__;
7986       result.__values__ = wrapper.__values__;
7987       return result;
7988     }
7989
7990     /*------------------------------------------------------------------------*/
7991
7992     /**
7993      * Creates an array of elements split into groups the length of `size`.
7994      * If `array` can't be split evenly, the final chunk will be the remaining
7995      * elements.
7996      *
7997      * @static
7998      * @memberOf _
7999      * @since 3.0.0
8000      * @category Array
8001      * @param {Array} array The array to process.
8002      * @param {number} [size=1] The length of each chunk
8003      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8004      * @returns {Array} Returns the new array of chunks.
8005      * @example
8006      *
8007      * _.chunk(['a', 'b', 'c', 'd'], 2);
8008      * // => [['a', 'b'], ['c', 'd']]
8009      *
8010      * _.chunk(['a', 'b', 'c', 'd'], 3);
8011      * // => [['a', 'b', 'c'], ['d']]
8012      */
8013     function chunk(array, size, guard) {
8014       if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
8015         size = 1;
8016       } else {
8017         size = nativeMax(toInteger(size), 0);
8018       }
8019       var length = array == null ? 0 : array.length;
8020       if (!length || size < 1) {
8021         return [];
8022       }
8023       var index = 0,
8024           resIndex = 0,
8025           result = Array(nativeCeil(length / size));
8026
8027       while (index < length) {
8028         result[resIndex++] = baseSlice(array, index, (index += size));
8029       }
8030       return result;
8031     }
8032
8033     /**
8034      * Creates an array with all falsey values removed. The values `false`, `null`,
8035      * `0`, `""`, `undefined`, and `NaN` are falsey.
8036      *
8037      * @static
8038      * @memberOf _
8039      * @since 0.1.0
8040      * @category Array
8041      * @param {Array} array The array to compact.
8042      * @returns {Array} Returns the new array of filtered values.
8043      * @example
8044      *
8045      * _.compact([0, 1, false, 2, '', 3]);
8046      * // => [1, 2, 3]
8047      */
8048     function compact(array) {
8049       var index = -1,
8050           length = array == null ? 0 : array.length,
8051           resIndex = 0,
8052           result = [];
8053
8054       while (++index < length) {
8055         var value = array[index];
8056         if (value) {
8057           result[resIndex++] = value;
8058         }
8059       }
8060       return result;
8061     }
8062
8063     /**
8064      * Creates a new array concatenating `array` with any additional arrays
8065      * and/or values.
8066      *
8067      * @static
8068      * @memberOf _
8069      * @since 4.0.0
8070      * @category Array
8071      * @param {Array} array The array to concatenate.
8072      * @param {...*} [values] The values to concatenate.
8073      * @returns {Array} Returns the new concatenated array.
8074      * @example
8075      *
8076      * var array = [1];
8077      * var other = _.concat(array, 2, [3], [[4]]);
8078      *
8079      * console.log(other);
8080      * // => [1, 2, 3, [4]]
8081      *
8082      * console.log(array);
8083      * // => [1]
8084      */
8085     function concat() {
8086       var length = arguments.length;
8087       if (!length) {
8088         return [];
8089       }
8090       var args = Array(length - 1),
8091           array = arguments[0],
8092           index = length;
8093
8094       while (index--) {
8095         args[index - 1] = arguments[index];
8096       }
8097       return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
8098     }
8099
8100     /**
8101      * Creates an array of `array` values not included in the other given arrays
8102      * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8103      * for equality comparisons. The order and references of result values are
8104      * determined by the first array.
8105      *
8106      * **Note:** Unlike `_.pullAll`, this method returns a new array.
8107      *
8108      * @static
8109      * @memberOf _
8110      * @since 0.1.0
8111      * @category Array
8112      * @param {Array} array The array to inspect.
8113      * @param {...Array} [values] The values to exclude.
8114      * @returns {Array} Returns the new array of filtered values.
8115      * @see _.without, _.xor
8116      * @example
8117      *
8118      * _.difference([2, 1], [2, 3]);
8119      * // => [1]
8120      */
8121     var difference = baseRest(function(array, values) {
8122       return isArrayLikeObject(array)
8123         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
8124         : [];
8125     });
8126
8127     /**
8128      * This method is like `_.difference` except that it accepts `iteratee` which
8129      * is invoked for each element of `array` and `values` to generate the criterion
8130      * by which they're compared. The order and references of result values are
8131      * determined by the first array. The iteratee is invoked with one argument:
8132      * (value).
8133      *
8134      * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
8135      *
8136      * @static
8137      * @memberOf _
8138      * @since 4.0.0
8139      * @category Array
8140      * @param {Array} array The array to inspect.
8141      * @param {...Array} [values] The values to exclude.
8142      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8143      * @returns {Array} Returns the new array of filtered values.
8144      * @example
8145      *
8146      * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8147      * // => [1.2]
8148      *
8149      * // The `_.property` iteratee shorthand.
8150      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
8151      * // => [{ 'x': 2 }]
8152      */
8153     var differenceBy = baseRest(function(array, values) {
8154       var iteratee = last(values);
8155       if (isArrayLikeObject(iteratee)) {
8156         iteratee = undefined;
8157       }
8158       return isArrayLikeObject(array)
8159         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
8160         : [];
8161     });
8162
8163     /**
8164      * This method is like `_.difference` except that it accepts `comparator`
8165      * which is invoked to compare elements of `array` to `values`. The order and
8166      * references of result values are determined by the first array. The comparator
8167      * is invoked with two arguments: (arrVal, othVal).
8168      *
8169      * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
8170      *
8171      * @static
8172      * @memberOf _
8173      * @since 4.0.0
8174      * @category Array
8175      * @param {Array} array The array to inspect.
8176      * @param {...Array} [values] The values to exclude.
8177      * @param {Function} [comparator] The comparator invoked per element.
8178      * @returns {Array} Returns the new array of filtered values.
8179      * @example
8180      *
8181      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8182      *
8183      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
8184      * // => [{ 'x': 2, 'y': 1 }]
8185      */
8186     var differenceWith = baseRest(function(array, values) {
8187       var comparator = last(values);
8188       if (isArrayLikeObject(comparator)) {
8189         comparator = undefined;
8190       }
8191       return isArrayLikeObject(array)
8192         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
8193         : [];
8194     });
8195
8196     /**
8197      * Creates a slice of `array` with `n` elements dropped from the beginning.
8198      *
8199      * @static
8200      * @memberOf _
8201      * @since 0.5.0
8202      * @category Array
8203      * @param {Array} array The array to query.
8204      * @param {number} [n=1] The number of elements to drop.
8205      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8206      * @returns {Array} Returns the slice of `array`.
8207      * @example
8208      *
8209      * _.drop([1, 2, 3]);
8210      * // => [2, 3]
8211      *
8212      * _.drop([1, 2, 3], 2);
8213      * // => [3]
8214      *
8215      * _.drop([1, 2, 3], 5);
8216      * // => []
8217      *
8218      * _.drop([1, 2, 3], 0);
8219      * // => [1, 2, 3]
8220      */
8221     function drop(array, n, guard) {
8222       var length = array == null ? 0 : array.length;
8223       if (!length) {
8224         return [];
8225       }
8226       n = (guard || n === undefined) ? 1 : toInteger(n);
8227       return baseSlice(array, n < 0 ? 0 : n, length);
8228     }
8229
8230     /**
8231      * Creates a slice of `array` with `n` elements dropped from the end.
8232      *
8233      * @static
8234      * @memberOf _
8235      * @since 3.0.0
8236      * @category Array
8237      * @param {Array} array The array to query.
8238      * @param {number} [n=1] The number of elements to drop.
8239      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8240      * @returns {Array} Returns the slice of `array`.
8241      * @example
8242      *
8243      * _.dropRight([1, 2, 3]);
8244      * // => [1, 2]
8245      *
8246      * _.dropRight([1, 2, 3], 2);
8247      * // => [1]
8248      *
8249      * _.dropRight([1, 2, 3], 5);
8250      * // => []
8251      *
8252      * _.dropRight([1, 2, 3], 0);
8253      * // => [1, 2, 3]
8254      */
8255     function dropRight(array, n, guard) {
8256       var length = array == null ? 0 : array.length;
8257       if (!length) {
8258         return [];
8259       }
8260       n = (guard || n === undefined) ? 1 : toInteger(n);
8261       n = length - n;
8262       return baseSlice(array, 0, n < 0 ? 0 : n);
8263     }
8264
8265     /**
8266      * Creates a slice of `array` excluding elements dropped from the end.
8267      * Elements are dropped until `predicate` returns falsey. The predicate is
8268      * invoked with three arguments: (value, index, array).
8269      *
8270      * @static
8271      * @memberOf _
8272      * @since 3.0.0
8273      * @category Array
8274      * @param {Array} array The array to query.
8275      * @param {Function} [predicate=_.identity] The function invoked per iteration.
8276      * @returns {Array} Returns the slice of `array`.
8277      * @example
8278      *
8279      * var users = [
8280      *   { 'user': 'barney',  'active': true },
8281      *   { 'user': 'fred',    'active': false },
8282      *   { 'user': 'pebbles', 'active': false }
8283      * ];
8284      *
8285      * _.dropRightWhile(users, function(o) { return !o.active; });
8286      * // => objects for ['barney']
8287      *
8288      * // The `_.matches` iteratee shorthand.
8289      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
8290      * // => objects for ['barney', 'fred']
8291      *
8292      * // The `_.matchesProperty` iteratee shorthand.
8293      * _.dropRightWhile(users, ['active', false]);
8294      * // => objects for ['barney']
8295      *
8296      * // The `_.property` iteratee shorthand.
8297      * _.dropRightWhile(users, 'active');
8298      * // => objects for ['barney', 'fred', 'pebbles']
8299      */
8300     function dropRightWhile(array, predicate) {
8301       return (array && array.length)
8302         ? baseWhile(array, getIteratee(predicate, 3), true, true)
8303         : [];
8304     }
8305
8306     /**
8307      * Creates a slice of `array` excluding elements dropped from the beginning.
8308      * Elements are dropped until `predicate` returns falsey. The predicate is
8309      * invoked with three arguments: (value, index, array).
8310      *
8311      * @static
8312      * @memberOf _
8313      * @since 3.0.0
8314      * @category Array
8315      * @param {Array} array The array to query.
8316      * @param {Function} [predicate=_.identity] The function invoked per iteration.
8317      * @returns {Array} Returns the slice of `array`.
8318      * @example
8319      *
8320      * var users = [
8321      *   { 'user': 'barney',  'active': false },
8322      *   { 'user': 'fred',    'active': false },
8323      *   { 'user': 'pebbles', 'active': true }
8324      * ];
8325      *
8326      * _.dropWhile(users, function(o) { return !o.active; });
8327      * // => objects for ['pebbles']
8328      *
8329      * // The `_.matches` iteratee shorthand.
8330      * _.dropWhile(users, { 'user': 'barney', 'active': false });
8331      * // => objects for ['fred', 'pebbles']
8332      *
8333      * // The `_.matchesProperty` iteratee shorthand.
8334      * _.dropWhile(users, ['active', false]);
8335      * // => objects for ['pebbles']
8336      *
8337      * // The `_.property` iteratee shorthand.
8338      * _.dropWhile(users, 'active');
8339      * // => objects for ['barney', 'fred', 'pebbles']
8340      */
8341     function dropWhile(array, predicate) {
8342       return (array && array.length)
8343         ? baseWhile(array, getIteratee(predicate, 3), true)
8344         : [];
8345     }
8346
8347     /**
8348      * Fills elements of `array` with `value` from `start` up to, but not
8349      * including, `end`.
8350      *
8351      * **Note:** This method mutates `array`.
8352      *
8353      * @static
8354      * @memberOf _
8355      * @since 3.2.0
8356      * @category Array
8357      * @param {Array} array The array to fill.
8358      * @param {*} value The value to fill `array` with.
8359      * @param {number} [start=0] The start position.
8360      * @param {number} [end=array.length] The end position.
8361      * @returns {Array} Returns `array`.
8362      * @example
8363      *
8364      * var array = [1, 2, 3];
8365      *
8366      * _.fill(array, 'a');
8367      * console.log(array);
8368      * // => ['a', 'a', 'a']
8369      *
8370      * _.fill(Array(3), 2);
8371      * // => [2, 2, 2]
8372      *
8373      * _.fill([4, 6, 8, 10], '*', 1, 3);
8374      * // => [4, '*', '*', 10]
8375      */
8376     function fill(array, value, start, end) {
8377       var length = array == null ? 0 : array.length;
8378       if (!length) {
8379         return [];
8380       }
8381       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
8382         start = 0;
8383         end = length;
8384       }
8385       return baseFill(array, value, start, end);
8386     }
8387
8388     /**
8389      * This method is like `_.find` except that it returns the index of the first
8390      * element `predicate` returns truthy for instead of the element itself.
8391      *
8392      * @static
8393      * @memberOf _
8394      * @since 1.1.0
8395      * @category Array
8396      * @param {Array} array The array to inspect.
8397      * @param {Function} [predicate=_.identity] The function invoked per iteration.
8398      * @param {number} [fromIndex=0] The index to search from.
8399      * @returns {number} Returns the index of the found element, else `-1`.
8400      * @example
8401      *
8402      * var users = [
8403      *   { 'user': 'barney',  'active': false },
8404      *   { 'user': 'fred',    'active': false },
8405      *   { 'user': 'pebbles', 'active': true }
8406      * ];
8407      *
8408      * _.findIndex(users, function(o) { return o.user == 'barney'; });
8409      * // => 0
8410      *
8411      * // The `_.matches` iteratee shorthand.
8412      * _.findIndex(users, { 'user': 'fred', 'active': false });
8413      * // => 1
8414      *
8415      * // The `_.matchesProperty` iteratee shorthand.
8416      * _.findIndex(users, ['active', false]);
8417      * // => 0
8418      *
8419      * // The `_.property` iteratee shorthand.
8420      * _.findIndex(users, 'active');
8421      * // => 2
8422      */
8423     function findIndex(array, predicate, fromIndex) {
8424       var length = array == null ? 0 : array.length;
8425       if (!length) {
8426         return -1;
8427       }
8428       var index = fromIndex == null ? 0 : toInteger(fromIndex);
8429       if (index < 0) {
8430         index = nativeMax(length + index, 0);
8431       }
8432       return baseFindIndex(array, getIteratee(predicate, 3), index);
8433     }
8434
8435     /**
8436      * This method is like `_.findIndex` except that it iterates over elements
8437      * of `collection` from right to left.
8438      *
8439      * @static
8440      * @memberOf _
8441      * @since 2.0.0
8442      * @category Array
8443      * @param {Array} array The array to inspect.
8444      * @param {Function} [predicate=_.identity] The function invoked per iteration.
8445      * @param {number} [fromIndex=array.length-1] The index to search from.
8446      * @returns {number} Returns the index of the found element, else `-1`.
8447      * @example
8448      *
8449      * var users = [
8450      *   { 'user': 'barney',  'active': true },
8451      *   { 'user': 'fred',    'active': false },
8452      *   { 'user': 'pebbles', 'active': false }
8453      * ];
8454      *
8455      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
8456      * // => 2
8457      *
8458      * // The `_.matches` iteratee shorthand.
8459      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
8460      * // => 0
8461      *
8462      * // The `_.matchesProperty` iteratee shorthand.
8463      * _.findLastIndex(users, ['active', false]);
8464      * // => 2
8465      *
8466      * // The `_.property` iteratee shorthand.
8467      * _.findLastIndex(users, 'active');
8468      * // => 0
8469      */
8470     function findLastIndex(array, predicate, fromIndex) {
8471       var length = array == null ? 0 : array.length;
8472       if (!length) {
8473         return -1;
8474       }
8475       var index = length - 1;
8476       if (fromIndex !== undefined) {
8477         index = toInteger(fromIndex);
8478         index = fromIndex < 0
8479           ? nativeMax(length + index, 0)
8480           : nativeMin(index, length - 1);
8481       }
8482       return baseFindIndex(array, getIteratee(predicate, 3), index, true);
8483     }
8484
8485     /**
8486      * Flattens `array` a single level deep.
8487      *
8488      * @static
8489      * @memberOf _
8490      * @since 0.1.0
8491      * @category Array
8492      * @param {Array} array The array to flatten.
8493      * @returns {Array} Returns the new flattened array.
8494      * @example
8495      *
8496      * _.flatten([1, [2, [3, [4]], 5]]);
8497      * // => [1, 2, [3, [4]], 5]
8498      */
8499     function flatten(array) {
8500       var length = array == null ? 0 : array.length;
8501       return length ? baseFlatten(array, 1) : [];
8502     }
8503
8504     /**
8505      * Recursively flattens `array`.
8506      *
8507      * @static
8508      * @memberOf _
8509      * @since 3.0.0
8510      * @category Array
8511      * @param {Array} array The array to flatten.
8512      * @returns {Array} Returns the new flattened array.
8513      * @example
8514      *
8515      * _.flattenDeep([1, [2, [3, [4]], 5]]);
8516      * // => [1, 2, 3, 4, 5]
8517      */
8518     function flattenDeep(array) {
8519       var length = array == null ? 0 : array.length;
8520       return length ? baseFlatten(array, INFINITY) : [];
8521     }
8522
8523     /**
8524      * Recursively flatten `array` up to `depth` times.
8525      *
8526      * @static
8527      * @memberOf _
8528      * @since 4.4.0
8529      * @category Array
8530      * @param {Array} array The array to flatten.
8531      * @param {number} [depth=1] The maximum recursion depth.
8532      * @returns {Array} Returns the new flattened array.
8533      * @example
8534      *
8535      * var array = [1, [2, [3, [4]], 5]];
8536      *
8537      * _.flattenDepth(array, 1);
8538      * // => [1, 2, [3, [4]], 5]
8539      *
8540      * _.flattenDepth(array, 2);
8541      * // => [1, 2, 3, [4], 5]
8542      */
8543     function flattenDepth(array, depth) {
8544       var length = array == null ? 0 : array.length;
8545       if (!length) {
8546         return [];
8547       }
8548       depth = depth === undefined ? 1 : toInteger(depth);
8549       return baseFlatten(array, depth);
8550     }
8551
8552     /**
8553      * The inverse of `_.toPairs`; this method returns an object composed
8554      * from key-value `pairs`.
8555      *
8556      * @static
8557      * @memberOf _
8558      * @since 4.0.0
8559      * @category Array
8560      * @param {Array} pairs The key-value pairs.
8561      * @returns {Object} Returns the new object.
8562      * @example
8563      *
8564      * _.fromPairs([['a', 1], ['b', 2]]);
8565      * // => { 'a': 1, 'b': 2 }
8566      */
8567     function fromPairs(pairs) {
8568       var index = -1,
8569           length = pairs == null ? 0 : pairs.length,
8570           result = {};
8571
8572       while (++index < length) {
8573         var pair = pairs[index];
8574         result[pair[0]] = pair[1];
8575       }
8576       return result;
8577     }
8578
8579     /**
8580      * Gets the first element of `array`.
8581      *
8582      * @static
8583      * @memberOf _
8584      * @since 0.1.0
8585      * @alias first
8586      * @category Array
8587      * @param {Array} array The array to query.
8588      * @returns {*} Returns the first element of `array`.
8589      * @example
8590      *
8591      * _.head([1, 2, 3]);
8592      * // => 1
8593      *
8594      * _.head([]);
8595      * // => undefined
8596      */
8597     function head(array) {
8598       return (array && array.length) ? array[0] : undefined;
8599     }
8600
8601     /**
8602      * Gets the index at which the first occurrence of `value` is found in `array`
8603      * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8604      * for equality comparisons. If `fromIndex` is negative, it's used as the
8605      * offset from the end of `array`.
8606      *
8607      * @static
8608      * @memberOf _
8609      * @since 0.1.0
8610      * @category Array
8611      * @param {Array} array The array to inspect.
8612      * @param {*} value The value to search for.
8613      * @param {number} [fromIndex=0] The index to search from.
8614      * @returns {number} Returns the index of the matched value, else `-1`.
8615      * @example
8616      *
8617      * _.indexOf([1, 2, 1, 2], 2);
8618      * // => 1
8619      *
8620      * // Search from the `fromIndex`.
8621      * _.indexOf([1, 2, 1, 2], 2, 2);
8622      * // => 3
8623      */
8624     function indexOf(array, value, fromIndex) {
8625       var length = array == null ? 0 : array.length;
8626       if (!length) {
8627         return -1;
8628       }
8629       var index = fromIndex == null ? 0 : toInteger(fromIndex);
8630       if (index < 0) {
8631         index = nativeMax(length + index, 0);
8632       }
8633       return baseIndexOf(array, value, index);
8634     }
8635
8636     /**
8637      * Gets all but the last element of `array`.
8638      *
8639      * @static
8640      * @memberOf _
8641      * @since 0.1.0
8642      * @category Array
8643      * @param {Array} array The array to query.
8644      * @returns {Array} Returns the slice of `array`.
8645      * @example
8646      *
8647      * _.initial([1, 2, 3]);
8648      * // => [1, 2]
8649      */
8650     function initial(array) {
8651       var length = array == null ? 0 : array.length;
8652       return length ? baseSlice(array, 0, -1) : [];
8653     }
8654
8655     /**
8656      * Creates an array of unique values that are included in all given arrays
8657      * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8658      * for equality comparisons. The order and references of result values are
8659      * determined by the first array.
8660      *
8661      * @static
8662      * @memberOf _
8663      * @since 0.1.0
8664      * @category Array
8665      * @param {...Array} [arrays] The arrays to inspect.
8666      * @returns {Array} Returns the new array of intersecting values.
8667      * @example
8668      *
8669      * _.intersection([2, 1], [2, 3]);
8670      * // => [2]
8671      */
8672     var intersection = baseRest(function(arrays) {
8673       var mapped = arrayMap(arrays, castArrayLikeObject);
8674       return (mapped.length && mapped[0] === arrays[0])
8675         ? baseIntersection(mapped)
8676         : [];
8677     });
8678
8679     /**
8680      * This method is like `_.intersection` except that it accepts `iteratee`
8681      * which is invoked for each element of each `arrays` to generate the criterion
8682      * by which they're compared. The order and references of result values are
8683      * determined by the first array. The iteratee is invoked with one argument:
8684      * (value).
8685      *
8686      * @static
8687      * @memberOf _
8688      * @since 4.0.0
8689      * @category Array
8690      * @param {...Array} [arrays] The arrays to inspect.
8691      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8692      * @returns {Array} Returns the new array of intersecting values.
8693      * @example
8694      *
8695      * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8696      * // => [2.1]
8697      *
8698      * // The `_.property` iteratee shorthand.
8699      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8700      * // => [{ 'x': 1 }]
8701      */
8702     var intersectionBy = baseRest(function(arrays) {
8703       var iteratee = last(arrays),
8704           mapped = arrayMap(arrays, castArrayLikeObject);
8705
8706       if (iteratee === last(mapped)) {
8707         iteratee = undefined;
8708       } else {
8709         mapped.pop();
8710       }
8711       return (mapped.length && mapped[0] === arrays[0])
8712         ? baseIntersection(mapped, getIteratee(iteratee, 2))
8713         : [];
8714     });
8715
8716     /**
8717      * This method is like `_.intersection` except that it accepts `comparator`
8718      * which is invoked to compare elements of `arrays`. The order and references
8719      * of result values are determined by the first array. The comparator is
8720      * invoked with two arguments: (arrVal, othVal).
8721      *
8722      * @static
8723      * @memberOf _
8724      * @since 4.0.0
8725      * @category Array
8726      * @param {...Array} [arrays] The arrays to inspect.
8727      * @param {Function} [comparator] The comparator invoked per element.
8728      * @returns {Array} Returns the new array of intersecting values.
8729      * @example
8730      *
8731      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8732      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8733      *
8734      * _.intersectionWith(objects, others, _.isEqual);
8735      * // => [{ 'x': 1, 'y': 2 }]
8736      */
8737     var intersectionWith = baseRest(function(arrays) {
8738       var comparator = last(arrays),
8739           mapped = arrayMap(arrays, castArrayLikeObject);
8740
8741       comparator = typeof comparator == 'function' ? comparator : undefined;
8742       if (comparator) {
8743         mapped.pop();
8744       }
8745       return (mapped.length && mapped[0] === arrays[0])
8746         ? baseIntersection(mapped, undefined, comparator)
8747         : [];
8748     });
8749
8750     /**
8751      * Converts all elements in `array` into a string separated by `separator`.
8752      *
8753      * @static
8754      * @memberOf _
8755      * @since 4.0.0
8756      * @category Array
8757      * @param {Array} array The array to convert.
8758      * @param {string} [separator=','] The element separator.
8759      * @returns {string} Returns the joined string.
8760      * @example
8761      *
8762      * _.join(['a', 'b', 'c'], '~');
8763      * // => 'a~b~c'
8764      */
8765     function join(array, separator) {
8766       return array == null ? '' : nativeJoin.call(array, separator);
8767     }
8768
8769     /**
8770      * Gets the last element of `array`.
8771      *
8772      * @static
8773      * @memberOf _
8774      * @since 0.1.0
8775      * @category Array
8776      * @param {Array} array The array to query.
8777      * @returns {*} Returns the last element of `array`.
8778      * @example
8779      *
8780      * _.last([1, 2, 3]);
8781      * // => 3
8782      */
8783     function last(array) {
8784       var length = array == null ? 0 : array.length;
8785       return length ? array[length - 1] : undefined;
8786     }
8787
8788     /**
8789      * This method is like `_.indexOf` except that it iterates over elements of
8790      * `array` from right to left.
8791      *
8792      * @static
8793      * @memberOf _
8794      * @since 0.1.0
8795      * @category Array
8796      * @param {Array} array The array to inspect.
8797      * @param {*} value The value to search for.
8798      * @param {number} [fromIndex=array.length-1] The index to search from.
8799      * @returns {number} Returns the index of the matched value, else `-1`.
8800      * @example
8801      *
8802      * _.lastIndexOf([1, 2, 1, 2], 2);
8803      * // => 3
8804      *
8805      * // Search from the `fromIndex`.
8806      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
8807      * // => 1
8808      */
8809     function lastIndexOf(array, value, fromIndex) {
8810       var length = array == null ? 0 : array.length;
8811       if (!length) {
8812         return -1;
8813       }
8814       var index = length;
8815       if (fromIndex !== undefined) {
8816         index = toInteger(fromIndex);
8817         index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
8818       }
8819       return value === value
8820         ? strictLastIndexOf(array, value, index)
8821         : baseFindIndex(array, baseIsNaN, index, true);
8822     }
8823
8824     /**
8825      * Gets the element at index `n` of `array`. If `n` is negative, the nth
8826      * element from the end is returned.
8827      *
8828      * @static
8829      * @memberOf _
8830      * @since 4.11.0
8831      * @category Array
8832      * @param {Array} array The array to query.
8833      * @param {number} [n=0] The index of the element to return.
8834      * @returns {*} Returns the nth element of `array`.
8835      * @example
8836      *
8837      * var array = ['a', 'b', 'c', 'd'];
8838      *
8839      * _.nth(array, 1);
8840      * // => 'b'
8841      *
8842      * _.nth(array, -2);
8843      * // => 'c';
8844      */
8845     function nth(array, n) {
8846       return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
8847     }
8848
8849     /**
8850      * Removes all given values from `array` using
8851      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8852      * for equality comparisons.
8853      *
8854      * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
8855      * to remove elements from an array by predicate.
8856      *
8857      * @static
8858      * @memberOf _
8859      * @since 2.0.0
8860      * @category Array
8861      * @param {Array} array The array to modify.
8862      * @param {...*} [values] The values to remove.
8863      * @returns {Array} Returns `array`.
8864      * @example
8865      *
8866      * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
8867      *
8868      * _.pull(array, 'a', 'c');
8869      * console.log(array);
8870      * // => ['b', 'b']
8871      */
8872     var pull = baseRest(pullAll);
8873
8874     /**
8875      * This method is like `_.pull` except that it accepts an array of values to remove.
8876      *
8877      * **Note:** Unlike `_.difference`, this method mutates `array`.
8878      *
8879      * @static
8880      * @memberOf _
8881      * @since 4.0.0
8882      * @category Array
8883      * @param {Array} array The array to modify.
8884      * @param {Array} values The values to remove.
8885      * @returns {Array} Returns `array`.
8886      * @example
8887      *
8888      * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
8889      *
8890      * _.pullAll(array, ['a', 'c']);
8891      * console.log(array);
8892      * // => ['b', 'b']
8893      */
8894     function pullAll(array, values) {
8895       return (array && array.length && values && values.length)
8896         ? basePullAll(array, values)
8897         : array;
8898     }
8899
8900     /**
8901      * This method is like `_.pullAll` except that it accepts `iteratee` which is
8902      * invoked for each element of `array` and `values` to generate the criterion
8903      * by which they're compared. The iteratee is invoked with one argument: (value).
8904      *
8905      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
8906      *
8907      * @static
8908      * @memberOf _
8909      * @since 4.0.0
8910      * @category Array
8911      * @param {Array} array The array to modify.
8912      * @param {Array} values The values to remove.
8913      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8914      * @returns {Array} Returns `array`.
8915      * @example
8916      *
8917      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
8918      *
8919      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
8920      * console.log(array);
8921      * // => [{ 'x': 2 }]
8922      */
8923     function pullAllBy(array, values, iteratee) {
8924       return (array && array.length && values && values.length)
8925         ? basePullAll(array, values, getIteratee(iteratee, 2))
8926         : array;
8927     }
8928
8929     /**
8930      * This method is like `_.pullAll` except that it accepts `comparator` which
8931      * is invoked to compare elements of `array` to `values`. The comparator is
8932      * invoked with two arguments: (arrVal, othVal).
8933      *
8934      * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
8935      *
8936      * @static
8937      * @memberOf _
8938      * @since 4.6.0
8939      * @category Array
8940      * @param {Array} array The array to modify.
8941      * @param {Array} values The values to remove.
8942      * @param {Function} [comparator] The comparator invoked per element.
8943      * @returns {Array} Returns `array`.
8944      * @example
8945      *
8946      * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
8947      *
8948      * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
8949      * console.log(array);
8950      * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
8951      */
8952     function pullAllWith(array, values, comparator) {
8953       return (array && array.length && values && values.length)
8954         ? basePullAll(array, values, undefined, comparator)
8955         : array;
8956     }
8957
8958     /**
8959      * Removes elements from `array` corresponding to `indexes` and returns an
8960      * array of removed elements.
8961      *
8962      * **Note:** Unlike `_.at`, this method mutates `array`.
8963      *
8964      * @static
8965      * @memberOf _
8966      * @since 3.0.0
8967      * @category Array
8968      * @param {Array} array The array to modify.
8969      * @param {...(number|number[])} [indexes] The indexes of elements to remove.
8970      * @returns {Array} Returns the new array of removed elements.
8971      * @example
8972      *
8973      * var array = ['a', 'b', 'c', 'd'];
8974      * var pulled = _.pullAt(array, [1, 3]);
8975      *
8976      * console.log(array);
8977      * // => ['a', 'c']
8978      *
8979      * console.log(pulled);
8980      * // => ['b', 'd']
8981      */
8982     var pullAt = flatRest(function(array, indexes) {
8983       var length = array == null ? 0 : array.length,
8984           result = baseAt(array, indexes);
8985
8986       basePullAt(array, arrayMap(indexes, function(index) {
8987         return isIndex(index, length) ? +index : index;
8988       }).sort(compareAscending));
8989
8990       return result;
8991     });
8992
8993     /**
8994      * Removes all elements from `array` that `predicate` returns truthy for
8995      * and returns an array of the removed elements. The predicate is invoked
8996      * with three arguments: (value, index, array).
8997      *
8998      * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
8999      * to pull elements from an array by value.
9000      *
9001      * @static
9002      * @memberOf _
9003      * @since 2.0.0
9004      * @category Array
9005      * @param {Array} array The array to modify.
9006      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9007      * @returns {Array} Returns the new array of removed elements.
9008      * @example
9009      *
9010      * var array = [1, 2, 3, 4];
9011      * var evens = _.remove(array, function(n) {
9012      *   return n % 2 == 0;
9013      * });
9014      *
9015      * console.log(array);
9016      * // => [1, 3]
9017      *
9018      * console.log(evens);
9019      * // => [2, 4]
9020      */
9021     function remove(array, predicate) {
9022       var result = [];
9023       if (!(array && array.length)) {
9024         return result;
9025       }
9026       var index = -1,
9027           indexes = [],
9028           length = array.length;
9029
9030       predicate = getIteratee(predicate, 3);
9031       while (++index < length) {
9032         var value = array[index];
9033         if (predicate(value, index, array)) {
9034           result.push(value);
9035           indexes.push(index);
9036         }
9037       }
9038       basePullAt(array, indexes);
9039       return result;
9040     }
9041
9042     /**
9043      * Reverses `array` so that the first element becomes the last, the second
9044      * element becomes the second to last, and so on.
9045      *
9046      * **Note:** This method mutates `array` and is based on
9047      * [`Array#reverse`](https://mdn.io/Array/reverse).
9048      *
9049      * @static
9050      * @memberOf _
9051      * @since 4.0.0
9052      * @category Array
9053      * @param {Array} array The array to modify.
9054      * @returns {Array} Returns `array`.
9055      * @example
9056      *
9057      * var array = [1, 2, 3];
9058      *
9059      * _.reverse(array);
9060      * // => [3, 2, 1]
9061      *
9062      * console.log(array);
9063      * // => [3, 2, 1]
9064      */
9065     function reverse(array) {
9066       return array == null ? array : nativeReverse.call(array);
9067     }
9068
9069     /**
9070      * Creates a slice of `array` from `start` up to, but not including, `end`.
9071      *
9072      * **Note:** This method is used instead of
9073      * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
9074      * returned.
9075      *
9076      * @static
9077      * @memberOf _
9078      * @since 3.0.0
9079      * @category Array
9080      * @param {Array} array The array to slice.
9081      * @param {number} [start=0] The start position.
9082      * @param {number} [end=array.length] The end position.
9083      * @returns {Array} Returns the slice of `array`.
9084      */
9085     function slice(array, start, end) {
9086       var length = array == null ? 0 : array.length;
9087       if (!length) {
9088         return [];
9089       }
9090       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
9091         start = 0;
9092         end = length;
9093       }
9094       else {
9095         start = start == null ? 0 : toInteger(start);
9096         end = end === undefined ? length : toInteger(end);
9097       }
9098       return baseSlice(array, start, end);
9099     }
9100
9101     /**
9102      * Uses a binary search to determine the lowest index at which `value`
9103      * should be inserted into `array` in order to maintain its sort order.
9104      *
9105      * @static
9106      * @memberOf _
9107      * @since 0.1.0
9108      * @category Array
9109      * @param {Array} array The sorted array to inspect.
9110      * @param {*} value The value to evaluate.
9111      * @returns {number} Returns the index at which `value` should be inserted
9112      *  into `array`.
9113      * @example
9114      *
9115      * _.sortedIndex([30, 50], 40);
9116      * // => 1
9117      */
9118     function sortedIndex(array, value) {
9119       return baseSortedIndex(array, value);
9120     }
9121
9122     /**
9123      * This method is like `_.sortedIndex` except that it accepts `iteratee`
9124      * which is invoked for `value` and each element of `array` to compute their
9125      * sort ranking. The iteratee is invoked with one argument: (value).
9126      *
9127      * @static
9128      * @memberOf _
9129      * @since 4.0.0
9130      * @category Array
9131      * @param {Array} array The sorted array to inspect.
9132      * @param {*} value The value to evaluate.
9133      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9134      * @returns {number} Returns the index at which `value` should be inserted
9135      *  into `array`.
9136      * @example
9137      *
9138      * var objects = [{ 'x': 4 }, { 'x': 5 }];
9139      *
9140      * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
9141      * // => 0
9142      *
9143      * // The `_.property` iteratee shorthand.
9144      * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
9145      * // => 0
9146      */
9147     function sortedIndexBy(array, value, iteratee) {
9148       return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
9149     }
9150
9151     /**
9152      * This method is like `_.indexOf` except that it performs a binary
9153      * search on a sorted `array`.
9154      *
9155      * @static
9156      * @memberOf _
9157      * @since 4.0.0
9158      * @category Array
9159      * @param {Array} array The array to inspect.
9160      * @param {*} value The value to search for.
9161      * @returns {number} Returns the index of the matched value, else `-1`.
9162      * @example
9163      *
9164      * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
9165      * // => 1
9166      */
9167     function sortedIndexOf(array, value) {
9168       var length = array == null ? 0 : array.length;
9169       if (length) {
9170         var index = baseSortedIndex(array, value);
9171         if (index < length && eq(array[index], value)) {
9172           return index;
9173         }
9174       }
9175       return -1;
9176     }
9177
9178     /**
9179      * This method is like `_.sortedIndex` except that it returns the highest
9180      * index at which `value` should be inserted into `array` in order to
9181      * maintain its sort order.
9182      *
9183      * @static
9184      * @memberOf _
9185      * @since 3.0.0
9186      * @category Array
9187      * @param {Array} array The sorted array to inspect.
9188      * @param {*} value The value to evaluate.
9189      * @returns {number} Returns the index at which `value` should be inserted
9190      *  into `array`.
9191      * @example
9192      *
9193      * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
9194      * // => 4
9195      */
9196     function sortedLastIndex(array, value) {
9197       return baseSortedIndex(array, value, true);
9198     }
9199
9200     /**
9201      * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
9202      * which is invoked for `value` and each element of `array` to compute their
9203      * sort ranking. The iteratee is invoked with one argument: (value).
9204      *
9205      * @static
9206      * @memberOf _
9207      * @since 4.0.0
9208      * @category Array
9209      * @param {Array} array The sorted array to inspect.
9210      * @param {*} value The value to evaluate.
9211      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9212      * @returns {number} Returns the index at which `value` should be inserted
9213      *  into `array`.
9214      * @example
9215      *
9216      * var objects = [{ 'x': 4 }, { 'x': 5 }];
9217      *
9218      * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
9219      * // => 1
9220      *
9221      * // The `_.property` iteratee shorthand.
9222      * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
9223      * // => 1
9224      */
9225     function sortedLastIndexBy(array, value, iteratee) {
9226       return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
9227     }
9228
9229     /**
9230      * This method is like `_.lastIndexOf` except that it performs a binary
9231      * search on a sorted `array`.
9232      *
9233      * @static
9234      * @memberOf _
9235      * @since 4.0.0
9236      * @category Array
9237      * @param {Array} array The array to inspect.
9238      * @param {*} value The value to search for.
9239      * @returns {number} Returns the index of the matched value, else `-1`.
9240      * @example
9241      *
9242      * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
9243      * // => 3
9244      */
9245     function sortedLastIndexOf(array, value) {
9246       var length = array == null ? 0 : array.length;
9247       if (length) {
9248         var index = baseSortedIndex(array, value, true) - 1;
9249         if (eq(array[index], value)) {
9250           return index;
9251         }
9252       }
9253       return -1;
9254     }
9255
9256     /**
9257      * This method is like `_.uniq` except that it's designed and optimized
9258      * for sorted arrays.
9259      *
9260      * @static
9261      * @memberOf _
9262      * @since 4.0.0
9263      * @category Array
9264      * @param {Array} array The array to inspect.
9265      * @returns {Array} Returns the new duplicate free array.
9266      * @example
9267      *
9268      * _.sortedUniq([1, 1, 2]);
9269      * // => [1, 2]
9270      */
9271     function sortedUniq(array) {
9272       return (array && array.length)
9273         ? baseSortedUniq(array)
9274         : [];
9275     }
9276
9277     /**
9278      * This method is like `_.uniqBy` except that it's designed and optimized
9279      * for sorted arrays.
9280      *
9281      * @static
9282      * @memberOf _
9283      * @since 4.0.0
9284      * @category Array
9285      * @param {Array} array The array to inspect.
9286      * @param {Function} [iteratee] The iteratee invoked per element.
9287      * @returns {Array} Returns the new duplicate free array.
9288      * @example
9289      *
9290      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
9291      * // => [1.1, 2.3]
9292      */
9293     function sortedUniqBy(array, iteratee) {
9294       return (array && array.length)
9295         ? baseSortedUniq(array, getIteratee(iteratee, 2))
9296         : [];
9297     }
9298
9299     /**
9300      * Gets all but the first element of `array`.
9301      *
9302      * @static
9303      * @memberOf _
9304      * @since 4.0.0
9305      * @category Array
9306      * @param {Array} array The array to query.
9307      * @returns {Array} Returns the slice of `array`.
9308      * @example
9309      *
9310      * _.tail([1, 2, 3]);
9311      * // => [2, 3]
9312      */
9313     function tail(array) {
9314       var length = array == null ? 0 : array.length;
9315       return length ? baseSlice(array, 1, length) : [];
9316     }
9317
9318     /**
9319      * Creates a slice of `array` with `n` elements taken from the beginning.
9320      *
9321      * @static
9322      * @memberOf _
9323      * @since 0.1.0
9324      * @category Array
9325      * @param {Array} array The array to query.
9326      * @param {number} [n=1] The number of elements to take.
9327      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9328      * @returns {Array} Returns the slice of `array`.
9329      * @example
9330      *
9331      * _.take([1, 2, 3]);
9332      * // => [1]
9333      *
9334      * _.take([1, 2, 3], 2);
9335      * // => [1, 2]
9336      *
9337      * _.take([1, 2, 3], 5);
9338      * // => [1, 2, 3]
9339      *
9340      * _.take([1, 2, 3], 0);
9341      * // => []
9342      */
9343     function take(array, n, guard) {
9344       if (!(array && array.length)) {
9345         return [];
9346       }
9347       n = (guard || n === undefined) ? 1 : toInteger(n);
9348       return baseSlice(array, 0, n < 0 ? 0 : n);
9349     }
9350
9351     /**
9352      * Creates a slice of `array` with `n` elements taken from the end.
9353      *
9354      * @static
9355      * @memberOf _
9356      * @since 3.0.0
9357      * @category Array
9358      * @param {Array} array The array to query.
9359      * @param {number} [n=1] The number of elements to take.
9360      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9361      * @returns {Array} Returns the slice of `array`.
9362      * @example
9363      *
9364      * _.takeRight([1, 2, 3]);
9365      * // => [3]
9366      *
9367      * _.takeRight([1, 2, 3], 2);
9368      * // => [2, 3]
9369      *
9370      * _.takeRight([1, 2, 3], 5);
9371      * // => [1, 2, 3]
9372      *
9373      * _.takeRight([1, 2, 3], 0);
9374      * // => []
9375      */
9376     function takeRight(array, n, guard) {
9377       var length = array == null ? 0 : array.length;
9378       if (!length) {
9379         return [];
9380       }
9381       n = (guard || n === undefined) ? 1 : toInteger(n);
9382       n = length - n;
9383       return baseSlice(array, n < 0 ? 0 : n, length);
9384     }
9385
9386     /**
9387      * Creates a slice of `array` with elements taken from the end. Elements are
9388      * taken until `predicate` returns falsey. The predicate is invoked with
9389      * three arguments: (value, index, array).
9390      *
9391      * @static
9392      * @memberOf _
9393      * @since 3.0.0
9394      * @category Array
9395      * @param {Array} array The array to query.
9396      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9397      * @returns {Array} Returns the slice of `array`.
9398      * @example
9399      *
9400      * var users = [
9401      *   { 'user': 'barney',  'active': true },
9402      *   { 'user': 'fred',    'active': false },
9403      *   { 'user': 'pebbles', 'active': false }
9404      * ];
9405      *
9406      * _.takeRightWhile(users, function(o) { return !o.active; });
9407      * // => objects for ['fred', 'pebbles']
9408      *
9409      * // The `_.matches` iteratee shorthand.
9410      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
9411      * // => objects for ['pebbles']
9412      *
9413      * // The `_.matchesProperty` iteratee shorthand.
9414      * _.takeRightWhile(users, ['active', false]);
9415      * // => objects for ['fred', 'pebbles']
9416      *
9417      * // The `_.property` iteratee shorthand.
9418      * _.takeRightWhile(users, 'active');
9419      * // => []
9420      */
9421     function takeRightWhile(array, predicate) {
9422       return (array && array.length)
9423         ? baseWhile(array, getIteratee(predicate, 3), false, true)
9424         : [];
9425     }
9426
9427     /**
9428      * Creates a slice of `array` with elements taken from the beginning. Elements
9429      * are taken until `predicate` returns falsey. The predicate is invoked with
9430      * three arguments: (value, index, array).
9431      *
9432      * @static
9433      * @memberOf _
9434      * @since 3.0.0
9435      * @category Array
9436      * @param {Array} array The array to query.
9437      * @param {Function} [predicate=_.identity] The function invoked per iteration.
9438      * @returns {Array} Returns the slice of `array`.
9439      * @example
9440      *
9441      * var users = [
9442      *   { 'user': 'barney',  'active': false },
9443      *   { 'user': 'fred',    'active': false },
9444      *   { 'user': 'pebbles', 'active': true }
9445      * ];
9446      *
9447      * _.takeWhile(users, function(o) { return !o.active; });
9448      * // => objects for ['barney', 'fred']
9449      *
9450      * // The `_.matches` iteratee shorthand.
9451      * _.takeWhile(users, { 'user': 'barney', 'active': false });
9452      * // => objects for ['barney']
9453      *
9454      * // The `_.matchesProperty` iteratee shorthand.
9455      * _.takeWhile(users, ['active', false]);
9456      * // => objects for ['barney', 'fred']
9457      *
9458      * // The `_.property` iteratee shorthand.
9459      * _.takeWhile(users, 'active');
9460      * // => []
9461      */
9462     function takeWhile(array, predicate) {
9463       return (array && array.length)
9464         ? baseWhile(array, getIteratee(predicate, 3))
9465         : [];
9466     }
9467
9468     /**
9469      * Creates an array of unique values, in order, from all given arrays using
9470      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9471      * for equality comparisons.
9472      *
9473      * @static
9474      * @memberOf _
9475      * @since 0.1.0
9476      * @category Array
9477      * @param {...Array} [arrays] The arrays to inspect.
9478      * @returns {Array} Returns the new array of combined values.
9479      * @example
9480      *
9481      * _.union([2], [1, 2]);
9482      * // => [2, 1]
9483      */
9484     var union = baseRest(function(arrays) {
9485       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
9486     });
9487
9488     /**
9489      * This method is like `_.union` except that it accepts `iteratee` which is
9490      * invoked for each element of each `arrays` to generate the criterion by
9491      * which uniqueness is computed. Result values are chosen from the first
9492      * array in which the value occurs. The iteratee is invoked with one argument:
9493      * (value).
9494      *
9495      * @static
9496      * @memberOf _
9497      * @since 4.0.0
9498      * @category Array
9499      * @param {...Array} [arrays] The arrays to inspect.
9500      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9501      * @returns {Array} Returns the new array of combined values.
9502      * @example
9503      *
9504      * _.unionBy([2.1], [1.2, 2.3], Math.floor);
9505      * // => [2.1, 1.2]
9506      *
9507      * // The `_.property` iteratee shorthand.
9508      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
9509      * // => [{ 'x': 1 }, { 'x': 2 }]
9510      */
9511     var unionBy = baseRest(function(arrays) {
9512       var iteratee = last(arrays);
9513       if (isArrayLikeObject(iteratee)) {
9514         iteratee = undefined;
9515       }
9516       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
9517     });
9518
9519     /**
9520      * This method is like `_.union` except that it accepts `comparator` which
9521      * is invoked to compare elements of `arrays`. Result values are chosen from
9522      * the first array in which the value occurs. The comparator is invoked
9523      * with two arguments: (arrVal, othVal).
9524      *
9525      * @static
9526      * @memberOf _
9527      * @since 4.0.0
9528      * @category Array
9529      * @param {...Array} [arrays] The arrays to inspect.
9530      * @param {Function} [comparator] The comparator invoked per element.
9531      * @returns {Array} Returns the new array of combined values.
9532      * @example
9533      *
9534      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
9535      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
9536      *
9537      * _.unionWith(objects, others, _.isEqual);
9538      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
9539      */
9540     var unionWith = baseRest(function(arrays) {
9541       var comparator = last(arrays);
9542       comparator = typeof comparator == 'function' ? comparator : undefined;
9543       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
9544     });
9545
9546     /**
9547      * Creates a duplicate-free version of an array, using
9548      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9549      * for equality comparisons, in which only the first occurrence of each element
9550      * is kept. The order of result values is determined by the order they occur
9551      * in the array.
9552      *
9553      * @static
9554      * @memberOf _
9555      * @since 0.1.0
9556      * @category Array
9557      * @param {Array} array The array to inspect.
9558      * @returns {Array} Returns the new duplicate free array.
9559      * @example
9560      *
9561      * _.uniq([2, 1, 2]);
9562      * // => [2, 1]
9563      */
9564     function uniq(array) {
9565       return (array && array.length) ? baseUniq(array) : [];
9566     }
9567
9568     /**
9569      * This method is like `_.uniq` except that it accepts `iteratee` which is
9570      * invoked for each element in `array` to generate the criterion by which
9571      * uniqueness is computed. The order of result values is determined by the
9572      * order they occur in the array. The iteratee is invoked with one argument:
9573      * (value).
9574      *
9575      * @static
9576      * @memberOf _
9577      * @since 4.0.0
9578      * @category Array
9579      * @param {Array} array The array to inspect.
9580      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9581      * @returns {Array} Returns the new duplicate free array.
9582      * @example
9583      *
9584      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
9585      * // => [2.1, 1.2]
9586      *
9587      * // The `_.property` iteratee shorthand.
9588      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
9589      * // => [{ 'x': 1 }, { 'x': 2 }]
9590      */
9591     function uniqBy(array, iteratee) {
9592       return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
9593     }
9594
9595     /**
9596      * This method is like `_.uniq` except that it accepts `comparator` which
9597      * is invoked to compare elements of `array`. The order of result values is
9598      * determined by the order they occur in the array.The comparator is invoked
9599      * with two arguments: (arrVal, othVal).
9600      *
9601      * @static
9602      * @memberOf _
9603      * @since 4.0.0
9604      * @category Array
9605      * @param {Array} array The array to inspect.
9606      * @param {Function} [comparator] The comparator invoked per element.
9607      * @returns {Array} Returns the new duplicate free array.
9608      * @example
9609      *
9610      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
9611      *
9612      * _.uniqWith(objects, _.isEqual);
9613      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
9614      */
9615     function uniqWith(array, comparator) {
9616       comparator = typeof comparator == 'function' ? comparator : undefined;
9617       return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
9618     }
9619
9620     /**
9621      * This method is like `_.zip` except that it accepts an array of grouped
9622      * elements and creates an array regrouping the elements to their pre-zip
9623      * configuration.
9624      *
9625      * @static
9626      * @memberOf _
9627      * @since 1.2.0
9628      * @category Array
9629      * @param {Array} array The array of grouped elements to process.
9630      * @returns {Array} Returns the new array of regrouped elements.
9631      * @example
9632      *
9633      * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
9634      * // => [['a', 1, true], ['b', 2, false]]
9635      *
9636      * _.unzip(zipped);
9637      * // => [['a', 'b'], [1, 2], [true, false]]
9638      */
9639     function unzip(array) {
9640       if (!(array && array.length)) {
9641         return [];
9642       }
9643       var length = 0;
9644       array = arrayFilter(array, function(group) {
9645         if (isArrayLikeObject(group)) {
9646           length = nativeMax(group.length, length);
9647           return true;
9648         }
9649       });
9650       return baseTimes(length, function(index) {
9651         return arrayMap(array, baseProperty(index));
9652       });
9653     }
9654
9655     /**
9656      * This method is like `_.unzip` except that it accepts `iteratee` to specify
9657      * how regrouped values should be combined. The iteratee is invoked with the
9658      * elements of each group: (...group).
9659      *
9660      * @static
9661      * @memberOf _
9662      * @since 3.8.0
9663      * @category Array
9664      * @param {Array} array The array of grouped elements to process.
9665      * @param {Function} [iteratee=_.identity] The function to combine
9666      *  regrouped values.
9667      * @returns {Array} Returns the new array of regrouped elements.
9668      * @example
9669      *
9670      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
9671      * // => [[1, 10, 100], [2, 20, 200]]
9672      *
9673      * _.unzipWith(zipped, _.add);
9674      * // => [3, 30, 300]
9675      */
9676     function unzipWith(array, iteratee) {
9677       if (!(array && array.length)) {
9678         return [];
9679       }
9680       var result = unzip(array);
9681       if (iteratee == null) {
9682         return result;
9683       }
9684       return arrayMap(result, function(group) {
9685         return apply(iteratee, undefined, group);
9686       });
9687     }
9688
9689     /**
9690      * Creates an array excluding all given values using
9691      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9692      * for equality comparisons.
9693      *
9694      * **Note:** Unlike `_.pull`, this method returns a new array.
9695      *
9696      * @static
9697      * @memberOf _
9698      * @since 0.1.0
9699      * @category Array
9700      * @param {Array} array The array to inspect.
9701      * @param {...*} [values] The values to exclude.
9702      * @returns {Array} Returns the new array of filtered values.
9703      * @see _.difference, _.xor
9704      * @example
9705      *
9706      * _.without([2, 1, 2, 3], 1, 2);
9707      * // => [3]
9708      */
9709     var without = baseRest(function(array, values) {
9710       return isArrayLikeObject(array)
9711         ? baseDifference(array, values)
9712         : [];
9713     });
9714
9715     /**
9716      * Creates an array of unique values that is the
9717      * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
9718      * of the given arrays. The order of result values is determined by the order
9719      * they occur in the arrays.
9720      *
9721      * @static
9722      * @memberOf _
9723      * @since 2.4.0
9724      * @category Array
9725      * @param {...Array} [arrays] The arrays to inspect.
9726      * @returns {Array} Returns the new array of filtered values.
9727      * @see _.difference, _.without
9728      * @example
9729      *
9730      * _.xor([2, 1], [2, 3]);
9731      * // => [1, 3]
9732      */
9733     var xor = baseRest(function(arrays) {
9734       return baseXor(arrayFilter(arrays, isArrayLikeObject));
9735     });
9736
9737     /**
9738      * This method is like `_.xor` except that it accepts `iteratee` which is
9739      * invoked for each element of each `arrays` to generate the criterion by
9740      * which by which they're compared. The order of result values is determined
9741      * by the order they occur in the arrays. The iteratee is invoked with one
9742      * argument: (value).
9743      *
9744      * @static
9745      * @memberOf _
9746      * @since 4.0.0
9747      * @category Array
9748      * @param {...Array} [arrays] The arrays to inspect.
9749      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9750      * @returns {Array} Returns the new array of filtered values.
9751      * @example
9752      *
9753      * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
9754      * // => [1.2, 3.4]
9755      *
9756      * // The `_.property` iteratee shorthand.
9757      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
9758      * // => [{ 'x': 2 }]
9759      */
9760     var xorBy = baseRest(function(arrays) {
9761       var iteratee = last(arrays);
9762       if (isArrayLikeObject(iteratee)) {
9763         iteratee = undefined;
9764       }
9765       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
9766     });
9767
9768     /**
9769      * This method is like `_.xor` except that it accepts `comparator` which is
9770      * invoked to compare elements of `arrays`. The order of result values is
9771      * determined by the order they occur in the arrays. The comparator is invoked
9772      * with two arguments: (arrVal, othVal).
9773      *
9774      * @static
9775      * @memberOf _
9776      * @since 4.0.0
9777      * @category Array
9778      * @param {...Array} [arrays] The arrays to inspect.
9779      * @param {Function} [comparator] The comparator invoked per element.
9780      * @returns {Array} Returns the new array of filtered values.
9781      * @example
9782      *
9783      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
9784      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
9785      *
9786      * _.xorWith(objects, others, _.isEqual);
9787      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
9788      */
9789     var xorWith = baseRest(function(arrays) {
9790       var comparator = last(arrays);
9791       comparator = typeof comparator == 'function' ? comparator : undefined;
9792       return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
9793     });
9794
9795     /**
9796      * Creates an array of grouped elements, the first of which contains the
9797      * first elements of the given arrays, the second of which contains the
9798      * second elements of the given arrays, and so on.
9799      *
9800      * @static
9801      * @memberOf _
9802      * @since 0.1.0
9803      * @category Array
9804      * @param {...Array} [arrays] The arrays to process.
9805      * @returns {Array} Returns the new array of grouped elements.
9806      * @example
9807      *
9808      * _.zip(['a', 'b'], [1, 2], [true, false]);
9809      * // => [['a', 1, true], ['b', 2, false]]
9810      */
9811     var zip = baseRest(unzip);
9812
9813     /**
9814      * This method is like `_.fromPairs` except that it accepts two arrays,
9815      * one of property identifiers and one of corresponding values.
9816      *
9817      * @static
9818      * @memberOf _
9819      * @since 0.4.0
9820      * @category Array
9821      * @param {Array} [props=[]] The property identifiers.
9822      * @param {Array} [values=[]] The property values.
9823      * @returns {Object} Returns the new object.
9824      * @example
9825      *
9826      * _.zipObject(['a', 'b'], [1, 2]);
9827      * // => { 'a': 1, 'b': 2 }
9828      */
9829     function zipObject(props, values) {
9830       return baseZipObject(props || [], values || [], assignValue);
9831     }
9832
9833     /**
9834      * This method is like `_.zipObject` except that it supports property paths.
9835      *
9836      * @static
9837      * @memberOf _
9838      * @since 4.1.0
9839      * @category Array
9840      * @param {Array} [props=[]] The property identifiers.
9841      * @param {Array} [values=[]] The property values.
9842      * @returns {Object} Returns the new object.
9843      * @example
9844      *
9845      * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
9846      * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
9847      */
9848     function zipObjectDeep(props, values) {
9849       return baseZipObject(props || [], values || [], baseSet);
9850     }
9851
9852     /**
9853      * This method is like `_.zip` except that it accepts `iteratee` to specify
9854      * how grouped values should be combined. The iteratee is invoked with the
9855      * elements of each group: (...group).
9856      *
9857      * @static
9858      * @memberOf _
9859      * @since 3.8.0
9860      * @category Array
9861      * @param {...Array} [arrays] The arrays to process.
9862      * @param {Function} [iteratee=_.identity] The function to combine
9863      *  grouped values.
9864      * @returns {Array} Returns the new array of grouped elements.
9865      * @example
9866      *
9867      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
9868      *   return a + b + c;
9869      * });
9870      * // => [111, 222]
9871      */
9872     var zipWith = baseRest(function(arrays) {
9873       var length = arrays.length,
9874           iteratee = length > 1 ? arrays[length - 1] : undefined;
9875
9876       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
9877       return unzipWith(arrays, iteratee);
9878     });
9879
9880     /*------------------------------------------------------------------------*/
9881
9882     /**
9883      * Creates a `lodash` wrapper instance that wraps `value` with explicit method
9884      * chain sequences enabled. The result of such sequences must be unwrapped
9885      * with `_#value`.
9886      *
9887      * @static
9888      * @memberOf _
9889      * @since 1.3.0
9890      * @category Seq
9891      * @param {*} value The value to wrap.
9892      * @returns {Object} Returns the new `lodash` wrapper instance.
9893      * @example
9894      *
9895      * var users = [
9896      *   { 'user': 'barney',  'age': 36 },
9897      *   { 'user': 'fred',    'age': 40 },
9898      *   { 'user': 'pebbles', 'age': 1 }
9899      * ];
9900      *
9901      * var youngest = _
9902      *   .chain(users)
9903      *   .sortBy('age')
9904      *   .map(function(o) {
9905      *     return o.user + ' is ' + o.age;
9906      *   })
9907      *   .head()
9908      *   .value();
9909      * // => 'pebbles is 1'
9910      */
9911     function chain(value) {
9912       var result = lodash(value);
9913       result.__chain__ = true;
9914       return result;
9915     }
9916
9917     /**
9918      * This method invokes `interceptor` and returns `value`. The interceptor
9919      * is invoked with one argument; (value). The purpose of this method is to
9920      * "tap into" a method chain sequence in order to modify intermediate results.
9921      *
9922      * @static
9923      * @memberOf _
9924      * @since 0.1.0
9925      * @category Seq
9926      * @param {*} value The value to provide to `interceptor`.
9927      * @param {Function} interceptor The function to invoke.
9928      * @returns {*} Returns `value`.
9929      * @example
9930      *
9931      * _([1, 2, 3])
9932      *  .tap(function(array) {
9933      *    // Mutate input array.
9934      *    array.pop();
9935      *  })
9936      *  .reverse()
9937      *  .value();
9938      * // => [2, 1]
9939      */
9940     function tap(value, interceptor) {
9941       interceptor(value);
9942       return value;
9943     }
9944
9945     /**
9946      * This method is like `_.tap` except that it returns the result of `interceptor`.
9947      * The purpose of this method is to "pass thru" values replacing intermediate
9948      * results in a method chain sequence.
9949      *
9950      * @static
9951      * @memberOf _
9952      * @since 3.0.0
9953      * @category Seq
9954      * @param {*} value The value to provide to `interceptor`.
9955      * @param {Function} interceptor The function to invoke.
9956      * @returns {*} Returns the result of `interceptor`.
9957      * @example
9958      *
9959      * _('  abc  ')
9960      *  .chain()
9961      *  .trim()
9962      *  .thru(function(value) {
9963      *    return [value];
9964      *  })
9965      *  .value();
9966      * // => ['abc']
9967      */
9968     function thru(value, interceptor) {
9969       return interceptor(value);
9970     }
9971
9972     /**
9973      * This method is the wrapper version of `_.at`.
9974      *
9975      * @name at
9976      * @memberOf _
9977      * @since 1.0.0
9978      * @category Seq
9979      * @param {...(string|string[])} [paths] The property paths to pick.
9980      * @returns {Object} Returns the new `lodash` wrapper instance.
9981      * @example
9982      *
9983      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
9984      *
9985      * _(object).at(['a[0].b.c', 'a[1]']).value();
9986      * // => [3, 4]
9987      */
9988     var wrapperAt = flatRest(function(paths) {
9989       var length = paths.length,
9990           start = length ? paths[0] : 0,
9991           value = this.__wrapped__,
9992           interceptor = function(object) { return baseAt(object, paths); };
9993
9994       if (length > 1 || this.__actions__.length ||
9995           !(value instanceof LazyWrapper) || !isIndex(start)) {
9996         return this.thru(interceptor);
9997       }
9998       value = value.slice(start, +start + (length ? 1 : 0));
9999       value.__actions__.push({
10000         'func': thru,
10001         'args': [interceptor],
10002         'thisArg': undefined
10003       });
10004       return new LodashWrapper(value, this.__chain__).thru(function(array) {
10005         if (length && !array.length) {
10006           array.push(undefined);
10007         }
10008         return array;
10009       });
10010     });
10011
10012     /**
10013      * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
10014      *
10015      * @name chain
10016      * @memberOf _
10017      * @since 0.1.0
10018      * @category Seq
10019      * @returns {Object} Returns the new `lodash` wrapper instance.
10020      * @example
10021      *
10022      * var users = [
10023      *   { 'user': 'barney', 'age': 36 },
10024      *   { 'user': 'fred',   'age': 40 }
10025      * ];
10026      *
10027      * // A sequence without explicit chaining.
10028      * _(users).head();
10029      * // => { 'user': 'barney', 'age': 36 }
10030      *
10031      * // A sequence with explicit chaining.
10032      * _(users)
10033      *   .chain()
10034      *   .head()
10035      *   .pick('user')
10036      *   .value();
10037      * // => { 'user': 'barney' }
10038      */
10039     function wrapperChain() {
10040       return chain(this);
10041     }
10042
10043     /**
10044      * Executes the chain sequence and returns the wrapped result.
10045      *
10046      * @name commit
10047      * @memberOf _
10048      * @since 3.2.0
10049      * @category Seq
10050      * @returns {Object} Returns the new `lodash` wrapper instance.
10051      * @example
10052      *
10053      * var array = [1, 2];
10054      * var wrapped = _(array).push(3);
10055      *
10056      * console.log(array);
10057      * // => [1, 2]
10058      *
10059      * wrapped = wrapped.commit();
10060      * console.log(array);
10061      * // => [1, 2, 3]
10062      *
10063      * wrapped.last();
10064      * // => 3
10065      *
10066      * console.log(array);
10067      * // => [1, 2, 3]
10068      */
10069     function wrapperCommit() {
10070       return new LodashWrapper(this.value(), this.__chain__);
10071     }
10072
10073     /**
10074      * Gets the next value on a wrapped object following the
10075      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
10076      *
10077      * @name next
10078      * @memberOf _
10079      * @since 4.0.0
10080      * @category Seq
10081      * @returns {Object} Returns the next iterator value.
10082      * @example
10083      *
10084      * var wrapped = _([1, 2]);
10085      *
10086      * wrapped.next();
10087      * // => { 'done': false, 'value': 1 }
10088      *
10089      * wrapped.next();
10090      * // => { 'done': false, 'value': 2 }
10091      *
10092      * wrapped.next();
10093      * // => { 'done': true, 'value': undefined }
10094      */
10095     function wrapperNext() {
10096       if (this.__values__ === undefined) {
10097         this.__values__ = toArray(this.value());
10098       }
10099       var done = this.__index__ >= this.__values__.length,
10100           value = done ? undefined : this.__values__[this.__index__++];
10101
10102       return { 'done': done, 'value': value };
10103     }
10104
10105     /**
10106      * Enables the wrapper to be iterable.
10107      *
10108      * @name Symbol.iterator
10109      * @memberOf _
10110      * @since 4.0.0
10111      * @category Seq
10112      * @returns {Object} Returns the wrapper object.
10113      * @example
10114      *
10115      * var wrapped = _([1, 2]);
10116      *
10117      * wrapped[Symbol.iterator]() === wrapped;
10118      * // => true
10119      *
10120      * Array.from(wrapped);
10121      * // => [1, 2]
10122      */
10123     function wrapperToIterator() {
10124       return this;
10125     }
10126
10127     /**
10128      * Creates a clone of the chain sequence planting `value` as the wrapped value.
10129      *
10130      * @name plant
10131      * @memberOf _
10132      * @since 3.2.0
10133      * @category Seq
10134      * @param {*} value The value to plant.
10135      * @returns {Object} Returns the new `lodash` wrapper instance.
10136      * @example
10137      *
10138      * function square(n) {
10139      *   return n * n;
10140      * }
10141      *
10142      * var wrapped = _([1, 2]).map(square);
10143      * var other = wrapped.plant([3, 4]);
10144      *
10145      * other.value();
10146      * // => [9, 16]
10147      *
10148      * wrapped.value();
10149      * // => [1, 4]
10150      */
10151     function wrapperPlant(value) {
10152       var result,
10153           parent = this;
10154
10155       while (parent instanceof baseLodash) {
10156         var clone = wrapperClone(parent);
10157         clone.__index__ = 0;
10158         clone.__values__ = undefined;
10159         if (result) {
10160           previous.__wrapped__ = clone;
10161         } else {
10162           result = clone;
10163         }
10164         var previous = clone;
10165         parent = parent.__wrapped__;
10166       }
10167       previous.__wrapped__ = value;
10168       return result;
10169     }
10170
10171     /**
10172      * This method is the wrapper version of `_.reverse`.
10173      *
10174      * **Note:** This method mutates the wrapped array.
10175      *
10176      * @name reverse
10177      * @memberOf _
10178      * @since 0.1.0
10179      * @category Seq
10180      * @returns {Object} Returns the new `lodash` wrapper instance.
10181      * @example
10182      *
10183      * var array = [1, 2, 3];
10184      *
10185      * _(array).reverse().value()
10186      * // => [3, 2, 1]
10187      *
10188      * console.log(array);
10189      * // => [3, 2, 1]
10190      */
10191     function wrapperReverse() {
10192       var value = this.__wrapped__;
10193       if (value instanceof LazyWrapper) {
10194         var wrapped = value;
10195         if (this.__actions__.length) {
10196           wrapped = new LazyWrapper(this);
10197         }
10198         wrapped = wrapped.reverse();
10199         wrapped.__actions__.push({
10200           'func': thru,
10201           'args': [reverse],
10202           'thisArg': undefined
10203         });
10204         return new LodashWrapper(wrapped, this.__chain__);
10205       }
10206       return this.thru(reverse);
10207     }
10208
10209     /**
10210      * Executes the chain sequence to resolve the unwrapped value.
10211      *
10212      * @name value
10213      * @memberOf _
10214      * @since 0.1.0
10215      * @alias toJSON, valueOf
10216      * @category Seq
10217      * @returns {*} Returns the resolved unwrapped value.
10218      * @example
10219      *
10220      * _([1, 2, 3]).value();
10221      * // => [1, 2, 3]
10222      */
10223     function wrapperValue() {
10224       return baseWrapperValue(this.__wrapped__, this.__actions__);
10225     }
10226
10227     /*------------------------------------------------------------------------*/
10228
10229     /**
10230      * Creates an object composed of keys generated from the results of running
10231      * each element of `collection` thru `iteratee`. The corresponding value of
10232      * each key is the number of times the key was returned by `iteratee`. The
10233      * iteratee is invoked with one argument: (value).
10234      *
10235      * @static
10236      * @memberOf _
10237      * @since 0.5.0
10238      * @category Collection
10239      * @param {Array|Object} collection The collection to iterate over.
10240      * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
10241      * @returns {Object} Returns the composed aggregate object.
10242      * @example
10243      *
10244      * _.countBy([6.1, 4.2, 6.3], Math.floor);
10245      * // => { '4': 1, '6': 2 }
10246      *
10247      * // The `_.property` iteratee shorthand.
10248      * _.countBy(['one', 'two', 'three'], 'length');
10249      * // => { '3': 2, '5': 1 }
10250      */
10251     var countBy = createAggregator(function(result, value, key) {
10252       if (hasOwnProperty.call(result, key)) {
10253         ++result[key];
10254       } else {
10255         baseAssignValue(result, key, 1);
10256       }
10257     });
10258
10259     /**
10260      * Checks if `predicate` returns truthy for **all** elements of `collection`.
10261      * Iteration is stopped once `predicate` returns falsey. The predicate is
10262      * invoked with three arguments: (value, index|key, collection).
10263      *
10264      * **Note:** This method returns `true` for
10265      * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
10266      * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
10267      * elements of empty collections.
10268      *
10269      * @static
10270      * @memberOf _
10271      * @since 0.1.0
10272      * @category Collection
10273      * @param {Array|Object} collection The collection to iterate over.
10274      * @param {Function} [predicate=_.identity] The function invoked per iteration.
10275      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10276      * @returns {boolean} Returns `true` if all elements pass the predicate check,
10277      *  else `false`.
10278      * @example
10279      *
10280      * _.every([true, 1, null, 'yes'], Boolean);
10281      * // => false
10282      *
10283      * var users = [
10284      *   { 'user': 'barney', 'age': 36, 'active': false },
10285      *   { 'user': 'fred',   'age': 40, 'active': false }
10286      * ];
10287      *
10288      * // The `_.matches` iteratee shorthand.
10289      * _.every(users, { 'user': 'barney', 'active': false });
10290      * // => false
10291      *
10292      * // The `_.matchesProperty` iteratee shorthand.
10293      * _.every(users, ['active', false]);
10294      * // => true
10295      *
10296      * // The `_.property` iteratee shorthand.
10297      * _.every(users, 'active');
10298      * // => false
10299      */
10300     function every(collection, predicate, guard) {
10301       var func = isArray(collection) ? arrayEvery : baseEvery;
10302       if (guard && isIterateeCall(collection, predicate, guard)) {
10303         predicate = undefined;
10304       }
10305       return func(collection, getIteratee(predicate, 3));
10306     }
10307
10308     /**
10309      * Iterates over elements of `collection`, returning an array of all elements
10310      * `predicate` returns truthy for. The predicate is invoked with three
10311      * arguments: (value, index|key, collection).
10312      *
10313      * **Note:** Unlike `_.remove`, this method returns a new array.
10314      *
10315      * @static
10316      * @memberOf _
10317      * @since 0.1.0
10318      * @category Collection
10319      * @param {Array|Object} collection The collection to iterate over.
10320      * @param {Function} [predicate=_.identity] The function invoked per iteration.
10321      * @returns {Array} Returns the new filtered array.
10322      * @see _.reject
10323      * @example
10324      *
10325      * var users = [
10326      *   { 'user': 'barney', 'age': 36, 'active': true },
10327      *   { 'user': 'fred',   'age': 40, 'active': false }
10328      * ];
10329      *
10330      * _.filter(users, function(o) { return !o.active; });
10331      * // => objects for ['fred']
10332      *
10333      * // The `_.matches` iteratee shorthand.
10334      * _.filter(users, { 'age': 36, 'active': true });
10335      * // => objects for ['barney']
10336      *
10337      * // The `_.matchesProperty` iteratee shorthand.
10338      * _.filter(users, ['active', false]);
10339      * // => objects for ['fred']
10340      *
10341      * // The `_.property` iteratee shorthand.
10342      * _.filter(users, 'active');
10343      * // => objects for ['barney']
10344      *
10345      * // Combining several predicates using `_.overEvery` or `_.overSome`.
10346      * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
10347      * // => objects for ['fred', 'barney']
10348      */
10349     function filter(collection, predicate) {
10350       var func = isArray(collection) ? arrayFilter : baseFilter;
10351       return func(collection, getIteratee(predicate, 3));
10352     }
10353
10354     /**
10355      * Iterates over elements of `collection`, returning the first element
10356      * `predicate` returns truthy for. The predicate is invoked with three
10357      * arguments: (value, index|key, collection).
10358      *
10359      * @static
10360      * @memberOf _
10361      * @since 0.1.0
10362      * @category Collection
10363      * @param {Array|Object} collection The collection to inspect.
10364      * @param {Function} [predicate=_.identity] The function invoked per iteration.
10365      * @param {number} [fromIndex=0] The index to search from.
10366      * @returns {*} Returns the matched element, else `undefined`.
10367      * @example
10368      *
10369      * var users = [
10370      *   { 'user': 'barney',  'age': 36, 'active': true },
10371      *   { 'user': 'fred',    'age': 40, 'active': false },
10372      *   { 'user': 'pebbles', 'age': 1,  'active': true }
10373      * ];
10374      *
10375      * _.find(users, function(o) { return o.age < 40; });
10376      * // => object for 'barney'
10377      *
10378      * // The `_.matches` iteratee shorthand.
10379      * _.find(users, { 'age': 1, 'active': true });
10380      * // => object for 'pebbles'
10381      *
10382      * // The `_.matchesProperty` iteratee shorthand.
10383      * _.find(users, ['active', false]);
10384      * // => object for 'fred'
10385      *
10386      * // The `_.property` iteratee shorthand.
10387      * _.find(users, 'active');
10388      * // => object for 'barney'
10389      */
10390     var find = createFind(findIndex);
10391
10392     /**
10393      * This method is like `_.find` except that it iterates over elements of
10394      * `collection` from right to left.
10395      *
10396      * @static
10397      * @memberOf _
10398      * @since 2.0.0
10399      * @category Collection
10400      * @param {Array|Object} collection The collection to inspect.
10401      * @param {Function} [predicate=_.identity] The function invoked per iteration.
10402      * @param {number} [fromIndex=collection.length-1] The index to search from.
10403      * @returns {*} Returns the matched element, else `undefined`.
10404      * @example
10405      *
10406      * _.findLast([1, 2, 3, 4], function(n) {
10407      *   return n % 2 == 1;
10408      * });
10409      * // => 3
10410      */
10411     var findLast = createFind(findLastIndex);
10412
10413     /**
10414      * Creates a flattened array of values by running each element in `collection`
10415      * thru `iteratee` and flattening the mapped results. The iteratee is invoked
10416      * with three arguments: (value, index|key, collection).
10417      *
10418      * @static
10419      * @memberOf _
10420      * @since 4.0.0
10421      * @category Collection
10422      * @param {Array|Object} collection The collection to iterate over.
10423      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10424      * @returns {Array} Returns the new flattened array.
10425      * @example
10426      *
10427      * function duplicate(n) {
10428      *   return [n, n];
10429      * }
10430      *
10431      * _.flatMap([1, 2], duplicate);
10432      * // => [1, 1, 2, 2]
10433      */
10434     function flatMap(collection, iteratee) {
10435       return baseFlatten(map(collection, iteratee), 1);
10436     }
10437
10438     /**
10439      * This method is like `_.flatMap` except that it recursively flattens the
10440      * mapped results.
10441      *
10442      * @static
10443      * @memberOf _
10444      * @since 4.7.0
10445      * @category Collection
10446      * @param {Array|Object} collection The collection to iterate over.
10447      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10448      * @returns {Array} Returns the new flattened array.
10449      * @example
10450      *
10451      * function duplicate(n) {
10452      *   return [[[n, n]]];
10453      * }
10454      *
10455      * _.flatMapDeep([1, 2], duplicate);
10456      * // => [1, 1, 2, 2]
10457      */
10458     function flatMapDeep(collection, iteratee) {
10459       return baseFlatten(map(collection, iteratee), INFINITY);
10460     }
10461
10462     /**
10463      * This method is like `_.flatMap` except that it recursively flattens the
10464      * mapped results up to `depth` times.
10465      *
10466      * @static
10467      * @memberOf _
10468      * @since 4.7.0
10469      * @category Collection
10470      * @param {Array|Object} collection The collection to iterate over.
10471      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10472      * @param {number} [depth=1] The maximum recursion depth.
10473      * @returns {Array} Returns the new flattened array.
10474      * @example
10475      *
10476      * function duplicate(n) {
10477      *   return [[[n, n]]];
10478      * }
10479      *
10480      * _.flatMapDepth([1, 2], duplicate, 2);
10481      * // => [[1, 1], [2, 2]]
10482      */
10483     function flatMapDepth(collection, iteratee, depth) {
10484       depth = depth === undefined ? 1 : toInteger(depth);
10485       return baseFlatten(map(collection, iteratee), depth);
10486     }
10487
10488     /**
10489      * Iterates over elements of `collection` and invokes `iteratee` for each element.
10490      * The iteratee is invoked with three arguments: (value, index|key, collection).
10491      * Iteratee functions may exit iteration early by explicitly returning `false`.
10492      *
10493      * **Note:** As with other "Collections" methods, objects with a "length"
10494      * property are iterated like arrays. To avoid this behavior use `_.forIn`
10495      * or `_.forOwn` for object iteration.
10496      *
10497      * @static
10498      * @memberOf _
10499      * @since 0.1.0
10500      * @alias each
10501      * @category Collection
10502      * @param {Array|Object} collection The collection to iterate over.
10503      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10504      * @returns {Array|Object} Returns `collection`.
10505      * @see _.forEachRight
10506      * @example
10507      *
10508      * _.forEach([1, 2], function(value) {
10509      *   console.log(value);
10510      * });
10511      * // => Logs `1` then `2`.
10512      *
10513      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
10514      *   console.log(key);
10515      * });
10516      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
10517      */
10518     function forEach(collection, iteratee) {
10519       var func = isArray(collection) ? arrayEach : baseEach;
10520       return func(collection, getIteratee(iteratee, 3));
10521     }
10522
10523     /**
10524      * This method is like `_.forEach` except that it iterates over elements of
10525      * `collection` from right to left.
10526      *
10527      * @static
10528      * @memberOf _
10529      * @since 2.0.0
10530      * @alias eachRight
10531      * @category Collection
10532      * @param {Array|Object} collection The collection to iterate over.
10533      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10534      * @returns {Array|Object} Returns `collection`.
10535      * @see _.forEach
10536      * @example
10537      *
10538      * _.forEachRight([1, 2], function(value) {
10539      *   console.log(value);
10540      * });
10541      * // => Logs `2` then `1`.
10542      */
10543     function forEachRight(collection, iteratee) {
10544       var func = isArray(collection) ? arrayEachRight : baseEachRight;
10545       return func(collection, getIteratee(iteratee, 3));
10546     }
10547
10548     /**
10549      * Creates an object composed of keys generated from the results of running
10550      * each element of `collection` thru `iteratee`. The order of grouped values
10551      * is determined by the order they occur in `collection`. The corresponding
10552      * value of each key is an array of elements responsible for generating the
10553      * key. The iteratee is invoked with one argument: (value).
10554      *
10555      * @static
10556      * @memberOf _
10557      * @since 0.1.0
10558      * @category Collection
10559      * @param {Array|Object} collection The collection to iterate over.
10560      * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
10561      * @returns {Object} Returns the composed aggregate object.
10562      * @example
10563      *
10564      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
10565      * // => { '4': [4.2], '6': [6.1, 6.3] }
10566      *
10567      * // The `_.property` iteratee shorthand.
10568      * _.groupBy(['one', 'two', 'three'], 'length');
10569      * // => { '3': ['one', 'two'], '5': ['three'] }
10570      */
10571     var groupBy = createAggregator(function(result, value, key) {
10572       if (hasOwnProperty.call(result, key)) {
10573         result[key].push(value);
10574       } else {
10575         baseAssignValue(result, key, [value]);
10576       }
10577     });
10578
10579     /**
10580      * Checks if `value` is in `collection`. If `collection` is a string, it's
10581      * checked for a substring of `value`, otherwise
10582      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
10583      * is used for equality comparisons. If `fromIndex` is negative, it's used as
10584      * the offset from the end of `collection`.
10585      *
10586      * @static
10587      * @memberOf _
10588      * @since 0.1.0
10589      * @category Collection
10590      * @param {Array|Object|string} collection The collection to inspect.
10591      * @param {*} value The value to search for.
10592      * @param {number} [fromIndex=0] The index to search from.
10593      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
10594      * @returns {boolean} Returns `true` if `value` is found, else `false`.
10595      * @example
10596      *
10597      * _.includes([1, 2, 3], 1);
10598      * // => true
10599      *
10600      * _.includes([1, 2, 3], 1, 2);
10601      * // => false
10602      *
10603      * _.includes({ 'a': 1, 'b': 2 }, 1);
10604      * // => true
10605      *
10606      * _.includes('abcd', 'bc');
10607      * // => true
10608      */
10609     function includes(collection, value, fromIndex, guard) {
10610       collection = isArrayLike(collection) ? collection : values(collection);
10611       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
10612
10613       var length = collection.length;
10614       if (fromIndex < 0) {
10615         fromIndex = nativeMax(length + fromIndex, 0);
10616       }
10617       return isString(collection)
10618         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
10619         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
10620     }
10621
10622     /**
10623      * Invokes the method at `path` of each element in `collection`, returning
10624      * an array of the results of each invoked method. Any additional arguments
10625      * are provided to each invoked method. If `path` is a function, it's invoked
10626      * for, and `this` bound to, each element in `collection`.
10627      *
10628      * @static
10629      * @memberOf _
10630      * @since 4.0.0
10631      * @category Collection
10632      * @param {Array|Object} collection The collection to iterate over.
10633      * @param {Array|Function|string} path The path of the method to invoke or
10634      *  the function invoked per iteration.
10635      * @param {...*} [args] The arguments to invoke each method with.
10636      * @returns {Array} Returns the array of results.
10637      * @example
10638      *
10639      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
10640      * // => [[1, 5, 7], [1, 2, 3]]
10641      *
10642      * _.invokeMap([123, 456], String.prototype.split, '');
10643      * // => [['1', '2', '3'], ['4', '5', '6']]
10644      */
10645     var invokeMap = baseRest(function(collection, path, args) {
10646       var index = -1,
10647           isFunc = typeof path == 'function',
10648           result = isArrayLike(collection) ? Array(collection.length) : [];
10649
10650       baseEach(collection, function(value) {
10651         result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
10652       });
10653       return result;
10654     });
10655
10656     /**
10657      * Creates an object composed of keys generated from the results of running
10658      * each element of `collection` thru `iteratee`. The corresponding value of
10659      * each key is the last element responsible for generating the key. The
10660      * iteratee is invoked with one argument: (value).
10661      *
10662      * @static
10663      * @memberOf _
10664      * @since 4.0.0
10665      * @category Collection
10666      * @param {Array|Object} collection The collection to iterate over.
10667      * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
10668      * @returns {Object} Returns the composed aggregate object.
10669      * @example
10670      *
10671      * var array = [
10672      *   { 'dir': 'left', 'code': 97 },
10673      *   { 'dir': 'right', 'code': 100 }
10674      * ];
10675      *
10676      * _.keyBy(array, function(o) {
10677      *   return String.fromCharCode(o.code);
10678      * });
10679      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
10680      *
10681      * _.keyBy(array, 'dir');
10682      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
10683      */
10684     var keyBy = createAggregator(function(result, value, key) {
10685       baseAssignValue(result, key, value);
10686     });
10687
10688     /**
10689      * Creates an array of values by running each element in `collection` thru
10690      * `iteratee`. The iteratee is invoked with three arguments:
10691      * (value, index|key, collection).
10692      *
10693      * Many lodash methods are guarded to work as iteratees for methods like
10694      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
10695      *
10696      * The guarded methods are:
10697      * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
10698      * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
10699      * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
10700      * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
10701      *
10702      * @static
10703      * @memberOf _
10704      * @since 0.1.0
10705      * @category Collection
10706      * @param {Array|Object} collection The collection to iterate over.
10707      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10708      * @returns {Array} Returns the new mapped array.
10709      * @example
10710      *
10711      * function square(n) {
10712      *   return n * n;
10713      * }
10714      *
10715      * _.map([4, 8], square);
10716      * // => [16, 64]
10717      *
10718      * _.map({ 'a': 4, 'b': 8 }, square);
10719      * // => [16, 64] (iteration order is not guaranteed)
10720      *
10721      * var users = [
10722      *   { 'user': 'barney' },
10723      *   { 'user': 'fred' }
10724      * ];
10725      *
10726      * // The `_.property` iteratee shorthand.
10727      * _.map(users, 'user');
10728      * // => ['barney', 'fred']
10729      */
10730     function map(collection, iteratee) {
10731       var func = isArray(collection) ? arrayMap : baseMap;
10732       return func(collection, getIteratee(iteratee, 3));
10733     }
10734
10735     /**
10736      * This method is like `_.sortBy` except that it allows specifying the sort
10737      * orders of the iteratees to sort by. If `orders` is unspecified, all values
10738      * are sorted in ascending order. Otherwise, specify an order of "desc" for
10739      * descending or "asc" for ascending sort order of corresponding values.
10740      *
10741      * @static
10742      * @memberOf _
10743      * @since 4.0.0
10744      * @category Collection
10745      * @param {Array|Object} collection The collection to iterate over.
10746      * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
10747      *  The iteratees to sort by.
10748      * @param {string[]} [orders] The sort orders of `iteratees`.
10749      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
10750      * @returns {Array} Returns the new sorted array.
10751      * @example
10752      *
10753      * var users = [
10754      *   { 'user': 'fred',   'age': 48 },
10755      *   { 'user': 'barney', 'age': 34 },
10756      *   { 'user': 'fred',   'age': 40 },
10757      *   { 'user': 'barney', 'age': 36 }
10758      * ];
10759      *
10760      * // Sort by `user` in ascending order and by `age` in descending order.
10761      * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
10762      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
10763      */
10764     function orderBy(collection, iteratees, orders, guard) {
10765       if (collection == null) {
10766         return [];
10767       }
10768       if (!isArray(iteratees)) {
10769         iteratees = iteratees == null ? [] : [iteratees];
10770       }
10771       orders = guard ? undefined : orders;
10772       if (!isArray(orders)) {
10773         orders = orders == null ? [] : [orders];
10774       }
10775       return baseOrderBy(collection, iteratees, orders);
10776     }
10777
10778     /**
10779      * Creates an array of elements split into two groups, the first of which
10780      * contains elements `predicate` returns truthy for, the second of which
10781      * contains elements `predicate` returns falsey for. The predicate is
10782      * invoked with one argument: (value).
10783      *
10784      * @static
10785      * @memberOf _
10786      * @since 3.0.0
10787      * @category Collection
10788      * @param {Array|Object} collection The collection to iterate over.
10789      * @param {Function} [predicate=_.identity] The function invoked per iteration.
10790      * @returns {Array} Returns the array of grouped elements.
10791      * @example
10792      *
10793      * var users = [
10794      *   { 'user': 'barney',  'age': 36, 'active': false },
10795      *   { 'user': 'fred',    'age': 40, 'active': true },
10796      *   { 'user': 'pebbles', 'age': 1,  'active': false }
10797      * ];
10798      *
10799      * _.partition(users, function(o) { return o.active; });
10800      * // => objects for [['fred'], ['barney', 'pebbles']]
10801      *
10802      * // The `_.matches` iteratee shorthand.
10803      * _.partition(users, { 'age': 1, 'active': false });
10804      * // => objects for [['pebbles'], ['barney', 'fred']]
10805      *
10806      * // The `_.matchesProperty` iteratee shorthand.
10807      * _.partition(users, ['active', false]);
10808      * // => objects for [['barney', 'pebbles'], ['fred']]
10809      *
10810      * // The `_.property` iteratee shorthand.
10811      * _.partition(users, 'active');
10812      * // => objects for [['fred'], ['barney', 'pebbles']]
10813      */
10814     var partition = createAggregator(function(result, value, key) {
10815       result[key ? 0 : 1].push(value);
10816     }, function() { return [[], []]; });
10817
10818     /**
10819      * Reduces `collection` to a value which is the accumulated result of running
10820      * each element in `collection` thru `iteratee`, where each successive
10821      * invocation is supplied the return value of the previous. If `accumulator`
10822      * is not given, the first element of `collection` is used as the initial
10823      * value. The iteratee is invoked with four arguments:
10824      * (accumulator, value, index|key, collection).
10825      *
10826      * Many lodash methods are guarded to work as iteratees for methods like
10827      * `_.reduce`, `_.reduceRight`, and `_.transform`.
10828      *
10829      * The guarded methods are:
10830      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
10831      * and `sortBy`
10832      *
10833      * @static
10834      * @memberOf _
10835      * @since 0.1.0
10836      * @category Collection
10837      * @param {Array|Object} collection The collection to iterate over.
10838      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10839      * @param {*} [accumulator] The initial value.
10840      * @returns {*} Returns the accumulated value.
10841      * @see _.reduceRight
10842      * @example
10843      *
10844      * _.reduce([1, 2], function(sum, n) {
10845      *   return sum + n;
10846      * }, 0);
10847      * // => 3
10848      *
10849      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
10850      *   (result[value] || (result[value] = [])).push(key);
10851      *   return result;
10852      * }, {});
10853      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
10854      */
10855     function reduce(collection, iteratee, accumulator) {
10856       var func = isArray(collection) ? arrayReduce : baseReduce,
10857           initAccum = arguments.length < 3;
10858
10859       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
10860     }
10861
10862     /**
10863      * This method is like `_.reduce` except that it iterates over elements of
10864      * `collection` from right to left.
10865      *
10866      * @static
10867      * @memberOf _
10868      * @since 0.1.0
10869      * @category Collection
10870      * @param {Array|Object} collection The collection to iterate over.
10871      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10872      * @param {*} [accumulator] The initial value.
10873      * @returns {*} Returns the accumulated value.
10874      * @see _.reduce
10875      * @example
10876      *
10877      * var array = [[0, 1], [2, 3], [4, 5]];
10878      *
10879      * _.reduceRight(array, function(flattened, other) {
10880      *   return flattened.concat(other);
10881      * }, []);
10882      * // => [4, 5, 2, 3, 0, 1]
10883      */
10884     function reduceRight(collection, iteratee, accumulator) {
10885       var func = isArray(collection) ? arrayReduceRight : baseReduce,
10886           initAccum = arguments.length < 3;
10887
10888       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
10889     }
10890
10891     /**
10892      * The opposite of `_.filter`; this method returns the elements of `collection`
10893      * that `predicate` does **not** return truthy for.
10894      *
10895      * @static
10896      * @memberOf _
10897      * @since 0.1.0
10898      * @category Collection
10899      * @param {Array|Object} collection The collection to iterate over.
10900      * @param {Function} [predicate=_.identity] The function invoked per iteration.
10901      * @returns {Array} Returns the new filtered array.
10902      * @see _.filter
10903      * @example
10904      *
10905      * var users = [
10906      *   { 'user': 'barney', 'age': 36, 'active': false },
10907      *   { 'user': 'fred',   'age': 40, 'active': true }
10908      * ];
10909      *
10910      * _.reject(users, function(o) { return !o.active; });
10911      * // => objects for ['fred']
10912      *
10913      * // The `_.matches` iteratee shorthand.
10914      * _.reject(users, { 'age': 40, 'active': true });
10915      * // => objects for ['barney']
10916      *
10917      * // The `_.matchesProperty` iteratee shorthand.
10918      * _.reject(users, ['active', false]);
10919      * // => objects for ['fred']
10920      *
10921      * // The `_.property` iteratee shorthand.
10922      * _.reject(users, 'active');
10923      * // => objects for ['barney']
10924      */
10925     function reject(collection, predicate) {
10926       var func = isArray(collection) ? arrayFilter : baseFilter;
10927       return func(collection, negate(getIteratee(predicate, 3)));
10928     }
10929
10930     /**
10931      * Gets a random element from `collection`.
10932      *
10933      * @static
10934      * @memberOf _
10935      * @since 2.0.0
10936      * @category Collection
10937      * @param {Array|Object} collection The collection to sample.
10938      * @returns {*} Returns the random element.
10939      * @example
10940      *
10941      * _.sample([1, 2, 3, 4]);
10942      * // => 2
10943      */
10944     function sample(collection) {
10945       var func = isArray(collection) ? arraySample : baseSample;
10946       return func(collection);
10947     }
10948
10949     /**
10950      * Gets `n` random elements at unique keys from `collection` up to the
10951      * size of `collection`.
10952      *
10953      * @static
10954      * @memberOf _
10955      * @since 4.0.0
10956      * @category Collection
10957      * @param {Array|Object} collection The collection to sample.
10958      * @param {number} [n=1] The number of elements to sample.
10959      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10960      * @returns {Array} Returns the random elements.
10961      * @example
10962      *
10963      * _.sampleSize([1, 2, 3], 2);
10964      * // => [3, 1]
10965      *
10966      * _.sampleSize([1, 2, 3], 4);
10967      * // => [2, 3, 1]
10968      */
10969     function sampleSize(collection, n, guard) {
10970       if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
10971         n = 1;
10972       } else {
10973         n = toInteger(n);
10974       }
10975       var func = isArray(collection) ? arraySampleSize : baseSampleSize;
10976       return func(collection, n);
10977     }
10978
10979     /**
10980      * Creates an array of shuffled values, using a version of the
10981      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
10982      *
10983      * @static
10984      * @memberOf _
10985      * @since 0.1.0
10986      * @category Collection
10987      * @param {Array|Object} collection The collection to shuffle.
10988      * @returns {Array} Returns the new shuffled array.
10989      * @example
10990      *
10991      * _.shuffle([1, 2, 3, 4]);
10992      * // => [4, 1, 3, 2]
10993      */
10994     function shuffle(collection) {
10995       var func = isArray(collection) ? arrayShuffle : baseShuffle;
10996       return func(collection);
10997     }
10998
10999     /**
11000      * Gets the size of `collection` by returning its length for array-like
11001      * values or the number of own enumerable string keyed properties for objects.
11002      *
11003      * @static
11004      * @memberOf _
11005      * @since 0.1.0
11006      * @category Collection
11007      * @param {Array|Object|string} collection The collection to inspect.
11008      * @returns {number} Returns the collection size.
11009      * @example
11010      *
11011      * _.size([1, 2, 3]);
11012      * // => 3
11013      *
11014      * _.size({ 'a': 1, 'b': 2 });
11015      * // => 2
11016      *
11017      * _.size('pebbles');
11018      * // => 7
11019      */
11020     function size(collection) {
11021       if (collection == null) {
11022         return 0;
11023       }
11024       if (isArrayLike(collection)) {
11025         return isString(collection) ? stringSize(collection) : collection.length;
11026       }
11027       var tag = getTag(collection);
11028       if (tag == mapTag || tag == setTag) {
11029         return collection.size;
11030       }
11031       return baseKeys(collection).length;
11032     }
11033
11034     /**
11035      * Checks if `predicate` returns truthy for **any** element of `collection`.
11036      * Iteration is stopped once `predicate` returns truthy. The predicate is
11037      * invoked with three arguments: (value, index|key, collection).
11038      *
11039      * @static
11040      * @memberOf _
11041      * @since 0.1.0
11042      * @category Collection
11043      * @param {Array|Object} collection The collection to iterate over.
11044      * @param {Function} [predicate=_.identity] The function invoked per iteration.
11045      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
11046      * @returns {boolean} Returns `true` if any element passes the predicate check,
11047      *  else `false`.
11048      * @example
11049      *
11050      * _.some([null, 0, 'yes', false], Boolean);
11051      * // => true
11052      *
11053      * var users = [
11054      *   { 'user': 'barney', 'active': true },
11055      *   { 'user': 'fred',   'active': false }
11056      * ];
11057      *
11058      * // The `_.matches` iteratee shorthand.
11059      * _.some(users, { 'user': 'barney', 'active': false });
11060      * // => false
11061      *
11062      * // The `_.matchesProperty` iteratee shorthand.
11063      * _.some(users, ['active', false]);
11064      * // => true
11065      *
11066      * // The `_.property` iteratee shorthand.
11067      * _.some(users, 'active');
11068      * // => true
11069      */
11070     function some(collection, predicate, guard) {
11071       var func = isArray(collection) ? arraySome : baseSome;
11072       if (guard && isIterateeCall(collection, predicate, guard)) {
11073         predicate = undefined;
11074       }
11075       return func(collection, getIteratee(predicate, 3));
11076     }
11077
11078     /**
11079      * Creates an array of elements, sorted in ascending order by the results of
11080      * running each element in a collection thru each iteratee. This method
11081      * performs a stable sort, that is, it preserves the original sort order of
11082      * equal elements. The iteratees are invoked with one argument: (value).
11083      *
11084      * @static
11085      * @memberOf _
11086      * @since 0.1.0
11087      * @category Collection
11088      * @param {Array|Object} collection The collection to iterate over.
11089      * @param {...(Function|Function[])} [iteratees=[_.identity]]
11090      *  The iteratees to sort by.
11091      * @returns {Array} Returns the new sorted array.
11092      * @example
11093      *
11094      * var users = [
11095      *   { 'user': 'fred',   'age': 48 },
11096      *   { 'user': 'barney', 'age': 36 },
11097      *   { 'user': 'fred',   'age': 30 },
11098      *   { 'user': 'barney', 'age': 34 }
11099      * ];
11100      *
11101      * _.sortBy(users, [function(o) { return o.user; }]);
11102      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
11103      *
11104      * _.sortBy(users, ['user', 'age']);
11105      * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
11106      */
11107     var sortBy = baseRest(function(collection, iteratees) {
11108       if (collection == null) {
11109         return [];
11110       }
11111       var length = iteratees.length;
11112       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
11113         iteratees = [];
11114       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
11115         iteratees = [iteratees[0]];
11116       }
11117       return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
11118     });
11119
11120     /*------------------------------------------------------------------------*/
11121
11122     /**
11123      * Gets the timestamp of the number of milliseconds that have elapsed since
11124      * the Unix epoch (1 January 1970 00:00:00 UTC).
11125      *
11126      * @static
11127      * @memberOf _
11128      * @since 2.4.0
11129      * @category Date
11130      * @returns {number} Returns the timestamp.
11131      * @example
11132      *
11133      * _.defer(function(stamp) {
11134      *   console.log(_.now() - stamp);
11135      * }, _.now());
11136      * // => Logs the number of milliseconds it took for the deferred invocation.
11137      */
11138     var now = ctxNow || function() {
11139       return root.Date.now();
11140     };
11141
11142     /*------------------------------------------------------------------------*/
11143
11144     /**
11145      * The opposite of `_.before`; this method creates a function that invokes
11146      * `func` once it's called `n` or more times.
11147      *
11148      * @static
11149      * @memberOf _
11150      * @since 0.1.0
11151      * @category Function
11152      * @param {number} n The number of calls before `func` is invoked.
11153      * @param {Function} func The function to restrict.
11154      * @returns {Function} Returns the new restricted function.
11155      * @example
11156      *
11157      * var saves = ['profile', 'settings'];
11158      *
11159      * var done = _.after(saves.length, function() {
11160      *   console.log('done saving!');
11161      * });
11162      *
11163      * _.forEach(saves, function(type) {
11164      *   asyncSave({ 'type': type, 'complete': done });
11165      * });
11166      * // => Logs 'done saving!' after the two async saves have completed.
11167      */
11168     function after(n, func) {
11169       if (typeof func != 'function') {
11170         throw new TypeError(FUNC_ERROR_TEXT);
11171       }
11172       n = toInteger(n);
11173       return function() {
11174         if (--n < 1) {
11175           return func.apply(this, arguments);
11176         }
11177       };
11178     }
11179
11180     /**
11181      * Creates a function that invokes `func`, with up to `n` arguments,
11182      * ignoring any additional arguments.
11183      *
11184      * @static
11185      * @memberOf _
11186      * @since 3.0.0
11187      * @category Function
11188      * @param {Function} func The function to cap arguments for.
11189      * @param {number} [n=func.length] The arity cap.
11190      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
11191      * @returns {Function} Returns the new capped function.
11192      * @example
11193      *
11194      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
11195      * // => [6, 8, 10]
11196      */
11197     function ary(func, n, guard) {
11198       n = guard ? undefined : n;
11199       n = (func && n == null) ? func.length : n;
11200       return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
11201     }
11202
11203     /**
11204      * Creates a function that invokes `func`, with the `this` binding and arguments
11205      * of the created function, while it's called less than `n` times. Subsequent
11206      * calls to the created function return the result of the last `func` invocation.
11207      *
11208      * @static
11209      * @memberOf _
11210      * @since 3.0.0
11211      * @category Function
11212      * @param {number} n The number of calls at which `func` is no longer invoked.
11213      * @param {Function} func The function to restrict.
11214      * @returns {Function} Returns the new restricted function.
11215      * @example
11216      *
11217      * jQuery(element).on('click', _.before(5, addContactToList));
11218      * // => Allows adding up to 4 contacts to the list.
11219      */
11220     function before(n, func) {
11221       var result;
11222       if (typeof func != 'function') {
11223         throw new TypeError(FUNC_ERROR_TEXT);
11224       }
11225       n = toInteger(n);
11226       return function() {
11227         if (--n > 0) {
11228           result = func.apply(this, arguments);
11229         }
11230         if (n <= 1) {
11231           func = undefined;
11232         }
11233         return result;
11234       };
11235     }
11236
11237     /**
11238      * Creates a function that invokes `func` with the `this` binding of `thisArg`
11239      * and `partials` prepended to the arguments it receives.
11240      *
11241      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
11242      * may be used as a placeholder for partially applied arguments.
11243      *
11244      * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
11245      * property of bound functions.
11246      *
11247      * @static
11248      * @memberOf _
11249      * @since 0.1.0
11250      * @category Function
11251      * @param {Function} func The function to bind.
11252      * @param {*} thisArg The `this` binding of `func`.
11253      * @param {...*} [partials] The arguments to be partially applied.
11254      * @returns {Function} Returns the new bound function.
11255      * @example
11256      *
11257      * function greet(greeting, punctuation) {
11258      *   return greeting + ' ' + this.user + punctuation;
11259      * }
11260      *
11261      * var object = { 'user': 'fred' };
11262      *
11263      * var bound = _.bind(greet, object, 'hi');
11264      * bound('!');
11265      * // => 'hi fred!'
11266      *
11267      * // Bound with placeholders.
11268      * var bound = _.bind(greet, object, _, '!');
11269      * bound('hi');
11270      * // => 'hi fred!'
11271      */
11272     var bind = baseRest(function(func, thisArg, partials) {
11273       var bitmask = WRAP_BIND_FLAG;
11274       if (partials.length) {
11275         var holders = replaceHolders(partials, getHolder(bind));
11276         bitmask |= WRAP_PARTIAL_FLAG;
11277       }
11278       return createWrap(func, bitmask, thisArg, partials, holders);
11279     });
11280
11281     /**
11282      * Creates a function that invokes the method at `object[key]` with `partials`
11283      * prepended to the arguments it receives.
11284      *
11285      * This method differs from `_.bind` by allowing bound functions to reference
11286      * methods that may be redefined or don't yet exist. See
11287      * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
11288      * for more details.
11289      *
11290      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
11291      * builds, may be used as a placeholder for partially applied arguments.
11292      *
11293      * @static
11294      * @memberOf _
11295      * @since 0.10.0
11296      * @category Function
11297      * @param {Object} object The object to invoke the method on.
11298      * @param {string} key The key of the method.
11299      * @param {...*} [partials] The arguments to be partially applied.
11300      * @returns {Function} Returns the new bound function.
11301      * @example
11302      *
11303      * var object = {
11304      *   'user': 'fred',
11305      *   'greet': function(greeting, punctuation) {
11306      *     return greeting + ' ' + this.user + punctuation;
11307      *   }
11308      * };
11309      *
11310      * var bound = _.bindKey(object, 'greet', 'hi');
11311      * bound('!');
11312      * // => 'hi fred!'
11313      *
11314      * object.greet = function(greeting, punctuation) {
11315      *   return greeting + 'ya ' + this.user + punctuation;
11316      * };
11317      *
11318      * bound('!');
11319      * // => 'hiya fred!'
11320      *
11321      * // Bound with placeholders.
11322      * var bound = _.bindKey(object, 'greet', _, '!');
11323      * bound('hi');
11324      * // => 'hiya fred!'
11325      */
11326     var bindKey = baseRest(function(object, key, partials) {
11327       var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
11328       if (partials.length) {
11329         var holders = replaceHolders(partials, getHolder(bindKey));
11330         bitmask |= WRAP_PARTIAL_FLAG;
11331       }
11332       return createWrap(key, bitmask, object, partials, holders);
11333     });
11334
11335     /**
11336      * Creates a function that accepts arguments of `func` and either invokes
11337      * `func` returning its result, if at least `arity` number of arguments have
11338      * been provided, or returns a function that accepts the remaining `func`
11339      * arguments, and so on. The arity of `func` may be specified if `func.length`
11340      * is not sufficient.
11341      *
11342      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
11343      * may be used as a placeholder for provided arguments.
11344      *
11345      * **Note:** This method doesn't set the "length" property of curried functions.
11346      *
11347      * @static
11348      * @memberOf _
11349      * @since 2.0.0
11350      * @category Function
11351      * @param {Function} func The function to curry.
11352      * @param {number} [arity=func.length] The arity of `func`.
11353      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
11354      * @returns {Function} Returns the new curried function.
11355      * @example
11356      *
11357      * var abc = function(a, b, c) {
11358      *   return [a, b, c];
11359      * };
11360      *
11361      * var curried = _.curry(abc);
11362      *
11363      * curried(1)(2)(3);
11364      * // => [1, 2, 3]
11365      *
11366      * curried(1, 2)(3);
11367      * // => [1, 2, 3]
11368      *
11369      * curried(1, 2, 3);
11370      * // => [1, 2, 3]
11371      *
11372      * // Curried with placeholders.
11373      * curried(1)(_, 3)(2);
11374      * // => [1, 2, 3]
11375      */
11376     function curry(func, arity, guard) {
11377       arity = guard ? undefined : arity;
11378       var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
11379       result.placeholder = curry.placeholder;
11380       return result;
11381     }
11382
11383     /**
11384      * This method is like `_.curry` except that arguments are applied to `func`
11385      * in the manner of `_.partialRight` instead of `_.partial`.
11386      *
11387      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
11388      * builds, may be used as a placeholder for provided arguments.
11389      *
11390      * **Note:** This method doesn't set the "length" property of curried functions.
11391      *
11392      * @static
11393      * @memberOf _
11394      * @since 3.0.0
11395      * @category Function
11396      * @param {Function} func The function to curry.
11397      * @param {number} [arity=func.length] The arity of `func`.
11398      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
11399      * @returns {Function} Returns the new curried function.
11400      * @example
11401      *
11402      * var abc = function(a, b, c) {
11403      *   return [a, b, c];
11404      * };
11405      *
11406      * var curried = _.curryRight(abc);
11407      *
11408      * curried(3)(2)(1);
11409      * // => [1, 2, 3]
11410      *
11411      * curried(2, 3)(1);
11412      * // => [1, 2, 3]
11413      *
11414      * curried(1, 2, 3);
11415      * // => [1, 2, 3]
11416      *
11417      * // Curried with placeholders.
11418      * curried(3)(1, _)(2);
11419      * // => [1, 2, 3]
11420      */
11421     function curryRight(func, arity, guard) {
11422       arity = guard ? undefined : arity;
11423       var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
11424       result.placeholder = curryRight.placeholder;
11425       return result;
11426     }
11427
11428     /**
11429      * Creates a debounced function that delays invoking `func` until after `wait`
11430      * milliseconds have elapsed since the last time the debounced function was
11431      * invoked. The debounced function comes with a `cancel` method to cancel
11432      * delayed `func` invocations and a `flush` method to immediately invoke them.
11433      * Provide `options` to indicate whether `func` should be invoked on the
11434      * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
11435      * with the last arguments provided to the debounced function. Subsequent
11436      * calls to the debounced function return the result of the last `func`
11437      * invocation.
11438      *
11439      * **Note:** If `leading` and `trailing` options are `true`, `func` is
11440      * invoked on the trailing edge of the timeout only if the debounced function
11441      * is invoked more than once during the `wait` timeout.
11442      *
11443      * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
11444      * until to the next tick, similar to `setTimeout` with a timeout of `0`.
11445      *
11446      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
11447      * for details over the differences between `_.debounce` and `_.throttle`.
11448      *
11449      * @static
11450      * @memberOf _
11451      * @since 0.1.0
11452      * @category Function
11453      * @param {Function} func The function to debounce.
11454      * @param {number} [wait=0] The number of milliseconds to delay.
11455      * @param {Object} [options={}] The options object.
11456      * @param {boolean} [options.leading=false]
11457      *  Specify invoking on the leading edge of the timeout.
11458      * @param {number} [options.maxWait]
11459      *  The maximum time `func` is allowed to be delayed before it's invoked.
11460      * @param {boolean} [options.trailing=true]
11461      *  Specify invoking on the trailing edge of the timeout.
11462      * @returns {Function} Returns the new debounced function.
11463      * @example
11464      *
11465      * // Avoid costly calculations while the window size is in flux.
11466      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
11467      *
11468      * // Invoke `sendMail` when clicked, debouncing subsequent calls.
11469      * jQuery(element).on('click', _.debounce(sendMail, 300, {
11470      *   'leading': true,
11471      *   'trailing': false
11472      * }));
11473      *
11474      * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
11475      * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
11476      * var source = new EventSource('/stream');
11477      * jQuery(source).on('message', debounced);
11478      *
11479      * // Cancel the trailing debounced invocation.
11480      * jQuery(window).on('popstate', debounced.cancel);
11481      */
11482     function debounce(func, wait, options) {
11483       var lastArgs,
11484           lastThis,
11485           maxWait,
11486           result,
11487           timerId,
11488           lastCallTime,
11489           lastInvokeTime = 0,
11490           leading = false,
11491           maxing = false,
11492           trailing = true;
11493
11494       if (typeof func != 'function') {
11495         throw new TypeError(FUNC_ERROR_TEXT);
11496       }
11497       wait = toNumber(wait) || 0;
11498       if (isObject(options)) {
11499         leading = !!options.leading;
11500         maxing = 'maxWait' in options;
11501         maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
11502         trailing = 'trailing' in options ? !!options.trailing : trailing;
11503       }
11504
11505       function invokeFunc(time) {
11506         var args = lastArgs,
11507             thisArg = lastThis;
11508
11509         lastArgs = lastThis = undefined;
11510         lastInvokeTime = time;
11511         result = func.apply(thisArg, args);
11512         return result;
11513       }
11514
11515       function leadingEdge(time) {
11516         // Reset any `maxWait` timer.
11517         lastInvokeTime = time;
11518         // Start the timer for the trailing edge.
11519         timerId = setTimeout(timerExpired, wait);
11520         // Invoke the leading edge.
11521         return leading ? invokeFunc(time) : result;
11522       }
11523
11524       function remainingWait(time) {
11525         var timeSinceLastCall = time - lastCallTime,
11526             timeSinceLastInvoke = time - lastInvokeTime,
11527             timeWaiting = wait - timeSinceLastCall;
11528
11529         return maxing
11530           ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
11531           : timeWaiting;
11532       }
11533
11534       function shouldInvoke(time) {
11535         var timeSinceLastCall = time - lastCallTime,
11536             timeSinceLastInvoke = time - lastInvokeTime;
11537
11538         // Either this is the first call, activity has stopped and we're at the
11539         // trailing edge, the system time has gone backwards and we're treating
11540         // it as the trailing edge, or we've hit the `maxWait` limit.
11541         return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
11542           (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
11543       }
11544
11545       function timerExpired() {
11546         var time = now();
11547         if (shouldInvoke(time)) {
11548           return trailingEdge(time);
11549         }
11550         // Restart the timer.
11551         timerId = setTimeout(timerExpired, remainingWait(time));
11552       }
11553
11554       function trailingEdge(time) {
11555         timerId = undefined;
11556
11557         // Only invoke if we have `lastArgs` which means `func` has been
11558         // debounced at least once.
11559         if (trailing && lastArgs) {
11560           return invokeFunc(time);
11561         }
11562         lastArgs = lastThis = undefined;
11563         return result;
11564       }
11565
11566       function cancel() {
11567         if (timerId !== undefined) {
11568           clearTimeout(timerId);
11569         }
11570         lastInvokeTime = 0;
11571         lastArgs = lastCallTime = lastThis = timerId = undefined;
11572       }
11573
11574       function flush() {
11575         return timerId === undefined ? result : trailingEdge(now());
11576       }
11577
11578       function debounced() {
11579         var time = now(),
11580             isInvoking = shouldInvoke(time);
11581
11582         lastArgs = arguments;
11583         lastThis = this;
11584         lastCallTime = time;
11585
11586         if (isInvoking) {
11587           if (timerId === undefined) {
11588             return leadingEdge(lastCallTime);
11589           }
11590           if (maxing) {
11591             // Handle invocations in a tight loop.
11592             clearTimeout(timerId);
11593             timerId = setTimeout(timerExpired, wait);
11594             return invokeFunc(lastCallTime);
11595           }
11596         }
11597         if (timerId === undefined) {
11598           timerId = setTimeout(timerExpired, wait);
11599         }
11600         return result;
11601       }
11602       debounced.cancel = cancel;
11603       debounced.flush = flush;
11604       return debounced;
11605     }
11606
11607     /**
11608      * Defers invoking the `func` until the current call stack has cleared. Any
11609      * additional arguments are provided to `func` when it's invoked.
11610      *
11611      * @static
11612      * @memberOf _
11613      * @since 0.1.0
11614      * @category Function
11615      * @param {Function} func The function to defer.
11616      * @param {...*} [args] The arguments to invoke `func` with.
11617      * @returns {number} Returns the timer id.
11618      * @example
11619      *
11620      * _.defer(function(text) {
11621      *   console.log(text);
11622      * }, 'deferred');
11623      * // => Logs 'deferred' after one millisecond.
11624      */
11625     var defer = baseRest(function(func, args) {
11626       return baseDelay(func, 1, args);
11627     });
11628
11629     /**
11630      * Invokes `func` after `wait` milliseconds. Any additional arguments are
11631      * provided to `func` when it's invoked.
11632      *
11633      * @static
11634      * @memberOf _
11635      * @since 0.1.0
11636      * @category Function
11637      * @param {Function} func The function to delay.
11638      * @param {number} wait The number of milliseconds to delay invocation.
11639      * @param {...*} [args] The arguments to invoke `func` with.
11640      * @returns {number} Returns the timer id.
11641      * @example
11642      *
11643      * _.delay(function(text) {
11644      *   console.log(text);
11645      * }, 1000, 'later');
11646      * // => Logs 'later' after one second.
11647      */
11648     var delay = baseRest(function(func, wait, args) {
11649       return baseDelay(func, toNumber(wait) || 0, args);
11650     });
11651
11652     /**
11653      * Creates a function that invokes `func` with arguments reversed.
11654      *
11655      * @static
11656      * @memberOf _
11657      * @since 4.0.0
11658      * @category Function
11659      * @param {Function} func The function to flip arguments for.
11660      * @returns {Function} Returns the new flipped function.
11661      * @example
11662      *
11663      * var flipped = _.flip(function() {
11664      *   return _.toArray(arguments);
11665      * });
11666      *
11667      * flipped('a', 'b', 'c', 'd');
11668      * // => ['d', 'c', 'b', 'a']
11669      */
11670     function flip(func) {
11671       return createWrap(func, WRAP_FLIP_FLAG);
11672     }
11673
11674     /**
11675      * Creates a function that memoizes the result of `func`. If `resolver` is
11676      * provided, it determines the cache key for storing the result based on the
11677      * arguments provided to the memoized function. By default, the first argument
11678      * provided to the memoized function is used as the map cache key. The `func`
11679      * is invoked with the `this` binding of the memoized function.
11680      *
11681      * **Note:** The cache is exposed as the `cache` property on the memoized
11682      * function. Its creation may be customized by replacing the `_.memoize.Cache`
11683      * constructor with one whose instances implement the
11684      * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
11685      * method interface of `clear`, `delete`, `get`, `has`, and `set`.
11686      *
11687      * @static
11688      * @memberOf _
11689      * @since 0.1.0
11690      * @category Function
11691      * @param {Function} func The function to have its output memoized.
11692      * @param {Function} [resolver] The function to resolve the cache key.
11693      * @returns {Function} Returns the new memoized function.
11694      * @example
11695      *
11696      * var object = { 'a': 1, 'b': 2 };
11697      * var other = { 'c': 3, 'd': 4 };
11698      *
11699      * var values = _.memoize(_.values);
11700      * values(object);
11701      * // => [1, 2]
11702      *
11703      * values(other);
11704      * // => [3, 4]
11705      *
11706      * object.a = 2;
11707      * values(object);
11708      * // => [1, 2]
11709      *
11710      * // Modify the result cache.
11711      * values.cache.set(object, ['a', 'b']);
11712      * values(object);
11713      * // => ['a', 'b']
11714      *
11715      * // Replace `_.memoize.Cache`.
11716      * _.memoize.Cache = WeakMap;
11717      */
11718     function memoize(func, resolver) {
11719       if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
11720         throw new TypeError(FUNC_ERROR_TEXT);
11721       }
11722       var memoized = function() {
11723         var args = arguments,
11724             key = resolver ? resolver.apply(this, args) : args[0],
11725             cache = memoized.cache;
11726
11727         if (cache.has(key)) {
11728           return cache.get(key);
11729         }
11730         var result = func.apply(this, args);
11731         memoized.cache = cache.set(key, result) || cache;
11732         return result;
11733       };
11734       memoized.cache = new (memoize.Cache || MapCache);
11735       return memoized;
11736     }
11737
11738     // Expose `MapCache`.
11739     memoize.Cache = MapCache;
11740
11741     /**
11742      * Creates a function that negates the result of the predicate `func`. The
11743      * `func` predicate is invoked with the `this` binding and arguments of the
11744      * created function.
11745      *
11746      * @static
11747      * @memberOf _
11748      * @since 3.0.0
11749      * @category Function
11750      * @param {Function} predicate The predicate to negate.
11751      * @returns {Function} Returns the new negated function.
11752      * @example
11753      *
11754      * function isEven(n) {
11755      *   return n % 2 == 0;
11756      * }
11757      *
11758      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
11759      * // => [1, 3, 5]
11760      */
11761     function negate(predicate) {
11762       if (typeof predicate != 'function') {
11763         throw new TypeError(FUNC_ERROR_TEXT);
11764       }
11765       return function() {
11766         var args = arguments;
11767         switch (args.length) {
11768           case 0: return !predicate.call(this);
11769           case 1: return !predicate.call(this, args[0]);
11770           case 2: return !predicate.call(this, args[0], args[1]);
11771           case 3: return !predicate.call(this, args[0], args[1], args[2]);
11772         }
11773         return !predicate.apply(this, args);
11774       };
11775     }
11776
11777     /**
11778      * Creates a function that is restricted to invoking `func` once. Repeat calls
11779      * to the function return the value of the first invocation. The `func` is
11780      * invoked with the `this` binding and arguments of the created function.
11781      *
11782      * @static
11783      * @memberOf _
11784      * @since 0.1.0
11785      * @category Function
11786      * @param {Function} func The function to restrict.
11787      * @returns {Function} Returns the new restricted function.
11788      * @example
11789      *
11790      * var initialize = _.once(createApplication);
11791      * initialize();
11792      * initialize();
11793      * // => `createApplication` is invoked once
11794      */
11795     function once(func) {
11796       return before(2, func);
11797     }
11798
11799     /**
11800      * Creates a function that invokes `func` with its arguments transformed.
11801      *
11802      * @static
11803      * @since 4.0.0
11804      * @memberOf _
11805      * @category Function
11806      * @param {Function} func The function to wrap.
11807      * @param {...(Function|Function[])} [transforms=[_.identity]]
11808      *  The argument transforms.
11809      * @returns {Function} Returns the new function.
11810      * @example
11811      *
11812      * function doubled(n) {
11813      *   return n * 2;
11814      * }
11815      *
11816      * function square(n) {
11817      *   return n * n;
11818      * }
11819      *
11820      * var func = _.overArgs(function(x, y) {
11821      *   return [x, y];
11822      * }, [square, doubled]);
11823      *
11824      * func(9, 3);
11825      * // => [81, 6]
11826      *
11827      * func(10, 5);
11828      * // => [100, 10]
11829      */
11830     var overArgs = castRest(function(func, transforms) {
11831       transforms = (transforms.length == 1 && isArray(transforms[0]))
11832         ? arrayMap(transforms[0], baseUnary(getIteratee()))
11833         : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
11834
11835       var funcsLength = transforms.length;
11836       return baseRest(function(args) {
11837         var index = -1,
11838             length = nativeMin(args.length, funcsLength);
11839
11840         while (++index < length) {
11841           args[index] = transforms[index].call(this, args[index]);
11842         }
11843         return apply(func, this, args);
11844       });
11845     });
11846
11847     /**
11848      * Creates a function that invokes `func` with `partials` prepended to the
11849      * arguments it receives. This method is like `_.bind` except it does **not**
11850      * alter the `this` binding.
11851      *
11852      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
11853      * builds, may be used as a placeholder for partially applied arguments.
11854      *
11855      * **Note:** This method doesn't set the "length" property of partially
11856      * applied functions.
11857      *
11858      * @static
11859      * @memberOf _
11860      * @since 0.2.0
11861      * @category Function
11862      * @param {Function} func The function to partially apply arguments to.
11863      * @param {...*} [partials] The arguments to be partially applied.
11864      * @returns {Function} Returns the new partially applied function.
11865      * @example
11866      *
11867      * function greet(greeting, name) {
11868      *   return greeting + ' ' + name;
11869      * }
11870      *
11871      * var sayHelloTo = _.partial(greet, 'hello');
11872      * sayHelloTo('fred');
11873      * // => 'hello fred'
11874      *
11875      * // Partially applied with placeholders.
11876      * var greetFred = _.partial(greet, _, 'fred');
11877      * greetFred('hi');
11878      * // => 'hi fred'
11879      */
11880     var partial = baseRest(function(func, partials) {
11881       var holders = replaceHolders(partials, getHolder(partial));
11882       return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
11883     });
11884
11885     /**
11886      * This method is like `_.partial` except that partially applied arguments
11887      * are appended to the arguments it receives.
11888      *
11889      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
11890      * builds, may be used as a placeholder for partially applied arguments.
11891      *
11892      * **Note:** This method doesn't set the "length" property of partially
11893      * applied functions.
11894      *
11895      * @static
11896      * @memberOf _
11897      * @since 1.0.0
11898      * @category Function
11899      * @param {Function} func The function to partially apply arguments to.
11900      * @param {...*} [partials] The arguments to be partially applied.
11901      * @returns {Function} Returns the new partially applied function.
11902      * @example
11903      *
11904      * function greet(greeting, name) {
11905      *   return greeting + ' ' + name;
11906      * }
11907      *
11908      * var greetFred = _.partialRight(greet, 'fred');
11909      * greetFred('hi');
11910      * // => 'hi fred'
11911      *
11912      * // Partially applied with placeholders.
11913      * var sayHelloTo = _.partialRight(greet, 'hello', _);
11914      * sayHelloTo('fred');
11915      * // => 'hello fred'
11916      */
11917     var partialRight = baseRest(function(func, partials) {
11918       var holders = replaceHolders(partials, getHolder(partialRight));
11919       return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
11920     });
11921
11922     /**
11923      * Creates a function that invokes `func` with arguments arranged according
11924      * to the specified `indexes` where the argument value at the first index is
11925      * provided as the first argument, the argument value at the second index is
11926      * provided as the second argument, and so on.
11927      *
11928      * @static
11929      * @memberOf _
11930      * @since 3.0.0
11931      * @category Function
11932      * @param {Function} func The function to rearrange arguments for.
11933      * @param {...(number|number[])} indexes The arranged argument indexes.
11934      * @returns {Function} Returns the new function.
11935      * @example
11936      *
11937      * var rearged = _.rearg(function(a, b, c) {
11938      *   return [a, b, c];
11939      * }, [2, 0, 1]);
11940      *
11941      * rearged('b', 'c', 'a')
11942      * // => ['a', 'b', 'c']
11943      */
11944     var rearg = flatRest(function(func, indexes) {
11945       return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
11946     });
11947
11948     /**
11949      * Creates a function that invokes `func` with the `this` binding of the
11950      * created function and arguments from `start` and beyond provided as
11951      * an array.
11952      *
11953      * **Note:** This method is based on the
11954      * [rest parameter](https://mdn.io/rest_parameters).
11955      *
11956      * @static
11957      * @memberOf _
11958      * @since 4.0.0
11959      * @category Function
11960      * @param {Function} func The function to apply a rest parameter to.
11961      * @param {number} [start=func.length-1] The start position of the rest parameter.
11962      * @returns {Function} Returns the new function.
11963      * @example
11964      *
11965      * var say = _.rest(function(what, names) {
11966      *   return what + ' ' + _.initial(names).join(', ') +
11967      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
11968      * });
11969      *
11970      * say('hello', 'fred', 'barney', 'pebbles');
11971      * // => 'hello fred, barney, & pebbles'
11972      */
11973     function rest(func, start) {
11974       if (typeof func != 'function') {
11975         throw new TypeError(FUNC_ERROR_TEXT);
11976       }
11977       start = start === undefined ? start : toInteger(start);
11978       return baseRest(func, start);
11979     }
11980
11981     /**
11982      * Creates a function that invokes `func` with the `this` binding of the
11983      * create function and an array of arguments much like
11984      * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
11985      *
11986      * **Note:** This method is based on the
11987      * [spread operator](https://mdn.io/spread_operator).
11988      *
11989      * @static
11990      * @memberOf _
11991      * @since 3.2.0
11992      * @category Function
11993      * @param {Function} func The function to spread arguments over.
11994      * @param {number} [start=0] The start position of the spread.
11995      * @returns {Function} Returns the new function.
11996      * @example
11997      *
11998      * var say = _.spread(function(who, what) {
11999      *   return who + ' says ' + what;
12000      * });
12001      *
12002      * say(['fred', 'hello']);
12003      * // => 'fred says hello'
12004      *
12005      * var numbers = Promise.all([
12006      *   Promise.resolve(40),
12007      *   Promise.resolve(36)
12008      * ]);
12009      *
12010      * numbers.then(_.spread(function(x, y) {
12011      *   return x + y;
12012      * }));
12013      * // => a Promise of 76
12014      */
12015     function spread(func, start) {
12016       if (typeof func != 'function') {
12017         throw new TypeError(FUNC_ERROR_TEXT);
12018       }
12019       start = start == null ? 0 : nativeMax(toInteger(start), 0);
12020       return baseRest(function(args) {
12021         var array = args[start],
12022             otherArgs = castSlice(args, 0, start);
12023
12024         if (array) {
12025           arrayPush(otherArgs, array);
12026         }
12027         return apply(func, this, otherArgs);
12028       });
12029     }
12030
12031     /**
12032      * Creates a throttled function that only invokes `func` at most once per
12033      * every `wait` milliseconds. The throttled function comes with a `cancel`
12034      * method to cancel delayed `func` invocations and a `flush` method to
12035      * immediately invoke them. Provide `options` to indicate whether `func`
12036      * should be invoked on the leading and/or trailing edge of the `wait`
12037      * timeout. The `func` is invoked with the last arguments provided to the
12038      * throttled function. Subsequent calls to the throttled function return the
12039      * result of the last `func` invocation.
12040      *
12041      * **Note:** If `leading` and `trailing` options are `true`, `func` is
12042      * invoked on the trailing edge of the timeout only if the throttled function
12043      * is invoked more than once during the `wait` timeout.
12044      *
12045      * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
12046      * until to the next tick, similar to `setTimeout` with a timeout of `0`.
12047      *
12048      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
12049      * for details over the differences between `_.throttle` and `_.debounce`.
12050      *
12051      * @static
12052      * @memberOf _
12053      * @since 0.1.0
12054      * @category Function
12055      * @param {Function} func The function to throttle.
12056      * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
12057      * @param {Object} [options={}] The options object.
12058      * @param {boolean} [options.leading=true]
12059      *  Specify invoking on the leading edge of the timeout.
12060      * @param {boolean} [options.trailing=true]
12061      *  Specify invoking on the trailing edge of the timeout.
12062      * @returns {Function} Returns the new throttled function.
12063      * @example
12064      *
12065      * // Avoid excessively updating the position while scrolling.
12066      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
12067      *
12068      * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
12069      * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
12070      * jQuery(element).on('click', throttled);
12071      *
12072      * // Cancel the trailing throttled invocation.
12073      * jQuery(window).on('popstate', throttled.cancel);
12074      */
12075     function throttle(func, wait, options) {
12076       var leading = true,
12077           trailing = true;
12078
12079       if (typeof func != 'function') {
12080         throw new TypeError(FUNC_ERROR_TEXT);
12081       }
12082       if (isObject(options)) {
12083         leading = 'leading' in options ? !!options.leading : leading;
12084         trailing = 'trailing' in options ? !!options.trailing : trailing;
12085       }
12086       return debounce(func, wait, {
12087         'leading': leading,
12088         'maxWait': wait,
12089         'trailing': trailing
12090       });
12091     }
12092
12093     /**
12094      * Creates a function that accepts up to one argument, ignoring any
12095      * additional arguments.
12096      *
12097      * @static
12098      * @memberOf _
12099      * @since 4.0.0
12100      * @category Function
12101      * @param {Function} func The function to cap arguments for.
12102      * @returns {Function} Returns the new capped function.
12103      * @example
12104      *
12105      * _.map(['6', '8', '10'], _.unary(parseInt));
12106      * // => [6, 8, 10]
12107      */
12108     function unary(func) {
12109       return ary(func, 1);
12110     }
12111
12112     /**
12113      * Creates a function that provides `value` to `wrapper` as its first
12114      * argument. Any additional arguments provided to the function are appended
12115      * to those provided to the `wrapper`. The wrapper is invoked with the `this`
12116      * binding of the created function.
12117      *
12118      * @static
12119      * @memberOf _
12120      * @since 0.1.0
12121      * @category Function
12122      * @param {*} value The value to wrap.
12123      * @param {Function} [wrapper=identity] The wrapper function.
12124      * @returns {Function} Returns the new function.
12125      * @example
12126      *
12127      * var p = _.wrap(_.escape, function(func, text) {
12128      *   return '<p>' + func(text) + '</p>';
12129      * });
12130      *
12131      * p('fred, barney, & pebbles');
12132      * // => '<p>fred, barney, &amp; pebbles</p>'
12133      */
12134     function wrap(value, wrapper) {
12135       return partial(castFunction(wrapper), value);
12136     }
12137
12138     /*------------------------------------------------------------------------*/
12139
12140     /**
12141      * Casts `value` as an array if it's not one.
12142      *
12143      * @static
12144      * @memberOf _
12145      * @since 4.4.0
12146      * @category Lang
12147      * @param {*} value The value to inspect.
12148      * @returns {Array} Returns the cast array.
12149      * @example
12150      *
12151      * _.castArray(1);
12152      * // => [1]
12153      *
12154      * _.castArray({ 'a': 1 });
12155      * // => [{ 'a': 1 }]
12156      *
12157      * _.castArray('abc');
12158      * // => ['abc']
12159      *
12160      * _.castArray(null);
12161      * // => [null]
12162      *
12163      * _.castArray(undefined);
12164      * // => [undefined]
12165      *
12166      * _.castArray();
12167      * // => []
12168      *
12169      * var array = [1, 2, 3];
12170      * console.log(_.castArray(array) === array);
12171      * // => true
12172      */
12173     function castArray() {
12174       if (!arguments.length) {
12175         return [];
12176       }
12177       var value = arguments[0];
12178       return isArray(value) ? value : [value];
12179     }
12180
12181     /**
12182      * Creates a shallow clone of `value`.
12183      *
12184      * **Note:** This method is loosely based on the
12185      * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
12186      * and supports cloning arrays, array buffers, booleans, date objects, maps,
12187      * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
12188      * arrays. The own enumerable properties of `arguments` objects are cloned
12189      * as plain objects. An empty object is returned for uncloneable values such
12190      * as error objects, functions, DOM nodes, and WeakMaps.
12191      *
12192      * @static
12193      * @memberOf _
12194      * @since 0.1.0
12195      * @category Lang
12196      * @param {*} value The value to clone.
12197      * @returns {*} Returns the cloned value.
12198      * @see _.cloneDeep
12199      * @example
12200      *
12201      * var objects = [{ 'a': 1 }, { 'b': 2 }];
12202      *
12203      * var shallow = _.clone(objects);
12204      * console.log(shallow[0] === objects[0]);
12205      * // => true
12206      */
12207     function clone(value) {
12208       return baseClone(value, CLONE_SYMBOLS_FLAG);
12209     }
12210
12211     /**
12212      * This method is like `_.clone` except that it accepts `customizer` which
12213      * is invoked to produce the cloned value. If `customizer` returns `undefined`,
12214      * cloning is handled by the method instead. The `customizer` is invoked with
12215      * up to four arguments; (value [, index|key, object, stack]).
12216      *
12217      * @static
12218      * @memberOf _
12219      * @since 4.0.0
12220      * @category Lang
12221      * @param {*} value The value to clone.
12222      * @param {Function} [customizer] The function to customize cloning.
12223      * @returns {*} Returns the cloned value.
12224      * @see _.cloneDeepWith
12225      * @example
12226      *
12227      * function customizer(value) {
12228      *   if (_.isElement(value)) {
12229      *     return value.cloneNode(false);
12230      *   }
12231      * }
12232      *
12233      * var el = _.cloneWith(document.body, customizer);
12234      *
12235      * console.log(el === document.body);
12236      * // => false
12237      * console.log(el.nodeName);
12238      * // => 'BODY'
12239      * console.log(el.childNodes.length);
12240      * // => 0
12241      */
12242     function cloneWith(value, customizer) {
12243       customizer = typeof customizer == 'function' ? customizer : undefined;
12244       return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
12245     }
12246
12247     /**
12248      * This method is like `_.clone` except that it recursively clones `value`.
12249      *
12250      * @static
12251      * @memberOf _
12252      * @since 1.0.0
12253      * @category Lang
12254      * @param {*} value The value to recursively clone.
12255      * @returns {*} Returns the deep cloned value.
12256      * @see _.clone
12257      * @example
12258      *
12259      * var objects = [{ 'a': 1 }, { 'b': 2 }];
12260      *
12261      * var deep = _.cloneDeep(objects);
12262      * console.log(deep[0] === objects[0]);
12263      * // => false
12264      */
12265     function cloneDeep(value) {
12266       return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
12267     }
12268
12269     /**
12270      * This method is like `_.cloneWith` except that it recursively clones `value`.
12271      *
12272      * @static
12273      * @memberOf _
12274      * @since 4.0.0
12275      * @category Lang
12276      * @param {*} value The value to recursively clone.
12277      * @param {Function} [customizer] The function to customize cloning.
12278      * @returns {*} Returns the deep cloned value.
12279      * @see _.cloneWith
12280      * @example
12281      *
12282      * function customizer(value) {
12283      *   if (_.isElement(value)) {
12284      *     return value.cloneNode(true);
12285      *   }
12286      * }
12287      *
12288      * var el = _.cloneDeepWith(document.body, customizer);
12289      *
12290      * console.log(el === document.body);
12291      * // => false
12292      * console.log(el.nodeName);
12293      * // => 'BODY'
12294      * console.log(el.childNodes.length);
12295      * // => 20
12296      */
12297     function cloneDeepWith(value, customizer) {
12298       customizer = typeof customizer == 'function' ? customizer : undefined;
12299       return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
12300     }
12301
12302     /**
12303      * Checks if `object` conforms to `source` by invoking the predicate
12304      * properties of `source` with the corresponding property values of `object`.
12305      *
12306      * **Note:** This method is equivalent to `_.conforms` when `source` is
12307      * partially applied.
12308      *
12309      * @static
12310      * @memberOf _
12311      * @since 4.14.0
12312      * @category Lang
12313      * @param {Object} object The object to inspect.
12314      * @param {Object} source The object of property predicates to conform to.
12315      * @returns {boolean} Returns `true` if `object` conforms, else `false`.
12316      * @example
12317      *
12318      * var object = { 'a': 1, 'b': 2 };
12319      *
12320      * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
12321      * // => true
12322      *
12323      * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
12324      * // => false
12325      */
12326     function conformsTo(object, source) {
12327       return source == null || baseConformsTo(object, source, keys(source));
12328     }
12329
12330     /**
12331      * Performs a
12332      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
12333      * comparison between two values to determine if they are equivalent.
12334      *
12335      * @static
12336      * @memberOf _
12337      * @since 4.0.0
12338      * @category Lang
12339      * @param {*} value The value to compare.
12340      * @param {*} other The other value to compare.
12341      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
12342      * @example
12343      *
12344      * var object = { 'a': 1 };
12345      * var other = { 'a': 1 };
12346      *
12347      * _.eq(object, object);
12348      * // => true
12349      *
12350      * _.eq(object, other);
12351      * // => false
12352      *
12353      * _.eq('a', 'a');
12354      * // => true
12355      *
12356      * _.eq('a', Object('a'));
12357      * // => false
12358      *
12359      * _.eq(NaN, NaN);
12360      * // => true
12361      */
12362     function eq(value, other) {
12363       return value === other || (value !== value && other !== other);
12364     }
12365
12366     /**
12367      * Checks if `value` is greater than `other`.
12368      *
12369      * @static
12370      * @memberOf _
12371      * @since 3.9.0
12372      * @category Lang
12373      * @param {*} value The value to compare.
12374      * @param {*} other The other value to compare.
12375      * @returns {boolean} Returns `true` if `value` is greater than `other`,
12376      *  else `false`.
12377      * @see _.lt
12378      * @example
12379      *
12380      * _.gt(3, 1);
12381      * // => true
12382      *
12383      * _.gt(3, 3);
12384      * // => false
12385      *
12386      * _.gt(1, 3);
12387      * // => false
12388      */
12389     var gt = createRelationalOperation(baseGt);
12390
12391     /**
12392      * Checks if `value` is greater than or equal to `other`.
12393      *
12394      * @static
12395      * @memberOf _
12396      * @since 3.9.0
12397      * @category Lang
12398      * @param {*} value The value to compare.
12399      * @param {*} other The other value to compare.
12400      * @returns {boolean} Returns `true` if `value` is greater than or equal to
12401      *  `other`, else `false`.
12402      * @see _.lte
12403      * @example
12404      *
12405      * _.gte(3, 1);
12406      * // => true
12407      *
12408      * _.gte(3, 3);
12409      * // => true
12410      *
12411      * _.gte(1, 3);
12412      * // => false
12413      */
12414     var gte = createRelationalOperation(function(value, other) {
12415       return value >= other;
12416     });
12417
12418     /**
12419      * Checks if `value` is likely an `arguments` object.
12420      *
12421      * @static
12422      * @memberOf _
12423      * @since 0.1.0
12424      * @category Lang
12425      * @param {*} value The value to check.
12426      * @returns {boolean} Returns `true` if `value` is an `arguments` object,
12427      *  else `false`.
12428      * @example
12429      *
12430      * _.isArguments(function() { return arguments; }());
12431      * // => true
12432      *
12433      * _.isArguments([1, 2, 3]);
12434      * // => false
12435      */
12436     var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
12437       return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
12438         !propertyIsEnumerable.call(value, 'callee');
12439     };
12440
12441     /**
12442      * Checks if `value` is classified as an `Array` object.
12443      *
12444      * @static
12445      * @memberOf _
12446      * @since 0.1.0
12447      * @category Lang
12448      * @param {*} value The value to check.
12449      * @returns {boolean} Returns `true` if `value` is an array, else `false`.
12450      * @example
12451      *
12452      * _.isArray([1, 2, 3]);
12453      * // => true
12454      *
12455      * _.isArray(document.body.children);
12456      * // => false
12457      *
12458      * _.isArray('abc');
12459      * // => false
12460      *
12461      * _.isArray(_.noop);
12462      * // => false
12463      */
12464     var isArray = Array.isArray;
12465
12466     /**
12467      * Checks if `value` is classified as an `ArrayBuffer` object.
12468      *
12469      * @static
12470      * @memberOf _
12471      * @since 4.3.0
12472      * @category Lang
12473      * @param {*} value The value to check.
12474      * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
12475      * @example
12476      *
12477      * _.isArrayBuffer(new ArrayBuffer(2));
12478      * // => true
12479      *
12480      * _.isArrayBuffer(new Array(2));
12481      * // => false
12482      */
12483     var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
12484
12485     /**
12486      * Checks if `value` is array-like. A value is considered array-like if it's
12487      * not a function and has a `value.length` that's an integer greater than or
12488      * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
12489      *
12490      * @static
12491      * @memberOf _
12492      * @since 4.0.0
12493      * @category Lang
12494      * @param {*} value The value to check.
12495      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
12496      * @example
12497      *
12498      * _.isArrayLike([1, 2, 3]);
12499      * // => true
12500      *
12501      * _.isArrayLike(document.body.children);
12502      * // => true
12503      *
12504      * _.isArrayLike('abc');
12505      * // => true
12506      *
12507      * _.isArrayLike(_.noop);
12508      * // => false
12509      */
12510     function isArrayLike(value) {
12511       return value != null && isLength(value.length) && !isFunction(value);
12512     }
12513
12514     /**
12515      * This method is like `_.isArrayLike` except that it also checks if `value`
12516      * is an object.
12517      *
12518      * @static
12519      * @memberOf _
12520      * @since 4.0.0
12521      * @category Lang
12522      * @param {*} value The value to check.
12523      * @returns {boolean} Returns `true` if `value` is an array-like object,
12524      *  else `false`.
12525      * @example
12526      *
12527      * _.isArrayLikeObject([1, 2, 3]);
12528      * // => true
12529      *
12530      * _.isArrayLikeObject(document.body.children);
12531      * // => true
12532      *
12533      * _.isArrayLikeObject('abc');
12534      * // => false
12535      *
12536      * _.isArrayLikeObject(_.noop);
12537      * // => false
12538      */
12539     function isArrayLikeObject(value) {
12540       return isObjectLike(value) && isArrayLike(value);
12541     }
12542
12543     /**
12544      * Checks if `value` is classified as a boolean primitive or object.
12545      *
12546      * @static
12547      * @memberOf _
12548      * @since 0.1.0
12549      * @category Lang
12550      * @param {*} value The value to check.
12551      * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
12552      * @example
12553      *
12554      * _.isBoolean(false);
12555      * // => true
12556      *
12557      * _.isBoolean(null);
12558      * // => false
12559      */
12560     function isBoolean(value) {
12561       return value === true || value === false ||
12562         (isObjectLike(value) && baseGetTag(value) == boolTag);
12563     }
12564
12565     /**
12566      * Checks if `value` is a buffer.
12567      *
12568      * @static
12569      * @memberOf _
12570      * @since 4.3.0
12571      * @category Lang
12572      * @param {*} value The value to check.
12573      * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
12574      * @example
12575      *
12576      * _.isBuffer(new Buffer(2));
12577      * // => true
12578      *
12579      * _.isBuffer(new Uint8Array(2));
12580      * // => false
12581      */
12582     var isBuffer = nativeIsBuffer || stubFalse;
12583
12584     /**
12585      * Checks if `value` is classified as a `Date` object.
12586      *
12587      * @static
12588      * @memberOf _
12589      * @since 0.1.0
12590      * @category Lang
12591      * @param {*} value The value to check.
12592      * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
12593      * @example
12594      *
12595      * _.isDate(new Date);
12596      * // => true
12597      *
12598      * _.isDate('Mon April 23 2012');
12599      * // => false
12600      */
12601     var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
12602
12603     /**
12604      * Checks if `value` is likely a DOM element.
12605      *
12606      * @static
12607      * @memberOf _
12608      * @since 0.1.0
12609      * @category Lang
12610      * @param {*} value The value to check.
12611      * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
12612      * @example
12613      *
12614      * _.isElement(document.body);
12615      * // => true
12616      *
12617      * _.isElement('<body>');
12618      * // => false
12619      */
12620     function isElement(value) {
12621       return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
12622     }
12623
12624     /**
12625      * Checks if `value` is an empty object, collection, map, or set.
12626      *
12627      * Objects are considered empty if they have no own enumerable string keyed
12628      * properties.
12629      *
12630      * Array-like values such as `arguments` objects, arrays, buffers, strings, or
12631      * jQuery-like collections are considered empty if they have a `length` of `0`.
12632      * Similarly, maps and sets are considered empty if they have a `size` of `0`.
12633      *
12634      * @static
12635      * @memberOf _
12636      * @since 0.1.0
12637      * @category Lang
12638      * @param {*} value The value to check.
12639      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
12640      * @example
12641      *
12642      * _.isEmpty(null);
12643      * // => true
12644      *
12645      * _.isEmpty(true);
12646      * // => true
12647      *
12648      * _.isEmpty(1);
12649      * // => true
12650      *
12651      * _.isEmpty([1, 2, 3]);
12652      * // => false
12653      *
12654      * _.isEmpty({ 'a': 1 });
12655      * // => false
12656      */
12657     function isEmpty(value) {
12658       if (value == null) {
12659         return true;
12660       }
12661       if (isArrayLike(value) &&
12662           (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
12663             isBuffer(value) || isTypedArray(value) || isArguments(value))) {
12664         return !value.length;
12665       }
12666       var tag = getTag(value);
12667       if (tag == mapTag || tag == setTag) {
12668         return !value.size;
12669       }
12670       if (isPrototype(value)) {
12671         return !baseKeys(value).length;
12672       }
12673       for (var key in value) {
12674         if (hasOwnProperty.call(value, key)) {
12675           return false;
12676         }
12677       }
12678       return true;
12679     }
12680
12681     /**
12682      * Performs a deep comparison between two values to determine if they are
12683      * equivalent.
12684      *
12685      * **Note:** This method supports comparing arrays, array buffers, booleans,
12686      * date objects, error objects, maps, numbers, `Object` objects, regexes,
12687      * sets, strings, symbols, and typed arrays. `Object` objects are compared
12688      * by their own, not inherited, enumerable properties. Functions and DOM
12689      * nodes are compared by strict equality, i.e. `===`.
12690      *
12691      * @static
12692      * @memberOf _
12693      * @since 0.1.0
12694      * @category Lang
12695      * @param {*} value The value to compare.
12696      * @param {*} other The other value to compare.
12697      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
12698      * @example
12699      *
12700      * var object = { 'a': 1 };
12701      * var other = { 'a': 1 };
12702      *
12703      * _.isEqual(object, other);
12704      * // => true
12705      *
12706      * object === other;
12707      * // => false
12708      */
12709     function isEqual(value, other) {
12710       return baseIsEqual(value, other);
12711     }
12712
12713     /**
12714      * This method is like `_.isEqual` except that it accepts `customizer` which
12715      * is invoked to compare values. If `customizer` returns `undefined`, comparisons
12716      * are handled by the method instead. The `customizer` is invoked with up to
12717      * six arguments: (objValue, othValue [, index|key, object, other, stack]).
12718      *
12719      * @static
12720      * @memberOf _
12721      * @since 4.0.0
12722      * @category Lang
12723      * @param {*} value The value to compare.
12724      * @param {*} other The other value to compare.
12725      * @param {Function} [customizer] The function to customize comparisons.
12726      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
12727      * @example
12728      *
12729      * function isGreeting(value) {
12730      *   return /^h(?:i|ello)$/.test(value);
12731      * }
12732      *
12733      * function customizer(objValue, othValue) {
12734      *   if (isGreeting(objValue) && isGreeting(othValue)) {
12735      *     return true;
12736      *   }
12737      * }
12738      *
12739      * var array = ['hello', 'goodbye'];
12740      * var other = ['hi', 'goodbye'];
12741      *
12742      * _.isEqualWith(array, other, customizer);
12743      * // => true
12744      */
12745     function isEqualWith(value, other, customizer) {
12746       customizer = typeof customizer == 'function' ? customizer : undefined;
12747       var result = customizer ? customizer(value, other) : undefined;
12748       return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
12749     }
12750
12751     /**
12752      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
12753      * `SyntaxError`, `TypeError`, or `URIError` object.
12754      *
12755      * @static
12756      * @memberOf _
12757      * @since 3.0.0
12758      * @category Lang
12759      * @param {*} value The value to check.
12760      * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
12761      * @example
12762      *
12763      * _.isError(new Error);
12764      * // => true
12765      *
12766      * _.isError(Error);
12767      * // => false
12768      */
12769     function isError(value) {
12770       if (!isObjectLike(value)) {
12771         return false;
12772       }
12773       var tag = baseGetTag(value);
12774       return tag == errorTag || tag == domExcTag ||
12775         (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
12776     }
12777
12778     /**
12779      * Checks if `value` is a finite primitive number.
12780      *
12781      * **Note:** This method is based on
12782      * [`Number.isFinite`](https://mdn.io/Number/isFinite).
12783      *
12784      * @static
12785      * @memberOf _
12786      * @since 0.1.0
12787      * @category Lang
12788      * @param {*} value The value to check.
12789      * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
12790      * @example
12791      *
12792      * _.isFinite(3);
12793      * // => true
12794      *
12795      * _.isFinite(Number.MIN_VALUE);
12796      * // => true
12797      *
12798      * _.isFinite(Infinity);
12799      * // => false
12800      *
12801      * _.isFinite('3');
12802      * // => false
12803      */
12804     function isFinite(value) {
12805       return typeof value == 'number' && nativeIsFinite(value);
12806     }
12807
12808     /**
12809      * Checks if `value` is classified as a `Function` object.
12810      *
12811      * @static
12812      * @memberOf _
12813      * @since 0.1.0
12814      * @category Lang
12815      * @param {*} value The value to check.
12816      * @returns {boolean} Returns `true` if `value` is a function, else `false`.
12817      * @example
12818      *
12819      * _.isFunction(_);
12820      * // => true
12821      *
12822      * _.isFunction(/abc/);
12823      * // => false
12824      */
12825     function isFunction(value) {
12826       if (!isObject(value)) {
12827         return false;
12828       }
12829       // The use of `Object#toString` avoids issues with the `typeof` operator
12830       // in Safari 9 which returns 'object' for typed arrays and other constructors.
12831       var tag = baseGetTag(value);
12832       return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
12833     }
12834
12835     /**
12836      * Checks if `value` is an integer.
12837      *
12838      * **Note:** This method is based on
12839      * [`Number.isInteger`](https://mdn.io/Number/isInteger).
12840      *
12841      * @static
12842      * @memberOf _
12843      * @since 4.0.0
12844      * @category Lang
12845      * @param {*} value The value to check.
12846      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
12847      * @example
12848      *
12849      * _.isInteger(3);
12850      * // => true
12851      *
12852      * _.isInteger(Number.MIN_VALUE);
12853      * // => false
12854      *
12855      * _.isInteger(Infinity);
12856      * // => false
12857      *
12858      * _.isInteger('3');
12859      * // => false
12860      */
12861     function isInteger(value) {
12862       return typeof value == 'number' && value == toInteger(value);
12863     }
12864
12865     /**
12866      * Checks if `value` is a valid array-like length.
12867      *
12868      * **Note:** This method is loosely based on
12869      * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
12870      *
12871      * @static
12872      * @memberOf _
12873      * @since 4.0.0
12874      * @category Lang
12875      * @param {*} value The value to check.
12876      * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
12877      * @example
12878      *
12879      * _.isLength(3);
12880      * // => true
12881      *
12882      * _.isLength(Number.MIN_VALUE);
12883      * // => false
12884      *
12885      * _.isLength(Infinity);
12886      * // => false
12887      *
12888      * _.isLength('3');
12889      * // => false
12890      */
12891     function isLength(value) {
12892       return typeof value == 'number' &&
12893         value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
12894     }
12895
12896     /**
12897      * Checks if `value` is the
12898      * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
12899      * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
12900      *
12901      * @static
12902      * @memberOf _
12903      * @since 0.1.0
12904      * @category Lang
12905      * @param {*} value The value to check.
12906      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
12907      * @example
12908      *
12909      * _.isObject({});
12910      * // => true
12911      *
12912      * _.isObject([1, 2, 3]);
12913      * // => true
12914      *
12915      * _.isObject(_.noop);
12916      * // => true
12917      *
12918      * _.isObject(null);
12919      * // => false
12920      */
12921     function isObject(value) {
12922       var type = typeof value;
12923       return value != null && (type == 'object' || type == 'function');
12924     }
12925
12926     /**
12927      * Checks if `value` is object-like. A value is object-like if it's not `null`
12928      * and has a `typeof` result of "object".
12929      *
12930      * @static
12931      * @memberOf _
12932      * @since 4.0.0
12933      * @category Lang
12934      * @param {*} value The value to check.
12935      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
12936      * @example
12937      *
12938      * _.isObjectLike({});
12939      * // => true
12940      *
12941      * _.isObjectLike([1, 2, 3]);
12942      * // => true
12943      *
12944      * _.isObjectLike(_.noop);
12945      * // => false
12946      *
12947      * _.isObjectLike(null);
12948      * // => false
12949      */
12950     function isObjectLike(value) {
12951       return value != null && typeof value == 'object';
12952     }
12953
12954     /**
12955      * Checks if `value` is classified as a `Map` object.
12956      *
12957      * @static
12958      * @memberOf _
12959      * @since 4.3.0
12960      * @category Lang
12961      * @param {*} value The value to check.
12962      * @returns {boolean} Returns `true` if `value` is a map, else `false`.
12963      * @example
12964      *
12965      * _.isMap(new Map);
12966      * // => true
12967      *
12968      * _.isMap(new WeakMap);
12969      * // => false
12970      */
12971     var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
12972
12973     /**
12974      * Performs a partial deep comparison between `object` and `source` to
12975      * determine if `object` contains equivalent property values.
12976      *
12977      * **Note:** This method is equivalent to `_.matches` when `source` is
12978      * partially applied.
12979      *
12980      * Partial comparisons will match empty array and empty object `source`
12981      * values against any array or object value, respectively. See `_.isEqual`
12982      * for a list of supported value comparisons.
12983      *
12984      * @static
12985      * @memberOf _
12986      * @since 3.0.0
12987      * @category Lang
12988      * @param {Object} object The object to inspect.
12989      * @param {Object} source The object of property values to match.
12990      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
12991      * @example
12992      *
12993      * var object = { 'a': 1, 'b': 2 };
12994      *
12995      * _.isMatch(object, { 'b': 2 });
12996      * // => true
12997      *
12998      * _.isMatch(object, { 'b': 1 });
12999      * // => false
13000      */
13001     function isMatch(object, source) {
13002       return object === source || baseIsMatch(object, source, getMatchData(source));
13003     }
13004
13005     /**
13006      * This method is like `_.isMatch` except that it accepts `customizer` which
13007      * is invoked to compare values. If `customizer` returns `undefined`, comparisons
13008      * are handled by the method instead. The `customizer` is invoked with five
13009      * arguments: (objValue, srcValue, index|key, object, source).
13010      *
13011      * @static
13012      * @memberOf _
13013      * @since 4.0.0
13014      * @category Lang
13015      * @param {Object} object The object to inspect.
13016      * @param {Object} source The object of property values to match.
13017      * @param {Function} [customizer] The function to customize comparisons.
13018      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
13019      * @example
13020      *
13021      * function isGreeting(value) {
13022      *   return /^h(?:i|ello)$/.test(value);
13023      * }
13024      *
13025      * function customizer(objValue, srcValue) {
13026      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
13027      *     return true;
13028      *   }
13029      * }
13030      *
13031      * var object = { 'greeting': 'hello' };
13032      * var source = { 'greeting': 'hi' };
13033      *
13034      * _.isMatchWith(object, source, customizer);
13035      * // => true
13036      */
13037     function isMatchWith(object, source, customizer) {
13038       customizer = typeof customizer == 'function' ? customizer : undefined;
13039       return baseIsMatch(object, source, getMatchData(source), customizer);
13040     }
13041
13042     /**
13043      * Checks if `value` is `NaN`.
13044      *
13045      * **Note:** This method is based on
13046      * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
13047      * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
13048      * `undefined` and other non-number values.
13049      *
13050      * @static
13051      * @memberOf _
13052      * @since 0.1.0
13053      * @category Lang
13054      * @param {*} value The value to check.
13055      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
13056      * @example
13057      *
13058      * _.isNaN(NaN);
13059      * // => true
13060      *
13061      * _.isNaN(new Number(NaN));
13062      * // => true
13063      *
13064      * isNaN(undefined);
13065      * // => true
13066      *
13067      * _.isNaN(undefined);
13068      * // => false
13069      */
13070     function isNaN(value) {
13071       // An `NaN` primitive is the only value that is not equal to itself.
13072       // Perform the `toStringTag` check first to avoid errors with some
13073       // ActiveX objects in IE.
13074       return isNumber(value) && value != +value;
13075     }
13076
13077     /**
13078      * Checks if `value` is a pristine native function.
13079      *
13080      * **Note:** This method can't reliably detect native functions in the presence
13081      * of the core-js package because core-js circumvents this kind of detection.
13082      * Despite multiple requests, the core-js maintainer has made it clear: any
13083      * attempt to fix the detection will be obstructed. As a result, we're left
13084      * with little choice but to throw an error. Unfortunately, this also affects
13085      * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
13086      * which rely on core-js.
13087      *
13088      * @static
13089      * @memberOf _
13090      * @since 3.0.0
13091      * @category Lang
13092      * @param {*} value The value to check.
13093      * @returns {boolean} Returns `true` if `value` is a native function,
13094      *  else `false`.
13095      * @example
13096      *
13097      * _.isNative(Array.prototype.push);
13098      * // => true
13099      *
13100      * _.isNative(_);
13101      * // => false
13102      */
13103     function isNative(value) {
13104       if (isMaskable(value)) {
13105         throw new Error(CORE_ERROR_TEXT);
13106       }
13107       return baseIsNative(value);
13108     }
13109
13110     /**
13111      * Checks if `value` is `null`.
13112      *
13113      * @static
13114      * @memberOf _
13115      * @since 0.1.0
13116      * @category Lang
13117      * @param {*} value The value to check.
13118      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
13119      * @example
13120      *
13121      * _.isNull(null);
13122      * // => true
13123      *
13124      * _.isNull(void 0);
13125      * // => false
13126      */
13127     function isNull(value) {
13128       return value === null;
13129     }
13130
13131     /**
13132      * Checks if `value` is `null` or `undefined`.
13133      *
13134      * @static
13135      * @memberOf _
13136      * @since 4.0.0
13137      * @category Lang
13138      * @param {*} value The value to check.
13139      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
13140      * @example
13141      *
13142      * _.isNil(null);
13143      * // => true
13144      *
13145      * _.isNil(void 0);
13146      * // => true
13147      *
13148      * _.isNil(NaN);
13149      * // => false
13150      */
13151     function isNil(value) {
13152       return value == null;
13153     }
13154
13155     /**
13156      * Checks if `value` is classified as a `Number` primitive or object.
13157      *
13158      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
13159      * classified as numbers, use the `_.isFinite` method.
13160      *
13161      * @static
13162      * @memberOf _
13163      * @since 0.1.0
13164      * @category Lang
13165      * @param {*} value The value to check.
13166      * @returns {boolean} Returns `true` if `value` is a number, else `false`.
13167      * @example
13168      *
13169      * _.isNumber(3);
13170      * // => true
13171      *
13172      * _.isNumber(Number.MIN_VALUE);
13173      * // => true
13174      *
13175      * _.isNumber(Infinity);
13176      * // => true
13177      *
13178      * _.isNumber('3');
13179      * // => false
13180      */
13181     function isNumber(value) {
13182       return typeof value == 'number' ||
13183         (isObjectLike(value) && baseGetTag(value) == numberTag);
13184     }
13185
13186     /**
13187      * Checks if `value` is a plain object, that is, an object created by the
13188      * `Object` constructor or one with a `[[Prototype]]` of `null`.
13189      *
13190      * @static
13191      * @memberOf _
13192      * @since 0.8.0
13193      * @category Lang
13194      * @param {*} value The value to check.
13195      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
13196      * @example
13197      *
13198      * function Foo() {
13199      *   this.a = 1;
13200      * }
13201      *
13202      * _.isPlainObject(new Foo);
13203      * // => false
13204      *
13205      * _.isPlainObject([1, 2, 3]);
13206      * // => false
13207      *
13208      * _.isPlainObject({ 'x': 0, 'y': 0 });
13209      * // => true
13210      *
13211      * _.isPlainObject(Object.create(null));
13212      * // => true
13213      */
13214     function isPlainObject(value) {
13215       if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
13216         return false;
13217       }
13218       var proto = getPrototype(value);
13219       if (proto === null) {
13220         return true;
13221       }
13222       var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
13223       return typeof Ctor == 'function' && Ctor instanceof Ctor &&
13224         funcToString.call(Ctor) == objectCtorString;
13225     }
13226
13227     /**
13228      * Checks if `value` is classified as a `RegExp` object.
13229      *
13230      * @static
13231      * @memberOf _
13232      * @since 0.1.0
13233      * @category Lang
13234      * @param {*} value The value to check.
13235      * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
13236      * @example
13237      *
13238      * _.isRegExp(/abc/);
13239      * // => true
13240      *
13241      * _.isRegExp('/abc/');
13242      * // => false
13243      */
13244     var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
13245
13246     /**
13247      * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
13248      * double precision number which isn't the result of a rounded unsafe integer.
13249      *
13250      * **Note:** This method is based on
13251      * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
13252      *
13253      * @static
13254      * @memberOf _
13255      * @since 4.0.0
13256      * @category Lang
13257      * @param {*} value The value to check.
13258      * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
13259      * @example
13260      *
13261      * _.isSafeInteger(3);
13262      * // => true
13263      *
13264      * _.isSafeInteger(Number.MIN_VALUE);
13265      * // => false
13266      *
13267      * _.isSafeInteger(Infinity);
13268      * // => false
13269      *
13270      * _.isSafeInteger('3');
13271      * // => false
13272      */
13273     function isSafeInteger(value) {
13274       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
13275     }
13276
13277     /**
13278      * Checks if `value` is classified as a `Set` object.
13279      *
13280      * @static
13281      * @memberOf _
13282      * @since 4.3.0
13283      * @category Lang
13284      * @param {*} value The value to check.
13285      * @returns {boolean} Returns `true` if `value` is a set, else `false`.
13286      * @example
13287      *
13288      * _.isSet(new Set);
13289      * // => true
13290      *
13291      * _.isSet(new WeakSet);
13292      * // => false
13293      */
13294     var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
13295
13296     /**
13297      * Checks if `value` is classified as a `String` primitive or object.
13298      *
13299      * @static
13300      * @since 0.1.0
13301      * @memberOf _
13302      * @category Lang
13303      * @param {*} value The value to check.
13304      * @returns {boolean} Returns `true` if `value` is a string, else `false`.
13305      * @example
13306      *
13307      * _.isString('abc');
13308      * // => true
13309      *
13310      * _.isString(1);
13311      * // => false
13312      */
13313     function isString(value) {
13314       return typeof value == 'string' ||
13315         (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
13316     }
13317
13318     /**
13319      * Checks if `value` is classified as a `Symbol` primitive or object.
13320      *
13321      * @static
13322      * @memberOf _
13323      * @since 4.0.0
13324      * @category Lang
13325      * @param {*} value The value to check.
13326      * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
13327      * @example
13328      *
13329      * _.isSymbol(Symbol.iterator);
13330      * // => true
13331      *
13332      * _.isSymbol('abc');
13333      * // => false
13334      */
13335     function isSymbol(value) {
13336       return typeof value == 'symbol' ||
13337         (isObjectLike(value) && baseGetTag(value) == symbolTag);
13338     }
13339
13340     /**
13341      * Checks if `value` is classified as a typed array.
13342      *
13343      * @static
13344      * @memberOf _
13345      * @since 3.0.0
13346      * @category Lang
13347      * @param {*} value The value to check.
13348      * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
13349      * @example
13350      *
13351      * _.isTypedArray(new Uint8Array);
13352      * // => true
13353      *
13354      * _.isTypedArray([]);
13355      * // => false
13356      */
13357     var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
13358
13359     /**
13360      * Checks if `value` is `undefined`.
13361      *
13362      * @static
13363      * @since 0.1.0
13364      * @memberOf _
13365      * @category Lang
13366      * @param {*} value The value to check.
13367      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
13368      * @example
13369      *
13370      * _.isUndefined(void 0);
13371      * // => true
13372      *
13373      * _.isUndefined(null);
13374      * // => false
13375      */
13376     function isUndefined(value) {
13377       return value === undefined;
13378     }
13379
13380     /**
13381      * Checks if `value` is classified as a `WeakMap` object.
13382      *
13383      * @static
13384      * @memberOf _
13385      * @since 4.3.0
13386      * @category Lang
13387      * @param {*} value The value to check.
13388      * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
13389      * @example
13390      *
13391      * _.isWeakMap(new WeakMap);
13392      * // => true
13393      *
13394      * _.isWeakMap(new Map);
13395      * // => false
13396      */
13397     function isWeakMap(value) {
13398       return isObjectLike(value) && getTag(value) == weakMapTag;
13399     }
13400
13401     /**
13402      * Checks if `value` is classified as a `WeakSet` object.
13403      *
13404      * @static
13405      * @memberOf _
13406      * @since 4.3.0
13407      * @category Lang
13408      * @param {*} value The value to check.
13409      * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
13410      * @example
13411      *
13412      * _.isWeakSet(new WeakSet);
13413      * // => true
13414      *
13415      * _.isWeakSet(new Set);
13416      * // => false
13417      */
13418     function isWeakSet(value) {
13419       return isObjectLike(value) && baseGetTag(value) == weakSetTag;
13420     }
13421
13422     /**
13423      * Checks if `value` is less than `other`.
13424      *
13425      * @static
13426      * @memberOf _
13427      * @since 3.9.0
13428      * @category Lang
13429      * @param {*} value The value to compare.
13430      * @param {*} other The other value to compare.
13431      * @returns {boolean} Returns `true` if `value` is less than `other`,
13432      *  else `false`.
13433      * @see _.gt
13434      * @example
13435      *
13436      * _.lt(1, 3);
13437      * // => true
13438      *
13439      * _.lt(3, 3);
13440      * // => false
13441      *
13442      * _.lt(3, 1);
13443      * // => false
13444      */
13445     var lt = createRelationalOperation(baseLt);
13446
13447     /**
13448      * Checks if `value` is less than or equal to `other`.
13449      *
13450      * @static
13451      * @memberOf _
13452      * @since 3.9.0
13453      * @category Lang
13454      * @param {*} value The value to compare.
13455      * @param {*} other The other value to compare.
13456      * @returns {boolean} Returns `true` if `value` is less than or equal to
13457      *  `other`, else `false`.
13458      * @see _.gte
13459      * @example
13460      *
13461      * _.lte(1, 3);
13462      * // => true
13463      *
13464      * _.lte(3, 3);
13465      * // => true
13466      *
13467      * _.lte(3, 1);
13468      * // => false
13469      */
13470     var lte = createRelationalOperation(function(value, other) {
13471       return value <= other;
13472     });
13473
13474     /**
13475      * Converts `value` to an array.
13476      *
13477      * @static
13478      * @since 0.1.0
13479      * @memberOf _
13480      * @category Lang
13481      * @param {*} value The value to convert.
13482      * @returns {Array} Returns the converted array.
13483      * @example
13484      *
13485      * _.toArray({ 'a': 1, 'b': 2 });
13486      * // => [1, 2]
13487      *
13488      * _.toArray('abc');
13489      * // => ['a', 'b', 'c']
13490      *
13491      * _.toArray(1);
13492      * // => []
13493      *
13494      * _.toArray(null);
13495      * // => []
13496      */
13497     function toArray(value) {
13498       if (!value) {
13499         return [];
13500       }
13501       if (isArrayLike(value)) {
13502         return isString(value) ? stringToArray(value) : copyArray(value);
13503       }
13504       if (symIterator && value[symIterator]) {
13505         return iteratorToArray(value[symIterator]());
13506       }
13507       var tag = getTag(value),
13508           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
13509
13510       return func(value);
13511     }
13512
13513     /**
13514      * Converts `value` to a finite number.
13515      *
13516      * @static
13517      * @memberOf _
13518      * @since 4.12.0
13519      * @category Lang
13520      * @param {*} value The value to convert.
13521      * @returns {number} Returns the converted number.
13522      * @example
13523      *
13524      * _.toFinite(3.2);
13525      * // => 3.2
13526      *
13527      * _.toFinite(Number.MIN_VALUE);
13528      * // => 5e-324
13529      *
13530      * _.toFinite(Infinity);
13531      * // => 1.7976931348623157e+308
13532      *
13533      * _.toFinite('3.2');
13534      * // => 3.2
13535      */
13536     function toFinite(value) {
13537       if (!value) {
13538         return value === 0 ? value : 0;
13539       }
13540       value = toNumber(value);
13541       if (value === INFINITY || value === -INFINITY) {
13542         var sign = (value < 0 ? -1 : 1);
13543         return sign * MAX_INTEGER;
13544       }
13545       return value === value ? value : 0;
13546     }
13547
13548     /**
13549      * Converts `value` to an integer.
13550      *
13551      * **Note:** This method is loosely based on
13552      * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
13553      *
13554      * @static
13555      * @memberOf _
13556      * @since 4.0.0
13557      * @category Lang
13558      * @param {*} value The value to convert.
13559      * @returns {number} Returns the converted integer.
13560      * @example
13561      *
13562      * _.toInteger(3.2);
13563      * // => 3
13564      *
13565      * _.toInteger(Number.MIN_VALUE);
13566      * // => 0
13567      *
13568      * _.toInteger(Infinity);
13569      * // => 1.7976931348623157e+308
13570      *
13571      * _.toInteger('3.2');
13572      * // => 3
13573      */
13574     function toInteger(value) {
13575       var result = toFinite(value),
13576           remainder = result % 1;
13577
13578       return result === result ? (remainder ? result - remainder : result) : 0;
13579     }
13580
13581     /**
13582      * Converts `value` to an integer suitable for use as the length of an
13583      * array-like object.
13584      *
13585      * **Note:** This method is based on
13586      * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
13587      *
13588      * @static
13589      * @memberOf _
13590      * @since 4.0.0
13591      * @category Lang
13592      * @param {*} value The value to convert.
13593      * @returns {number} Returns the converted integer.
13594      * @example
13595      *
13596      * _.toLength(3.2);
13597      * // => 3
13598      *
13599      * _.toLength(Number.MIN_VALUE);
13600      * // => 0
13601      *
13602      * _.toLength(Infinity);
13603      * // => 4294967295
13604      *
13605      * _.toLength('3.2');
13606      * // => 3
13607      */
13608     function toLength(value) {
13609       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
13610     }
13611
13612     /**
13613      * Converts `value` to a number.
13614      *
13615      * @static
13616      * @memberOf _
13617      * @since 4.0.0
13618      * @category Lang
13619      * @param {*} value The value to process.
13620      * @returns {number} Returns the number.
13621      * @example
13622      *
13623      * _.toNumber(3.2);
13624      * // => 3.2
13625      *
13626      * _.toNumber(Number.MIN_VALUE);
13627      * // => 5e-324
13628      *
13629      * _.toNumber(Infinity);
13630      * // => Infinity
13631      *
13632      * _.toNumber('3.2');
13633      * // => 3.2
13634      */
13635     function toNumber(value) {
13636       if (typeof value == 'number') {
13637         return value;
13638       }
13639       if (isSymbol(value)) {
13640         return NAN;
13641       }
13642       if (isObject(value)) {
13643         var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
13644         value = isObject(other) ? (other + '') : other;
13645       }
13646       if (typeof value != 'string') {
13647         return value === 0 ? value : +value;
13648       }
13649       value = baseTrim(value);
13650       var isBinary = reIsBinary.test(value);
13651       return (isBinary || reIsOctal.test(value))
13652         ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
13653         : (reIsBadHex.test(value) ? NAN : +value);
13654     }
13655
13656     /**
13657      * Converts `value` to a plain object flattening inherited enumerable string
13658      * keyed properties of `value` to own properties of the plain object.
13659      *
13660      * @static
13661      * @memberOf _
13662      * @since 3.0.0
13663      * @category Lang
13664      * @param {*} value The value to convert.
13665      * @returns {Object} Returns the converted plain object.
13666      * @example
13667      *
13668      * function Foo() {
13669      *   this.b = 2;
13670      * }
13671      *
13672      * Foo.prototype.c = 3;
13673      *
13674      * _.assign({ 'a': 1 }, new Foo);
13675      * // => { 'a': 1, 'b': 2 }
13676      *
13677      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
13678      * // => { 'a': 1, 'b': 2, 'c': 3 }
13679      */
13680     function toPlainObject(value) {
13681       return copyObject(value, keysIn(value));
13682     }
13683
13684     /**
13685      * Converts `value` to a safe integer. A safe integer can be compared and
13686      * represented correctly.
13687      *
13688      * @static
13689      * @memberOf _
13690      * @since 4.0.0
13691      * @category Lang
13692      * @param {*} value The value to convert.
13693      * @returns {number} Returns the converted integer.
13694      * @example
13695      *
13696      * _.toSafeInteger(3.2);
13697      * // => 3
13698      *
13699      * _.toSafeInteger(Number.MIN_VALUE);
13700      * // => 0
13701      *
13702      * _.toSafeInteger(Infinity);
13703      * // => 9007199254740991
13704      *
13705      * _.toSafeInteger('3.2');
13706      * // => 3
13707      */
13708     function toSafeInteger(value) {
13709       return value
13710         ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
13711         : (value === 0 ? value : 0);
13712     }
13713
13714     /**
13715      * Converts `value` to a string. An empty string is returned for `null`
13716      * and `undefined` values. The sign of `-0` is preserved.
13717      *
13718      * @static
13719      * @memberOf _
13720      * @since 4.0.0
13721      * @category Lang
13722      * @param {*} value The value to convert.
13723      * @returns {string} Returns the converted string.
13724      * @example
13725      *
13726      * _.toString(null);
13727      * // => ''
13728      *
13729      * _.toString(-0);
13730      * // => '-0'
13731      *
13732      * _.toString([1, 2, 3]);
13733      * // => '1,2,3'
13734      */
13735     function toString(value) {
13736       return value == null ? '' : baseToString(value);
13737     }
13738
13739     /*------------------------------------------------------------------------*/
13740
13741     /**
13742      * Assigns own enumerable string keyed properties of source objects to the
13743      * destination object. Source objects are applied from left to right.
13744      * Subsequent sources overwrite property assignments of previous sources.
13745      *
13746      * **Note:** This method mutates `object` and is loosely based on
13747      * [`Object.assign`](https://mdn.io/Object/assign).
13748      *
13749      * @static
13750      * @memberOf _
13751      * @since 0.10.0
13752      * @category Object
13753      * @param {Object} object The destination object.
13754      * @param {...Object} [sources] The source objects.
13755      * @returns {Object} Returns `object`.
13756      * @see _.assignIn
13757      * @example
13758      *
13759      * function Foo() {
13760      *   this.a = 1;
13761      * }
13762      *
13763      * function Bar() {
13764      *   this.c = 3;
13765      * }
13766      *
13767      * Foo.prototype.b = 2;
13768      * Bar.prototype.d = 4;
13769      *
13770      * _.assign({ 'a': 0 }, new Foo, new Bar);
13771      * // => { 'a': 1, 'c': 3 }
13772      */
13773     var assign = createAssigner(function(object, source) {
13774       if (isPrototype(source) || isArrayLike(source)) {
13775         copyObject(source, keys(source), object);
13776         return;
13777       }
13778       for (var key in source) {
13779         if (hasOwnProperty.call(source, key)) {
13780           assignValue(object, key, source[key]);
13781         }
13782       }
13783     });
13784
13785     /**
13786      * This method is like `_.assign` except that it iterates over own and
13787      * inherited source properties.
13788      *
13789      * **Note:** This method mutates `object`.
13790      *
13791      * @static
13792      * @memberOf _
13793      * @since 4.0.0
13794      * @alias extend
13795      * @category Object
13796      * @param {Object} object The destination object.
13797      * @param {...Object} [sources] The source objects.
13798      * @returns {Object} Returns `object`.
13799      * @see _.assign
13800      * @example
13801      *
13802      * function Foo() {
13803      *   this.a = 1;
13804      * }
13805      *
13806      * function Bar() {
13807      *   this.c = 3;
13808      * }
13809      *
13810      * Foo.prototype.b = 2;
13811      * Bar.prototype.d = 4;
13812      *
13813      * _.assignIn({ 'a': 0 }, new Foo, new Bar);
13814      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
13815      */
13816     var assignIn = createAssigner(function(object, source) {
13817       copyObject(source, keysIn(source), object);
13818     });
13819
13820     /**
13821      * This method is like `_.assignIn` except that it accepts `customizer`
13822      * which is invoked to produce the assigned values. If `customizer` returns
13823      * `undefined`, assignment is handled by the method instead. The `customizer`
13824      * is invoked with five arguments: (objValue, srcValue, key, object, source).
13825      *
13826      * **Note:** This method mutates `object`.
13827      *
13828      * @static
13829      * @memberOf _
13830      * @since 4.0.0
13831      * @alias extendWith
13832      * @category Object
13833      * @param {Object} object The destination object.
13834      * @param {...Object} sources The source objects.
13835      * @param {Function} [customizer] The function to customize assigned values.
13836      * @returns {Object} Returns `object`.
13837      * @see _.assignWith
13838      * @example
13839      *
13840      * function customizer(objValue, srcValue) {
13841      *   return _.isUndefined(objValue) ? srcValue : objValue;
13842      * }
13843      *
13844      * var defaults = _.partialRight(_.assignInWith, customizer);
13845      *
13846      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
13847      * // => { 'a': 1, 'b': 2 }
13848      */
13849     var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
13850       copyObject(source, keysIn(source), object, customizer);
13851     });
13852
13853     /**
13854      * This method is like `_.assign` except that it accepts `customizer`
13855      * which is invoked to produce the assigned values. If `customizer` returns
13856      * `undefined`, assignment is handled by the method instead. The `customizer`
13857      * is invoked with five arguments: (objValue, srcValue, key, object, source).
13858      *
13859      * **Note:** This method mutates `object`.
13860      *
13861      * @static
13862      * @memberOf _
13863      * @since 4.0.0
13864      * @category Object
13865      * @param {Object} object The destination object.
13866      * @param {...Object} sources The source objects.
13867      * @param {Function} [customizer] The function to customize assigned values.
13868      * @returns {Object} Returns `object`.
13869      * @see _.assignInWith
13870      * @example
13871      *
13872      * function customizer(objValue, srcValue) {
13873      *   return _.isUndefined(objValue) ? srcValue : objValue;
13874      * }
13875      *
13876      * var defaults = _.partialRight(_.assignWith, customizer);
13877      *
13878      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
13879      * // => { 'a': 1, 'b': 2 }
13880      */
13881     var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
13882       copyObject(source, keys(source), object, customizer);
13883     });
13884
13885     /**
13886      * Creates an array of values corresponding to `paths` of `object`.
13887      *
13888      * @static
13889      * @memberOf _
13890      * @since 1.0.0
13891      * @category Object
13892      * @param {Object} object The object to iterate over.
13893      * @param {...(string|string[])} [paths] The property paths to pick.
13894      * @returns {Array} Returns the picked values.
13895      * @example
13896      *
13897      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
13898      *
13899      * _.at(object, ['a[0].b.c', 'a[1]']);
13900      * // => [3, 4]
13901      */
13902     var at = flatRest(baseAt);
13903
13904     /**
13905      * Creates an object that inherits from the `prototype` object. If a
13906      * `properties` object is given, its own enumerable string keyed properties
13907      * are assigned to the created object.
13908      *
13909      * @static
13910      * @memberOf _
13911      * @since 2.3.0
13912      * @category Object
13913      * @param {Object} prototype The object to inherit from.
13914      * @param {Object} [properties] The properties to assign to the object.
13915      * @returns {Object} Returns the new object.
13916      * @example
13917      *
13918      * function Shape() {
13919      *   this.x = 0;
13920      *   this.y = 0;
13921      * }
13922      *
13923      * function Circle() {
13924      *   Shape.call(this);
13925      * }
13926      *
13927      * Circle.prototype = _.create(Shape.prototype, {
13928      *   'constructor': Circle
13929      * });
13930      *
13931      * var circle = new Circle;
13932      * circle instanceof Circle;
13933      * // => true
13934      *
13935      * circle instanceof Shape;
13936      * // => true
13937      */
13938     function create(prototype, properties) {
13939       var result = baseCreate(prototype);
13940       return properties == null ? result : baseAssign(result, properties);
13941     }
13942
13943     /**
13944      * Assigns own and inherited enumerable string keyed properties of source
13945      * objects to the destination object for all destination properties that
13946      * resolve to `undefined`. Source objects are applied from left to right.
13947      * Once a property is set, additional values of the same property are ignored.
13948      *
13949      * **Note:** This method mutates `object`.
13950      *
13951      * @static
13952      * @since 0.1.0
13953      * @memberOf _
13954      * @category Object
13955      * @param {Object} object The destination object.
13956      * @param {...Object} [sources] The source objects.
13957      * @returns {Object} Returns `object`.
13958      * @see _.defaultsDeep
13959      * @example
13960      *
13961      * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
13962      * // => { 'a': 1, 'b': 2 }
13963      */
13964     var defaults = baseRest(function(object, sources) {
13965       object = Object(object);
13966
13967       var index = -1;
13968       var length = sources.length;
13969       var guard = length > 2 ? sources[2] : undefined;
13970
13971       if (guard && isIterateeCall(sources[0], sources[1], guard)) {
13972         length = 1;
13973       }
13974
13975       while (++index < length) {
13976         var source = sources[index];
13977         var props = keysIn(source);
13978         var propsIndex = -1;
13979         var propsLength = props.length;
13980
13981         while (++propsIndex < propsLength) {
13982           var key = props[propsIndex];
13983           var value = object[key];
13984
13985           if (value === undefined ||
13986               (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
13987             object[key] = source[key];
13988           }
13989         }
13990       }
13991
13992       return object;
13993     });
13994
13995     /**
13996      * This method is like `_.defaults` except that it recursively assigns
13997      * default properties.
13998      *
13999      * **Note:** This method mutates `object`.
14000      *
14001      * @static
14002      * @memberOf _
14003      * @since 3.10.0
14004      * @category Object
14005      * @param {Object} object The destination object.
14006      * @param {...Object} [sources] The source objects.
14007      * @returns {Object} Returns `object`.
14008      * @see _.defaults
14009      * @example
14010      *
14011      * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
14012      * // => { 'a': { 'b': 2, 'c': 3 } }
14013      */
14014     var defaultsDeep = baseRest(function(args) {
14015       args.push(undefined, customDefaultsMerge);
14016       return apply(mergeWith, undefined, args);
14017     });
14018
14019     /**
14020      * This method is like `_.find` except that it returns the key of the first
14021      * element `predicate` returns truthy for instead of the element itself.
14022      *
14023      * @static
14024      * @memberOf _
14025      * @since 1.1.0
14026      * @category Object
14027      * @param {Object} object The object to inspect.
14028      * @param {Function} [predicate=_.identity] The function invoked per iteration.
14029      * @returns {string|undefined} Returns the key of the matched element,
14030      *  else `undefined`.
14031      * @example
14032      *
14033      * var users = {
14034      *   'barney':  { 'age': 36, 'active': true },
14035      *   'fred':    { 'age': 40, 'active': false },
14036      *   'pebbles': { 'age': 1,  'active': true }
14037      * };
14038      *
14039      * _.findKey(users, function(o) { return o.age < 40; });
14040      * // => 'barney' (iteration order is not guaranteed)
14041      *
14042      * // The `_.matches` iteratee shorthand.
14043      * _.findKey(users, { 'age': 1, 'active': true });
14044      * // => 'pebbles'
14045      *
14046      * // The `_.matchesProperty` iteratee shorthand.
14047      * _.findKey(users, ['active', false]);
14048      * // => 'fred'
14049      *
14050      * // The `_.property` iteratee shorthand.
14051      * _.findKey(users, 'active');
14052      * // => 'barney'
14053      */
14054     function findKey(object, predicate) {
14055       return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
14056     }
14057
14058     /**
14059      * This method is like `_.findKey` except that it iterates over elements of
14060      * a collection in the opposite order.
14061      *
14062      * @static
14063      * @memberOf _
14064      * @since 2.0.0
14065      * @category Object
14066      * @param {Object} object The object to inspect.
14067      * @param {Function} [predicate=_.identity] The function invoked per iteration.
14068      * @returns {string|undefined} Returns the key of the matched element,
14069      *  else `undefined`.
14070      * @example
14071      *
14072      * var users = {
14073      *   'barney':  { 'age': 36, 'active': true },
14074      *   'fred':    { 'age': 40, 'active': false },
14075      *   'pebbles': { 'age': 1,  'active': true }
14076      * };
14077      *
14078      * _.findLastKey(users, function(o) { return o.age < 40; });
14079      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
14080      *
14081      * // The `_.matches` iteratee shorthand.
14082      * _.findLastKey(users, { 'age': 36, 'active': true });
14083      * // => 'barney'
14084      *
14085      * // The `_.matchesProperty` iteratee shorthand.
14086      * _.findLastKey(users, ['active', false]);
14087      * // => 'fred'
14088      *
14089      * // The `_.property` iteratee shorthand.
14090      * _.findLastKey(users, 'active');
14091      * // => 'pebbles'
14092      */
14093     function findLastKey(object, predicate) {
14094       return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
14095     }
14096
14097     /**
14098      * Iterates over own and inherited enumerable string keyed properties of an
14099      * object and invokes `iteratee` for each property. The iteratee is invoked
14100      * with three arguments: (value, key, object). Iteratee functions may exit
14101      * iteration early by explicitly returning `false`.
14102      *
14103      * @static
14104      * @memberOf _
14105      * @since 0.3.0
14106      * @category Object
14107      * @param {Object} object The object to iterate over.
14108      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14109      * @returns {Object} Returns `object`.
14110      * @see _.forInRight
14111      * @example
14112      *
14113      * function Foo() {
14114      *   this.a = 1;
14115      *   this.b = 2;
14116      * }
14117      *
14118      * Foo.prototype.c = 3;
14119      *
14120      * _.forIn(new Foo, function(value, key) {
14121      *   console.log(key);
14122      * });
14123      * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
14124      */
14125     function forIn(object, iteratee) {
14126       return object == null
14127         ? object
14128         : baseFor(object, getIteratee(iteratee, 3), keysIn);
14129     }
14130
14131     /**
14132      * This method is like `_.forIn` except that it iterates over properties of
14133      * `object` in the opposite order.
14134      *
14135      * @static
14136      * @memberOf _
14137      * @since 2.0.0
14138      * @category Object
14139      * @param {Object} object The object to iterate over.
14140      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14141      * @returns {Object} Returns `object`.
14142      * @see _.forIn
14143      * @example
14144      *
14145      * function Foo() {
14146      *   this.a = 1;
14147      *   this.b = 2;
14148      * }
14149      *
14150      * Foo.prototype.c = 3;
14151      *
14152      * _.forInRight(new Foo, function(value, key) {
14153      *   console.log(key);
14154      * });
14155      * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
14156      */
14157     function forInRight(object, iteratee) {
14158       return object == null
14159         ? object
14160         : baseForRight(object, getIteratee(iteratee, 3), keysIn);
14161     }
14162
14163     /**
14164      * Iterates over own enumerable string keyed properties of an object and
14165      * invokes `iteratee` for each property. The iteratee is invoked with three
14166      * arguments: (value, key, object). Iteratee functions may exit iteration
14167      * early by explicitly returning `false`.
14168      *
14169      * @static
14170      * @memberOf _
14171      * @since 0.3.0
14172      * @category Object
14173      * @param {Object} object The object to iterate over.
14174      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14175      * @returns {Object} Returns `object`.
14176      * @see _.forOwnRight
14177      * @example
14178      *
14179      * function Foo() {
14180      *   this.a = 1;
14181      *   this.b = 2;
14182      * }
14183      *
14184      * Foo.prototype.c = 3;
14185      *
14186      * _.forOwn(new Foo, function(value, key) {
14187      *   console.log(key);
14188      * });
14189      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
14190      */
14191     function forOwn(object, iteratee) {
14192       return object && baseForOwn(object, getIteratee(iteratee, 3));
14193     }
14194
14195     /**
14196      * This method is like `_.forOwn` except that it iterates over properties of
14197      * `object` in the opposite order.
14198      *
14199      * @static
14200      * @memberOf _
14201      * @since 2.0.0
14202      * @category Object
14203      * @param {Object} object The object to iterate over.
14204      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14205      * @returns {Object} Returns `object`.
14206      * @see _.forOwn
14207      * @example
14208      *
14209      * function Foo() {
14210      *   this.a = 1;
14211      *   this.b = 2;
14212      * }
14213      *
14214      * Foo.prototype.c = 3;
14215      *
14216      * _.forOwnRight(new Foo, function(value, key) {
14217      *   console.log(key);
14218      * });
14219      * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
14220      */
14221     function forOwnRight(object, iteratee) {
14222       return object && baseForOwnRight(object, getIteratee(iteratee, 3));
14223     }
14224
14225     /**
14226      * Creates an array of function property names from own enumerable properties
14227      * of `object`.
14228      *
14229      * @static
14230      * @since 0.1.0
14231      * @memberOf _
14232      * @category Object
14233      * @param {Object} object The object to inspect.
14234      * @returns {Array} Returns the function names.
14235      * @see _.functionsIn
14236      * @example
14237      *
14238      * function Foo() {
14239      *   this.a = _.constant('a');
14240      *   this.b = _.constant('b');
14241      * }
14242      *
14243      * Foo.prototype.c = _.constant('c');
14244      *
14245      * _.functions(new Foo);
14246      * // => ['a', 'b']
14247      */
14248     function functions(object) {
14249       return object == null ? [] : baseFunctions(object, keys(object));
14250     }
14251
14252     /**
14253      * Creates an array of function property names from own and inherited
14254      * enumerable properties of `object`.
14255      *
14256      * @static
14257      * @memberOf _
14258      * @since 4.0.0
14259      * @category Object
14260      * @param {Object} object The object to inspect.
14261      * @returns {Array} Returns the function names.
14262      * @see _.functions
14263      * @example
14264      *
14265      * function Foo() {
14266      *   this.a = _.constant('a');
14267      *   this.b = _.constant('b');
14268      * }
14269      *
14270      * Foo.prototype.c = _.constant('c');
14271      *
14272      * _.functionsIn(new Foo);
14273      * // => ['a', 'b', 'c']
14274      */
14275     function functionsIn(object) {
14276       return object == null ? [] : baseFunctions(object, keysIn(object));
14277     }
14278
14279     /**
14280      * Gets the value at `path` of `object`. If the resolved value is
14281      * `undefined`, the `defaultValue` is returned in its place.
14282      *
14283      * @static
14284      * @memberOf _
14285      * @since 3.7.0
14286      * @category Object
14287      * @param {Object} object The object to query.
14288      * @param {Array|string} path The path of the property to get.
14289      * @param {*} [defaultValue] The value returned for `undefined` resolved values.
14290      * @returns {*} Returns the resolved value.
14291      * @example
14292      *
14293      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
14294      *
14295      * _.get(object, 'a[0].b.c');
14296      * // => 3
14297      *
14298      * _.get(object, ['a', '0', 'b', 'c']);
14299      * // => 3
14300      *
14301      * _.get(object, 'a.b.c', 'default');
14302      * // => 'default'
14303      */
14304     function get(object, path, defaultValue) {
14305       var result = object == null ? undefined : baseGet(object, path);
14306       return result === undefined ? defaultValue : result;
14307     }
14308
14309     /**
14310      * Checks if `path` is a direct property of `object`.
14311      *
14312      * @static
14313      * @since 0.1.0
14314      * @memberOf _
14315      * @category Object
14316      * @param {Object} object The object to query.
14317      * @param {Array|string} path The path to check.
14318      * @returns {boolean} Returns `true` if `path` exists, else `false`.
14319      * @example
14320      *
14321      * var object = { 'a': { 'b': 2 } };
14322      * var other = _.create({ 'a': _.create({ 'b': 2 }) });
14323      *
14324      * _.has(object, 'a');
14325      * // => true
14326      *
14327      * _.has(object, 'a.b');
14328      * // => true
14329      *
14330      * _.has(object, ['a', 'b']);
14331      * // => true
14332      *
14333      * _.has(other, 'a');
14334      * // => false
14335      */
14336     function has(object, path) {
14337       return object != null && hasPath(object, path, baseHas);
14338     }
14339
14340     /**
14341      * Checks if `path` is a direct or inherited property of `object`.
14342      *
14343      * @static
14344      * @memberOf _
14345      * @since 4.0.0
14346      * @category Object
14347      * @param {Object} object The object to query.
14348      * @param {Array|string} path The path to check.
14349      * @returns {boolean} Returns `true` if `path` exists, else `false`.
14350      * @example
14351      *
14352      * var object = _.create({ 'a': _.create({ 'b': 2 }) });
14353      *
14354      * _.hasIn(object, 'a');
14355      * // => true
14356      *
14357      * _.hasIn(object, 'a.b');
14358      * // => true
14359      *
14360      * _.hasIn(object, ['a', 'b']);
14361      * // => true
14362      *
14363      * _.hasIn(object, 'b');
14364      * // => false
14365      */
14366     function hasIn(object, path) {
14367       return object != null && hasPath(object, path, baseHasIn);
14368     }
14369
14370     /**
14371      * Creates an object composed of the inverted keys and values of `object`.
14372      * If `object` contains duplicate values, subsequent values overwrite
14373      * property assignments of previous values.
14374      *
14375      * @static
14376      * @memberOf _
14377      * @since 0.7.0
14378      * @category Object
14379      * @param {Object} object The object to invert.
14380      * @returns {Object} Returns the new inverted object.
14381      * @example
14382      *
14383      * var object = { 'a': 1, 'b': 2, 'c': 1 };
14384      *
14385      * _.invert(object);
14386      * // => { '1': 'c', '2': 'b' }
14387      */
14388     var invert = createInverter(function(result, value, key) {
14389       if (value != null &&
14390           typeof value.toString != 'function') {
14391         value = nativeObjectToString.call(value);
14392       }
14393
14394       result[value] = key;
14395     }, constant(identity));
14396
14397     /**
14398      * This method is like `_.invert` except that the inverted object is generated
14399      * from the results of running each element of `object` thru `iteratee`. The
14400      * corresponding inverted value of each inverted key is an array of keys
14401      * responsible for generating the inverted value. The iteratee is invoked
14402      * with one argument: (value).
14403      *
14404      * @static
14405      * @memberOf _
14406      * @since 4.1.0
14407      * @category Object
14408      * @param {Object} object The object to invert.
14409      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
14410      * @returns {Object} Returns the new inverted object.
14411      * @example
14412      *
14413      * var object = { 'a': 1, 'b': 2, 'c': 1 };
14414      *
14415      * _.invertBy(object);
14416      * // => { '1': ['a', 'c'], '2': ['b'] }
14417      *
14418      * _.invertBy(object, function(value) {
14419      *   return 'group' + value;
14420      * });
14421      * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
14422      */
14423     var invertBy = createInverter(function(result, value, key) {
14424       if (value != null &&
14425           typeof value.toString != 'function') {
14426         value = nativeObjectToString.call(value);
14427       }
14428
14429       if (hasOwnProperty.call(result, value)) {
14430         result[value].push(key);
14431       } else {
14432         result[value] = [key];
14433       }
14434     }, getIteratee);
14435
14436     /**
14437      * Invokes the method at `path` of `object`.
14438      *
14439      * @static
14440      * @memberOf _
14441      * @since 4.0.0
14442      * @category Object
14443      * @param {Object} object The object to query.
14444      * @param {Array|string} path The path of the method to invoke.
14445      * @param {...*} [args] The arguments to invoke the method with.
14446      * @returns {*} Returns the result of the invoked method.
14447      * @example
14448      *
14449      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
14450      *
14451      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
14452      * // => [2, 3]
14453      */
14454     var invoke = baseRest(baseInvoke);
14455
14456     /**
14457      * Creates an array of the own enumerable property names of `object`.
14458      *
14459      * **Note:** Non-object values are coerced to objects. See the
14460      * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
14461      * for more details.
14462      *
14463      * @static
14464      * @since 0.1.0
14465      * @memberOf _
14466      * @category Object
14467      * @param {Object} object The object to query.
14468      * @returns {Array} Returns the array of property names.
14469      * @example
14470      *
14471      * function Foo() {
14472      *   this.a = 1;
14473      *   this.b = 2;
14474      * }
14475      *
14476      * Foo.prototype.c = 3;
14477      *
14478      * _.keys(new Foo);
14479      * // => ['a', 'b'] (iteration order is not guaranteed)
14480      *
14481      * _.keys('hi');
14482      * // => ['0', '1']
14483      */
14484     function keys(object) {
14485       return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
14486     }
14487
14488     /**
14489      * Creates an array of the own and inherited enumerable property names of `object`.
14490      *
14491      * **Note:** Non-object values are coerced to objects.
14492      *
14493      * @static
14494      * @memberOf _
14495      * @since 3.0.0
14496      * @category Object
14497      * @param {Object} object The object to query.
14498      * @returns {Array} Returns the array of property names.
14499      * @example
14500      *
14501      * function Foo() {
14502      *   this.a = 1;
14503      *   this.b = 2;
14504      * }
14505      *
14506      * Foo.prototype.c = 3;
14507      *
14508      * _.keysIn(new Foo);
14509      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
14510      */
14511     function keysIn(object) {
14512       return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
14513     }
14514
14515     /**
14516      * The opposite of `_.mapValues`; this method creates an object with the
14517      * same values as `object` and keys generated by running each own enumerable
14518      * string keyed property of `object` thru `iteratee`. The iteratee is invoked
14519      * with three arguments: (value, key, object).
14520      *
14521      * @static
14522      * @memberOf _
14523      * @since 3.8.0
14524      * @category Object
14525      * @param {Object} object The object to iterate over.
14526      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14527      * @returns {Object} Returns the new mapped object.
14528      * @see _.mapValues
14529      * @example
14530      *
14531      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
14532      *   return key + value;
14533      * });
14534      * // => { 'a1': 1, 'b2': 2 }
14535      */
14536     function mapKeys(object, iteratee) {
14537       var result = {};
14538       iteratee = getIteratee(iteratee, 3);
14539
14540       baseForOwn(object, function(value, key, object) {
14541         baseAssignValue(result, iteratee(value, key, object), value);
14542       });
14543       return result;
14544     }
14545
14546     /**
14547      * Creates an object with the same keys as `object` and values generated
14548      * by running each own enumerable string keyed property of `object` thru
14549      * `iteratee`. The iteratee is invoked with three arguments:
14550      * (value, key, object).
14551      *
14552      * @static
14553      * @memberOf _
14554      * @since 2.4.0
14555      * @category Object
14556      * @param {Object} object The object to iterate over.
14557      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14558      * @returns {Object} Returns the new mapped object.
14559      * @see _.mapKeys
14560      * @example
14561      *
14562      * var users = {
14563      *   'fred':    { 'user': 'fred',    'age': 40 },
14564      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
14565      * };
14566      *
14567      * _.mapValues(users, function(o) { return o.age; });
14568      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
14569      *
14570      * // The `_.property` iteratee shorthand.
14571      * _.mapValues(users, 'age');
14572      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
14573      */
14574     function mapValues(object, iteratee) {
14575       var result = {};
14576       iteratee = getIteratee(iteratee, 3);
14577
14578       baseForOwn(object, function(value, key, object) {
14579         baseAssignValue(result, key, iteratee(value, key, object));
14580       });
14581       return result;
14582     }
14583
14584     /**
14585      * This method is like `_.assign` except that it recursively merges own and
14586      * inherited enumerable string keyed properties of source objects into the
14587      * destination object. Source properties that resolve to `undefined` are
14588      * skipped if a destination value exists. Array and plain object properties
14589      * are merged recursively. Other objects and value types are overridden by
14590      * assignment. Source objects are applied from left to right. Subsequent
14591      * sources overwrite property assignments of previous sources.
14592      *
14593      * **Note:** This method mutates `object`.
14594      *
14595      * @static
14596      * @memberOf _
14597      * @since 0.5.0
14598      * @category Object
14599      * @param {Object} object The destination object.
14600      * @param {...Object} [sources] The source objects.
14601      * @returns {Object} Returns `object`.
14602      * @example
14603      *
14604      * var object = {
14605      *   'a': [{ 'b': 2 }, { 'd': 4 }]
14606      * };
14607      *
14608      * var other = {
14609      *   'a': [{ 'c': 3 }, { 'e': 5 }]
14610      * };
14611      *
14612      * _.merge(object, other);
14613      * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
14614      */
14615     var merge = createAssigner(function(object, source, srcIndex) {
14616       baseMerge(object, source, srcIndex);
14617     });
14618
14619     /**
14620      * This method is like `_.merge` except that it accepts `customizer` which
14621      * is invoked to produce the merged values of the destination and source
14622      * properties. If `customizer` returns `undefined`, merging is handled by the
14623      * method instead. The `customizer` is invoked with six arguments:
14624      * (objValue, srcValue, key, object, source, stack).
14625      *
14626      * **Note:** This method mutates `object`.
14627      *
14628      * @static
14629      * @memberOf _
14630      * @since 4.0.0
14631      * @category Object
14632      * @param {Object} object The destination object.
14633      * @param {...Object} sources The source objects.
14634      * @param {Function} customizer The function to customize assigned values.
14635      * @returns {Object} Returns `object`.
14636      * @example
14637      *
14638      * function customizer(objValue, srcValue) {
14639      *   if (_.isArray(objValue)) {
14640      *     return objValue.concat(srcValue);
14641      *   }
14642      * }
14643      *
14644      * var object = { 'a': [1], 'b': [2] };
14645      * var other = { 'a': [3], 'b': [4] };
14646      *
14647      * _.mergeWith(object, other, customizer);
14648      * // => { 'a': [1, 3], 'b': [2, 4] }
14649      */
14650     var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
14651       baseMerge(object, source, srcIndex, customizer);
14652     });
14653
14654     /**
14655      * The opposite of `_.pick`; this method creates an object composed of the
14656      * own and inherited enumerable property paths of `object` that are not omitted.
14657      *
14658      * **Note:** This method is considerably slower than `_.pick`.
14659      *
14660      * @static
14661      * @since 0.1.0
14662      * @memberOf _
14663      * @category Object
14664      * @param {Object} object The source object.
14665      * @param {...(string|string[])} [paths] The property paths to omit.
14666      * @returns {Object} Returns the new object.
14667      * @example
14668      *
14669      * var object = { 'a': 1, 'b': '2', 'c': 3 };
14670      *
14671      * _.omit(object, ['a', 'c']);
14672      * // => { 'b': '2' }
14673      */
14674     var omit = flatRest(function(object, paths) {
14675       var result = {};
14676       if (object == null) {
14677         return result;
14678       }
14679       var isDeep = false;
14680       paths = arrayMap(paths, function(path) {
14681         path = castPath(path, object);
14682         isDeep || (isDeep = path.length > 1);
14683         return path;
14684       });
14685       copyObject(object, getAllKeysIn(object), result);
14686       if (isDeep) {
14687         result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
14688       }
14689       var length = paths.length;
14690       while (length--) {
14691         baseUnset(result, paths[length]);
14692       }
14693       return result;
14694     });
14695
14696     /**
14697      * The opposite of `_.pickBy`; this method creates an object composed of
14698      * the own and inherited enumerable string keyed properties of `object` that
14699      * `predicate` doesn't return truthy for. The predicate is invoked with two
14700      * arguments: (value, key).
14701      *
14702      * @static
14703      * @memberOf _
14704      * @since 4.0.0
14705      * @category Object
14706      * @param {Object} object The source object.
14707      * @param {Function} [predicate=_.identity] The function invoked per property.
14708      * @returns {Object} Returns the new object.
14709      * @example
14710      *
14711      * var object = { 'a': 1, 'b': '2', 'c': 3 };
14712      *
14713      * _.omitBy(object, _.isNumber);
14714      * // => { 'b': '2' }
14715      */
14716     function omitBy(object, predicate) {
14717       return pickBy(object, negate(getIteratee(predicate)));
14718     }
14719
14720     /**
14721      * Creates an object composed of the picked `object` properties.
14722      *
14723      * @static
14724      * @since 0.1.0
14725      * @memberOf _
14726      * @category Object
14727      * @param {Object} object The source object.
14728      * @param {...(string|string[])} [paths] The property paths to pick.
14729      * @returns {Object} Returns the new object.
14730      * @example
14731      *
14732      * var object = { 'a': 1, 'b': '2', 'c': 3 };
14733      *
14734      * _.pick(object, ['a', 'c']);
14735      * // => { 'a': 1, 'c': 3 }
14736      */
14737     var pick = flatRest(function(object, paths) {
14738       return object == null ? {} : basePick(object, paths);
14739     });
14740
14741     /**
14742      * Creates an object composed of the `object` properties `predicate` returns
14743      * truthy for. The predicate is invoked with two arguments: (value, key).
14744      *
14745      * @static
14746      * @memberOf _
14747      * @since 4.0.0
14748      * @category Object
14749      * @param {Object} object The source object.
14750      * @param {Function} [predicate=_.identity] The function invoked per property.
14751      * @returns {Object} Returns the new object.
14752      * @example
14753      *
14754      * var object = { 'a': 1, 'b': '2', 'c': 3 };
14755      *
14756      * _.pickBy(object, _.isNumber);
14757      * // => { 'a': 1, 'c': 3 }
14758      */
14759     function pickBy(object, predicate) {
14760       if (object == null) {
14761         return {};
14762       }
14763       var props = arrayMap(getAllKeysIn(object), function(prop) {
14764         return [prop];
14765       });
14766       predicate = getIteratee(predicate);
14767       return basePickBy(object, props, function(value, path) {
14768         return predicate(value, path[0]);
14769       });
14770     }
14771
14772     /**
14773      * This method is like `_.get` except that if the resolved value is a
14774      * function it's invoked with the `this` binding of its parent object and
14775      * its result is returned.
14776      *
14777      * @static
14778      * @since 0.1.0
14779      * @memberOf _
14780      * @category Object
14781      * @param {Object} object The object to query.
14782      * @param {Array|string} path The path of the property to resolve.
14783      * @param {*} [defaultValue] The value returned for `undefined` resolved values.
14784      * @returns {*} Returns the resolved value.
14785      * @example
14786      *
14787      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
14788      *
14789      * _.result(object, 'a[0].b.c1');
14790      * // => 3
14791      *
14792      * _.result(object, 'a[0].b.c2');
14793      * // => 4
14794      *
14795      * _.result(object, 'a[0].b.c3', 'default');
14796      * // => 'default'
14797      *
14798      * _.result(object, 'a[0].b.c3', _.constant('default'));
14799      * // => 'default'
14800      */
14801     function result(object, path, defaultValue) {
14802       path = castPath(path, object);
14803
14804       var index = -1,
14805           length = path.length;
14806
14807       // Ensure the loop is entered when path is empty.
14808       if (!length) {
14809         length = 1;
14810         object = undefined;
14811       }
14812       while (++index < length) {
14813         var value = object == null ? undefined : object[toKey(path[index])];
14814         if (value === undefined) {
14815           index = length;
14816           value = defaultValue;
14817         }
14818         object = isFunction(value) ? value.call(object) : value;
14819       }
14820       return object;
14821     }
14822
14823     /**
14824      * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
14825      * it's created. Arrays are created for missing index properties while objects
14826      * are created for all other missing properties. Use `_.setWith` to customize
14827      * `path` creation.
14828      *
14829      * **Note:** This method mutates `object`.
14830      *
14831      * @static
14832      * @memberOf _
14833      * @since 3.7.0
14834      * @category Object
14835      * @param {Object} object The object to modify.
14836      * @param {Array|string} path The path of the property to set.
14837      * @param {*} value The value to set.
14838      * @returns {Object} Returns `object`.
14839      * @example
14840      *
14841      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
14842      *
14843      * _.set(object, 'a[0].b.c', 4);
14844      * console.log(object.a[0].b.c);
14845      * // => 4
14846      *
14847      * _.set(object, ['x', '0', 'y', 'z'], 5);
14848      * console.log(object.x[0].y.z);
14849      * // => 5
14850      */
14851     function set(object, path, value) {
14852       return object == null ? object : baseSet(object, path, value);
14853     }
14854
14855     /**
14856      * This method is like `_.set` except that it accepts `customizer` which is
14857      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
14858      * path creation is handled by the method instead. The `customizer` is invoked
14859      * with three arguments: (nsValue, key, nsObject).
14860      *
14861      * **Note:** This method mutates `object`.
14862      *
14863      * @static
14864      * @memberOf _
14865      * @since 4.0.0
14866      * @category Object
14867      * @param {Object} object The object to modify.
14868      * @param {Array|string} path The path of the property to set.
14869      * @param {*} value The value to set.
14870      * @param {Function} [customizer] The function to customize assigned values.
14871      * @returns {Object} Returns `object`.
14872      * @example
14873      *
14874      * var object = {};
14875      *
14876      * _.setWith(object, '[0][1]', 'a', Object);
14877      * // => { '0': { '1': 'a' } }
14878      */
14879     function setWith(object, path, value, customizer) {
14880       customizer = typeof customizer == 'function' ? customizer : undefined;
14881       return object == null ? object : baseSet(object, path, value, customizer);
14882     }
14883
14884     /**
14885      * Creates an array of own enumerable string keyed-value pairs for `object`
14886      * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
14887      * entries are returned.
14888      *
14889      * @static
14890      * @memberOf _
14891      * @since 4.0.0
14892      * @alias entries
14893      * @category Object
14894      * @param {Object} object The object to query.
14895      * @returns {Array} Returns the key-value pairs.
14896      * @example
14897      *
14898      * function Foo() {
14899      *   this.a = 1;
14900      *   this.b = 2;
14901      * }
14902      *
14903      * Foo.prototype.c = 3;
14904      *
14905      * _.toPairs(new Foo);
14906      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
14907      */
14908     var toPairs = createToPairs(keys);
14909
14910     /**
14911      * Creates an array of own and inherited enumerable string keyed-value pairs
14912      * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
14913      * or set, its entries are returned.
14914      *
14915      * @static
14916      * @memberOf _
14917      * @since 4.0.0
14918      * @alias entriesIn
14919      * @category Object
14920      * @param {Object} object The object to query.
14921      * @returns {Array} Returns the key-value pairs.
14922      * @example
14923      *
14924      * function Foo() {
14925      *   this.a = 1;
14926      *   this.b = 2;
14927      * }
14928      *
14929      * Foo.prototype.c = 3;
14930      *
14931      * _.toPairsIn(new Foo);
14932      * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
14933      */
14934     var toPairsIn = createToPairs(keysIn);
14935
14936     /**
14937      * An alternative to `_.reduce`; this method transforms `object` to a new
14938      * `accumulator` object which is the result of running each of its own
14939      * enumerable string keyed properties thru `iteratee`, with each invocation
14940      * potentially mutating the `accumulator` object. If `accumulator` is not
14941      * provided, a new object with the same `[[Prototype]]` will be used. The
14942      * iteratee is invoked with four arguments: (accumulator, value, key, object).
14943      * Iteratee functions may exit iteration early by explicitly returning `false`.
14944      *
14945      * @static
14946      * @memberOf _
14947      * @since 1.3.0
14948      * @category Object
14949      * @param {Object} object The object to iterate over.
14950      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14951      * @param {*} [accumulator] The custom accumulator value.
14952      * @returns {*} Returns the accumulated value.
14953      * @example
14954      *
14955      * _.transform([2, 3, 4], function(result, n) {
14956      *   result.push(n *= n);
14957      *   return n % 2 == 0;
14958      * }, []);
14959      * // => [4, 9]
14960      *
14961      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
14962      *   (result[value] || (result[value] = [])).push(key);
14963      * }, {});
14964      * // => { '1': ['a', 'c'], '2': ['b'] }
14965      */
14966     function transform(object, iteratee, accumulator) {
14967       var isArr = isArray(object),
14968           isArrLike = isArr || isBuffer(object) || isTypedArray(object);
14969
14970       iteratee = getIteratee(iteratee, 4);
14971       if (accumulator == null) {
14972         var Ctor = object && object.constructor;
14973         if (isArrLike) {
14974           accumulator = isArr ? new Ctor : [];
14975         }
14976         else if (isObject(object)) {
14977           accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
14978         }
14979         else {
14980           accumulator = {};
14981         }
14982       }
14983       (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
14984         return iteratee(accumulator, value, index, object);
14985       });
14986       return accumulator;
14987     }
14988
14989     /**
14990      * Removes the property at `path` of `object`.
14991      *
14992      * **Note:** This method mutates `object`.
14993      *
14994      * @static
14995      * @memberOf _
14996      * @since 4.0.0
14997      * @category Object
14998      * @param {Object} object The object to modify.
14999      * @param {Array|string} path The path of the property to unset.
15000      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
15001      * @example
15002      *
15003      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
15004      * _.unset(object, 'a[0].b.c');
15005      * // => true
15006      *
15007      * console.log(object);
15008      * // => { 'a': [{ 'b': {} }] };
15009      *
15010      * _.unset(object, ['a', '0', 'b', 'c']);
15011      * // => true
15012      *
15013      * console.log(object);
15014      * // => { 'a': [{ 'b': {} }] };
15015      */
15016     function unset(object, path) {
15017       return object == null ? true : baseUnset(object, path);
15018     }
15019
15020     /**
15021      * This method is like `_.set` except that accepts `updater` to produce the
15022      * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
15023      * is invoked with one argument: (value).
15024      *
15025      * **Note:** This method mutates `object`.
15026      *
15027      * @static
15028      * @memberOf _
15029      * @since 4.6.0
15030      * @category Object
15031      * @param {Object} object The object to modify.
15032      * @param {Array|string} path The path of the property to set.
15033      * @param {Function} updater The function to produce the updated value.
15034      * @returns {Object} Returns `object`.
15035      * @example
15036      *
15037      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
15038      *
15039      * _.update(object, 'a[0].b.c', function(n) { return n * n; });
15040      * console.log(object.a[0].b.c);
15041      * // => 9
15042      *
15043      * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
15044      * console.log(object.x[0].y.z);
15045      * // => 0
15046      */
15047     function update(object, path, updater) {
15048       return object == null ? object : baseUpdate(object, path, castFunction(updater));
15049     }
15050
15051     /**
15052      * This method is like `_.update` except that it accepts `customizer` which is
15053      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
15054      * path creation is handled by the method instead. The `customizer` is invoked
15055      * with three arguments: (nsValue, key, nsObject).
15056      *
15057      * **Note:** This method mutates `object`.
15058      *
15059      * @static
15060      * @memberOf _
15061      * @since 4.6.0
15062      * @category Object
15063      * @param {Object} object The object to modify.
15064      * @param {Array|string} path The path of the property to set.
15065      * @param {Function} updater The function to produce the updated value.
15066      * @param {Function} [customizer] The function to customize assigned values.
15067      * @returns {Object} Returns `object`.
15068      * @example
15069      *
15070      * var object = {};
15071      *
15072      * _.updateWith(object, '[0][1]', _.constant('a'), Object);
15073      * // => { '0': { '1': 'a' } }
15074      */
15075     function updateWith(object, path, updater, customizer) {
15076       customizer = typeof customizer == 'function' ? customizer : undefined;
15077       return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
15078     }
15079
15080     /**
15081      * Creates an array of the own enumerable string keyed property values of `object`.
15082      *
15083      * **Note:** Non-object values are coerced to objects.
15084      *
15085      * @static
15086      * @since 0.1.0
15087      * @memberOf _
15088      * @category Object
15089      * @param {Object} object The object to query.
15090      * @returns {Array} Returns the array of property values.
15091      * @example
15092      *
15093      * function Foo() {
15094      *   this.a = 1;
15095      *   this.b = 2;
15096      * }
15097      *
15098      * Foo.prototype.c = 3;
15099      *
15100      * _.values(new Foo);
15101      * // => [1, 2] (iteration order is not guaranteed)
15102      *
15103      * _.values('hi');
15104      * // => ['h', 'i']
15105      */
15106     function values(object) {
15107       return object == null ? [] : baseValues(object, keys(object));
15108     }
15109
15110     /**
15111      * Creates an array of the own and inherited enumerable string keyed property
15112      * values of `object`.
15113      *
15114      * **Note:** Non-object values are coerced to objects.
15115      *
15116      * @static
15117      * @memberOf _
15118      * @since 3.0.0
15119      * @category Object
15120      * @param {Object} object The object to query.
15121      * @returns {Array} Returns the array of property values.
15122      * @example
15123      *
15124      * function Foo() {
15125      *   this.a = 1;
15126      *   this.b = 2;
15127      * }
15128      *
15129      * Foo.prototype.c = 3;
15130      *
15131      * _.valuesIn(new Foo);
15132      * // => [1, 2, 3] (iteration order is not guaranteed)
15133      */
15134     function valuesIn(object) {
15135       return object == null ? [] : baseValues(object, keysIn(object));
15136     }
15137
15138     /*------------------------------------------------------------------------*/
15139
15140     /**
15141      * Clamps `number` within the inclusive `lower` and `upper` bounds.
15142      *
15143      * @static
15144      * @memberOf _
15145      * @since 4.0.0
15146      * @category Number
15147      * @param {number} number The number to clamp.
15148      * @param {number} [lower] The lower bound.
15149      * @param {number} upper The upper bound.
15150      * @returns {number} Returns the clamped number.
15151      * @example
15152      *
15153      * _.clamp(-10, -5, 5);
15154      * // => -5
15155      *
15156      * _.clamp(10, -5, 5);
15157      * // => 5
15158      */
15159     function clamp(number, lower, upper) {
15160       if (upper === undefined) {
15161         upper = lower;
15162         lower = undefined;
15163       }
15164       if (upper !== undefined) {
15165         upper = toNumber(upper);
15166         upper = upper === upper ? upper : 0;
15167       }
15168       if (lower !== undefined) {
15169         lower = toNumber(lower);
15170         lower = lower === lower ? lower : 0;
15171       }
15172       return baseClamp(toNumber(number), lower, upper);
15173     }
15174
15175     /**
15176      * Checks if `n` is between `start` and up to, but not including, `end`. If
15177      * `end` is not specified, it's set to `start` with `start` then set to `0`.
15178      * If `start` is greater than `end` the params are swapped to support
15179      * negative ranges.
15180      *
15181      * @static
15182      * @memberOf _
15183      * @since 3.3.0
15184      * @category Number
15185      * @param {number} number The number to check.
15186      * @param {number} [start=0] The start of the range.
15187      * @param {number} end The end of the range.
15188      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
15189      * @see _.range, _.rangeRight
15190      * @example
15191      *
15192      * _.inRange(3, 2, 4);
15193      * // => true
15194      *
15195      * _.inRange(4, 8);
15196      * // => true
15197      *
15198      * _.inRange(4, 2);
15199      * // => false
15200      *
15201      * _.inRange(2, 2);
15202      * // => false
15203      *
15204      * _.inRange(1.2, 2);
15205      * // => true
15206      *
15207      * _.inRange(5.2, 4);
15208      * // => false
15209      *
15210      * _.inRange(-3, -2, -6);
15211      * // => true
15212      */
15213     function inRange(number, start, end) {
15214       start = toFinite(start);
15215       if (end === undefined) {
15216         end = start;
15217         start = 0;
15218       } else {
15219         end = toFinite(end);
15220       }
15221       number = toNumber(number);
15222       return baseInRange(number, start, end);
15223     }
15224
15225     /**
15226      * Produces a random number between the inclusive `lower` and `upper` bounds.
15227      * If only one argument is provided a number between `0` and the given number
15228      * is returned. If `floating` is `true`, or either `lower` or `upper` are
15229      * floats, a floating-point number is returned instead of an integer.
15230      *
15231      * **Note:** JavaScript follows the IEEE-754 standard for resolving
15232      * floating-point values which can produce unexpected results.
15233      *
15234      * @static
15235      * @memberOf _
15236      * @since 0.7.0
15237      * @category Number
15238      * @param {number} [lower=0] The lower bound.
15239      * @param {number} [upper=1] The upper bound.
15240      * @param {boolean} [floating] Specify returning a floating-point number.
15241      * @returns {number} Returns the random number.
15242      * @example
15243      *
15244      * _.random(0, 5);
15245      * // => an integer between 0 and 5
15246      *
15247      * _.random(5);
15248      * // => also an integer between 0 and 5
15249      *
15250      * _.random(5, true);
15251      * // => a floating-point number between 0 and 5
15252      *
15253      * _.random(1.2, 5.2);
15254      * // => a floating-point number between 1.2 and 5.2
15255      */
15256     function random(lower, upper, floating) {
15257       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
15258         upper = floating = undefined;
15259       }
15260       if (floating === undefined) {
15261         if (typeof upper == 'boolean') {
15262           floating = upper;
15263           upper = undefined;
15264         }
15265         else if (typeof lower == 'boolean') {
15266           floating = lower;
15267           lower = undefined;
15268         }
15269       }
15270       if (lower === undefined && upper === undefined) {
15271         lower = 0;
15272         upper = 1;
15273       }
15274       else {
15275         lower = toFinite(lower);
15276         if (upper === undefined) {
15277           upper = lower;
15278           lower = 0;
15279         } else {
15280           upper = toFinite(upper);
15281         }
15282       }
15283       if (lower > upper) {
15284         var temp = lower;
15285         lower = upper;
15286         upper = temp;
15287       }
15288       if (floating || lower % 1 || upper % 1) {
15289         var rand = nativeRandom();
15290         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
15291       }
15292       return baseRandom(lower, upper);
15293     }
15294
15295     /*------------------------------------------------------------------------*/
15296
15297     /**
15298      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
15299      *
15300      * @static
15301      * @memberOf _
15302      * @since 3.0.0
15303      * @category String
15304      * @param {string} [string=''] The string to convert.
15305      * @returns {string} Returns the camel cased string.
15306      * @example
15307      *
15308      * _.camelCase('Foo Bar');
15309      * // => 'fooBar'
15310      *
15311      * _.camelCase('--foo-bar--');
15312      * // => 'fooBar'
15313      *
15314      * _.camelCase('__FOO_BAR__');
15315      * // => 'fooBar'
15316      */
15317     var camelCase = createCompounder(function(result, word, index) {
15318       word = word.toLowerCase();
15319       return result + (index ? capitalize(word) : word);
15320     });
15321
15322     /**
15323      * Converts the first character of `string` to upper case and the remaining
15324      * to lower case.
15325      *
15326      * @static
15327      * @memberOf _
15328      * @since 3.0.0
15329      * @category String
15330      * @param {string} [string=''] The string to capitalize.
15331      * @returns {string} Returns the capitalized string.
15332      * @example
15333      *
15334      * _.capitalize('FRED');
15335      * // => 'Fred'
15336      */
15337     function capitalize(string) {
15338       return upperFirst(toString(string).toLowerCase());
15339     }
15340
15341     /**
15342      * Deburrs `string` by converting
15343      * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
15344      * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
15345      * letters to basic Latin letters and removing
15346      * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
15347      *
15348      * @static
15349      * @memberOf _
15350      * @since 3.0.0
15351      * @category String
15352      * @param {string} [string=''] The string to deburr.
15353      * @returns {string} Returns the deburred string.
15354      * @example
15355      *
15356      * _.deburr('déjà vu');
15357      * // => 'deja vu'
15358      */
15359     function deburr(string) {
15360       string = toString(string);
15361       return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
15362     }
15363
15364     /**
15365      * Checks if `string` ends with the given target string.
15366      *
15367      * @static
15368      * @memberOf _
15369      * @since 3.0.0
15370      * @category String
15371      * @param {string} [string=''] The string to inspect.
15372      * @param {string} [target] The string to search for.
15373      * @param {number} [position=string.length] The position to search up to.
15374      * @returns {boolean} Returns `true` if `string` ends with `target`,
15375      *  else `false`.
15376      * @example
15377      *
15378      * _.endsWith('abc', 'c');
15379      * // => true
15380      *
15381      * _.endsWith('abc', 'b');
15382      * // => false
15383      *
15384      * _.endsWith('abc', 'b', 2);
15385      * // => true
15386      */
15387     function endsWith(string, target, position) {
15388       string = toString(string);
15389       target = baseToString(target);
15390
15391       var length = string.length;
15392       position = position === undefined
15393         ? length
15394         : baseClamp(toInteger(position), 0, length);
15395
15396       var end = position;
15397       position -= target.length;
15398       return position >= 0 && string.slice(position, end) == target;
15399     }
15400
15401     /**
15402      * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
15403      * corresponding HTML entities.
15404      *
15405      * **Note:** No other characters are escaped. To escape additional
15406      * characters use a third-party library like [_he_](https://mths.be/he).
15407      *
15408      * Though the ">" character is escaped for symmetry, characters like
15409      * ">" and "/" don't need escaping in HTML and have no special meaning
15410      * unless they're part of a tag or unquoted attribute value. See
15411      * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
15412      * (under "semi-related fun fact") for more details.
15413      *
15414      * When working with HTML you should always
15415      * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
15416      * XSS vectors.
15417      *
15418      * @static
15419      * @since 0.1.0
15420      * @memberOf _
15421      * @category String
15422      * @param {string} [string=''] The string to escape.
15423      * @returns {string} Returns the escaped string.
15424      * @example
15425      *
15426      * _.escape('fred, barney, & pebbles');
15427      * // => 'fred, barney, &amp; pebbles'
15428      */
15429     function escape(string) {
15430       string = toString(string);
15431       return (string && reHasUnescapedHtml.test(string))
15432         ? string.replace(reUnescapedHtml, escapeHtmlChar)
15433         : string;
15434     }
15435
15436     /**
15437      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
15438      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
15439      *
15440      * @static
15441      * @memberOf _
15442      * @since 3.0.0
15443      * @category String
15444      * @param {string} [string=''] The string to escape.
15445      * @returns {string} Returns the escaped string.
15446      * @example
15447      *
15448      * _.escapeRegExp('[lodash](https://lodash.com/)');
15449      * // => '\[lodash\]\(https://lodash\.com/\)'
15450      */
15451     function escapeRegExp(string) {
15452       string = toString(string);
15453       return (string && reHasRegExpChar.test(string))
15454         ? string.replace(reRegExpChar, '\\$&')
15455         : string;
15456     }
15457
15458     /**
15459      * Converts `string` to
15460      * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
15461      *
15462      * @static
15463      * @memberOf _
15464      * @since 3.0.0
15465      * @category String
15466      * @param {string} [string=''] The string to convert.
15467      * @returns {string} Returns the kebab cased string.
15468      * @example
15469      *
15470      * _.kebabCase('Foo Bar');
15471      * // => 'foo-bar'
15472      *
15473      * _.kebabCase('fooBar');
15474      * // => 'foo-bar'
15475      *
15476      * _.kebabCase('__FOO_BAR__');
15477      * // => 'foo-bar'
15478      */
15479     var kebabCase = createCompounder(function(result, word, index) {
15480       return result + (index ? '-' : '') + word.toLowerCase();
15481     });
15482
15483     /**
15484      * Converts `string`, as space separated words, to lower case.
15485      *
15486      * @static
15487      * @memberOf _
15488      * @since 4.0.0
15489      * @category String
15490      * @param {string} [string=''] The string to convert.
15491      * @returns {string} Returns the lower cased string.
15492      * @example
15493      *
15494      * _.lowerCase('--Foo-Bar--');
15495      * // => 'foo bar'
15496      *
15497      * _.lowerCase('fooBar');
15498      * // => 'foo bar'
15499      *
15500      * _.lowerCase('__FOO_BAR__');
15501      * // => 'foo bar'
15502      */
15503     var lowerCase = createCompounder(function(result, word, index) {
15504       return result + (index ? ' ' : '') + word.toLowerCase();
15505     });
15506
15507     /**
15508      * Converts the first character of `string` to lower case.
15509      *
15510      * @static
15511      * @memberOf _
15512      * @since 4.0.0
15513      * @category String
15514      * @param {string} [string=''] The string to convert.
15515      * @returns {string} Returns the converted string.
15516      * @example
15517      *
15518      * _.lowerFirst('Fred');
15519      * // => 'fred'
15520      *
15521      * _.lowerFirst('FRED');
15522      * // => 'fRED'
15523      */
15524     var lowerFirst = createCaseFirst('toLowerCase');
15525
15526     /**
15527      * Pads `string` on the left and right sides if it's shorter than `length`.
15528      * Padding characters are truncated if they can't be evenly divided by `length`.
15529      *
15530      * @static
15531      * @memberOf _
15532      * @since 3.0.0
15533      * @category String
15534      * @param {string} [string=''] The string to pad.
15535      * @param {number} [length=0] The padding length.
15536      * @param {string} [chars=' '] The string used as padding.
15537      * @returns {string} Returns the padded string.
15538      * @example
15539      *
15540      * _.pad('abc', 8);
15541      * // => '  abc   '
15542      *
15543      * _.pad('abc', 8, '_-');
15544      * // => '_-abc_-_'
15545      *
15546      * _.pad('abc', 3);
15547      * // => 'abc'
15548      */
15549     function pad(string, length, chars) {
15550       string = toString(string);
15551       length = toInteger(length);
15552
15553       var strLength = length ? stringSize(string) : 0;
15554       if (!length || strLength >= length) {
15555         return string;
15556       }
15557       var mid = (length - strLength) / 2;
15558       return (
15559         createPadding(nativeFloor(mid), chars) +
15560         string +
15561         createPadding(nativeCeil(mid), chars)
15562       );
15563     }
15564
15565     /**
15566      * Pads `string` on the right side if it's shorter than `length`. Padding
15567      * characters are truncated if they exceed `length`.
15568      *
15569      * @static
15570      * @memberOf _
15571      * @since 4.0.0
15572      * @category String
15573      * @param {string} [string=''] The string to pad.
15574      * @param {number} [length=0] The padding length.
15575      * @param {string} [chars=' '] The string used as padding.
15576      * @returns {string} Returns the padded string.
15577      * @example
15578      *
15579      * _.padEnd('abc', 6);
15580      * // => 'abc   '
15581      *
15582      * _.padEnd('abc', 6, '_-');
15583      * // => 'abc_-_'
15584      *
15585      * _.padEnd('abc', 3);
15586      * // => 'abc'
15587      */
15588     function padEnd(string, length, chars) {
15589       string = toString(string);
15590       length = toInteger(length);
15591
15592       var strLength = length ? stringSize(string) : 0;
15593       return (length && strLength < length)
15594         ? (string + createPadding(length - strLength, chars))
15595         : string;
15596     }
15597
15598     /**
15599      * Pads `string` on the left side if it's shorter than `length`. Padding
15600      * characters are truncated if they exceed `length`.
15601      *
15602      * @static
15603      * @memberOf _
15604      * @since 4.0.0
15605      * @category String
15606      * @param {string} [string=''] The string to pad.
15607      * @param {number} [length=0] The padding length.
15608      * @param {string} [chars=' '] The string used as padding.
15609      * @returns {string} Returns the padded string.
15610      * @example
15611      *
15612      * _.padStart('abc', 6);
15613      * // => '   abc'
15614      *
15615      * _.padStart('abc', 6, '_-');
15616      * // => '_-_abc'
15617      *
15618      * _.padStart('abc', 3);
15619      * // => 'abc'
15620      */
15621     function padStart(string, length, chars) {
15622       string = toString(string);
15623       length = toInteger(length);
15624
15625       var strLength = length ? stringSize(string) : 0;
15626       return (length && strLength < length)
15627         ? (createPadding(length - strLength, chars) + string)
15628         : string;
15629     }
15630
15631     /**
15632      * Converts `string` to an integer of the specified radix. If `radix` is
15633      * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
15634      * hexadecimal, in which case a `radix` of `16` is used.
15635      *
15636      * **Note:** This method aligns with the
15637      * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
15638      *
15639      * @static
15640      * @memberOf _
15641      * @since 1.1.0
15642      * @category String
15643      * @param {string} string The string to convert.
15644      * @param {number} [radix=10] The radix to interpret `value` by.
15645      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15646      * @returns {number} Returns the converted integer.
15647      * @example
15648      *
15649      * _.parseInt('08');
15650      * // => 8
15651      *
15652      * _.map(['6', '08', '10'], _.parseInt);
15653      * // => [6, 8, 10]
15654      */
15655     function parseInt(string, radix, guard) {
15656       if (guard || radix == null) {
15657         radix = 0;
15658       } else if (radix) {
15659         radix = +radix;
15660       }
15661       return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
15662     }
15663
15664     /**
15665      * Repeats the given string `n` times.
15666      *
15667      * @static
15668      * @memberOf _
15669      * @since 3.0.0
15670      * @category String
15671      * @param {string} [string=''] The string to repeat.
15672      * @param {number} [n=1] The number of times to repeat the string.
15673      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15674      * @returns {string} Returns the repeated string.
15675      * @example
15676      *
15677      * _.repeat('*', 3);
15678      * // => '***'
15679      *
15680      * _.repeat('abc', 2);
15681      * // => 'abcabc'
15682      *
15683      * _.repeat('abc', 0);
15684      * // => ''
15685      */
15686     function repeat(string, n, guard) {
15687       if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
15688         n = 1;
15689       } else {
15690         n = toInteger(n);
15691       }
15692       return baseRepeat(toString(string), n);
15693     }
15694
15695     /**
15696      * Replaces matches for `pattern` in `string` with `replacement`.
15697      *
15698      * **Note:** This method is based on
15699      * [`String#replace`](https://mdn.io/String/replace).
15700      *
15701      * @static
15702      * @memberOf _
15703      * @since 4.0.0
15704      * @category String
15705      * @param {string} [string=''] The string to modify.
15706      * @param {RegExp|string} pattern The pattern to replace.
15707      * @param {Function|string} replacement The match replacement.
15708      * @returns {string} Returns the modified string.
15709      * @example
15710      *
15711      * _.replace('Hi Fred', 'Fred', 'Barney');
15712      * // => 'Hi Barney'
15713      */
15714     function replace() {
15715       var args = arguments,
15716           string = toString(args[0]);
15717
15718       return args.length < 3 ? string : string.replace(args[1], args[2]);
15719     }
15720
15721     /**
15722      * Converts `string` to
15723      * [snake case](https://en.wikipedia.org/wiki/Snake_case).
15724      *
15725      * @static
15726      * @memberOf _
15727      * @since 3.0.0
15728      * @category String
15729      * @param {string} [string=''] The string to convert.
15730      * @returns {string} Returns the snake cased string.
15731      * @example
15732      *
15733      * _.snakeCase('Foo Bar');
15734      * // => 'foo_bar'
15735      *
15736      * _.snakeCase('fooBar');
15737      * // => 'foo_bar'
15738      *
15739      * _.snakeCase('--FOO-BAR--');
15740      * // => 'foo_bar'
15741      */
15742     var snakeCase = createCompounder(function(result, word, index) {
15743       return result + (index ? '_' : '') + word.toLowerCase();
15744     });
15745
15746     /**
15747      * Splits `string` by `separator`.
15748      *
15749      * **Note:** This method is based on
15750      * [`String#split`](https://mdn.io/String/split).
15751      *
15752      * @static
15753      * @memberOf _
15754      * @since 4.0.0
15755      * @category String
15756      * @param {string} [string=''] The string to split.
15757      * @param {RegExp|string} separator The separator pattern to split by.
15758      * @param {number} [limit] The length to truncate results to.
15759      * @returns {Array} Returns the string segments.
15760      * @example
15761      *
15762      * _.split('a-b-c', '-', 2);
15763      * // => ['a', 'b']
15764      */
15765     function split(string, separator, limit) {
15766       if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
15767         separator = limit = undefined;
15768       }
15769       limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
15770       if (!limit) {
15771         return [];
15772       }
15773       string = toString(string);
15774       if (string && (
15775             typeof separator == 'string' ||
15776             (separator != null && !isRegExp(separator))
15777           )) {
15778         separator = baseToString(separator);
15779         if (!separator && hasUnicode(string)) {
15780           return castSlice(stringToArray(string), 0, limit);
15781         }
15782       }
15783       return string.split(separator, limit);
15784     }
15785
15786     /**
15787      * Converts `string` to
15788      * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
15789      *
15790      * @static
15791      * @memberOf _
15792      * @since 3.1.0
15793      * @category String
15794      * @param {string} [string=''] The string to convert.
15795      * @returns {string} Returns the start cased string.
15796      * @example
15797      *
15798      * _.startCase('--foo-bar--');
15799      * // => 'Foo Bar'
15800      *
15801      * _.startCase('fooBar');
15802      * // => 'Foo Bar'
15803      *
15804      * _.startCase('__FOO_BAR__');
15805      * // => 'FOO BAR'
15806      */
15807     var startCase = createCompounder(function(result, word, index) {
15808       return result + (index ? ' ' : '') + upperFirst(word);
15809     });
15810
15811     /**
15812      * Checks if `string` starts with the given target string.
15813      *
15814      * @static
15815      * @memberOf _
15816      * @since 3.0.0
15817      * @category String
15818      * @param {string} [string=''] The string to inspect.
15819      * @param {string} [target] The string to search for.
15820      * @param {number} [position=0] The position to search from.
15821      * @returns {boolean} Returns `true` if `string` starts with `target`,
15822      *  else `false`.
15823      * @example
15824      *
15825      * _.startsWith('abc', 'a');
15826      * // => true
15827      *
15828      * _.startsWith('abc', 'b');
15829      * // => false
15830      *
15831      * _.startsWith('abc', 'b', 1);
15832      * // => true
15833      */
15834     function startsWith(string, target, position) {
15835       string = toString(string);
15836       position = position == null
15837         ? 0
15838         : baseClamp(toInteger(position), 0, string.length);
15839
15840       target = baseToString(target);
15841       return string.slice(position, position + target.length) == target;
15842     }
15843
15844     /**
15845      * Creates a compiled template function that can interpolate data properties
15846      * in "interpolate" delimiters, HTML-escape interpolated data properties in
15847      * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
15848      * properties may be accessed as free variables in the template. If a setting
15849      * object is given, it takes precedence over `_.templateSettings` values.
15850      *
15851      * **Note:** In the development build `_.template` utilizes
15852      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
15853      * for easier debugging.
15854      *
15855      * For more information on precompiling templates see
15856      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
15857      *
15858      * For more information on Chrome extension sandboxes see
15859      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
15860      *
15861      * @static
15862      * @since 0.1.0
15863      * @memberOf _
15864      * @category String
15865      * @param {string} [string=''] The template string.
15866      * @param {Object} [options={}] The options object.
15867      * @param {RegExp} [options.escape=_.templateSettings.escape]
15868      *  The HTML "escape" delimiter.
15869      * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
15870      *  The "evaluate" delimiter.
15871      * @param {Object} [options.imports=_.templateSettings.imports]
15872      *  An object to import into the template as free variables.
15873      * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
15874      *  The "interpolate" delimiter.
15875      * @param {string} [options.sourceURL='lodash.templateSources[n]']
15876      *  The sourceURL of the compiled template.
15877      * @param {string} [options.variable='obj']
15878      *  The data object variable name.
15879      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15880      * @returns {Function} Returns the compiled template function.
15881      * @example
15882      *
15883      * // Use the "interpolate" delimiter to create a compiled template.
15884      * var compiled = _.template('hello <%= user %>!');
15885      * compiled({ 'user': 'fred' });
15886      * // => 'hello fred!'
15887      *
15888      * // Use the HTML "escape" delimiter to escape data property values.
15889      * var compiled = _.template('<b><%- value %></b>');
15890      * compiled({ 'value': '<script>' });
15891      * // => '<b>&lt;script&gt;</b>'
15892      *
15893      * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
15894      * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
15895      * compiled({ 'users': ['fred', 'barney'] });
15896      * // => '<li>fred</li><li>barney</li>'
15897      *
15898      * // Use the internal `print` function in "evaluate" delimiters.
15899      * var compiled = _.template('<% print("hello " + user); %>!');
15900      * compiled({ 'user': 'barney' });
15901      * // => 'hello barney!'
15902      *
15903      * // Use the ES template literal delimiter as an "interpolate" delimiter.
15904      * // Disable support by replacing the "interpolate" delimiter.
15905      * var compiled = _.template('hello ${ user }!');
15906      * compiled({ 'user': 'pebbles' });
15907      * // => 'hello pebbles!'
15908      *
15909      * // Use backslashes to treat delimiters as plain text.
15910      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
15911      * compiled({ 'value': 'ignored' });
15912      * // => '<%- value %>'
15913      *
15914      * // Use the `imports` option to import `jQuery` as `jq`.
15915      * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
15916      * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
15917      * compiled({ 'users': ['fred', 'barney'] });
15918      * // => '<li>fred</li><li>barney</li>'
15919      *
15920      * // Use the `sourceURL` option to specify a custom sourceURL for the template.
15921      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
15922      * compiled(data);
15923      * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
15924      *
15925      * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
15926      * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
15927      * compiled.source;
15928      * // => function(data) {
15929      * //   var __t, __p = '';
15930      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
15931      * //   return __p;
15932      * // }
15933      *
15934      * // Use custom template delimiters.
15935      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
15936      * var compiled = _.template('hello {{ user }}!');
15937      * compiled({ 'user': 'mustache' });
15938      * // => 'hello mustache!'
15939      *
15940      * // Use the `source` property to inline compiled templates for meaningful
15941      * // line numbers in error messages and stack traces.
15942      * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
15943      *   var JST = {\
15944      *     "main": ' + _.template(mainText).source + '\
15945      *   };\
15946      * ');
15947      */
15948     function template(string, options, guard) {
15949       // Based on John Resig's `tmpl` implementation
15950       // (http://ejohn.org/blog/javascript-micro-templating/)
15951       // and Laura Doktorova's doT.js (https://github.com/olado/doT).
15952       var settings = lodash.templateSettings;
15953
15954       if (guard && isIterateeCall(string, options, guard)) {
15955         options = undefined;
15956       }
15957       string = toString(string);
15958       options = assignInWith({}, options, settings, customDefaultsAssignIn);
15959
15960       var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
15961           importsKeys = keys(imports),
15962           importsValues = baseValues(imports, importsKeys);
15963
15964       var isEscaping,
15965           isEvaluating,
15966           index = 0,
15967           interpolate = options.interpolate || reNoMatch,
15968           source = "__p += '";
15969
15970       // Compile the regexp to match each delimiter.
15971       var reDelimiters = RegExp(
15972         (options.escape || reNoMatch).source + '|' +
15973         interpolate.source + '|' +
15974         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
15975         (options.evaluate || reNoMatch).source + '|$'
15976       , 'g');
15977
15978       // Use a sourceURL for easier debugging.
15979       // The sourceURL gets injected into the source that's eval-ed, so be careful
15980       // to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
15981       // and escape the comment, thus injecting code that gets evaled.
15982       var sourceURL = '//# sourceURL=' +
15983         (hasOwnProperty.call(options, 'sourceURL')
15984           ? (options.sourceURL + '').replace(/\s/g, ' ')
15985           : ('lodash.templateSources[' + (++templateCounter) + ']')
15986         ) + '\n';
15987
15988       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
15989         interpolateValue || (interpolateValue = esTemplateValue);
15990
15991         // Escape characters that can't be included in string literals.
15992         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
15993
15994         // Replace delimiters with snippets.
15995         if (escapeValue) {
15996           isEscaping = true;
15997           source += "' +\n__e(" + escapeValue + ") +\n'";
15998         }
15999         if (evaluateValue) {
16000           isEvaluating = true;
16001           source += "';\n" + evaluateValue + ";\n__p += '";
16002         }
16003         if (interpolateValue) {
16004           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
16005         }
16006         index = offset + match.length;
16007
16008         // The JS engine embedded in Adobe products needs `match` returned in
16009         // order to produce the correct `offset` value.
16010         return match;
16011       });
16012
16013       source += "';\n";
16014
16015       // If `variable` is not specified wrap a with-statement around the generated
16016       // code to add the data object to the top of the scope chain.
16017       var variable = hasOwnProperty.call(options, 'variable') && options.variable;
16018       if (!variable) {
16019         source = 'with (obj) {\n' + source + '\n}\n';
16020       }
16021       // Throw an error if a forbidden character was found in `variable`, to prevent
16022       // potential command injection attacks.
16023       else if (reForbiddenIdentifierChars.test(variable)) {
16024         throw new Error(INVALID_TEMPL_VAR_ERROR_TEXT);
16025       }
16026
16027       // Cleanup code by stripping empty strings.
16028       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
16029         .replace(reEmptyStringMiddle, '$1')
16030         .replace(reEmptyStringTrailing, '$1;');
16031
16032       // Frame code as the function body.
16033       source = 'function(' + (variable || 'obj') + ') {\n' +
16034         (variable
16035           ? ''
16036           : 'obj || (obj = {});\n'
16037         ) +
16038         "var __t, __p = ''" +
16039         (isEscaping
16040            ? ', __e = _.escape'
16041            : ''
16042         ) +
16043         (isEvaluating
16044           ? ', __j = Array.prototype.join;\n' +
16045             "function print() { __p += __j.call(arguments, '') }\n"
16046           : ';\n'
16047         ) +
16048         source +
16049         'return __p\n}';
16050
16051       var result = attempt(function() {
16052         return Function(importsKeys, sourceURL + 'return ' + source)
16053           .apply(undefined, importsValues);
16054       });
16055
16056       // Provide the compiled function's source by its `toString` method or
16057       // the `source` property as a convenience for inlining compiled templates.
16058       result.source = source;
16059       if (isError(result)) {
16060         throw result;
16061       }
16062       return result;
16063     }
16064
16065     /**
16066      * Converts `string`, as a whole, to lower case just like
16067      * [String#toLowerCase](https://mdn.io/toLowerCase).
16068      *
16069      * @static
16070      * @memberOf _
16071      * @since 4.0.0
16072      * @category String
16073      * @param {string} [string=''] The string to convert.
16074      * @returns {string} Returns the lower cased string.
16075      * @example
16076      *
16077      * _.toLower('--Foo-Bar--');
16078      * // => '--foo-bar--'
16079      *
16080      * _.toLower('fooBar');
16081      * // => 'foobar'
16082      *
16083      * _.toLower('__FOO_BAR__');
16084      * // => '__foo_bar__'
16085      */
16086     function toLower(value) {
16087       return toString(value).toLowerCase();
16088     }
16089
16090     /**
16091      * Converts `string`, as a whole, to upper case just like
16092      * [String#toUpperCase](https://mdn.io/toUpperCase).
16093      *
16094      * @static
16095      * @memberOf _
16096      * @since 4.0.0
16097      * @category String
16098      * @param {string} [string=''] The string to convert.
16099      * @returns {string} Returns the upper cased string.
16100      * @example
16101      *
16102      * _.toUpper('--foo-bar--');
16103      * // => '--FOO-BAR--'
16104      *
16105      * _.toUpper('fooBar');
16106      * // => 'FOOBAR'
16107      *
16108      * _.toUpper('__foo_bar__');
16109      * // => '__FOO_BAR__'
16110      */
16111     function toUpper(value) {
16112       return toString(value).toUpperCase();
16113     }
16114
16115     /**
16116      * Removes leading and trailing whitespace or specified characters from `string`.
16117      *
16118      * @static
16119      * @memberOf _
16120      * @since 3.0.0
16121      * @category String
16122      * @param {string} [string=''] The string to trim.
16123      * @param {string} [chars=whitespace] The characters to trim.
16124      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16125      * @returns {string} Returns the trimmed string.
16126      * @example
16127      *
16128      * _.trim('  abc  ');
16129      * // => 'abc'
16130      *
16131      * _.trim('-_-abc-_-', '_-');
16132      * // => 'abc'
16133      *
16134      * _.map(['  foo  ', '  bar  '], _.trim);
16135      * // => ['foo', 'bar']
16136      */
16137     function trim(string, chars, guard) {
16138       string = toString(string);
16139       if (string && (guard || chars === undefined)) {
16140         return baseTrim(string);
16141       }
16142       if (!string || !(chars = baseToString(chars))) {
16143         return string;
16144       }
16145       var strSymbols = stringToArray(string),
16146           chrSymbols = stringToArray(chars),
16147           start = charsStartIndex(strSymbols, chrSymbols),
16148           end = charsEndIndex(strSymbols, chrSymbols) + 1;
16149
16150       return castSlice(strSymbols, start, end).join('');
16151     }
16152
16153     /**
16154      * Removes trailing whitespace or specified characters from `string`.
16155      *
16156      * @static
16157      * @memberOf _
16158      * @since 4.0.0
16159      * @category String
16160      * @param {string} [string=''] The string to trim.
16161      * @param {string} [chars=whitespace] The characters to trim.
16162      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16163      * @returns {string} Returns the trimmed string.
16164      * @example
16165      *
16166      * _.trimEnd('  abc  ');
16167      * // => '  abc'
16168      *
16169      * _.trimEnd('-_-abc-_-', '_-');
16170      * // => '-_-abc'
16171      */
16172     function trimEnd(string, chars, guard) {
16173       string = toString(string);
16174       if (string && (guard || chars === undefined)) {
16175         return string.slice(0, trimmedEndIndex(string) + 1);
16176       }
16177       if (!string || !(chars = baseToString(chars))) {
16178         return string;
16179       }
16180       var strSymbols = stringToArray(string),
16181           end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
16182
16183       return castSlice(strSymbols, 0, end).join('');
16184     }
16185
16186     /**
16187      * Removes leading whitespace or specified characters from `string`.
16188      *
16189      * @static
16190      * @memberOf _
16191      * @since 4.0.0
16192      * @category String
16193      * @param {string} [string=''] The string to trim.
16194      * @param {string} [chars=whitespace] The characters to trim.
16195      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16196      * @returns {string} Returns the trimmed string.
16197      * @example
16198      *
16199      * _.trimStart('  abc  ');
16200      * // => 'abc  '
16201      *
16202      * _.trimStart('-_-abc-_-', '_-');
16203      * // => 'abc-_-'
16204      */
16205     function trimStart(string, chars, guard) {
16206       string = toString(string);
16207       if (string && (guard || chars === undefined)) {
16208         return string.replace(reTrimStart, '');
16209       }
16210       if (!string || !(chars = baseToString(chars))) {
16211         return string;
16212       }
16213       var strSymbols = stringToArray(string),
16214           start = charsStartIndex(strSymbols, stringToArray(chars));
16215
16216       return castSlice(strSymbols, start).join('');
16217     }
16218
16219     /**
16220      * Truncates `string` if it's longer than the given maximum string length.
16221      * The last characters of the truncated string are replaced with the omission
16222      * string which defaults to "...".
16223      *
16224      * @static
16225      * @memberOf _
16226      * @since 4.0.0
16227      * @category String
16228      * @param {string} [string=''] The string to truncate.
16229      * @param {Object} [options={}] The options object.
16230      * @param {number} [options.length=30] The maximum string length.
16231      * @param {string} [options.omission='...'] The string to indicate text is omitted.
16232      * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
16233      * @returns {string} Returns the truncated string.
16234      * @example
16235      *
16236      * _.truncate('hi-diddly-ho there, neighborino');
16237      * // => 'hi-diddly-ho there, neighbo...'
16238      *
16239      * _.truncate('hi-diddly-ho there, neighborino', {
16240      *   'length': 24,
16241      *   'separator': ' '
16242      * });
16243      * // => 'hi-diddly-ho there,...'
16244      *
16245      * _.truncate('hi-diddly-ho there, neighborino', {
16246      *   'length': 24,
16247      *   'separator': /,? +/
16248      * });
16249      * // => 'hi-diddly-ho there...'
16250      *
16251      * _.truncate('hi-diddly-ho there, neighborino', {
16252      *   'omission': ' [...]'
16253      * });
16254      * // => 'hi-diddly-ho there, neig [...]'
16255      */
16256     function truncate(string, options) {
16257       var length = DEFAULT_TRUNC_LENGTH,
16258           omission = DEFAULT_TRUNC_OMISSION;
16259
16260       if (isObject(options)) {
16261         var separator = 'separator' in options ? options.separator : separator;
16262         length = 'length' in options ? toInteger(options.length) : length;
16263         omission = 'omission' in options ? baseToString(options.omission) : omission;
16264       }
16265       string = toString(string);
16266
16267       var strLength = string.length;
16268       if (hasUnicode(string)) {
16269         var strSymbols = stringToArray(string);
16270         strLength = strSymbols.length;
16271       }
16272       if (length >= strLength) {
16273         return string;
16274       }
16275       var end = length - stringSize(omission);
16276       if (end < 1) {
16277         return omission;
16278       }
16279       var result = strSymbols
16280         ? castSlice(strSymbols, 0, end).join('')
16281         : string.slice(0, end);
16282
16283       if (separator === undefined) {
16284         return result + omission;
16285       }
16286       if (strSymbols) {
16287         end += (result.length - end);
16288       }
16289       if (isRegExp(separator)) {
16290         if (string.slice(end).search(separator)) {
16291           var match,
16292               substring = result;
16293
16294           if (!separator.global) {
16295             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
16296           }
16297           separator.lastIndex = 0;
16298           while ((match = separator.exec(substring))) {
16299             var newEnd = match.index;
16300           }
16301           result = result.slice(0, newEnd === undefined ? end : newEnd);
16302         }
16303       } else if (string.indexOf(baseToString(separator), end) != end) {
16304         var index = result.lastIndexOf(separator);
16305         if (index > -1) {
16306           result = result.slice(0, index);
16307         }
16308       }
16309       return result + omission;
16310     }
16311
16312     /**
16313      * The inverse of `_.escape`; this method converts the HTML entities
16314      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
16315      * their corresponding characters.
16316      *
16317      * **Note:** No other HTML entities are unescaped. To unescape additional
16318      * HTML entities use a third-party library like [_he_](https://mths.be/he).
16319      *
16320      * @static
16321      * @memberOf _
16322      * @since 0.6.0
16323      * @category String
16324      * @param {string} [string=''] The string to unescape.
16325      * @returns {string} Returns the unescaped string.
16326      * @example
16327      *
16328      * _.unescape('fred, barney, &amp; pebbles');
16329      * // => 'fred, barney, & pebbles'
16330      */
16331     function unescape(string) {
16332       string = toString(string);
16333       return (string && reHasEscapedHtml.test(string))
16334         ? string.replace(reEscapedHtml, unescapeHtmlChar)
16335         : string;
16336     }
16337
16338     /**
16339      * Converts `string`, as space separated words, to upper case.
16340      *
16341      * @static
16342      * @memberOf _
16343      * @since 4.0.0
16344      * @category String
16345      * @param {string} [string=''] The string to convert.
16346      * @returns {string} Returns the upper cased string.
16347      * @example
16348      *
16349      * _.upperCase('--foo-bar');
16350      * // => 'FOO BAR'
16351      *
16352      * _.upperCase('fooBar');
16353      * // => 'FOO BAR'
16354      *
16355      * _.upperCase('__foo_bar__');
16356      * // => 'FOO BAR'
16357      */
16358     var upperCase = createCompounder(function(result, word, index) {
16359       return result + (index ? ' ' : '') + word.toUpperCase();
16360     });
16361
16362     /**
16363      * Converts the first character of `string` to upper case.
16364      *
16365      * @static
16366      * @memberOf _
16367      * @since 4.0.0
16368      * @category String
16369      * @param {string} [string=''] The string to convert.
16370      * @returns {string} Returns the converted string.
16371      * @example
16372      *
16373      * _.upperFirst('fred');
16374      * // => 'Fred'
16375      *
16376      * _.upperFirst('FRED');
16377      * // => 'FRED'
16378      */
16379     var upperFirst = createCaseFirst('toUpperCase');
16380
16381     /**
16382      * Splits `string` into an array of its words.
16383      *
16384      * @static
16385      * @memberOf _
16386      * @since 3.0.0
16387      * @category String
16388      * @param {string} [string=''] The string to inspect.
16389      * @param {RegExp|string} [pattern] The pattern to match words.
16390      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16391      * @returns {Array} Returns the words of `string`.
16392      * @example
16393      *
16394      * _.words('fred, barney, & pebbles');
16395      * // => ['fred', 'barney', 'pebbles']
16396      *
16397      * _.words('fred, barney, & pebbles', /[^, ]+/g);
16398      * // => ['fred', 'barney', '&', 'pebbles']
16399      */
16400     function words(string, pattern, guard) {
16401       string = toString(string);
16402       pattern = guard ? undefined : pattern;
16403
16404       if (pattern === undefined) {
16405         return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
16406       }
16407       return string.match(pattern) || [];
16408     }
16409
16410     /*------------------------------------------------------------------------*/
16411
16412     /**
16413      * Attempts to invoke `func`, returning either the result or the caught error
16414      * object. Any additional arguments are provided to `func` when it's invoked.
16415      *
16416      * @static
16417      * @memberOf _
16418      * @since 3.0.0
16419      * @category Util
16420      * @param {Function} func The function to attempt.
16421      * @param {...*} [args] The arguments to invoke `func` with.
16422      * @returns {*} Returns the `func` result or error object.
16423      * @example
16424      *
16425      * // Avoid throwing errors for invalid selectors.
16426      * var elements = _.attempt(function(selector) {
16427      *   return document.querySelectorAll(selector);
16428      * }, '>_>');
16429      *
16430      * if (_.isError(elements)) {
16431      *   elements = [];
16432      * }
16433      */
16434     var attempt = baseRest(function(func, args) {
16435       try {
16436         return apply(func, undefined, args);
16437       } catch (e) {
16438         return isError(e) ? e : new Error(e);
16439       }
16440     });
16441
16442     /**
16443      * Binds methods of an object to the object itself, overwriting the existing
16444      * method.
16445      *
16446      * **Note:** This method doesn't set the "length" property of bound functions.
16447      *
16448      * @static
16449      * @since 0.1.0
16450      * @memberOf _
16451      * @category Util
16452      * @param {Object} object The object to bind and assign the bound methods to.
16453      * @param {...(string|string[])} methodNames The object method names to bind.
16454      * @returns {Object} Returns `object`.
16455      * @example
16456      *
16457      * var view = {
16458      *   'label': 'docs',
16459      *   'click': function() {
16460      *     console.log('clicked ' + this.label);
16461      *   }
16462      * };
16463      *
16464      * _.bindAll(view, ['click']);
16465      * jQuery(element).on('click', view.click);
16466      * // => Logs 'clicked docs' when clicked.
16467      */
16468     var bindAll = flatRest(function(object, methodNames) {
16469       arrayEach(methodNames, function(key) {
16470         key = toKey(key);
16471         baseAssignValue(object, key, bind(object[key], object));
16472       });
16473       return object;
16474     });
16475
16476     /**
16477      * Creates a function that iterates over `pairs` and invokes the corresponding
16478      * function of the first predicate to return truthy. The predicate-function
16479      * pairs are invoked with the `this` binding and arguments of the created
16480      * function.
16481      *
16482      * @static
16483      * @memberOf _
16484      * @since 4.0.0
16485      * @category Util
16486      * @param {Array} pairs The predicate-function pairs.
16487      * @returns {Function} Returns the new composite function.
16488      * @example
16489      *
16490      * var func = _.cond([
16491      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
16492      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
16493      *   [_.stubTrue,                      _.constant('no match')]
16494      * ]);
16495      *
16496      * func({ 'a': 1, 'b': 2 });
16497      * // => 'matches A'
16498      *
16499      * func({ 'a': 0, 'b': 1 });
16500      * // => 'matches B'
16501      *
16502      * func({ 'a': '1', 'b': '2' });
16503      * // => 'no match'
16504      */
16505     function cond(pairs) {
16506       var length = pairs == null ? 0 : pairs.length,
16507           toIteratee = getIteratee();
16508
16509       pairs = !length ? [] : arrayMap(pairs, function(pair) {
16510         if (typeof pair[1] != 'function') {
16511           throw new TypeError(FUNC_ERROR_TEXT);
16512         }
16513         return [toIteratee(pair[0]), pair[1]];
16514       });
16515
16516       return baseRest(function(args) {
16517         var index = -1;
16518         while (++index < length) {
16519           var pair = pairs[index];
16520           if (apply(pair[0], this, args)) {
16521             return apply(pair[1], this, args);
16522           }
16523         }
16524       });
16525     }
16526
16527     /**
16528      * Creates a function that invokes the predicate properties of `source` with
16529      * the corresponding property values of a given object, returning `true` if
16530      * all predicates return truthy, else `false`.
16531      *
16532      * **Note:** The created function is equivalent to `_.conformsTo` with
16533      * `source` partially applied.
16534      *
16535      * @static
16536      * @memberOf _
16537      * @since 4.0.0
16538      * @category Util
16539      * @param {Object} source The object of property predicates to conform to.
16540      * @returns {Function} Returns the new spec function.
16541      * @example
16542      *
16543      * var objects = [
16544      *   { 'a': 2, 'b': 1 },
16545      *   { 'a': 1, 'b': 2 }
16546      * ];
16547      *
16548      * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
16549      * // => [{ 'a': 1, 'b': 2 }]
16550      */
16551     function conforms(source) {
16552       return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
16553     }
16554
16555     /**
16556      * Creates a function that returns `value`.
16557      *
16558      * @static
16559      * @memberOf _
16560      * @since 2.4.0
16561      * @category Util
16562      * @param {*} value The value to return from the new function.
16563      * @returns {Function} Returns the new constant function.
16564      * @example
16565      *
16566      * var objects = _.times(2, _.constant({ 'a': 1 }));
16567      *
16568      * console.log(objects);
16569      * // => [{ 'a': 1 }, { 'a': 1 }]
16570      *
16571      * console.log(objects[0] === objects[1]);
16572      * // => true
16573      */
16574     function constant(value) {
16575       return function() {
16576         return value;
16577       };
16578     }
16579
16580     /**
16581      * Checks `value` to determine whether a default value should be returned in
16582      * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
16583      * or `undefined`.
16584      *
16585      * @static
16586      * @memberOf _
16587      * @since 4.14.0
16588      * @category Util
16589      * @param {*} value The value to check.
16590      * @param {*} defaultValue The default value.
16591      * @returns {*} Returns the resolved value.
16592      * @example
16593      *
16594      * _.defaultTo(1, 10);
16595      * // => 1
16596      *
16597      * _.defaultTo(undefined, 10);
16598      * // => 10
16599      */
16600     function defaultTo(value, defaultValue) {
16601       return (value == null || value !== value) ? defaultValue : value;
16602     }
16603
16604     /**
16605      * Creates a function that returns the result of invoking the given functions
16606      * with the `this` binding of the created function, where each successive
16607      * invocation is supplied the return value of the previous.
16608      *
16609      * @static
16610      * @memberOf _
16611      * @since 3.0.0
16612      * @category Util
16613      * @param {...(Function|Function[])} [funcs] The functions to invoke.
16614      * @returns {Function} Returns the new composite function.
16615      * @see _.flowRight
16616      * @example
16617      *
16618      * function square(n) {
16619      *   return n * n;
16620      * }
16621      *
16622      * var addSquare = _.flow([_.add, square]);
16623      * addSquare(1, 2);
16624      * // => 9
16625      */
16626     var flow = createFlow();
16627
16628     /**
16629      * This method is like `_.flow` except that it creates a function that
16630      * invokes the given functions from right to left.
16631      *
16632      * @static
16633      * @since 3.0.0
16634      * @memberOf _
16635      * @category Util
16636      * @param {...(Function|Function[])} [funcs] The functions to invoke.
16637      * @returns {Function} Returns the new composite function.
16638      * @see _.flow
16639      * @example
16640      *
16641      * function square(n) {
16642      *   return n * n;
16643      * }
16644      *
16645      * var addSquare = _.flowRight([square, _.add]);
16646      * addSquare(1, 2);
16647      * // => 9
16648      */
16649     var flowRight = createFlow(true);
16650
16651     /**
16652      * This method returns the first argument it receives.
16653      *
16654      * @static
16655      * @since 0.1.0
16656      * @memberOf _
16657      * @category Util
16658      * @param {*} value Any value.
16659      * @returns {*} Returns `value`.
16660      * @example
16661      *
16662      * var object = { 'a': 1 };
16663      *
16664      * console.log(_.identity(object) === object);
16665      * // => true
16666      */
16667     function identity(value) {
16668       return value;
16669     }
16670
16671     /**
16672      * Creates a function that invokes `func` with the arguments of the created
16673      * function. If `func` is a property name, the created function returns the
16674      * property value for a given element. If `func` is an array or object, the
16675      * created function returns `true` for elements that contain the equivalent
16676      * source properties, otherwise it returns `false`.
16677      *
16678      * @static
16679      * @since 4.0.0
16680      * @memberOf _
16681      * @category Util
16682      * @param {*} [func=_.identity] The value to convert to a callback.
16683      * @returns {Function} Returns the callback.
16684      * @example
16685      *
16686      * var users = [
16687      *   { 'user': 'barney', 'age': 36, 'active': true },
16688      *   { 'user': 'fred',   'age': 40, 'active': false }
16689      * ];
16690      *
16691      * // The `_.matches` iteratee shorthand.
16692      * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
16693      * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
16694      *
16695      * // The `_.matchesProperty` iteratee shorthand.
16696      * _.filter(users, _.iteratee(['user', 'fred']));
16697      * // => [{ 'user': 'fred', 'age': 40 }]
16698      *
16699      * // The `_.property` iteratee shorthand.
16700      * _.map(users, _.iteratee('user'));
16701      * // => ['barney', 'fred']
16702      *
16703      * // Create custom iteratee shorthands.
16704      * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
16705      *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
16706      *     return func.test(string);
16707      *   };
16708      * });
16709      *
16710      * _.filter(['abc', 'def'], /ef/);
16711      * // => ['def']
16712      */
16713     function iteratee(func) {
16714       return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
16715     }
16716
16717     /**
16718      * Creates a function that performs a partial deep comparison between a given
16719      * object and `source`, returning `true` if the given object has equivalent
16720      * property values, else `false`.
16721      *
16722      * **Note:** The created function is equivalent to `_.isMatch` with `source`
16723      * partially applied.
16724      *
16725      * Partial comparisons will match empty array and empty object `source`
16726      * values against any array or object value, respectively. See `_.isEqual`
16727      * for a list of supported value comparisons.
16728      *
16729      * **Note:** Multiple values can be checked by combining several matchers
16730      * using `_.overSome`
16731      *
16732      * @static
16733      * @memberOf _
16734      * @since 3.0.0
16735      * @category Util
16736      * @param {Object} source The object of property values to match.
16737      * @returns {Function} Returns the new spec function.
16738      * @example
16739      *
16740      * var objects = [
16741      *   { 'a': 1, 'b': 2, 'c': 3 },
16742      *   { 'a': 4, 'b': 5, 'c': 6 }
16743      * ];
16744      *
16745      * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
16746      * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
16747      *
16748      * // Checking for several possible values
16749      * _.filter(objects, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })]));
16750      * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
16751      */
16752     function matches(source) {
16753       return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
16754     }
16755
16756     /**
16757      * Creates a function that performs a partial deep comparison between the
16758      * value at `path` of a given object to `srcValue`, returning `true` if the
16759      * object value is equivalent, else `false`.
16760      *
16761      * **Note:** Partial comparisons will match empty array and empty object
16762      * `srcValue` values against any array or object value, respectively. See
16763      * `_.isEqual` for a list of supported value comparisons.
16764      *
16765      * **Note:** Multiple values can be checked by combining several matchers
16766      * using `_.overSome`
16767      *
16768      * @static
16769      * @memberOf _
16770      * @since 3.2.0
16771      * @category Util
16772      * @param {Array|string} path The path of the property to get.
16773      * @param {*} srcValue The value to match.
16774      * @returns {Function} Returns the new spec function.
16775      * @example
16776      *
16777      * var objects = [
16778      *   { 'a': 1, 'b': 2, 'c': 3 },
16779      *   { 'a': 4, 'b': 5, 'c': 6 }
16780      * ];
16781      *
16782      * _.find(objects, _.matchesProperty('a', 4));
16783      * // => { 'a': 4, 'b': 5, 'c': 6 }
16784      *
16785      * // Checking for several possible values
16786      * _.filter(objects, _.overSome([_.matchesProperty('a', 1), _.matchesProperty('a', 4)]));
16787      * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
16788      */
16789     function matchesProperty(path, srcValue) {
16790       return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
16791     }
16792
16793     /**
16794      * Creates a function that invokes the method at `path` of a given object.
16795      * Any additional arguments are provided to the invoked method.
16796      *
16797      * @static
16798      * @memberOf _
16799      * @since 3.7.0
16800      * @category Util
16801      * @param {Array|string} path The path of the method to invoke.
16802      * @param {...*} [args] The arguments to invoke the method with.
16803      * @returns {Function} Returns the new invoker function.
16804      * @example
16805      *
16806      * var objects = [
16807      *   { 'a': { 'b': _.constant(2) } },
16808      *   { 'a': { 'b': _.constant(1) } }
16809      * ];
16810      *
16811      * _.map(objects, _.method('a.b'));
16812      * // => [2, 1]
16813      *
16814      * _.map(objects, _.method(['a', 'b']));
16815      * // => [2, 1]
16816      */
16817     var method = baseRest(function(path, args) {
16818       return function(object) {
16819         return baseInvoke(object, path, args);
16820       };
16821     });
16822
16823     /**
16824      * The opposite of `_.method`; this method creates a function that invokes
16825      * the method at a given path of `object`. Any additional arguments are
16826      * provided to the invoked method.
16827      *
16828      * @static
16829      * @memberOf _
16830      * @since 3.7.0
16831      * @category Util
16832      * @param {Object} object The object to query.
16833      * @param {...*} [args] The arguments to invoke the method with.
16834      * @returns {Function} Returns the new invoker function.
16835      * @example
16836      *
16837      * var array = _.times(3, _.constant),
16838      *     object = { 'a': array, 'b': array, 'c': array };
16839      *
16840      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
16841      * // => [2, 0]
16842      *
16843      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
16844      * // => [2, 0]
16845      */
16846     var methodOf = baseRest(function(object, args) {
16847       return function(path) {
16848         return baseInvoke(object, path, args);
16849       };
16850     });
16851
16852     /**
16853      * Adds all own enumerable string keyed function properties of a source
16854      * object to the destination object. If `object` is a function, then methods
16855      * are added to its prototype as well.
16856      *
16857      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
16858      * avoid conflicts caused by modifying the original.
16859      *
16860      * @static
16861      * @since 0.1.0
16862      * @memberOf _
16863      * @category Util
16864      * @param {Function|Object} [object=lodash] The destination object.
16865      * @param {Object} source The object of functions to add.
16866      * @param {Object} [options={}] The options object.
16867      * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
16868      * @returns {Function|Object} Returns `object`.
16869      * @example
16870      *
16871      * function vowels(string) {
16872      *   return _.filter(string, function(v) {
16873      *     return /[aeiou]/i.test(v);
16874      *   });
16875      * }
16876      *
16877      * _.mixin({ 'vowels': vowels });
16878      * _.vowels('fred');
16879      * // => ['e']
16880      *
16881      * _('fred').vowels().value();
16882      * // => ['e']
16883      *
16884      * _.mixin({ 'vowels': vowels }, { 'chain': false });
16885      * _('fred').vowels();
16886      * // => ['e']
16887      */
16888     function mixin(object, source, options) {
16889       var props = keys(source),
16890           methodNames = baseFunctions(source, props);
16891
16892       if (options == null &&
16893           !(isObject(source) && (methodNames.length || !props.length))) {
16894         options = source;
16895         source = object;
16896         object = this;
16897         methodNames = baseFunctions(source, keys(source));
16898       }
16899       var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
16900           isFunc = isFunction(object);
16901
16902       arrayEach(methodNames, function(methodName) {
16903         var func = source[methodName];
16904         object[methodName] = func;
16905         if (isFunc) {
16906           object.prototype[methodName] = function() {
16907             var chainAll = this.__chain__;
16908             if (chain || chainAll) {
16909               var result = object(this.__wrapped__),
16910                   actions = result.__actions__ = copyArray(this.__actions__);
16911
16912               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
16913               result.__chain__ = chainAll;
16914               return result;
16915             }
16916             return func.apply(object, arrayPush([this.value()], arguments));
16917           };
16918         }
16919       });
16920
16921       return object;
16922     }
16923
16924     /**
16925      * Reverts the `_` variable to its previous value and returns a reference to
16926      * the `lodash` function.
16927      *
16928      * @static
16929      * @since 0.1.0
16930      * @memberOf _
16931      * @category Util
16932      * @returns {Function} Returns the `lodash` function.
16933      * @example
16934      *
16935      * var lodash = _.noConflict();
16936      */
16937     function noConflict() {
16938       if (root._ === this) {
16939         root._ = oldDash;
16940       }
16941       return this;
16942     }
16943
16944     /**
16945      * This method returns `undefined`.
16946      *
16947      * @static
16948      * @memberOf _
16949      * @since 2.3.0
16950      * @category Util
16951      * @example
16952      *
16953      * _.times(2, _.noop);
16954      * // => [undefined, undefined]
16955      */
16956     function noop() {
16957       // No operation performed.
16958     }
16959
16960     /**
16961      * Creates a function that gets the argument at index `n`. If `n` is negative,
16962      * the nth argument from the end is returned.
16963      *
16964      * @static
16965      * @memberOf _
16966      * @since 4.0.0
16967      * @category Util
16968      * @param {number} [n=0] The index of the argument to return.
16969      * @returns {Function} Returns the new pass-thru function.
16970      * @example
16971      *
16972      * var func = _.nthArg(1);
16973      * func('a', 'b', 'c', 'd');
16974      * // => 'b'
16975      *
16976      * var func = _.nthArg(-2);
16977      * func('a', 'b', 'c', 'd');
16978      * // => 'c'
16979      */
16980     function nthArg(n) {
16981       n = toInteger(n);
16982       return baseRest(function(args) {
16983         return baseNth(args, n);
16984       });
16985     }
16986
16987     /**
16988      * Creates a function that invokes `iteratees` with the arguments it receives
16989      * and returns their results.
16990      *
16991      * @static
16992      * @memberOf _
16993      * @since 4.0.0
16994      * @category Util
16995      * @param {...(Function|Function[])} [iteratees=[_.identity]]
16996      *  The iteratees to invoke.
16997      * @returns {Function} Returns the new function.
16998      * @example
16999      *
17000      * var func = _.over([Math.max, Math.min]);
17001      *
17002      * func(1, 2, 3, 4);
17003      * // => [4, 1]
17004      */
17005     var over = createOver(arrayMap);
17006
17007     /**
17008      * Creates a function that checks if **all** of the `predicates` return
17009      * truthy when invoked with the arguments it receives.
17010      *
17011      * Following shorthands are possible for providing predicates.
17012      * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
17013      * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
17014      *
17015      * @static
17016      * @memberOf _
17017      * @since 4.0.0
17018      * @category Util
17019      * @param {...(Function|Function[])} [predicates=[_.identity]]
17020      *  The predicates to check.
17021      * @returns {Function} Returns the new function.
17022      * @example
17023      *
17024      * var func = _.overEvery([Boolean, isFinite]);
17025      *
17026      * func('1');
17027      * // => true
17028      *
17029      * func(null);
17030      * // => false
17031      *
17032      * func(NaN);
17033      * // => false
17034      */
17035     var overEvery = createOver(arrayEvery);
17036
17037     /**
17038      * Creates a function that checks if **any** of the `predicates` return
17039      * truthy when invoked with the arguments it receives.
17040      *
17041      * Following shorthands are possible for providing predicates.
17042      * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
17043      * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
17044      *
17045      * @static
17046      * @memberOf _
17047      * @since 4.0.0
17048      * @category Util
17049      * @param {...(Function|Function[])} [predicates=[_.identity]]
17050      *  The predicates to check.
17051      * @returns {Function} Returns the new function.
17052      * @example
17053      *
17054      * var func = _.overSome([Boolean, isFinite]);
17055      *
17056      * func('1');
17057      * // => true
17058      *
17059      * func(null);
17060      * // => true
17061      *
17062      * func(NaN);
17063      * // => false
17064      *
17065      * var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }])
17066      * var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]])
17067      */
17068     var overSome = createOver(arraySome);
17069
17070     /**
17071      * Creates a function that returns the value at `path` of a given object.
17072      *
17073      * @static
17074      * @memberOf _
17075      * @since 2.4.0
17076      * @category Util
17077      * @param {Array|string} path The path of the property to get.
17078      * @returns {Function} Returns the new accessor function.
17079      * @example
17080      *
17081      * var objects = [
17082      *   { 'a': { 'b': 2 } },
17083      *   { 'a': { 'b': 1 } }
17084      * ];
17085      *
17086      * _.map(objects, _.property('a.b'));
17087      * // => [2, 1]
17088      *
17089      * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
17090      * // => [1, 2]
17091      */
17092     function property(path) {
17093       return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
17094     }
17095
17096     /**
17097      * The opposite of `_.property`; this method creates a function that returns
17098      * the value at a given path of `object`.
17099      *
17100      * @static
17101      * @memberOf _
17102      * @since 3.0.0
17103      * @category Util
17104      * @param {Object} object The object to query.
17105      * @returns {Function} Returns the new accessor function.
17106      * @example
17107      *
17108      * var array = [0, 1, 2],
17109      *     object = { 'a': array, 'b': array, 'c': array };
17110      *
17111      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
17112      * // => [2, 0]
17113      *
17114      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
17115      * // => [2, 0]
17116      */
17117     function propertyOf(object) {
17118       return function(path) {
17119         return object == null ? undefined : baseGet(object, path);
17120       };
17121     }
17122
17123     /**
17124      * Creates an array of numbers (positive and/or negative) progressing from
17125      * `start` up to, but not including, `end`. A step of `-1` is used if a negative
17126      * `start` is specified without an `end` or `step`. If `end` is not specified,
17127      * it's set to `start` with `start` then set to `0`.
17128      *
17129      * **Note:** JavaScript follows the IEEE-754 standard for resolving
17130      * floating-point values which can produce unexpected results.
17131      *
17132      * @static
17133      * @since 0.1.0
17134      * @memberOf _
17135      * @category Util
17136      * @param {number} [start=0] The start of the range.
17137      * @param {number} end The end of the range.
17138      * @param {number} [step=1] The value to increment or decrement by.
17139      * @returns {Array} Returns the range of numbers.
17140      * @see _.inRange, _.rangeRight
17141      * @example
17142      *
17143      * _.range(4);
17144      * // => [0, 1, 2, 3]
17145      *
17146      * _.range(-4);
17147      * // => [0, -1, -2, -3]
17148      *
17149      * _.range(1, 5);
17150      * // => [1, 2, 3, 4]
17151      *
17152      * _.range(0, 20, 5);
17153      * // => [0, 5, 10, 15]
17154      *
17155      * _.range(0, -4, -1);
17156      * // => [0, -1, -2, -3]
17157      *
17158      * _.range(1, 4, 0);
17159      * // => [1, 1, 1]
17160      *
17161      * _.range(0);
17162      * // => []
17163      */
17164     var range = createRange();
17165
17166     /**
17167      * This method is like `_.range` except that it populates values in
17168      * descending order.
17169      *
17170      * @static
17171      * @memberOf _
17172      * @since 4.0.0
17173      * @category Util
17174      * @param {number} [start=0] The start of the range.
17175      * @param {number} end The end of the range.
17176      * @param {number} [step=1] The value to increment or decrement by.
17177      * @returns {Array} Returns the range of numbers.
17178      * @see _.inRange, _.range
17179      * @example
17180      *
17181      * _.rangeRight(4);
17182      * // => [3, 2, 1, 0]
17183      *
17184      * _.rangeRight(-4);
17185      * // => [-3, -2, -1, 0]
17186      *
17187      * _.rangeRight(1, 5);
17188      * // => [4, 3, 2, 1]
17189      *
17190      * _.rangeRight(0, 20, 5);
17191      * // => [15, 10, 5, 0]
17192      *
17193      * _.rangeRight(0, -4, -1);
17194      * // => [-3, -2, -1, 0]
17195      *
17196      * _.rangeRight(1, 4, 0);
17197      * // => [1, 1, 1]
17198      *
17199      * _.rangeRight(0);
17200      * // => []
17201      */
17202     var rangeRight = createRange(true);
17203
17204     /**
17205      * This method returns a new empty array.
17206      *
17207      * @static
17208      * @memberOf _
17209      * @since 4.13.0
17210      * @category Util
17211      * @returns {Array} Returns the new empty array.
17212      * @example
17213      *
17214      * var arrays = _.times(2, _.stubArray);
17215      *
17216      * console.log(arrays);
17217      * // => [[], []]
17218      *
17219      * console.log(arrays[0] === arrays[1]);
17220      * // => false
17221      */
17222     function stubArray() {
17223       return [];
17224     }
17225
17226     /**
17227      * This method returns `false`.
17228      *
17229      * @static
17230      * @memberOf _
17231      * @since 4.13.0
17232      * @category Util
17233      * @returns {boolean} Returns `false`.
17234      * @example
17235      *
17236      * _.times(2, _.stubFalse);
17237      * // => [false, false]
17238      */
17239     function stubFalse() {
17240       return false;
17241     }
17242
17243     /**
17244      * This method returns a new empty object.
17245      *
17246      * @static
17247      * @memberOf _
17248      * @since 4.13.0
17249      * @category Util
17250      * @returns {Object} Returns the new empty object.
17251      * @example
17252      *
17253      * var objects = _.times(2, _.stubObject);
17254      *
17255      * console.log(objects);
17256      * // => [{}, {}]
17257      *
17258      * console.log(objects[0] === objects[1]);
17259      * // => false
17260      */
17261     function stubObject() {
17262       return {};
17263     }
17264
17265     /**
17266      * This method returns an empty string.
17267      *
17268      * @static
17269      * @memberOf _
17270      * @since 4.13.0
17271      * @category Util
17272      * @returns {string} Returns the empty string.
17273      * @example
17274      *
17275      * _.times(2, _.stubString);
17276      * // => ['', '']
17277      */
17278     function stubString() {
17279       return '';
17280     }
17281
17282     /**
17283      * This method returns `true`.
17284      *
17285      * @static
17286      * @memberOf _
17287      * @since 4.13.0
17288      * @category Util
17289      * @returns {boolean} Returns `true`.
17290      * @example
17291      *
17292      * _.times(2, _.stubTrue);
17293      * // => [true, true]
17294      */
17295     function stubTrue() {
17296       return true;
17297     }
17298
17299     /**
17300      * Invokes the iteratee `n` times, returning an array of the results of
17301      * each invocation. The iteratee is invoked with one argument; (index).
17302      *
17303      * @static
17304      * @since 0.1.0
17305      * @memberOf _
17306      * @category Util
17307      * @param {number} n The number of times to invoke `iteratee`.
17308      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
17309      * @returns {Array} Returns the array of results.
17310      * @example
17311      *
17312      * _.times(3, String);
17313      * // => ['0', '1', '2']
17314      *
17315      *  _.times(4, _.constant(0));
17316      * // => [0, 0, 0, 0]
17317      */
17318     function times(n, iteratee) {
17319       n = toInteger(n);
17320       if (n < 1 || n > MAX_SAFE_INTEGER) {
17321         return [];
17322       }
17323       var index = MAX_ARRAY_LENGTH,
17324           length = nativeMin(n, MAX_ARRAY_LENGTH);
17325
17326       iteratee = getIteratee(iteratee);
17327       n -= MAX_ARRAY_LENGTH;
17328
17329       var result = baseTimes(length, iteratee);
17330       while (++index < n) {
17331         iteratee(index);
17332       }
17333       return result;
17334     }
17335
17336     /**
17337      * Converts `value` to a property path array.
17338      *
17339      * @static
17340      * @memberOf _
17341      * @since 4.0.0
17342      * @category Util
17343      * @param {*} value The value to convert.
17344      * @returns {Array} Returns the new property path array.
17345      * @example
17346      *
17347      * _.toPath('a.b.c');
17348      * // => ['a', 'b', 'c']
17349      *
17350      * _.toPath('a[0].b.c');
17351      * // => ['a', '0', 'b', 'c']
17352      */
17353     function toPath(value) {
17354       if (isArray(value)) {
17355         return arrayMap(value, toKey);
17356       }
17357       return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
17358     }
17359
17360     /**
17361      * Generates a unique ID. If `prefix` is given, the ID is appended to it.
17362      *
17363      * @static
17364      * @since 0.1.0
17365      * @memberOf _
17366      * @category Util
17367      * @param {string} [prefix=''] The value to prefix the ID with.
17368      * @returns {string} Returns the unique ID.
17369      * @example
17370      *
17371      * _.uniqueId('contact_');
17372      * // => 'contact_104'
17373      *
17374      * _.uniqueId();
17375      * // => '105'
17376      */
17377     function uniqueId(prefix) {
17378       var id = ++idCounter;
17379       return toString(prefix) + id;
17380     }
17381
17382     /*------------------------------------------------------------------------*/
17383
17384     /**
17385      * Adds two numbers.
17386      *
17387      * @static
17388      * @memberOf _
17389      * @since 3.4.0
17390      * @category Math
17391      * @param {number} augend The first number in an addition.
17392      * @param {number} addend The second number in an addition.
17393      * @returns {number} Returns the total.
17394      * @example
17395      *
17396      * _.add(6, 4);
17397      * // => 10
17398      */
17399     var add = createMathOperation(function(augend, addend) {
17400       return augend + addend;
17401     }, 0);
17402
17403     /**
17404      * Computes `number` rounded up to `precision`.
17405      *
17406      * @static
17407      * @memberOf _
17408      * @since 3.10.0
17409      * @category Math
17410      * @param {number} number The number to round up.
17411      * @param {number} [precision=0] The precision to round up to.
17412      * @returns {number} Returns the rounded up number.
17413      * @example
17414      *
17415      * _.ceil(4.006);
17416      * // => 5
17417      *
17418      * _.ceil(6.004, 2);
17419      * // => 6.01
17420      *
17421      * _.ceil(6040, -2);
17422      * // => 6100
17423      */
17424     var ceil = createRound('ceil');
17425
17426     /**
17427      * Divide two numbers.
17428      *
17429      * @static
17430      * @memberOf _
17431      * @since 4.7.0
17432      * @category Math
17433      * @param {number} dividend The first number in a division.
17434      * @param {number} divisor The second number in a division.
17435      * @returns {number} Returns the quotient.
17436      * @example
17437      *
17438      * _.divide(6, 4);
17439      * // => 1.5
17440      */
17441     var divide = createMathOperation(function(dividend, divisor) {
17442       return dividend / divisor;
17443     }, 1);
17444
17445     /**
17446      * Computes `number` rounded down to `precision`.
17447      *
17448      * @static
17449      * @memberOf _
17450      * @since 3.10.0
17451      * @category Math
17452      * @param {number} number The number to round down.
17453      * @param {number} [precision=0] The precision to round down to.
17454      * @returns {number} Returns the rounded down number.
17455      * @example
17456      *
17457      * _.floor(4.006);
17458      * // => 4
17459      *
17460      * _.floor(0.046, 2);
17461      * // => 0.04
17462      *
17463      * _.floor(4060, -2);
17464      * // => 4000
17465      */
17466     var floor = createRound('floor');
17467
17468     /**
17469      * Computes the maximum value of `array`. If `array` is empty or falsey,
17470      * `undefined` is returned.
17471      *
17472      * @static
17473      * @since 0.1.0
17474      * @memberOf _
17475      * @category Math
17476      * @param {Array} array The array to iterate over.
17477      * @returns {*} Returns the maximum value.
17478      * @example
17479      *
17480      * _.max([4, 2, 8, 6]);
17481      * // => 8
17482      *
17483      * _.max([]);
17484      * // => undefined
17485      */
17486     function max(array) {
17487       return (array && array.length)
17488         ? baseExtremum(array, identity, baseGt)
17489         : undefined;
17490     }
17491
17492     /**
17493      * This method is like `_.max` except that it accepts `iteratee` which is
17494      * invoked for each element in `array` to generate the criterion by which
17495      * the value is ranked. The iteratee is invoked with one argument: (value).
17496      *
17497      * @static
17498      * @memberOf _
17499      * @since 4.0.0
17500      * @category Math
17501      * @param {Array} array The array to iterate over.
17502      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
17503      * @returns {*} Returns the maximum value.
17504      * @example
17505      *
17506      * var objects = [{ 'n': 1 }, { 'n': 2 }];
17507      *
17508      * _.maxBy(objects, function(o) { return o.n; });
17509      * // => { 'n': 2 }
17510      *
17511      * // The `_.property` iteratee shorthand.
17512      * _.maxBy(objects, 'n');
17513      * // => { 'n': 2 }
17514      */
17515     function maxBy(array, iteratee) {
17516       return (array && array.length)
17517         ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
17518         : undefined;
17519     }
17520
17521     /**
17522      * Computes the mean of the values in `array`.
17523      *
17524      * @static
17525      * @memberOf _
17526      * @since 4.0.0
17527      * @category Math
17528      * @param {Array} array The array to iterate over.
17529      * @returns {number} Returns the mean.
17530      * @example
17531      *
17532      * _.mean([4, 2, 8, 6]);
17533      * // => 5
17534      */
17535     function mean(array) {
17536       return baseMean(array, identity);
17537     }
17538
17539     /**
17540      * This method is like `_.mean` except that it accepts `iteratee` which is
17541      * invoked for each element in `array` to generate the value to be averaged.
17542      * The iteratee is invoked with one argument: (value).
17543      *
17544      * @static
17545      * @memberOf _
17546      * @since 4.7.0
17547      * @category Math
17548      * @param {Array} array The array to iterate over.
17549      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
17550      * @returns {number} Returns the mean.
17551      * @example
17552      *
17553      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
17554      *
17555      * _.meanBy(objects, function(o) { return o.n; });
17556      * // => 5
17557      *
17558      * // The `_.property` iteratee shorthand.
17559      * _.meanBy(objects, 'n');
17560      * // => 5
17561      */
17562     function meanBy(array, iteratee) {
17563       return baseMean(array, getIteratee(iteratee, 2));
17564     }
17565
17566     /**
17567      * Computes the minimum value of `array`. If `array` is empty or falsey,
17568      * `undefined` is returned.
17569      *
17570      * @static
17571      * @since 0.1.0
17572      * @memberOf _
17573      * @category Math
17574      * @param {Array} array The array to iterate over.
17575      * @returns {*} Returns the minimum value.
17576      * @example
17577      *
17578      * _.min([4, 2, 8, 6]);
17579      * // => 2
17580      *
17581      * _.min([]);
17582      * // => undefined
17583      */
17584     function min(array) {
17585       return (array && array.length)
17586         ? baseExtremum(array, identity, baseLt)
17587         : undefined;
17588     }
17589
17590     /**
17591      * This method is like `_.min` except that it accepts `iteratee` which is
17592      * invoked for each element in `array` to generate the criterion by which
17593      * the value is ranked. The iteratee is invoked with one argument: (value).
17594      *
17595      * @static
17596      * @memberOf _
17597      * @since 4.0.0
17598      * @category Math
17599      * @param {Array} array The array to iterate over.
17600      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
17601      * @returns {*} Returns the minimum value.
17602      * @example
17603      *
17604      * var objects = [{ 'n': 1 }, { 'n': 2 }];
17605      *
17606      * _.minBy(objects, function(o) { return o.n; });
17607      * // => { 'n': 1 }
17608      *
17609      * // The `_.property` iteratee shorthand.
17610      * _.minBy(objects, 'n');
17611      * // => { 'n': 1 }
17612      */
17613     function minBy(array, iteratee) {
17614       return (array && array.length)
17615         ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
17616         : undefined;
17617     }
17618
17619     /**
17620      * Multiply two numbers.
17621      *
17622      * @static
17623      * @memberOf _
17624      * @since 4.7.0
17625      * @category Math
17626      * @param {number} multiplier The first number in a multiplication.
17627      * @param {number} multiplicand The second number in a multiplication.
17628      * @returns {number} Returns the product.
17629      * @example
17630      *
17631      * _.multiply(6, 4);
17632      * // => 24
17633      */
17634     var multiply = createMathOperation(function(multiplier, multiplicand) {
17635       return multiplier * multiplicand;
17636     }, 1);
17637
17638     /**
17639      * Computes `number` rounded to `precision`.
17640      *
17641      * @static
17642      * @memberOf _
17643      * @since 3.10.0
17644      * @category Math
17645      * @param {number} number The number to round.
17646      * @param {number} [precision=0] The precision to round to.
17647      * @returns {number} Returns the rounded number.
17648      * @example
17649      *
17650      * _.round(4.006);
17651      * // => 4
17652      *
17653      * _.round(4.006, 2);
17654      * // => 4.01
17655      *
17656      * _.round(4060, -2);
17657      * // => 4100
17658      */
17659     var round = createRound('round');
17660
17661     /**
17662      * Subtract two numbers.
17663      *
17664      * @static
17665      * @memberOf _
17666      * @since 4.0.0
17667      * @category Math
17668      * @param {number} minuend The first number in a subtraction.
17669      * @param {number} subtrahend The second number in a subtraction.
17670      * @returns {number} Returns the difference.
17671      * @example
17672      *
17673      * _.subtract(6, 4);
17674      * // => 2
17675      */
17676     var subtract = createMathOperation(function(minuend, subtrahend) {
17677       return minuend - subtrahend;
17678     }, 0);
17679
17680     /**
17681      * Computes the sum of the values in `array`.
17682      *
17683      * @static
17684      * @memberOf _
17685      * @since 3.4.0
17686      * @category Math
17687      * @param {Array} array The array to iterate over.
17688      * @returns {number} Returns the sum.
17689      * @example
17690      *
17691      * _.sum([4, 2, 8, 6]);
17692      * // => 20
17693      */
17694     function sum(array) {
17695       return (array && array.length)
17696         ? baseSum(array, identity)
17697         : 0;
17698     }
17699
17700     /**
17701      * This method is like `_.sum` except that it accepts `iteratee` which is
17702      * invoked for each element in `array` to generate the value to be summed.
17703      * The iteratee is invoked with one argument: (value).
17704      *
17705      * @static
17706      * @memberOf _
17707      * @since 4.0.0
17708      * @category Math
17709      * @param {Array} array The array to iterate over.
17710      * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
17711      * @returns {number} Returns the sum.
17712      * @example
17713      *
17714      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
17715      *
17716      * _.sumBy(objects, function(o) { return o.n; });
17717      * // => 20
17718      *
17719      * // The `_.property` iteratee shorthand.
17720      * _.sumBy(objects, 'n');
17721      * // => 20
17722      */
17723     function sumBy(array, iteratee) {
17724       return (array && array.length)
17725         ? baseSum(array, getIteratee(iteratee, 2))
17726         : 0;
17727     }
17728
17729     /*------------------------------------------------------------------------*/
17730
17731     // Add methods that return wrapped values in chain sequences.
17732     lodash.after = after;
17733     lodash.ary = ary;
17734     lodash.assign = assign;
17735     lodash.assignIn = assignIn;
17736     lodash.assignInWith = assignInWith;
17737     lodash.assignWith = assignWith;
17738     lodash.at = at;
17739     lodash.before = before;
17740     lodash.bind = bind;
17741     lodash.bindAll = bindAll;
17742     lodash.bindKey = bindKey;
17743     lodash.castArray = castArray;
17744     lodash.chain = chain;
17745     lodash.chunk = chunk;
17746     lodash.compact = compact;
17747     lodash.concat = concat;
17748     lodash.cond = cond;
17749     lodash.conforms = conforms;
17750     lodash.constant = constant;
17751     lodash.countBy = countBy;
17752     lodash.create = create;
17753     lodash.curry = curry;
17754     lodash.curryRight = curryRight;
17755     lodash.debounce = debounce;
17756     lodash.defaults = defaults;
17757     lodash.defaultsDeep = defaultsDeep;
17758     lodash.defer = defer;
17759     lodash.delay = delay;
17760     lodash.difference = difference;
17761     lodash.differenceBy = differenceBy;
17762     lodash.differenceWith = differenceWith;
17763     lodash.drop = drop;
17764     lodash.dropRight = dropRight;
17765     lodash.dropRightWhile = dropRightWhile;
17766     lodash.dropWhile = dropWhile;
17767     lodash.fill = fill;
17768     lodash.filter = filter;
17769     lodash.flatMap = flatMap;
17770     lodash.flatMapDeep = flatMapDeep;
17771     lodash.flatMapDepth = flatMapDepth;
17772     lodash.flatten = flatten;
17773     lodash.flattenDeep = flattenDeep;
17774     lodash.flattenDepth = flattenDepth;
17775     lodash.flip = flip;
17776     lodash.flow = flow;
17777     lodash.flowRight = flowRight;
17778     lodash.fromPairs = fromPairs;
17779     lodash.functions = functions;
17780     lodash.functionsIn = functionsIn;
17781     lodash.groupBy = groupBy;
17782     lodash.initial = initial;
17783     lodash.intersection = intersection;
17784     lodash.intersectionBy = intersectionBy;
17785     lodash.intersectionWith = intersectionWith;
17786     lodash.invert = invert;
17787     lodash.invertBy = invertBy;
17788     lodash.invokeMap = invokeMap;
17789     lodash.iteratee = iteratee;
17790     lodash.keyBy = keyBy;
17791     lodash.keys = keys;
17792     lodash.keysIn = keysIn;
17793     lodash.map = map;
17794     lodash.mapKeys = mapKeys;
17795     lodash.mapValues = mapValues;
17796     lodash.matches = matches;
17797     lodash.matchesProperty = matchesProperty;
17798     lodash.memoize = memoize;
17799     lodash.merge = merge;
17800     lodash.mergeWith = mergeWith;
17801     lodash.method = method;
17802     lodash.methodOf = methodOf;
17803     lodash.mixin = mixin;
17804     lodash.negate = negate;
17805     lodash.nthArg = nthArg;
17806     lodash.omit = omit;
17807     lodash.omitBy = omitBy;
17808     lodash.once = once;
17809     lodash.orderBy = orderBy;
17810     lodash.over = over;
17811     lodash.overArgs = overArgs;
17812     lodash.overEvery = overEvery;
17813     lodash.overSome = overSome;
17814     lodash.partial = partial;
17815     lodash.partialRight = partialRight;
17816     lodash.partition = partition;
17817     lodash.pick = pick;
17818     lodash.pickBy = pickBy;
17819     lodash.property = property;
17820     lodash.propertyOf = propertyOf;
17821     lodash.pull = pull;
17822     lodash.pullAll = pullAll;
17823     lodash.pullAllBy = pullAllBy;
17824     lodash.pullAllWith = pullAllWith;
17825     lodash.pullAt = pullAt;
17826     lodash.range = range;
17827     lodash.rangeRight = rangeRight;
17828     lodash.rearg = rearg;
17829     lodash.reject = reject;
17830     lodash.remove = remove;
17831     lodash.rest = rest;
17832     lodash.reverse = reverse;
17833     lodash.sampleSize = sampleSize;
17834     lodash.set = set;
17835     lodash.setWith = setWith;
17836     lodash.shuffle = shuffle;
17837     lodash.slice = slice;
17838     lodash.sortBy = sortBy;
17839     lodash.sortedUniq = sortedUniq;
17840     lodash.sortedUniqBy = sortedUniqBy;
17841     lodash.split = split;
17842     lodash.spread = spread;
17843     lodash.tail = tail;
17844     lodash.take = take;
17845     lodash.takeRight = takeRight;
17846     lodash.takeRightWhile = takeRightWhile;
17847     lodash.takeWhile = takeWhile;
17848     lodash.tap = tap;
17849     lodash.throttle = throttle;
17850     lodash.thru = thru;
17851     lodash.toArray = toArray;
17852     lodash.toPairs = toPairs;
17853     lodash.toPairsIn = toPairsIn;
17854     lodash.toPath = toPath;
17855     lodash.toPlainObject = toPlainObject;
17856     lodash.transform = transform;
17857     lodash.unary = unary;
17858     lodash.union = union;
17859     lodash.unionBy = unionBy;
17860     lodash.unionWith = unionWith;
17861     lodash.uniq = uniq;
17862     lodash.uniqBy = uniqBy;
17863     lodash.uniqWith = uniqWith;
17864     lodash.unset = unset;
17865     lodash.unzip = unzip;
17866     lodash.unzipWith = unzipWith;
17867     lodash.update = update;
17868     lodash.updateWith = updateWith;
17869     lodash.values = values;
17870     lodash.valuesIn = valuesIn;
17871     lodash.without = without;
17872     lodash.words = words;
17873     lodash.wrap = wrap;
17874     lodash.xor = xor;
17875     lodash.xorBy = xorBy;
17876     lodash.xorWith = xorWith;
17877     lodash.zip = zip;
17878     lodash.zipObject = zipObject;
17879     lodash.zipObjectDeep = zipObjectDeep;
17880     lodash.zipWith = zipWith;
17881
17882     // Add aliases.
17883     lodash.entries = toPairs;
17884     lodash.entriesIn = toPairsIn;
17885     lodash.extend = assignIn;
17886     lodash.extendWith = assignInWith;
17887
17888     // Add methods to `lodash.prototype`.
17889     mixin(lodash, lodash);
17890
17891     /*------------------------------------------------------------------------*/
17892
17893     // Add methods that return unwrapped values in chain sequences.
17894     lodash.add = add;
17895     lodash.attempt = attempt;
17896     lodash.camelCase = camelCase;
17897     lodash.capitalize = capitalize;
17898     lodash.ceil = ceil;
17899     lodash.clamp = clamp;
17900     lodash.clone = clone;
17901     lodash.cloneDeep = cloneDeep;
17902     lodash.cloneDeepWith = cloneDeepWith;
17903     lodash.cloneWith = cloneWith;
17904     lodash.conformsTo = conformsTo;
17905     lodash.deburr = deburr;
17906     lodash.defaultTo = defaultTo;
17907     lodash.divide = divide;
17908     lodash.endsWith = endsWith;
17909     lodash.eq = eq;
17910     lodash.escape = escape;
17911     lodash.escapeRegExp = escapeRegExp;
17912     lodash.every = every;
17913     lodash.find = find;
17914     lodash.findIndex = findIndex;
17915     lodash.findKey = findKey;
17916     lodash.findLast = findLast;
17917     lodash.findLastIndex = findLastIndex;
17918     lodash.findLastKey = findLastKey;
17919     lodash.floor = floor;
17920     lodash.forEach = forEach;
17921     lodash.forEachRight = forEachRight;
17922     lodash.forIn = forIn;
17923     lodash.forInRight = forInRight;
17924     lodash.forOwn = forOwn;
17925     lodash.forOwnRight = forOwnRight;
17926     lodash.get = get;
17927     lodash.gt = gt;
17928     lodash.gte = gte;
17929     lodash.has = has;
17930     lodash.hasIn = hasIn;
17931     lodash.head = head;
17932     lodash.identity = identity;
17933     lodash.includes = includes;
17934     lodash.indexOf = indexOf;
17935     lodash.inRange = inRange;
17936     lodash.invoke = invoke;
17937     lodash.isArguments = isArguments;
17938     lodash.isArray = isArray;
17939     lodash.isArrayBuffer = isArrayBuffer;
17940     lodash.isArrayLike = isArrayLike;
17941     lodash.isArrayLikeObject = isArrayLikeObject;
17942     lodash.isBoolean = isBoolean;
17943     lodash.isBuffer = isBuffer;
17944     lodash.isDate = isDate;
17945     lodash.isElement = isElement;
17946     lodash.isEmpty = isEmpty;
17947     lodash.isEqual = isEqual;
17948     lodash.isEqualWith = isEqualWith;
17949     lodash.isError = isError;
17950     lodash.isFinite = isFinite;
17951     lodash.isFunction = isFunction;
17952     lodash.isInteger = isInteger;
17953     lodash.isLength = isLength;
17954     lodash.isMap = isMap;
17955     lodash.isMatch = isMatch;
17956     lodash.isMatchWith = isMatchWith;
17957     lodash.isNaN = isNaN;
17958     lodash.isNative = isNative;
17959     lodash.isNil = isNil;
17960     lodash.isNull = isNull;
17961     lodash.isNumber = isNumber;
17962     lodash.isObject = isObject;
17963     lodash.isObjectLike = isObjectLike;
17964     lodash.isPlainObject = isPlainObject;
17965     lodash.isRegExp = isRegExp;
17966     lodash.isSafeInteger = isSafeInteger;
17967     lodash.isSet = isSet;
17968     lodash.isString = isString;
17969     lodash.isSymbol = isSymbol;
17970     lodash.isTypedArray = isTypedArray;
17971     lodash.isUndefined = isUndefined;
17972     lodash.isWeakMap = isWeakMap;
17973     lodash.isWeakSet = isWeakSet;
17974     lodash.join = join;
17975     lodash.kebabCase = kebabCase;
17976     lodash.last = last;
17977     lodash.lastIndexOf = lastIndexOf;
17978     lodash.lowerCase = lowerCase;
17979     lodash.lowerFirst = lowerFirst;
17980     lodash.lt = lt;
17981     lodash.lte = lte;
17982     lodash.max = max;
17983     lodash.maxBy = maxBy;
17984     lodash.mean = mean;
17985     lodash.meanBy = meanBy;
17986     lodash.min = min;
17987     lodash.minBy = minBy;
17988     lodash.stubArray = stubArray;
17989     lodash.stubFalse = stubFalse;
17990     lodash.stubObject = stubObject;
17991     lodash.stubString = stubString;
17992     lodash.stubTrue = stubTrue;
17993     lodash.multiply = multiply;
17994     lodash.nth = nth;
17995     lodash.noConflict = noConflict;
17996     lodash.noop = noop;
17997     lodash.now = now;
17998     lodash.pad = pad;
17999     lodash.padEnd = padEnd;
18000     lodash.padStart = padStart;
18001     lodash.parseInt = parseInt;
18002     lodash.random = random;
18003     lodash.reduce = reduce;
18004     lodash.reduceRight = reduceRight;
18005     lodash.repeat = repeat;
18006     lodash.replace = replace;
18007     lodash.result = result;
18008     lodash.round = round;
18009     lodash.runInContext = runInContext;
18010     lodash.sample = sample;
18011     lodash.size = size;
18012     lodash.snakeCase = snakeCase;
18013     lodash.some = some;
18014     lodash.sortedIndex = sortedIndex;
18015     lodash.sortedIndexBy = sortedIndexBy;
18016     lodash.sortedIndexOf = sortedIndexOf;
18017     lodash.sortedLastIndex = sortedLastIndex;
18018     lodash.sortedLastIndexBy = sortedLastIndexBy;
18019     lodash.sortedLastIndexOf = sortedLastIndexOf;
18020     lodash.startCase = startCase;
18021     lodash.startsWith = startsWith;
18022     lodash.subtract = subtract;
18023     lodash.sum = sum;
18024     lodash.sumBy = sumBy;
18025     lodash.template = template;
18026     lodash.times = times;
18027     lodash.toFinite = toFinite;
18028     lodash.toInteger = toInteger;
18029     lodash.toLength = toLength;
18030     lodash.toLower = toLower;
18031     lodash.toNumber = toNumber;
18032     lodash.toSafeInteger = toSafeInteger;
18033     lodash.toString = toString;
18034     lodash.toUpper = toUpper;
18035     lodash.trim = trim;
18036     lodash.trimEnd = trimEnd;
18037     lodash.trimStart = trimStart;
18038     lodash.truncate = truncate;
18039     lodash.unescape = unescape;
18040     lodash.uniqueId = uniqueId;
18041     lodash.upperCase = upperCase;
18042     lodash.upperFirst = upperFirst;
18043
18044     // Add aliases.
18045     lodash.each = forEach;
18046     lodash.eachRight = forEachRight;
18047     lodash.first = head;
18048
18049     mixin(lodash, (function() {
18050       var source = {};
18051       baseForOwn(lodash, function(func, methodName) {
18052         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
18053           source[methodName] = func;
18054         }
18055       });
18056       return source;
18057     }()), { 'chain': false });
18058
18059     /*------------------------------------------------------------------------*/
18060
18061     /**
18062      * The semantic version number.
18063      *
18064      * @static
18065      * @memberOf _
18066      * @type {string}
18067      */
18068     lodash.VERSION = VERSION;
18069
18070     // Assign default placeholders.
18071     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
18072       lodash[methodName].placeholder = lodash;
18073     });
18074
18075     // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
18076     arrayEach(['drop', 'take'], function(methodName, index) {
18077       LazyWrapper.prototype[methodName] = function(n) {
18078         n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
18079
18080         var result = (this.__filtered__ && !index)
18081           ? new LazyWrapper(this)
18082           : this.clone();
18083
18084         if (result.__filtered__) {
18085           result.__takeCount__ = nativeMin(n, result.__takeCount__);
18086         } else {
18087           result.__views__.push({
18088             'size': nativeMin(n, MAX_ARRAY_LENGTH),
18089             'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
18090           });
18091         }
18092         return result;
18093       };
18094
18095       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
18096         return this.reverse()[methodName](n).reverse();
18097       };
18098     });
18099
18100     // Add `LazyWrapper` methods that accept an `iteratee` value.
18101     arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
18102       var type = index + 1,
18103           isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
18104
18105       LazyWrapper.prototype[methodName] = function(iteratee) {
18106         var result = this.clone();
18107         result.__iteratees__.push({
18108           'iteratee': getIteratee(iteratee, 3),
18109           'type': type
18110         });
18111         result.__filtered__ = result.__filtered__ || isFilter;
18112         return result;
18113       };
18114     });
18115
18116     // Add `LazyWrapper` methods for `_.head` and `_.last`.
18117     arrayEach(['head', 'last'], function(methodName, index) {
18118       var takeName = 'take' + (index ? 'Right' : '');
18119
18120       LazyWrapper.prototype[methodName] = function() {
18121         return this[takeName](1).value()[0];
18122       };
18123     });
18124
18125     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
18126     arrayEach(['initial', 'tail'], function(methodName, index) {
18127       var dropName = 'drop' + (index ? '' : 'Right');
18128
18129       LazyWrapper.prototype[methodName] = function() {
18130         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
18131       };
18132     });
18133
18134     LazyWrapper.prototype.compact = function() {
18135       return this.filter(identity);
18136     };
18137
18138     LazyWrapper.prototype.find = function(predicate) {
18139       return this.filter(predicate).head();
18140     };
18141
18142     LazyWrapper.prototype.findLast = function(predicate) {
18143       return this.reverse().find(predicate);
18144     };
18145
18146     LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
18147       if (typeof path == 'function') {
18148         return new LazyWrapper(this);
18149       }
18150       return this.map(function(value) {
18151         return baseInvoke(value, path, args);
18152       });
18153     });
18154
18155     LazyWrapper.prototype.reject = function(predicate) {
18156       return this.filter(negate(getIteratee(predicate)));
18157     };
18158
18159     LazyWrapper.prototype.slice = function(start, end) {
18160       start = toInteger(start);
18161
18162       var result = this;
18163       if (result.__filtered__ && (start > 0 || end < 0)) {
18164         return new LazyWrapper(result);
18165       }
18166       if (start < 0) {
18167         result = result.takeRight(-start);
18168       } else if (start) {
18169         result = result.drop(start);
18170       }
18171       if (end !== undefined) {
18172         end = toInteger(end);
18173         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
18174       }
18175       return result;
18176     };
18177
18178     LazyWrapper.prototype.takeRightWhile = function(predicate) {
18179       return this.reverse().takeWhile(predicate).reverse();
18180     };
18181
18182     LazyWrapper.prototype.toArray = function() {
18183       return this.take(MAX_ARRAY_LENGTH);
18184     };
18185
18186     // Add `LazyWrapper` methods to `lodash.prototype`.
18187     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
18188       var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
18189           isTaker = /^(?:head|last)$/.test(methodName),
18190           lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
18191           retUnwrapped = isTaker || /^find/.test(methodName);
18192
18193       if (!lodashFunc) {
18194         return;
18195       }
18196       lodash.prototype[methodName] = function() {
18197         var value = this.__wrapped__,
18198             args = isTaker ? [1] : arguments,
18199             isLazy = value instanceof LazyWrapper,
18200             iteratee = args[0],
18201             useLazy = isLazy || isArray(value);
18202
18203         var interceptor = function(value) {
18204           var result = lodashFunc.apply(lodash, arrayPush([value], args));
18205           return (isTaker && chainAll) ? result[0] : result;
18206         };
18207
18208         if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
18209           // Avoid lazy use if the iteratee has a "length" value other than `1`.
18210           isLazy = useLazy = false;
18211         }
18212         var chainAll = this.__chain__,
18213             isHybrid = !!this.__actions__.length,
18214             isUnwrapped = retUnwrapped && !chainAll,
18215             onlyLazy = isLazy && !isHybrid;
18216
18217         if (!retUnwrapped && useLazy) {
18218           value = onlyLazy ? value : new LazyWrapper(this);
18219           var result = func.apply(value, args);
18220           result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
18221           return new LodashWrapper(result, chainAll);
18222         }
18223         if (isUnwrapped && onlyLazy) {
18224           return func.apply(this, args);
18225         }
18226         result = this.thru(interceptor);
18227         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
18228       };
18229     });
18230
18231     // Add `Array` methods to `lodash.prototype`.
18232     arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
18233       var func = arrayProto[methodName],
18234           chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
18235           retUnwrapped = /^(?:pop|shift)$/.test(methodName);
18236
18237       lodash.prototype[methodName] = function() {
18238         var args = arguments;
18239         if (retUnwrapped && !this.__chain__) {
18240           var value = this.value();
18241           return func.apply(isArray(value) ? value : [], args);
18242         }
18243         return this[chainName](function(value) {
18244           return func.apply(isArray(value) ? value : [], args);
18245         });
18246       };
18247     });
18248
18249     // Map minified method names to their real names.
18250     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
18251       var lodashFunc = lodash[methodName];
18252       if (lodashFunc) {
18253         var key = lodashFunc.name + '';
18254         if (!hasOwnProperty.call(realNames, key)) {
18255           realNames[key] = [];
18256         }
18257         realNames[key].push({ 'name': methodName, 'func': lodashFunc });
18258       }
18259     });
18260
18261     realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
18262       'name': 'wrapper',
18263       'func': undefined
18264     }];
18265
18266     // Add methods to `LazyWrapper`.
18267     LazyWrapper.prototype.clone = lazyClone;
18268     LazyWrapper.prototype.reverse = lazyReverse;
18269     LazyWrapper.prototype.value = lazyValue;
18270
18271     // Add chain sequence methods to the `lodash` wrapper.
18272     lodash.prototype.at = wrapperAt;
18273     lodash.prototype.chain = wrapperChain;
18274     lodash.prototype.commit = wrapperCommit;
18275     lodash.prototype.next = wrapperNext;
18276     lodash.prototype.plant = wrapperPlant;
18277     lodash.prototype.reverse = wrapperReverse;
18278     lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
18279
18280     // Add lazy aliases.
18281     lodash.prototype.first = lodash.prototype.head;
18282
18283     if (symIterator) {
18284       lodash.prototype[symIterator] = wrapperToIterator;
18285     }
18286     return lodash;
18287   });
18288
18289   /*--------------------------------------------------------------------------*/
18290
18291   // Export lodash.
18292   var _ = runInContext();
18293
18294   // Some AMD build optimizers, like r.js, check for condition patterns like:
18295   if (true) {
18296     // Expose Lodash on the global object to prevent errors when Lodash is
18297     // loaded by a script tag in the presence of an AMD loader.
18298     // See http://requirejs.org/docs/errors.html#mismatch for more details.
18299     // Use `_.noConflict` to remove Lodash from the global object.
18300     root._ = _;
18301
18302     // Define as an anonymous module so, through path mapping, it can be
18303     // referenced as the "underscore" module.
18304     !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {
18305       return _;
18306     }).call(exports, __webpack_require__, exports, module),
18307                 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
18308   }
18309   // Check for `exports` after `define` in case a build optimizer adds it.
18310   else {}
18311 }.call(this));
18312
18313
18314 /***/ }),
18315
18316 /***/ "./src/client.ts":
18317 /*!***********************!*\
18318   !*** ./src/client.ts ***!
18319   \***********************/
18320 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
18321
18322 "use strict";
18323
18324 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18325     if (k2 === undefined) k2 = k;
18326     var desc = Object.getOwnPropertyDescriptor(m, k);
18327     if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18328       desc = { enumerable: true, get: function() { return m[k]; } };
18329     }
18330     Object.defineProperty(o, k2, desc);
18331 }) : (function(o, m, k, k2) {
18332     if (k2 === undefined) k2 = k;
18333     o[k2] = m[k];
18334 }));
18335 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18336     Object.defineProperty(o, "default", { enumerable: true, value: v });
18337 }) : function(o, v) {
18338     o["default"] = v;
18339 });
18340 var __importStar = (this && this.__importStar) || function (mod) {
18341     if (mod && mod.__esModule) return mod;
18342     var result = {};
18343     if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18344     __setModuleDefault(result, mod);
18345     return result;
18346 };
18347 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18348     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18349     return new (P || (P = Promise))(function (resolve, reject) {
18350         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18351         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18352         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18353         step((generator = generator.apply(thisArg, _arguments || [])).next());
18354     });
18355 };
18356 var __importDefault = (this && this.__importDefault) || function (mod) {
18357     return (mod && mod.__esModule) ? mod : { "default": mod };
18358 };
18359 Object.defineProperty(exports, "__esModule", ({ value: true }));
18360 const outline_1 = __webpack_require__(/*! ./outline */ "./src/outline.ts");
18361 const cursor_1 = __webpack_require__(/*! ./cursor */ "./src/cursor.ts");
18362 const keyboardjs_1 = __importDefault(__webpack_require__(/*! keyboardjs */ "./node_modules/keyboardjs/dist/keyboard.js"));
18363 const rawOutline = __importStar(__webpack_require__(/*! ./test-data.json */ "./src/test-data.json"));
18364 const help_1 = __webpack_require__(/*! help */ "./src/help.ts");
18365 const search_1 = __webpack_require__(/*! ./search */ "./src/search.ts");
18366 let outlineData = rawOutline;
18367 if (localStorage.getItem('activeOutline')) {
18368     const outlineId = localStorage.getItem('activeOutline');
18369     outlineData = JSON.parse(localStorage.getItem(outlineId));
18370 }
18371 const state = new Map();
18372 const outline = new outline_1.Outline(outlineData);
18373 outliner().innerHTML = outline.render();
18374 const cursor = new cursor_1.Cursor();
18375 cursor.set('.node');
18376 const search = new search_1.Search();
18377 function outliner() {
18378     return document.querySelector('#outliner');
18379 }
18380 document.getElementById('display-help').addEventListener('click', e => {
18381     e.preventDefault();
18382     e.stopPropagation();
18383     (0, help_1.showHelp)();
18384 });
18385 keyboardjs_1.default.withContext('navigation', () => {
18386     keyboardjs_1.default.bind('j', e => {
18387         const sibling = cursor.get().nextElementSibling;
18388         if (sibling) {
18389             if (e.shiftKey) {
18390                 const res = outline.swapNodeWithNextSibling(cursor.getIdOfNode());
18391                 const html = outline.renderNode(res.parentNode);
18392                 if (res.parentNode.id === '000000') {
18393                     cursor.get().parentElement.innerHTML = html;
18394                 }
18395                 else {
18396                     cursor.get().parentElement.outerHTML = html;
18397                 }
18398                 cursor.set(`#id-${res.targetNode.id}`);
18399                 save();
18400             }
18401             else {
18402                 cursor.set(`#id-${sibling.getAttribute('data-id')}`);
18403             }
18404         }
18405     });
18406     keyboardjs_1.default.bind('shift + /', e => {
18407         (0, help_1.showHelp)();
18408     });
18409     keyboardjs_1.default.bind('k', e => {
18410         const sibling = cursor.get().previousElementSibling;
18411         if (sibling && !sibling.classList.contains('nodeContent')) {
18412             if (e.shiftKey) {
18413                 const res = outline.swapNodeWithPreviousSibling(cursor.getIdOfNode());
18414                 const html = outline.renderNode(res.parentNode);
18415                 if (res.parentNode.id === '000000') {
18416                     cursor.get().parentElement.innerHTML = html;
18417                 }
18418                 else {
18419                     cursor.get().parentElement.outerHTML = html;
18420                 }
18421                 cursor.set(`#id-${res.targetNode.id}`);
18422                 save();
18423             }
18424             else {
18425                 cursor.set(`#id-${sibling.getAttribute('data-id')}`);
18426             }
18427         }
18428     });
18429     keyboardjs_1.default.bind('l', e => {
18430         if (cursor.isNodeCollapsed()) {
18431             return;
18432         }
18433         if (e.shiftKey) {
18434             const res = outline.lowerNodeToChild(cursor.getIdOfNode());
18435             const html = outline.renderNode(res.oldParentNode);
18436             if (res.oldParentNode.id === '000000') {
18437                 cursor.get().parentElement.innerHTML = html;
18438             }
18439             else {
18440                 cursor.get().parentElement.outerHTML = html;
18441             }
18442             cursor.set(`#id-${res.targetNode.id}`);
18443         }
18444         else {
18445             const children = cursor.get().querySelector('.node');
18446             if (children) {
18447                 cursor.set(`#id-${children.getAttribute('data-id')}`);
18448             }
18449         }
18450     });
18451     keyboardjs_1.default.bind('h', e => {
18452         const parent = cursor.get().parentElement;
18453         if (parent && parent.classList.contains('node')) {
18454             if (e.shiftKey) {
18455                 if (outline.data.tree.children.map(n => n.id).includes(cursor.getIdOfNode())) {
18456                     return;
18457                 }
18458                 const res = outline.liftNodeToParent(cursor.getIdOfNode());
18459                 const html = outline.renderNode(res.parentNode);
18460                 if (res.parentNode.id === '000000') {
18461                     cursor.get().parentElement.parentElement.innerHTML = html;
18462                 }
18463                 else {
18464                     cursor.get().parentElement.parentElement.outerHTML = html;
18465                 }
18466                 cursor.set(`#id-${res.targetNode.id}`);
18467                 save();
18468             }
18469             else {
18470                 cursor.set(`#id-${parent.getAttribute('data-id')}`);
18471             }
18472         }
18473     });
18474     keyboardjs_1.default.bind('z', e => {
18475         if (cursor.isNodeExpanded()) {
18476             cursor.collapse();
18477             outline.fold(cursor.getIdOfNode());
18478         }
18479         else if (cursor.isNodeCollapsed()) {
18480             cursor.expand();
18481             outline.unfold(cursor.getIdOfNode());
18482         }
18483         save();
18484     });
18485     keyboardjs_1.default.bind('shift + 4', e => {
18486         e.preventDefault();
18487         cursor.get().classList.add('hidden-cursor');
18488         const contentNode = cursor.get().querySelector('.nodeContent');
18489         contentNode.innerHTML = outline.data.contentNodes[cursor.getIdOfNode()].content;
18490         contentNode.contentEditable = "true";
18491         const range = document.createRange();
18492         range.selectNodeContents(contentNode);
18493         range.collapse(false);
18494         const selection = window.getSelection();
18495         selection.removeAllRanges();
18496         selection.addRange(range);
18497         contentNode.focus();
18498         keyboardjs_1.default.setContext('editing');
18499     });
18500     keyboardjs_1.default.bind('i', e => {
18501         e.preventDefault();
18502         cursor.get().classList.add('hidden-cursor');
18503         const contentNode = cursor.get().querySelector('.nodeContent');
18504         contentNode.innerHTML = outline.data.contentNodes[cursor.getIdOfNode()].content;
18505         contentNode.contentEditable = "true";
18506         contentNode.focus();
18507         keyboardjs_1.default.setContext('editing');
18508     });
18509     keyboardjs_1.default.bind('shift + x', e => {
18510         e.preventDefault();
18511         cursor.get().classList.toggle('strikethrough');
18512         outline.data.contentNodes[cursor.getIdOfNode()].strikethrough = cursor.get().classList.contains('strikethrough');
18513         save();
18514     });
18515     keyboardjs_1.default.bind('tab', e => {
18516         e.preventDefault();
18517         const res = outline.createChildNode(cursor.getIdOfNode());
18518         const html = outline.renderNode(res.parentNode);
18519         cursor.get().outerHTML = html;
18520         cursor.set(`#id-${res.node.id}`);
18521         save();
18522     });
18523     keyboardjs_1.default.bind('enter', e => {
18524         if (e.shiftKey) {
18525             return;
18526         }
18527         e.preventDefault();
18528         e.preventRepeat();
18529         const res = outline.createSiblingNode(cursor.getIdOfNode());
18530         const html = outline.renderNode(res.parentNode);
18531         if (res.parentNode.id === '000000') {
18532             cursor.get().parentElement.innerHTML = html;
18533         }
18534         else {
18535             cursor.get().parentElement.outerHTML = html;
18536         }
18537         cursor.set(`#id-${res.node.id}`);
18538         save();
18539     });
18540     keyboardjs_1.default.bind('d', e => {
18541         if (!e.shiftKey) {
18542             return;
18543         }
18544         const res = outline.removeNode(cursor.getIdOfNode());
18545         const html = outline.renderNode(res.parentNode);
18546         const prevSibling = cursor.get().previousElementSibling;
18547         const nextSibling = cursor.get().nextElementSibling;
18548         if (res.parentNode.id === '000000') {
18549             cursor.get().parentElement.innerHTML = html;
18550         }
18551         else {
18552             cursor.get().parentElement.outerHTML = html;
18553         }
18554         if (prevSibling.getAttribute('data-id')) {
18555             cursor.set(`#id-${prevSibling.getAttribute('data-id')}`);
18556         }
18557         else if (nextSibling.getAttribute('data-id')) {
18558             cursor.set(`#id-${nextSibling.getAttribute('data-id')}`);
18559         }
18560         else {
18561             console.log(res.parentNode.id);
18562             cursor.set(`#id-${res.parentNode.id}`);
18563         }
18564         save();
18565     });
18566 });
18567 keyboardjs_1.default.withContext('editing', () => {
18568     keyboardjs_1.default.bind(['esc', 'enter'], e => {
18569         cursor.get().classList.remove('hidden-cursor');
18570         const contentNode = cursor.get().querySelector('.nodeContent');
18571         contentNode.contentEditable = "false";
18572         contentNode.blur();
18573         keyboardjs_1.default.setContext('navigation');
18574         outline.updateContent(cursor.getIdOfNode(), contentNode.innerHTML.trim());
18575         contentNode.innerHTML = outline.renderContent(cursor.getIdOfNode());
18576         save();
18577     });
18578 });
18579 keyboardjs_1.default.setContext('navigation');
18580 search.createIndex({
18581     id: "string",
18582     created: "number",
18583     type: "string",
18584     content: "string",
18585     strikethrough: "boolean"
18586 }).then(() => __awaiter(void 0, void 0, void 0, function* () {
18587     yield search.indexBatch(outline.data.contentNodes);
18588     search.bindEvents();
18589 }));
18590 function recursivelyExpand(start) {
18591     if (start.classList.contains('node')) {
18592         if (start.classList.contains('collapsed')) {
18593             start.classList.remove('collapsed');
18594             start.classList.add('expanded');
18595             outline.unfold(start.getAttribute('data-id'));
18596         }
18597         if (start.parentElement) {
18598             recursivelyExpand(start.parentElement);
18599         }
18600     }
18601 }
18602 search.onTermSelection = (docId) => {
18603     recursivelyExpand(document.getElementById(`id-${docId}`).parentElement);
18604     cursor.set(`#id-${docId}`);
18605     save();
18606 };
18607 function saveImmediate() {
18608     localStorage.setItem(outline.data.id, JSON.stringify(outline.data));
18609     localStorage.setItem('activeOutline', outline.data.id);
18610     console.log('saved...', outline.data);
18611     state.delete('saveTimeout');
18612 }
18613 function save() {
18614     if (!state.has('saveTimeout')) {
18615         state.set('saveTimeout', setTimeout(saveImmediate, 2000));
18616     }
18617 }
18618 save();
18619
18620
18621 /***/ }),
18622
18623 /***/ "./src/cursor.ts":
18624 /*!***********************!*\
18625   !*** ./src/cursor.ts ***!
18626   \***********************/
18627 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
18628
18629 "use strict";
18630
18631 Object.defineProperty(exports, "__esModule", ({ value: true }));
18632 exports.Cursor = void 0;
18633 const dom_1 = __webpack_require__(/*! dom */ "./src/dom.ts");
18634 class Cursor {
18635     constructor() {
18636     }
18637     get() {
18638         return document.querySelector('.cursor');
18639     }
18640     getIdOfNode() {
18641         return this.get().getAttribute('data-id');
18642     }
18643     unset() {
18644         const el = this.get();
18645         if (el) {
18646             el.classList.remove('cursor');
18647         }
18648     }
18649     set(elementId) {
18650         this.unset();
18651         const el = document.querySelector(elementId);
18652         if (el) {
18653             el.classList.add('cursor');
18654             if (!(0, dom_1.isVisible)(el)) {
18655                 el.scrollIntoView(true);
18656             }
18657         }
18658     }
18659     collapse() {
18660         this.get().classList.remove('expanded');
18661         this.get().classList.add('collapsed');
18662     }
18663     expand() {
18664         this.get().classList.remove('collapsed');
18665         this.get().classList.add('expanded');
18666     }
18667     isNodeCollapsed() {
18668         return this.get().classList.contains('collapsed');
18669     }
18670     isNodeExpanded() {
18671         return this.get().classList.contains('expanded');
18672     }
18673 }
18674 exports.Cursor = Cursor;
18675
18676
18677 /***/ }),
18678
18679 /***/ "./src/dom.ts":
18680 /*!********************!*\
18681   !*** ./src/dom.ts ***!
18682   \********************/
18683 /***/ ((__unused_webpack_module, exports) => {
18684
18685 "use strict";
18686
18687 Object.defineProperty(exports, "__esModule", ({ value: true }));
18688 exports.isVisible = void 0;
18689 function isVisible(element) {
18690     const rect = element.getBoundingClientRect();
18691     return (rect.top >= 0 &&
18692         rect.left >= 0 &&
18693         rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
18694         rect.right <= (window.innerWidth || document.documentElement.clientWidth));
18695 }
18696 exports.isVisible = isVisible;
18697
18698
18699 /***/ }),
18700
18701 /***/ "./src/help.ts":
18702 /*!*********************!*\
18703   !*** ./src/help.ts ***!
18704   \*********************/
18705 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
18706
18707 "use strict";
18708
18709 var __importDefault = (this && this.__importDefault) || function (mod) {
18710     return (mod && mod.__esModule) ? mod : { "default": mod };
18711 };
18712 Object.defineProperty(exports, "__esModule", ({ value: true }));
18713 exports.showHelp = void 0;
18714 const keyboardjs_1 = __importDefault(__webpack_require__(/*! keyboardjs */ "./node_modules/keyboardjs/dist/keyboard.js"));
18715 const lodash_1 = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js");
18716 const keyboardCommands = {
18717     'h': 'Move the cursor to the Parent Element of the current node',
18718     'l': 'Move the cursor to the first Child Element of the current node',
18719     'j': 'Move the cursor to the next sibling of the current node',
18720     'k': 'Move the cursor to the previous sibling of the current node',
18721     'enter': 'Add a new node as a sibling to the current node',
18722     'tab': 'Add a new node as the child of the current node',
18723     'shift + j': 'Swap the current node with next sibling node',
18724     'shift + k': 'Swap the current node with the previous sibling node',
18725     'shift + h': 'Lift the current node to be a sibling of the parent node',
18726     'shift + l': 'Lower the current node to be a child of the previous sibling node',
18727     'shift + d': 'Delete the current node',
18728     'shift + f': 'Open the search modal',
18729     'i': 'Enter "edit" mode, and place the cursor at the start of the editable content',
18730     '$': 'Enter "edit" mode, and place the cursor at the end of the editable content',
18731     'escape': 'Exit the current mode and return to "navigation" mode',
18732     '?': 'Display this help dialogue'
18733 };
18734 const modalHTML = `
18735   <div class="modal">
18736   <div class="modal-content">
18737     <h1>Help</h1>
18738     <table>
18739     <thead>
18740     <tr>
18741     <th>Key</th>
18742     <th>Action</th>
18743     </tr>
18744     </thead>
18745     <tbody>
18746     ${(0, lodash_1.map)(keyboardCommands, (text, key) => {
18747     return `
18748       <tr>
18749         <td>
18750           <kbd>${key}</kbd>
18751         </td>
18752         <td>
18753           ${text}
18754         </td>
18755       </tr>
18756       `;
18757 }).join("\n")}
18758     </tbody>
18759     </table>
18760   </div>
18761   </div>
18762 `;
18763 function showHelp() {
18764     document.querySelector('body').innerHTML += modalHTML;
18765     keyboardjs_1.default.setContext('help');
18766 }
18767 exports.showHelp = showHelp;
18768 keyboardjs_1.default.withContext('help', () => {
18769     keyboardjs_1.default.bind('escape', e => {
18770         document.querySelector('.modal').remove();
18771         keyboardjs_1.default.setContext('navigation');
18772     });
18773 });
18774
18775
18776 /***/ }),
18777
18778 /***/ "./src/outline.ts":
18779 /*!************************!*\
18780   !*** ./src/outline.ts ***!
18781   \************************/
18782 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
18783
18784 "use strict";
18785
18786 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18787     if (k2 === undefined) k2 = k;
18788     var desc = Object.getOwnPropertyDescriptor(m, k);
18789     if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18790       desc = { enumerable: true, get: function() { return m[k]; } };
18791     }
18792     Object.defineProperty(o, k2, desc);
18793 }) : (function(o, m, k, k2) {
18794     if (k2 === undefined) k2 = k;
18795     o[k2] = m[k];
18796 }));
18797 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18798     Object.defineProperty(o, "default", { enumerable: true, value: v });
18799 }) : function(o, v) {
18800     o["default"] = v;
18801 });
18802 var __importStar = (this && this.__importStar) || function (mod) {
18803     if (mod && mod.__esModule) return mod;
18804     var result = {};
18805     if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18806     __setModuleDefault(result, mod);
18807     return result;
18808 };
18809 Object.defineProperty(exports, "__esModule", ({ value: true }));
18810 exports.Outline = void 0;
18811 const _ = __importStar(__webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"));
18812 const uuid_1 = __webpack_require__(/*! uuid */ "./node_modules/uuid/dist/commonjs-browser/index.js");
18813 const marked_1 = __webpack_require__(/*! marked */ "./node_modules/marked/lib/marked.cjs");
18814 ;
18815 class Outline {
18816     constructor(outlineData) {
18817         this.data = outlineData;
18818     }
18819     findNodeInTree(root, id, action, runState = false) {
18820         let run = runState;
18821         if (run) {
18822             return;
18823         }
18824         _.each(root.children, (childNode, idx) => {
18825             if (childNode.id === id) {
18826                 action(childNode, root);
18827                 run = true;
18828                 return false;
18829             }
18830             else if (childNode.children) {
18831                 this.findNodeInTree(childNode, id, action, run);
18832             }
18833         });
18834     }
18835     fold(nodeId) {
18836         this.findNodeInTree(this.data.tree, nodeId, item => {
18837             item.collapsed = true;
18838         });
18839     }
18840     unfold(nodeId) {
18841         this.findNodeInTree(this.data.tree, nodeId, item => {
18842             item.collapsed = false;
18843         });
18844     }
18845     flattenOutlineTreeChildren(tree) {
18846         return tree.children.map(node => node.id);
18847     }
18848     liftNodeToParent(nodeId) {
18849         let run = false;
18850         let targetNode, parentNode;
18851         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18852             targetNode = tNode;
18853             this.findNodeInTree(this.data.tree, pNode.id, (originalParentNode, newParentNode) => {
18854                 ;
18855                 if (run) {
18856                     return;
18857                 }
18858                 parentNode = newParentNode;
18859                 run = true;
18860                 const flatId = newParentNode.children.map(n => n.id);
18861                 const originalNodePosition = originalParentNode.children.map(n => n.id).indexOf(targetNode.id);
18862                 const newNodePosition = flatId.indexOf(originalParentNode.id);
18863                 originalParentNode.children.splice(originalNodePosition, 1);
18864                 newParentNode.children.splice(newNodePosition + 1, 0, targetNode);
18865             });
18866         });
18867         return {
18868             targetNode,
18869             parentNode
18870         };
18871     }
18872     lowerNodeToChild(nodeId) {
18873         let run = false;
18874         let targetNode, newParentNode, oldParentNode;
18875         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18876             if (run) {
18877                 return;
18878             }
18879             run = true;
18880             targetNode = tNode;
18881             let idList = pNode.children.map(n => n.id);
18882             if (idList.length === 1) {
18883                 return;
18884             }
18885             const position = idList.indexOf(targetNode.id);
18886             const prevSiblingPosition = position - 1;
18887             pNode.children[prevSiblingPosition].children.splice(0, 0, targetNode);
18888             pNode.children.splice(position, 1);
18889             newParentNode = pNode.children[prevSiblingPosition];
18890             oldParentNode = pNode;
18891         });
18892         return {
18893             targetNode,
18894             newParentNode,
18895             oldParentNode
18896         };
18897     }
18898     swapNodeWithNextSibling(nodeId) {
18899         let targetNode, parentNode;
18900         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18901             targetNode = tNode;
18902             parentNode = pNode;
18903             const flatId = parentNode.children.map(n => n.id);
18904             const nodePosition = flatId.indexOf(targetNode.id);
18905             if (nodePosition === (flatId.length - 1)) {
18906                 return;
18907             }
18908             parentNode.children.splice(nodePosition, 1);
18909             parentNode.children.splice(nodePosition + 1, 0, targetNode);
18910         });
18911         return {
18912             targetNode,
18913             parentNode
18914         };
18915     }
18916     swapNodeWithPreviousSibling(nodeId) {
18917         let targetNode, parentNode;
18918         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18919             targetNode = tNode;
18920             parentNode = pNode;
18921             const flatId = parentNode.children.map(n => n.id);
18922             const nodePosition = flatId.indexOf(targetNode.id);
18923             if (nodePosition === 0) {
18924                 return;
18925             }
18926             parentNode.children.splice(nodePosition, 1);
18927             parentNode.children.splice(nodePosition - 1, 0, targetNode);
18928         });
18929         return {
18930             targetNode,
18931             parentNode
18932         };
18933     }
18934     createSiblingNode(targetNode, nodeData) {
18935         const outlineNode = nodeData || {
18936             id: (0, uuid_1.v4)(),
18937             created: Date.now(),
18938             type: 'text',
18939             content: '---',
18940             strikethrough: false
18941         };
18942         this.data.contentNodes[outlineNode.id] = outlineNode;
18943         let parentNode;
18944         this.findNodeInTree(this.data.tree, targetNode, (node, parent) => {
18945             const position = parent.children.map(n => n.id).indexOf(targetNode);
18946             parent.children.splice(position + 1, 0, {
18947                 id: outlineNode.id,
18948                 collapsed: false,
18949                 children: []
18950             });
18951             parentNode = parent;
18952         });
18953         return {
18954             node: outlineNode,
18955             parentNode
18956         };
18957     }
18958     createChildNode(currentNode, nodeId) {
18959         const node = nodeId ? this.data.contentNodes[nodeId] :
18960             {
18961                 id: (0, uuid_1.v4)(),
18962                 created: Date.now(),
18963                 type: 'text',
18964                 content: '---',
18965                 strikethrough: false
18966             };
18967         if (!nodeId) {
18968             this.data.contentNodes[node.id] = node;
18969         }
18970         let parentNode;
18971         this.findNodeInTree(this.data.tree, currentNode, (foundNode, parent) => {
18972             foundNode.children.unshift({
18973                 id: node.id,
18974                 children: [],
18975                 collapsed: false
18976             });
18977             parentNode = foundNode;
18978         });
18979         return {
18980             node,
18981             parentNode
18982         };
18983     }
18984     removeNode(nodeId) {
18985         let run = false;
18986         let removedNode, parentNode;
18987         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18988             if (run) {
18989                 return;
18990             }
18991             run = true;
18992             removedNode = tNode;
18993             parentNode = pNode;
18994             let position = parentNode.children.map(n => n.id).indexOf(tNode.id);
18995             parentNode.children.splice(position, 1);
18996         });
18997         return {
18998             removedNode,
18999             parentNode
19000         };
19001     }
19002     updateContent(id, content) {
19003         if (!this.data.contentNodes[id]) {
19004             throw new Error('Invalid node');
19005         }
19006         this.data.contentNodes[id].content = content;
19007     }
19008     renderContent(nodeId) {
19009         let node = this.data.contentNodes[nodeId];
19010         let content;
19011         switch (node.type) {
19012             case 'text':
19013                 content = marked_1.marked.parse(node.content);
19014                 break;
19015             default:
19016                 content = node.content;
19017                 break;
19018         }
19019         return content;
19020     }
19021     renderNode(node) {
19022         if (node.id === '000000') {
19023             return this.render();
19024         }
19025         const collapse = node.collapsed ? 'collapsed' : 'expanded';
19026         const content = this.data.contentNodes[node.id] || {
19027             id: node.id,
19028             created: Date.now(),
19029             type: 'text',
19030             content: '',
19031             strikethrough: false
19032         };
19033         const strikethrough = content.strikethrough ? 'strikethrough' : '';
19034         let html = `<div class="node ${collapse} ${strikethrough}" data-id="${node.id}" id="id-${node.id}">
19035     <div class="nodeContent" data-type="${content.type}">
19036       ${this.renderContent(node.id)}
19037     </div>
19038     ${node.children.length ? _.map(node.children, this.renderNode.bind(this)).join("\n") : ''}
19039     </div>`;
19040         return html;
19041     }
19042     render() {
19043         return _.map(this.data.tree.children, this.renderNode.bind(this)).join("\n");
19044     }
19045 }
19046 exports.Outline = Outline;
19047
19048
19049 /***/ }),
19050
19051 /***/ "./src/search.ts":
19052 /*!***********************!*\
19053   !*** ./src/search.ts ***!
19054   \***********************/
19055 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
19056
19057 "use strict";
19058
19059 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
19060     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19061     return new (P || (P = Promise))(function (resolve, reject) {
19062         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
19063         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19064         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19065         step((generator = generator.apply(thisArg, _arguments || [])).next());
19066     });
19067 };
19068 var __importDefault = (this && this.__importDefault) || function (mod) {
19069     return (mod && mod.__esModule) ? mod : { "default": mod };
19070 };
19071 Object.defineProperty(exports, "__esModule", ({ value: true }));
19072 exports.Search = void 0;
19073 const lyra_1 = __webpack_require__(/*! @lyrasearch/lyra */ "./node_modules/@lyrasearch/lyra/dist/cjs/index.cjs");
19074 const lodash_1 = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js");
19075 const keyboardjs_1 = __importDefault(__webpack_require__(/*! keyboardjs */ "./node_modules/keyboardjs/dist/keyboard.js"));
19076 const dom_1 = __webpack_require__(/*! dom */ "./src/dom.ts");
19077 const searchModal = `
19078 <div class="modal">
19079 <div class="modal-content" id="search">
19080 <input type="text" id="search-query" placeholder="enter fuzzy search terms">
19081 <ul id="search-results">
19082 </ul>
19083 </div>
19084 </div>
19085 `;
19086 class Search {
19087     constructor() {
19088         this.state = 'notready';
19089     }
19090     createIndex(schema) {
19091         return __awaiter(this, void 0, void 0, function* () {
19092             this.db = yield (0, lyra_1.create)({
19093                 schema
19094             });
19095             this.state = 'ready';
19096         });
19097     }
19098     bindEvents() {
19099         keyboardjs_1.default.withContext('search', () => {
19100             keyboardjs_1.default.bind('escape', e => {
19101                 document.querySelector('.modal').remove();
19102                 keyboardjs_1.default.setContext('navigation');
19103             });
19104             keyboardjs_1.default.bind('down', e => {
19105                 e.preventDefault();
19106                 document.getElementById('search-query').blur();
19107                 const el = document.querySelector('.search-result.selected');
19108                 if (el.nextElementSibling) {
19109                     el.classList.remove('selected');
19110                     el.nextElementSibling.classList.add('selected');
19111                     if (!(0, dom_1.isVisible)(el.nextElementSibling)) {
19112                         el.nextElementSibling.scrollIntoView();
19113                     }
19114                 }
19115             });
19116             keyboardjs_1.default.bind('up', e => {
19117                 e.preventDefault();
19118                 const el = document.querySelector('.search-result.selected');
19119                 if (el.previousElementSibling) {
19120                     el.classList.remove('selected');
19121                     el.previousElementSibling.classList.add('selected');
19122                     if (!(0, dom_1.isVisible)(el.previousElementSibling)) {
19123                         el.previousElementSibling.scrollIntoView();
19124                     }
19125                 }
19126             });
19127             keyboardjs_1.default.bind('enter', e => {
19128                 const el = document.querySelector('.search-result.selected');
19129                 const docId = el.getAttribute('data-id');
19130                 document.querySelector('.modal').remove();
19131                 keyboardjs_1.default.setContext('navigation');
19132                 if (this.onTermSelection) {
19133                     this.onTermSelection(docId);
19134                 }
19135             });
19136         });
19137         keyboardjs_1.default.withContext('navigation', () => {
19138             keyboardjs_1.default.bind('shift + f', e => {
19139                 e.preventDefault();
19140                 e.stopPropagation();
19141                 document.querySelector('body').innerHTML += searchModal;
19142                 const el = document.getElementById('search-query');
19143                 el.focus();
19144                 el.addEventListener('keyup', this.debounceSearch.bind(this));
19145                 keyboardjs_1.default.setContext('search');
19146             });
19147         });
19148     }
19149     debounceSearch(e) {
19150         if (this.debounce) {
19151             clearInterval(this.debounce);
19152         }
19153         const el = e.target;
19154         const query = el.value.toString().trim();
19155         if (query.length) {
19156             this.debounce = setTimeout(() => {
19157                 this.displaySearch(query, e);
19158             }, 100);
19159         }
19160     }
19161     displaySearch(terms, e) {
19162         return __awaiter(this, void 0, void 0, function* () {
19163             if (!this.state) {
19164                 return;
19165             }
19166             const res = yield this.search(terms);
19167             const resultContainer = document.getElementById('search-results');
19168             if (res.hits.length === 0) {
19169                 resultContainer.innerHTML = '<li><em>No Results</em></li>';
19170                 return;
19171             }
19172             const html = res.hits.map((doc, idx) => {
19173                 const content = doc.document.content.toString();
19174                 const display = content.substring(0, 100);
19175                 return `
19176       <li class="search-result ${idx === 0 ? 'selected' : ''}" data-id="${doc.id}">${display}${content.length > display.length ? '...' : ''}</li>
19177       `;
19178             });
19179             resultContainer.innerHTML = html.join("\n");
19180         });
19181     }
19182     indexDoc(doc) {
19183         return (0, lyra_1.insert)(this.db, doc);
19184     }
19185     indexBatch(docs) {
19186         return (0, lyra_1.insertBatch)(this.db, (0, lodash_1.map)(docs, doc => doc));
19187     }
19188     search(term) {
19189         return (0, lyra_1.search)(this.db, {
19190             term: term.trim(),
19191             properties: ["content"]
19192         });
19193     }
19194 }
19195 exports.Search = Search;
19196
19197
19198 /***/ }),
19199
19200 /***/ "./node_modules/uuid/dist/commonjs-browser/index.js":
19201 /*!**********************************************************!*\
19202   !*** ./node_modules/uuid/dist/commonjs-browser/index.js ***!
19203   \**********************************************************/
19204 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19205
19206 "use strict";
19207
19208
19209 Object.defineProperty(exports, "__esModule", ({
19210   value: true
19211 }));
19212 Object.defineProperty(exports, "NIL", ({
19213   enumerable: true,
19214   get: function get() {
19215     return _nil.default;
19216   }
19217 }));
19218 Object.defineProperty(exports, "parse", ({
19219   enumerable: true,
19220   get: function get() {
19221     return _parse.default;
19222   }
19223 }));
19224 Object.defineProperty(exports, "stringify", ({
19225   enumerable: true,
19226   get: function get() {
19227     return _stringify.default;
19228   }
19229 }));
19230 Object.defineProperty(exports, "v1", ({
19231   enumerable: true,
19232   get: function get() {
19233     return _v.default;
19234   }
19235 }));
19236 Object.defineProperty(exports, "v3", ({
19237   enumerable: true,
19238   get: function get() {
19239     return _v2.default;
19240   }
19241 }));
19242 Object.defineProperty(exports, "v4", ({
19243   enumerable: true,
19244   get: function get() {
19245     return _v3.default;
19246   }
19247 }));
19248 Object.defineProperty(exports, "v5", ({
19249   enumerable: true,
19250   get: function get() {
19251     return _v4.default;
19252   }
19253 }));
19254 Object.defineProperty(exports, "validate", ({
19255   enumerable: true,
19256   get: function get() {
19257     return _validate.default;
19258   }
19259 }));
19260 Object.defineProperty(exports, "version", ({
19261   enumerable: true,
19262   get: function get() {
19263     return _version.default;
19264   }
19265 }));
19266
19267 var _v = _interopRequireDefault(__webpack_require__(/*! ./v1.js */ "./node_modules/uuid/dist/commonjs-browser/v1.js"));
19268
19269 var _v2 = _interopRequireDefault(__webpack_require__(/*! ./v3.js */ "./node_modules/uuid/dist/commonjs-browser/v3.js"));
19270
19271 var _v3 = _interopRequireDefault(__webpack_require__(/*! ./v4.js */ "./node_modules/uuid/dist/commonjs-browser/v4.js"));
19272
19273 var _v4 = _interopRequireDefault(__webpack_require__(/*! ./v5.js */ "./node_modules/uuid/dist/commonjs-browser/v5.js"));
19274
19275 var _nil = _interopRequireDefault(__webpack_require__(/*! ./nil.js */ "./node_modules/uuid/dist/commonjs-browser/nil.js"));
19276
19277 var _version = _interopRequireDefault(__webpack_require__(/*! ./version.js */ "./node_modules/uuid/dist/commonjs-browser/version.js"));
19278
19279 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19280
19281 var _stringify = _interopRequireDefault(__webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js"));
19282
19283 var _parse = _interopRequireDefault(__webpack_require__(/*! ./parse.js */ "./node_modules/uuid/dist/commonjs-browser/parse.js"));
19284
19285 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19286
19287 /***/ }),
19288
19289 /***/ "./node_modules/uuid/dist/commonjs-browser/md5.js":
19290 /*!********************************************************!*\
19291   !*** ./node_modules/uuid/dist/commonjs-browser/md5.js ***!
19292   \********************************************************/
19293 /***/ ((__unused_webpack_module, exports) => {
19294
19295 "use strict";
19296
19297
19298 Object.defineProperty(exports, "__esModule", ({
19299   value: true
19300 }));
19301 exports["default"] = void 0;
19302
19303 /*
19304  * Browser-compatible JavaScript MD5
19305  *
19306  * Modification of JavaScript MD5
19307  * https://github.com/blueimp/JavaScript-MD5
19308  *
19309  * Copyright 2011, Sebastian Tschan
19310  * https://blueimp.net
19311  *
19312  * Licensed under the MIT license:
19313  * https://opensource.org/licenses/MIT
19314  *
19315  * Based on
19316  * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
19317  * Digest Algorithm, as defined in RFC 1321.
19318  * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
19319  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
19320  * Distributed under the BSD License
19321  * See http://pajhome.org.uk/crypt/md5 for more info.
19322  */
19323 function md5(bytes) {
19324   if (typeof bytes === 'string') {
19325     const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
19326
19327     bytes = new Uint8Array(msg.length);
19328
19329     for (let i = 0; i < msg.length; ++i) {
19330       bytes[i] = msg.charCodeAt(i);
19331     }
19332   }
19333
19334   return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8));
19335 }
19336 /*
19337  * Convert an array of little-endian words to an array of bytes
19338  */
19339
19340
19341 function md5ToHexEncodedArray(input) {
19342   const output = [];
19343   const length32 = input.length * 32;
19344   const hexTab = '0123456789abcdef';
19345
19346   for (let i = 0; i < length32; i += 8) {
19347     const x = input[i >> 5] >>> i % 32 & 0xff;
19348     const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16);
19349     output.push(hex);
19350   }
19351
19352   return output;
19353 }
19354 /**
19355  * Calculate output length with padding and bit length
19356  */
19357
19358
19359 function getOutputLength(inputLength8) {
19360   return (inputLength8 + 64 >>> 9 << 4) + 14 + 1;
19361 }
19362 /*
19363  * Calculate the MD5 of an array of little-endian words, and a bit length.
19364  */
19365
19366
19367 function wordsToMd5(x, len) {
19368   /* append padding */
19369   x[len >> 5] |= 0x80 << len % 32;
19370   x[getOutputLength(len) - 1] = len;
19371   let a = 1732584193;
19372   let b = -271733879;
19373   let c = -1732584194;
19374   let d = 271733878;
19375
19376   for (let i = 0; i < x.length; i += 16) {
19377     const olda = a;
19378     const oldb = b;
19379     const oldc = c;
19380     const oldd = d;
19381     a = md5ff(a, b, c, d, x[i], 7, -680876936);
19382     d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
19383     c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
19384     b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
19385     a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
19386     d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
19387     c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
19388     b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
19389     a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
19390     d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
19391     c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
19392     b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
19393     a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
19394     d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
19395     c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
19396     b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
19397     a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
19398     d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
19399     c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
19400     b = md5gg(b, c, d, a, x[i], 20, -373897302);
19401     a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
19402     d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
19403     c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
19404     b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
19405     a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
19406     d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
19407     c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
19408     b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
19409     a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
19410     d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
19411     c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
19412     b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
19413     a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
19414     d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
19415     c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
19416     b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
19417     a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
19418     d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
19419     c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
19420     b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
19421     a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
19422     d = md5hh(d, a, b, c, x[i], 11, -358537222);
19423     c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
19424     b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
19425     a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
19426     d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
19427     c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
19428     b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
19429     a = md5ii(a, b, c, d, x[i], 6, -198630844);
19430     d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
19431     c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
19432     b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
19433     a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
19434     d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
19435     c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
19436     b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
19437     a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
19438     d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
19439     c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
19440     b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
19441     a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
19442     d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
19443     c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
19444     b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
19445     a = safeAdd(a, olda);
19446     b = safeAdd(b, oldb);
19447     c = safeAdd(c, oldc);
19448     d = safeAdd(d, oldd);
19449   }
19450
19451   return [a, b, c, d];
19452 }
19453 /*
19454  * Convert an array bytes to an array of little-endian words
19455  * Characters >255 have their high-byte silently ignored.
19456  */
19457
19458
19459 function bytesToWords(input) {
19460   if (input.length === 0) {
19461     return [];
19462   }
19463
19464   const length8 = input.length * 8;
19465   const output = new Uint32Array(getOutputLength(length8));
19466
19467   for (let i = 0; i < length8; i += 8) {
19468     output[i >> 5] |= (input[i / 8] & 0xff) << i % 32;
19469   }
19470
19471   return output;
19472 }
19473 /*
19474  * Add integers, wrapping at 2^32. This uses 16-bit operations internally
19475  * to work around bugs in some JS interpreters.
19476  */
19477
19478
19479 function safeAdd(x, y) {
19480   const lsw = (x & 0xffff) + (y & 0xffff);
19481   const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
19482   return msw << 16 | lsw & 0xffff;
19483 }
19484 /*
19485  * Bitwise rotate a 32-bit number to the left.
19486  */
19487
19488
19489 function bitRotateLeft(num, cnt) {
19490   return num << cnt | num >>> 32 - cnt;
19491 }
19492 /*
19493  * These functions implement the four basic operations the algorithm uses.
19494  */
19495
19496
19497 function md5cmn(q, a, b, x, s, t) {
19498   return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
19499 }
19500
19501 function md5ff(a, b, c, d, x, s, t) {
19502   return md5cmn(b & c | ~b & d, a, b, x, s, t);
19503 }
19504
19505 function md5gg(a, b, c, d, x, s, t) {
19506   return md5cmn(b & d | c & ~d, a, b, x, s, t);
19507 }
19508
19509 function md5hh(a, b, c, d, x, s, t) {
19510   return md5cmn(b ^ c ^ d, a, b, x, s, t);
19511 }
19512
19513 function md5ii(a, b, c, d, x, s, t) {
19514   return md5cmn(c ^ (b | ~d), a, b, x, s, t);
19515 }
19516
19517 var _default = md5;
19518 exports["default"] = _default;
19519
19520 /***/ }),
19521
19522 /***/ "./node_modules/uuid/dist/commonjs-browser/native.js":
19523 /*!***********************************************************!*\
19524   !*** ./node_modules/uuid/dist/commonjs-browser/native.js ***!
19525   \***********************************************************/
19526 /***/ ((__unused_webpack_module, exports) => {
19527
19528 "use strict";
19529
19530
19531 Object.defineProperty(exports, "__esModule", ({
19532   value: true
19533 }));
19534 exports["default"] = void 0;
19535 const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
19536 var _default = {
19537   randomUUID
19538 };
19539 exports["default"] = _default;
19540
19541 /***/ }),
19542
19543 /***/ "./node_modules/uuid/dist/commonjs-browser/nil.js":
19544 /*!********************************************************!*\
19545   !*** ./node_modules/uuid/dist/commonjs-browser/nil.js ***!
19546   \********************************************************/
19547 /***/ ((__unused_webpack_module, exports) => {
19548
19549 "use strict";
19550
19551
19552 Object.defineProperty(exports, "__esModule", ({
19553   value: true
19554 }));
19555 exports["default"] = void 0;
19556 var _default = '00000000-0000-0000-0000-000000000000';
19557 exports["default"] = _default;
19558
19559 /***/ }),
19560
19561 /***/ "./node_modules/uuid/dist/commonjs-browser/parse.js":
19562 /*!**********************************************************!*\
19563   !*** ./node_modules/uuid/dist/commonjs-browser/parse.js ***!
19564   \**********************************************************/
19565 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19566
19567 "use strict";
19568
19569
19570 Object.defineProperty(exports, "__esModule", ({
19571   value: true
19572 }));
19573 exports["default"] = void 0;
19574
19575 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19576
19577 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19578
19579 function parse(uuid) {
19580   if (!(0, _validate.default)(uuid)) {
19581     throw TypeError('Invalid UUID');
19582   }
19583
19584   let v;
19585   const arr = new Uint8Array(16); // Parse ########-....-....-....-............
19586
19587   arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
19588   arr[1] = v >>> 16 & 0xff;
19589   arr[2] = v >>> 8 & 0xff;
19590   arr[3] = v & 0xff; // Parse ........-####-....-....-............
19591
19592   arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
19593   arr[5] = v & 0xff; // Parse ........-....-####-....-............
19594
19595   arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
19596   arr[7] = v & 0xff; // Parse ........-....-....-####-............
19597
19598   arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
19599   arr[9] = v & 0xff; // Parse ........-....-....-....-############
19600   // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
19601
19602   arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;
19603   arr[11] = v / 0x100000000 & 0xff;
19604   arr[12] = v >>> 24 & 0xff;
19605   arr[13] = v >>> 16 & 0xff;
19606   arr[14] = v >>> 8 & 0xff;
19607   arr[15] = v & 0xff;
19608   return arr;
19609 }
19610
19611 var _default = parse;
19612 exports["default"] = _default;
19613
19614 /***/ }),
19615
19616 /***/ "./node_modules/uuid/dist/commonjs-browser/regex.js":
19617 /*!**********************************************************!*\
19618   !*** ./node_modules/uuid/dist/commonjs-browser/regex.js ***!
19619   \**********************************************************/
19620 /***/ ((__unused_webpack_module, exports) => {
19621
19622 "use strict";
19623
19624
19625 Object.defineProperty(exports, "__esModule", ({
19626   value: true
19627 }));
19628 exports["default"] = void 0;
19629 var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
19630 exports["default"] = _default;
19631
19632 /***/ }),
19633
19634 /***/ "./node_modules/uuid/dist/commonjs-browser/rng.js":
19635 /*!********************************************************!*\
19636   !*** ./node_modules/uuid/dist/commonjs-browser/rng.js ***!
19637   \********************************************************/
19638 /***/ ((__unused_webpack_module, exports) => {
19639
19640 "use strict";
19641
19642
19643 Object.defineProperty(exports, "__esModule", ({
19644   value: true
19645 }));
19646 exports["default"] = rng;
19647 // Unique ID creation requires a high quality random # generator. In the browser we therefore
19648 // require the crypto API and do not support built-in fallback to lower quality random number
19649 // generators (like Math.random()).
19650 let getRandomValues;
19651 const rnds8 = new Uint8Array(16);
19652
19653 function rng() {
19654   // lazy load so that environments that need to polyfill have a chance to do so
19655   if (!getRandomValues) {
19656     // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
19657     getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
19658
19659     if (!getRandomValues) {
19660       throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
19661     }
19662   }
19663
19664   return getRandomValues(rnds8);
19665 }
19666
19667 /***/ }),
19668
19669 /***/ "./node_modules/uuid/dist/commonjs-browser/sha1.js":
19670 /*!*********************************************************!*\
19671   !*** ./node_modules/uuid/dist/commonjs-browser/sha1.js ***!
19672   \*********************************************************/
19673 /***/ ((__unused_webpack_module, exports) => {
19674
19675 "use strict";
19676
19677
19678 Object.defineProperty(exports, "__esModule", ({
19679   value: true
19680 }));
19681 exports["default"] = void 0;
19682
19683 // Adapted from Chris Veness' SHA1 code at
19684 // http://www.movable-type.co.uk/scripts/sha1.html
19685 function f(s, x, y, z) {
19686   switch (s) {
19687     case 0:
19688       return x & y ^ ~x & z;
19689
19690     case 1:
19691       return x ^ y ^ z;
19692
19693     case 2:
19694       return x & y ^ x & z ^ y & z;
19695
19696     case 3:
19697       return x ^ y ^ z;
19698   }
19699 }
19700
19701 function ROTL(x, n) {
19702   return x << n | x >>> 32 - n;
19703 }
19704
19705 function sha1(bytes) {
19706   const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
19707   const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
19708
19709   if (typeof bytes === 'string') {
19710     const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
19711
19712     bytes = [];
19713
19714     for (let i = 0; i < msg.length; ++i) {
19715       bytes.push(msg.charCodeAt(i));
19716     }
19717   } else if (!Array.isArray(bytes)) {
19718     // Convert Array-like to Array
19719     bytes = Array.prototype.slice.call(bytes);
19720   }
19721
19722   bytes.push(0x80);
19723   const l = bytes.length / 4 + 2;
19724   const N = Math.ceil(l / 16);
19725   const M = new Array(N);
19726
19727   for (let i = 0; i < N; ++i) {
19728     const arr = new Uint32Array(16);
19729
19730     for (let j = 0; j < 16; ++j) {
19731       arr[j] = bytes[i * 64 + j * 4] << 24 | bytes[i * 64 + j * 4 + 1] << 16 | bytes[i * 64 + j * 4 + 2] << 8 | bytes[i * 64 + j * 4 + 3];
19732     }
19733
19734     M[i] = arr;
19735   }
19736
19737   M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32);
19738   M[N - 1][14] = Math.floor(M[N - 1][14]);
19739   M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff;
19740
19741   for (let i = 0; i < N; ++i) {
19742     const W = new Uint32Array(80);
19743
19744     for (let t = 0; t < 16; ++t) {
19745       W[t] = M[i][t];
19746     }
19747
19748     for (let t = 16; t < 80; ++t) {
19749       W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
19750     }
19751
19752     let a = H[0];
19753     let b = H[1];
19754     let c = H[2];
19755     let d = H[3];
19756     let e = H[4];
19757
19758     for (let t = 0; t < 80; ++t) {
19759       const s = Math.floor(t / 20);
19760       const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0;
19761       e = d;
19762       d = c;
19763       c = ROTL(b, 30) >>> 0;
19764       b = a;
19765       a = T;
19766     }
19767
19768     H[0] = H[0] + a >>> 0;
19769     H[1] = H[1] + b >>> 0;
19770     H[2] = H[2] + c >>> 0;
19771     H[3] = H[3] + d >>> 0;
19772     H[4] = H[4] + e >>> 0;
19773   }
19774
19775   return [H[0] >> 24 & 0xff, H[0] >> 16 & 0xff, H[0] >> 8 & 0xff, H[0] & 0xff, H[1] >> 24 & 0xff, H[1] >> 16 & 0xff, H[1] >> 8 & 0xff, H[1] & 0xff, H[2] >> 24 & 0xff, H[2] >> 16 & 0xff, H[2] >> 8 & 0xff, H[2] & 0xff, H[3] >> 24 & 0xff, H[3] >> 16 & 0xff, H[3] >> 8 & 0xff, H[3] & 0xff, H[4] >> 24 & 0xff, H[4] >> 16 & 0xff, H[4] >> 8 & 0xff, H[4] & 0xff];
19776 }
19777
19778 var _default = sha1;
19779 exports["default"] = _default;
19780
19781 /***/ }),
19782
19783 /***/ "./node_modules/uuid/dist/commonjs-browser/stringify.js":
19784 /*!**************************************************************!*\
19785   !*** ./node_modules/uuid/dist/commonjs-browser/stringify.js ***!
19786   \**************************************************************/
19787 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19788
19789 "use strict";
19790
19791
19792 Object.defineProperty(exports, "__esModule", ({
19793   value: true
19794 }));
19795 exports["default"] = void 0;
19796 exports.unsafeStringify = unsafeStringify;
19797
19798 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19799
19800 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19801
19802 /**
19803  * Convert array of 16 byte values to UUID string format of the form:
19804  * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
19805  */
19806 const byteToHex = [];
19807
19808 for (let i = 0; i < 256; ++i) {
19809   byteToHex.push((i + 0x100).toString(16).slice(1));
19810 }
19811
19812 function unsafeStringify(arr, offset = 0) {
19813   // Note: Be careful editing this code!  It's been tuned for performance
19814   // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
19815   return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
19816 }
19817
19818 function stringify(arr, offset = 0) {
19819   const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID.  If this throws, it's likely due to one
19820   // of the following:
19821   // - One or more input array values don't map to a hex octet (leading to
19822   // "undefined" in the uuid)
19823   // - Invalid input values for the RFC `version` or `variant` fields
19824
19825   if (!(0, _validate.default)(uuid)) {
19826     throw TypeError('Stringified UUID is invalid');
19827   }
19828
19829   return uuid;
19830 }
19831
19832 var _default = stringify;
19833 exports["default"] = _default;
19834
19835 /***/ }),
19836
19837 /***/ "./node_modules/uuid/dist/commonjs-browser/v1.js":
19838 /*!*******************************************************!*\
19839   !*** ./node_modules/uuid/dist/commonjs-browser/v1.js ***!
19840   \*******************************************************/
19841 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19842
19843 "use strict";
19844
19845
19846 Object.defineProperty(exports, "__esModule", ({
19847   value: true
19848 }));
19849 exports["default"] = void 0;
19850
19851 var _rng = _interopRequireDefault(__webpack_require__(/*! ./rng.js */ "./node_modules/uuid/dist/commonjs-browser/rng.js"));
19852
19853 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19854
19855 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19856
19857 // **`v1()` - Generate time-based UUID**
19858 //
19859 // Inspired by https://github.com/LiosK/UUID.js
19860 // and http://docs.python.org/library/uuid.html
19861 let _nodeId;
19862
19863 let _clockseq; // Previous uuid creation time
19864
19865
19866 let _lastMSecs = 0;
19867 let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details
19868
19869 function v1(options, buf, offset) {
19870   let i = buf && offset || 0;
19871   const b = buf || new Array(16);
19872   options = options || {};
19873   let node = options.node || _nodeId;
19874   let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not
19875   // specified.  We do this lazily to minimize issues related to insufficient
19876   // system entropy.  See #189
19877
19878   if (node == null || clockseq == null) {
19879     const seedBytes = options.random || (options.rng || _rng.default)();
19880
19881     if (node == null) {
19882       // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
19883       node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
19884     }
19885
19886     if (clockseq == null) {
19887       // Per 4.2.2, randomize (14 bit) clockseq
19888       clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
19889     }
19890   } // UUID timestamps are 100 nano-second units since the Gregorian epoch,
19891   // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
19892   // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
19893   // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
19894
19895
19896   let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock
19897   // cycle to simulate higher resolution clock
19898
19899   let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)
19900
19901   const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression
19902
19903   if (dt < 0 && options.clockseq === undefined) {
19904     clockseq = clockseq + 1 & 0x3fff;
19905   } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
19906   // time interval
19907
19908
19909   if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
19910     nsecs = 0;
19911   } // Per 4.2.1.2 Throw error if too many uuids are requested
19912
19913
19914   if (nsecs >= 10000) {
19915     throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
19916   }
19917
19918   _lastMSecs = msecs;
19919   _lastNSecs = nsecs;
19920   _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
19921
19922   msecs += 12219292800000; // `time_low`
19923
19924   const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
19925   b[i++] = tl >>> 24 & 0xff;
19926   b[i++] = tl >>> 16 & 0xff;
19927   b[i++] = tl >>> 8 & 0xff;
19928   b[i++] = tl & 0xff; // `time_mid`
19929
19930   const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;
19931   b[i++] = tmh >>> 8 & 0xff;
19932   b[i++] = tmh & 0xff; // `time_high_and_version`
19933
19934   b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
19935
19936   b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
19937
19938   b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`
19939
19940   b[i++] = clockseq & 0xff; // `node`
19941
19942   for (let n = 0; n < 6; ++n) {
19943     b[i + n] = node[n];
19944   }
19945
19946   return buf || (0, _stringify.unsafeStringify)(b);
19947 }
19948
19949 var _default = v1;
19950 exports["default"] = _default;
19951
19952 /***/ }),
19953
19954 /***/ "./node_modules/uuid/dist/commonjs-browser/v3.js":
19955 /*!*******************************************************!*\
19956   !*** ./node_modules/uuid/dist/commonjs-browser/v3.js ***!
19957   \*******************************************************/
19958 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19959
19960 "use strict";
19961
19962
19963 Object.defineProperty(exports, "__esModule", ({
19964   value: true
19965 }));
19966 exports["default"] = void 0;
19967
19968 var _v = _interopRequireDefault(__webpack_require__(/*! ./v35.js */ "./node_modules/uuid/dist/commonjs-browser/v35.js"));
19969
19970 var _md = _interopRequireDefault(__webpack_require__(/*! ./md5.js */ "./node_modules/uuid/dist/commonjs-browser/md5.js"));
19971
19972 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19973
19974 const v3 = (0, _v.default)('v3', 0x30, _md.default);
19975 var _default = v3;
19976 exports["default"] = _default;
19977
19978 /***/ }),
19979
19980 /***/ "./node_modules/uuid/dist/commonjs-browser/v35.js":
19981 /*!********************************************************!*\
19982   !*** ./node_modules/uuid/dist/commonjs-browser/v35.js ***!
19983   \********************************************************/
19984 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19985
19986 "use strict";
19987
19988
19989 Object.defineProperty(exports, "__esModule", ({
19990   value: true
19991 }));
19992 exports.URL = exports.DNS = void 0;
19993 exports["default"] = v35;
19994
19995 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19996
19997 var _parse = _interopRequireDefault(__webpack_require__(/*! ./parse.js */ "./node_modules/uuid/dist/commonjs-browser/parse.js"));
19998
19999 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20000
20001 function stringToBytes(str) {
20002   str = unescape(encodeURIComponent(str)); // UTF8 escape
20003
20004   const bytes = [];
20005
20006   for (let i = 0; i < str.length; ++i) {
20007     bytes.push(str.charCodeAt(i));
20008   }
20009
20010   return bytes;
20011 }
20012
20013 const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
20014 exports.DNS = DNS;
20015 const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
20016 exports.URL = URL;
20017
20018 function v35(name, version, hashfunc) {
20019   function generateUUID(value, namespace, buf, offset) {
20020     var _namespace;
20021
20022     if (typeof value === 'string') {
20023       value = stringToBytes(value);
20024     }
20025
20026     if (typeof namespace === 'string') {
20027       namespace = (0, _parse.default)(namespace);
20028     }
20029
20030     if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) {
20031       throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
20032     } // Compute hash of namespace and value, Per 4.3
20033     // Future: Use spread syntax when supported on all platforms, e.g. `bytes =
20034     // hashfunc([...namespace, ... value])`
20035
20036
20037     let bytes = new Uint8Array(16 + value.length);
20038     bytes.set(namespace);
20039     bytes.set(value, namespace.length);
20040     bytes = hashfunc(bytes);
20041     bytes[6] = bytes[6] & 0x0f | version;
20042     bytes[8] = bytes[8] & 0x3f | 0x80;
20043
20044     if (buf) {
20045       offset = offset || 0;
20046
20047       for (let i = 0; i < 16; ++i) {
20048         buf[offset + i] = bytes[i];
20049       }
20050
20051       return buf;
20052     }
20053
20054     return (0, _stringify.unsafeStringify)(bytes);
20055   } // Function#name is not settable on some platforms (#270)
20056
20057
20058   try {
20059     generateUUID.name = name; // eslint-disable-next-line no-empty
20060   } catch (err) {} // For CommonJS default export support
20061
20062
20063   generateUUID.DNS = DNS;
20064   generateUUID.URL = URL;
20065   return generateUUID;
20066 }
20067
20068 /***/ }),
20069
20070 /***/ "./node_modules/uuid/dist/commonjs-browser/v4.js":
20071 /*!*******************************************************!*\
20072   !*** ./node_modules/uuid/dist/commonjs-browser/v4.js ***!
20073   \*******************************************************/
20074 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
20075
20076 "use strict";
20077
20078
20079 Object.defineProperty(exports, "__esModule", ({
20080   value: true
20081 }));
20082 exports["default"] = void 0;
20083
20084 var _native = _interopRequireDefault(__webpack_require__(/*! ./native.js */ "./node_modules/uuid/dist/commonjs-browser/native.js"));
20085
20086 var _rng = _interopRequireDefault(__webpack_require__(/*! ./rng.js */ "./node_modules/uuid/dist/commonjs-browser/rng.js"));
20087
20088 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
20089
20090 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20091
20092 function v4(options, buf, offset) {
20093   if (_native.default.randomUUID && !buf && !options) {
20094     return _native.default.randomUUID();
20095   }
20096
20097   options = options || {};
20098
20099   const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
20100
20101
20102   rnds[6] = rnds[6] & 0x0f | 0x40;
20103   rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
20104
20105   if (buf) {
20106     offset = offset || 0;
20107
20108     for (let i = 0; i < 16; ++i) {
20109       buf[offset + i] = rnds[i];
20110     }
20111
20112     return buf;
20113   }
20114
20115   return (0, _stringify.unsafeStringify)(rnds);
20116 }
20117
20118 var _default = v4;
20119 exports["default"] = _default;
20120
20121 /***/ }),
20122
20123 /***/ "./node_modules/uuid/dist/commonjs-browser/v5.js":
20124 /*!*******************************************************!*\
20125   !*** ./node_modules/uuid/dist/commonjs-browser/v5.js ***!
20126   \*******************************************************/
20127 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
20128
20129 "use strict";
20130
20131
20132 Object.defineProperty(exports, "__esModule", ({
20133   value: true
20134 }));
20135 exports["default"] = void 0;
20136
20137 var _v = _interopRequireDefault(__webpack_require__(/*! ./v35.js */ "./node_modules/uuid/dist/commonjs-browser/v35.js"));
20138
20139 var _sha = _interopRequireDefault(__webpack_require__(/*! ./sha1.js */ "./node_modules/uuid/dist/commonjs-browser/sha1.js"));
20140
20141 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20142
20143 const v5 = (0, _v.default)('v5', 0x50, _sha.default);
20144 var _default = v5;
20145 exports["default"] = _default;
20146
20147 /***/ }),
20148
20149 /***/ "./node_modules/uuid/dist/commonjs-browser/validate.js":
20150 /*!*************************************************************!*\
20151   !*** ./node_modules/uuid/dist/commonjs-browser/validate.js ***!
20152   \*************************************************************/
20153 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
20154
20155 "use strict";
20156
20157
20158 Object.defineProperty(exports, "__esModule", ({
20159   value: true
20160 }));
20161 exports["default"] = void 0;
20162
20163 var _regex = _interopRequireDefault(__webpack_require__(/*! ./regex.js */ "./node_modules/uuid/dist/commonjs-browser/regex.js"));
20164
20165 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20166
20167 function validate(uuid) {
20168   return typeof uuid === 'string' && _regex.default.test(uuid);
20169 }
20170
20171 var _default = validate;
20172 exports["default"] = _default;
20173
20174 /***/ }),
20175
20176 /***/ "./node_modules/uuid/dist/commonjs-browser/version.js":
20177 /*!************************************************************!*\
20178   !*** ./node_modules/uuid/dist/commonjs-browser/version.js ***!
20179   \************************************************************/
20180 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
20181
20182 "use strict";
20183
20184
20185 Object.defineProperty(exports, "__esModule", ({
20186   value: true
20187 }));
20188 exports["default"] = void 0;
20189
20190 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
20191
20192 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20193
20194 function version(uuid) {
20195   if (!(0, _validate.default)(uuid)) {
20196     throw TypeError('Invalid UUID');
20197   }
20198
20199   return parseInt(uuid.slice(14, 15), 16);
20200 }
20201
20202 var _default = version;
20203 exports["default"] = _default;
20204
20205 /***/ }),
20206
20207 /***/ "./node_modules/@lyrasearch/lyra/dist/cjs/index.cjs":
20208 /*!**********************************************************!*\
20209   !*** ./node_modules/@lyrasearch/lyra/dist/cjs/index.cjs ***!
20210   \**********************************************************/
20211 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
20212
20213 "use strict";
20214
20215 Object.defineProperty(exports, "__esModule", ({
20216     value: true
20217 }));
20218 function _export(target, all) {
20219     for(var name in all)Object.defineProperty(target, name, {
20220         enumerable: true,
20221         get: all[name]
20222     });
20223 }
20224 _export(exports, {
20225     create: ()=>create,
20226     insert: ()=>insert,
20227     insertWithHooks: ()=>insertWithHooks,
20228     insertBatch: ()=>insertBatch,
20229     remove: ()=>remove,
20230     search: ()=>search,
20231     save: ()=>save,
20232     load: ()=>load,
20233     requireLyra: ()=>requireLyra
20234 });
20235 let _esmCreate;
20236 let _esmInsert;
20237 let _esmInsertWithHooks;
20238 let _esmInsertBatch;
20239 let _esmRemove;
20240 let _esmSearch;
20241 let _esmSave;
20242 let _esmLoad;
20243 async function create(...args) {
20244     if (!_esmCreate) {
20245         const imported = await Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_node_js-node_modules_lyrasearch_lyra_dis-426440"), __webpack_require__.e("node_modules_lyrasearch_lyra_dist_methods_create_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ../methods/create.js */ "./node_modules/@lyrasearch/lyra/dist/methods/create.js"));
20246         _esmCreate = imported.create;
20247     }
20248     return _esmCreate(...args);
20249 }
20250 async function insert(...args) {
20251     if (!_esmInsert) {
20252         const imported = await Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_radix_js"), __webpack_require__.e("node_modules_lyrasearch_lyra_dist_methods_insert_js-node_modules_lyrasearch_lyra_dist_radix-t-7cfd98")]).then(__webpack_require__.bind(__webpack_require__, /*! ../methods/insert.js */ "./node_modules/@lyrasearch/lyra/dist/methods/insert.js"));
20253         _esmInsert = imported.insert;
20254     }
20255     return _esmInsert(...args);
20256 }
20257 async function insertWithHooks(...args) {
20258     if (!_esmInsertWithHooks) {
20259         const imported = await Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_radix_js"), __webpack_require__.e("node_modules_lyrasearch_lyra_dist_methods_insert_js-node_modules_lyrasearch_lyra_dist_radix-t-7cfd98")]).then(__webpack_require__.bind(__webpack_require__, /*! ../methods/insert.js */ "./node_modules/@lyrasearch/lyra/dist/methods/insert.js"));
20260         _esmInsertWithHooks = imported.insertWithHooks;
20261     }
20262     return _esmInsertWithHooks(...args);
20263 }
20264 async function insertBatch(...args) {
20265     if (!_esmInsertBatch) {
20266         const imported = await Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_radix_js"), __webpack_require__.e("node_modules_lyrasearch_lyra_dist_methods_insert_js-node_modules_lyrasearch_lyra_dist_radix-t-7cfd98")]).then(__webpack_require__.bind(__webpack_require__, /*! ../methods/insert.js */ "./node_modules/@lyrasearch/lyra/dist/methods/insert.js"));
20267         _esmInsertBatch = imported.insertBatch;
20268     }
20269     return _esmInsertBatch(...args);
20270 }
20271 async function remove(...args) {
20272     if (!_esmRemove) {
20273         const imported = await Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_node_js-node_modules_lyrasearch_lyra_dis-426440"), __webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_radix_js"), __webpack_require__.e("node_modules_lyrasearch_lyra_dist_methods_remove_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ../methods/remove.js */ "./node_modules/@lyrasearch/lyra/dist/methods/remove.js"));
20274         _esmRemove = imported.remove;
20275     }
20276     return _esmRemove(...args);
20277 }
20278 async function search(...args) {
20279     if (!_esmSearch) {
20280         const imported = await Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_node_js-node_modules_lyrasearch_lyra_dis-426440"), __webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_radix_js"), __webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_methods_search_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ../methods/search.js */ "./node_modules/@lyrasearch/lyra/dist/methods/search.js"));
20281         _esmSearch = imported.search;
20282     }
20283     return _esmSearch(...args);
20284 }
20285 async function save(...args) {
20286     if (!_esmSave) {
20287         const imported = await __webpack_require__.e(/*! import() */ "node_modules_lyrasearch_lyra_dist_methods_save_js").then(__webpack_require__.bind(__webpack_require__, /*! ../methods/save.js */ "./node_modules/@lyrasearch/lyra/dist/methods/save.js"));
20288         _esmSave = imported.save;
20289     }
20290     return _esmSave(...args);
20291 }
20292 async function load(...args) {
20293     if (!_esmLoad) {
20294         const imported = await __webpack_require__.e(/*! import() */ "node_modules_lyrasearch_lyra_dist_methods_load_js").then(__webpack_require__.bind(__webpack_require__, /*! ../methods/load.js */ "./node_modules/@lyrasearch/lyra/dist/methods/load.js"));
20295         _esmLoad = imported.load;
20296     }
20297     return _esmLoad(...args);
20298 }
20299 function requireLyra(callback) {
20300     Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_node_js-node_modules_lyrasearch_lyra_dis-426440"), __webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_radix-tree_radix_js"), __webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_methods_search_js"), __webpack_require__.e("vendors-node_modules_lyrasearch_lyra_dist_index_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ../index.js */ "./node_modules/@lyrasearch/lyra/dist/index.js")).then((loaded)=>setTimeout(()=>callback(undefined, loaded), 1)).catch((error)=>setTimeout(()=>callback(error), 1));
20301 }
20302
20303 //# sourceMappingURL=index.js.map
20304
20305 /***/ }),
20306
20307 /***/ "./node_modules/marked/lib/marked.cjs":
20308 /*!********************************************!*\
20309   !*** ./node_modules/marked/lib/marked.cjs ***!
20310   \********************************************/
20311 /***/ ((__unused_webpack_module, exports) => {
20312
20313 "use strict";
20314 /**
20315  * marked v4.2.12 - a markdown parser
20316  * Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)
20317  * https://github.com/markedjs/marked
20318  */
20319
20320 /**
20321  * DO NOT EDIT THIS FILE
20322  * The code in this file is generated from files in ./src/
20323  */
20324
20325
20326
20327 function _defineProperties(target, props) {
20328   for (var i = 0; i < props.length; i++) {
20329     var descriptor = props[i];
20330     descriptor.enumerable = descriptor.enumerable || false;
20331     descriptor.configurable = true;
20332     if ("value" in descriptor) descriptor.writable = true;
20333     Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
20334   }
20335 }
20336 function _createClass(Constructor, protoProps, staticProps) {
20337   if (protoProps) _defineProperties(Constructor.prototype, protoProps);
20338   if (staticProps) _defineProperties(Constructor, staticProps);
20339   Object.defineProperty(Constructor, "prototype", {
20340     writable: false
20341   });
20342   return Constructor;
20343 }
20344 function _unsupportedIterableToArray(o, minLen) {
20345   if (!o) return;
20346   if (typeof o === "string") return _arrayLikeToArray(o, minLen);
20347   var n = Object.prototype.toString.call(o).slice(8, -1);
20348   if (n === "Object" && o.constructor) n = o.constructor.name;
20349   if (n === "Map" || n === "Set") return Array.from(o);
20350   if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
20351 }
20352 function _arrayLikeToArray(arr, len) {
20353   if (len == null || len > arr.length) len = arr.length;
20354   for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
20355   return arr2;
20356 }
20357 function _createForOfIteratorHelperLoose(o, allowArrayLike) {
20358   var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
20359   if (it) return (it = it.call(o)).next.bind(it);
20360   if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
20361     if (it) o = it;
20362     var i = 0;
20363     return function () {
20364       if (i >= o.length) return {
20365         done: true
20366       };
20367       return {
20368         done: false,
20369         value: o[i++]
20370       };
20371     };
20372   }
20373   throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
20374 }
20375 function _toPrimitive(input, hint) {
20376   if (typeof input !== "object" || input === null) return input;
20377   var prim = input[Symbol.toPrimitive];
20378   if (prim !== undefined) {
20379     var res = prim.call(input, hint || "default");
20380     if (typeof res !== "object") return res;
20381     throw new TypeError("@@toPrimitive must return a primitive value.");
20382   }
20383   return (hint === "string" ? String : Number)(input);
20384 }
20385 function _toPropertyKey(arg) {
20386   var key = _toPrimitive(arg, "string");
20387   return typeof key === "symbol" ? key : String(key);
20388 }
20389
20390 function getDefaults() {
20391   return {
20392     async: false,
20393     baseUrl: null,
20394     breaks: false,
20395     extensions: null,
20396     gfm: true,
20397     headerIds: true,
20398     headerPrefix: '',
20399     highlight: null,
20400     langPrefix: 'language-',
20401     mangle: true,
20402     pedantic: false,
20403     renderer: null,
20404     sanitize: false,
20405     sanitizer: null,
20406     silent: false,
20407     smartypants: false,
20408     tokenizer: null,
20409     walkTokens: null,
20410     xhtml: false
20411   };
20412 }
20413 exports.defaults = getDefaults();
20414 function changeDefaults(newDefaults) {
20415   exports.defaults = newDefaults;
20416 }
20417
20418 /**
20419  * Helpers
20420  */
20421 var escapeTest = /[&<>"']/;
20422 var escapeReplace = new RegExp(escapeTest.source, 'g');
20423 var escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
20424 var escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
20425 var escapeReplacements = {
20426   '&': '&amp;',
20427   '<': '&lt;',
20428   '>': '&gt;',
20429   '"': '&quot;',
20430   "'": '&#39;'
20431 };
20432 var getEscapeReplacement = function getEscapeReplacement(ch) {
20433   return escapeReplacements[ch];
20434 };
20435 function escape(html, encode) {
20436   if (encode) {
20437     if (escapeTest.test(html)) {
20438       return html.replace(escapeReplace, getEscapeReplacement);
20439     }
20440   } else {
20441     if (escapeTestNoEncode.test(html)) {
20442       return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
20443     }
20444   }
20445   return html;
20446 }
20447 var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
20448
20449 /**
20450  * @param {string} html
20451  */
20452 function unescape(html) {
20453   // explicitly match decimal, hex, and named HTML entities
20454   return html.replace(unescapeTest, function (_, n) {
20455     n = n.toLowerCase();
20456     if (n === 'colon') return ':';
20457     if (n.charAt(0) === '#') {
20458       return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1));
20459     }
20460     return '';
20461   });
20462 }
20463 var caret = /(^|[^\[])\^/g;
20464
20465 /**
20466  * @param {string | RegExp} regex
20467  * @param {string} opt
20468  */
20469 function edit(regex, opt) {
20470   regex = typeof regex === 'string' ? regex : regex.source;
20471   opt = opt || '';
20472   var obj = {
20473     replace: function replace(name, val) {
20474       val = val.source || val;
20475       val = val.replace(caret, '$1');
20476       regex = regex.replace(name, val);
20477       return obj;
20478     },
20479     getRegex: function getRegex() {
20480       return new RegExp(regex, opt);
20481     }
20482   };
20483   return obj;
20484 }
20485 var nonWordAndColonTest = /[^\w:]/g;
20486 var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
20487
20488 /**
20489  * @param {boolean} sanitize
20490  * @param {string} base
20491  * @param {string} href
20492  */
20493 function cleanUrl(sanitize, base, href) {
20494   if (sanitize) {
20495     var prot;
20496     try {
20497       prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, '').toLowerCase();
20498     } catch (e) {
20499       return null;
20500     }
20501     if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
20502       return null;
20503     }
20504   }
20505   if (base && !originIndependentUrl.test(href)) {
20506     href = resolveUrl(base, href);
20507   }
20508   try {
20509     href = encodeURI(href).replace(/%25/g, '%');
20510   } catch (e) {
20511     return null;
20512   }
20513   return href;
20514 }
20515 var baseUrls = {};
20516 var justDomain = /^[^:]+:\/*[^/]*$/;
20517 var protocol = /^([^:]+:)[\s\S]*$/;
20518 var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
20519
20520 /**
20521  * @param {string} base
20522  * @param {string} href
20523  */
20524 function resolveUrl(base, href) {
20525   if (!baseUrls[' ' + base]) {
20526     // we can ignore everything in base after the last slash of its path component,
20527     // but we might need to add _that_
20528     // https://tools.ietf.org/html/rfc3986#section-3
20529     if (justDomain.test(base)) {
20530       baseUrls[' ' + base] = base + '/';
20531     } else {
20532       baseUrls[' ' + base] = rtrim(base, '/', true);
20533     }
20534   }
20535   base = baseUrls[' ' + base];
20536   var relativeBase = base.indexOf(':') === -1;
20537   if (href.substring(0, 2) === '//') {
20538     if (relativeBase) {
20539       return href;
20540     }
20541     return base.replace(protocol, '$1') + href;
20542   } else if (href.charAt(0) === '/') {
20543     if (relativeBase) {
20544       return href;
20545     }
20546     return base.replace(domain, '$1') + href;
20547   } else {
20548     return base + href;
20549   }
20550 }
20551 var noopTest = {
20552   exec: function noopTest() {}
20553 };
20554 function merge(obj) {
20555   var i = 1,
20556     target,
20557     key;
20558   for (; i < arguments.length; i++) {
20559     target = arguments[i];
20560     for (key in target) {
20561       if (Object.prototype.hasOwnProperty.call(target, key)) {
20562         obj[key] = target[key];
20563       }
20564     }
20565   }
20566   return obj;
20567 }
20568 function splitCells(tableRow, count) {
20569   // ensure that every cell-delimiting pipe has a space
20570   // before it to distinguish it from an escaped pipe
20571   var row = tableRow.replace(/\|/g, function (match, offset, str) {
20572       var escaped = false,
20573         curr = offset;
20574       while (--curr >= 0 && str[curr] === '\\') {
20575         escaped = !escaped;
20576       }
20577       if (escaped) {
20578         // odd number of slashes means | is escaped
20579         // so we leave it alone
20580         return '|';
20581       } else {
20582         // add space before unescaped |
20583         return ' |';
20584       }
20585     }),
20586     cells = row.split(/ \|/);
20587   var i = 0;
20588
20589   // First/last cell in a row cannot be empty if it has no leading/trailing pipe
20590   if (!cells[0].trim()) {
20591     cells.shift();
20592   }
20593   if (cells.length > 0 && !cells[cells.length - 1].trim()) {
20594     cells.pop();
20595   }
20596   if (cells.length > count) {
20597     cells.splice(count);
20598   } else {
20599     while (cells.length < count) {
20600       cells.push('');
20601     }
20602   }
20603   for (; i < cells.length; i++) {
20604     // leading or trailing whitespace is ignored per the gfm spec
20605     cells[i] = cells[i].trim().replace(/\\\|/g, '|');
20606   }
20607   return cells;
20608 }
20609
20610 /**
20611  * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
20612  * /c*$/ is vulnerable to REDOS.
20613  *
20614  * @param {string} str
20615  * @param {string} c
20616  * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey.
20617  */
20618 function rtrim(str, c, invert) {
20619   var l = str.length;
20620   if (l === 0) {
20621     return '';
20622   }
20623
20624   // Length of suffix matching the invert condition.
20625   var suffLen = 0;
20626
20627   // Step left until we fail to match the invert condition.
20628   while (suffLen < l) {
20629     var currChar = str.charAt(l - suffLen - 1);
20630     if (currChar === c && !invert) {
20631       suffLen++;
20632     } else if (currChar !== c && invert) {
20633       suffLen++;
20634     } else {
20635       break;
20636     }
20637   }
20638   return str.slice(0, l - suffLen);
20639 }
20640 function findClosingBracket(str, b) {
20641   if (str.indexOf(b[1]) === -1) {
20642     return -1;
20643   }
20644   var l = str.length;
20645   var level = 0,
20646     i = 0;
20647   for (; i < l; i++) {
20648     if (str[i] === '\\') {
20649       i++;
20650     } else if (str[i] === b[0]) {
20651       level++;
20652     } else if (str[i] === b[1]) {
20653       level--;
20654       if (level < 0) {
20655         return i;
20656       }
20657     }
20658   }
20659   return -1;
20660 }
20661 function checkSanitizeDeprecation(opt) {
20662   if (opt && opt.sanitize && !opt.silent) {
20663     console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
20664   }
20665 }
20666
20667 // copied from https://stackoverflow.com/a/5450113/806777
20668 /**
20669  * @param {string} pattern
20670  * @param {number} count
20671  */
20672 function repeatString(pattern, count) {
20673   if (count < 1) {
20674     return '';
20675   }
20676   var result = '';
20677   while (count > 1) {
20678     if (count & 1) {
20679       result += pattern;
20680     }
20681     count >>= 1;
20682     pattern += pattern;
20683   }
20684   return result + pattern;
20685 }
20686
20687 function outputLink(cap, link, raw, lexer) {
20688   var href = link.href;
20689   var title = link.title ? escape(link.title) : null;
20690   var text = cap[1].replace(/\\([\[\]])/g, '$1');
20691   if (cap[0].charAt(0) !== '!') {
20692     lexer.state.inLink = true;
20693     var token = {
20694       type: 'link',
20695       raw: raw,
20696       href: href,
20697       title: title,
20698       text: text,
20699       tokens: lexer.inlineTokens(text)
20700     };
20701     lexer.state.inLink = false;
20702     return token;
20703   }
20704   return {
20705     type: 'image',
20706     raw: raw,
20707     href: href,
20708     title: title,
20709     text: escape(text)
20710   };
20711 }
20712 function indentCodeCompensation(raw, text) {
20713   var matchIndentToCode = raw.match(/^(\s+)(?:```)/);
20714   if (matchIndentToCode === null) {
20715     return text;
20716   }
20717   var indentToCode = matchIndentToCode[1];
20718   return text.split('\n').map(function (node) {
20719     var matchIndentInNode = node.match(/^\s+/);
20720     if (matchIndentInNode === null) {
20721       return node;
20722     }
20723     var indentInNode = matchIndentInNode[0];
20724     if (indentInNode.length >= indentToCode.length) {
20725       return node.slice(indentToCode.length);
20726     }
20727     return node;
20728   }).join('\n');
20729 }
20730
20731 /**
20732  * Tokenizer
20733  */
20734 var Tokenizer = /*#__PURE__*/function () {
20735   function Tokenizer(options) {
20736     this.options = options || exports.defaults;
20737   }
20738   var _proto = Tokenizer.prototype;
20739   _proto.space = function space(src) {
20740     var cap = this.rules.block.newline.exec(src);
20741     if (cap && cap[0].length > 0) {
20742       return {
20743         type: 'space',
20744         raw: cap[0]
20745       };
20746     }
20747   };
20748   _proto.code = function code(src) {
20749     var cap = this.rules.block.code.exec(src);
20750     if (cap) {
20751       var text = cap[0].replace(/^ {1,4}/gm, '');
20752       return {
20753         type: 'code',
20754         raw: cap[0],
20755         codeBlockStyle: 'indented',
20756         text: !this.options.pedantic ? rtrim(text, '\n') : text
20757       };
20758     }
20759   };
20760   _proto.fences = function fences(src) {
20761     var cap = this.rules.block.fences.exec(src);
20762     if (cap) {
20763       var raw = cap[0];
20764       var text = indentCodeCompensation(raw, cap[3] || '');
20765       return {
20766         type: 'code',
20767         raw: raw,
20768         lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
20769         text: text
20770       };
20771     }
20772   };
20773   _proto.heading = function heading(src) {
20774     var cap = this.rules.block.heading.exec(src);
20775     if (cap) {
20776       var text = cap[2].trim();
20777
20778       // remove trailing #s
20779       if (/#$/.test(text)) {
20780         var trimmed = rtrim(text, '#');
20781         if (this.options.pedantic) {
20782           text = trimmed.trim();
20783         } else if (!trimmed || / $/.test(trimmed)) {
20784           // CommonMark requires space before trailing #s
20785           text = trimmed.trim();
20786         }
20787       }
20788       return {
20789         type: 'heading',
20790         raw: cap[0],
20791         depth: cap[1].length,
20792         text: text,
20793         tokens: this.lexer.inline(text)
20794       };
20795     }
20796   };
20797   _proto.hr = function hr(src) {
20798     var cap = this.rules.block.hr.exec(src);
20799     if (cap) {
20800       return {
20801         type: 'hr',
20802         raw: cap[0]
20803       };
20804     }
20805   };
20806   _proto.blockquote = function blockquote(src) {
20807     var cap = this.rules.block.blockquote.exec(src);
20808     if (cap) {
20809       var text = cap[0].replace(/^ *>[ \t]?/gm, '');
20810       var top = this.lexer.state.top;
20811       this.lexer.state.top = true;
20812       var tokens = this.lexer.blockTokens(text);
20813       this.lexer.state.top = top;
20814       return {
20815         type: 'blockquote',
20816         raw: cap[0],
20817         tokens: tokens,
20818         text: text
20819       };
20820     }
20821   };
20822   _proto.list = function list(src) {
20823     var cap = this.rules.block.list.exec(src);
20824     if (cap) {
20825       var raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
20826       var bull = cap[1].trim();
20827       var isordered = bull.length > 1;
20828       var list = {
20829         type: 'list',
20830         raw: '',
20831         ordered: isordered,
20832         start: isordered ? +bull.slice(0, -1) : '',
20833         loose: false,
20834         items: []
20835       };
20836       bull = isordered ? "\\d{1,9}\\" + bull.slice(-1) : "\\" + bull;
20837       if (this.options.pedantic) {
20838         bull = isordered ? bull : '[*+-]';
20839       }
20840
20841       // Get next list item
20842       var itemRegex = new RegExp("^( {0,3}" + bull + ")((?:[\t ][^\\n]*)?(?:\\n|$))");
20843
20844       // Check if current bullet point can start a new List Item
20845       while (src) {
20846         endEarly = false;
20847         if (!(cap = itemRegex.exec(src))) {
20848           break;
20849         }
20850         if (this.rules.block.hr.test(src)) {
20851           // End list if bullet was actually HR (possibly move into itemRegex?)
20852           break;
20853         }
20854         raw = cap[0];
20855         src = src.substring(raw.length);
20856         line = cap[2].split('\n', 1)[0].replace(/^\t+/, function (t) {
20857           return ' '.repeat(3 * t.length);
20858         });
20859         nextLine = src.split('\n', 1)[0];
20860         if (this.options.pedantic) {
20861           indent = 2;
20862           itemContents = line.trimLeft();
20863         } else {
20864           indent = cap[2].search(/[^ ]/); // Find first non-space char
20865           indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
20866           itemContents = line.slice(indent);
20867           indent += cap[1].length;
20868         }
20869         blankLine = false;
20870         if (!line && /^ *$/.test(nextLine)) {
20871           // Items begin with at most one blank line
20872           raw += nextLine + '\n';
20873           src = src.substring(nextLine.length + 1);
20874           endEarly = true;
20875         }
20876         if (!endEarly) {
20877           var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))");
20878           var hrRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)");
20879           var fencesBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:```|~~~)");
20880           var headingBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}#");
20881
20882           // Check if following lines should be included in List Item
20883           while (src) {
20884             rawLine = src.split('\n', 1)[0];
20885             nextLine = rawLine;
20886
20887             // Re-align to follow commonmark nesting rules
20888             if (this.options.pedantic) {
20889               nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, '  ');
20890             }
20891
20892             // End list item if found code fences
20893             if (fencesBeginRegex.test(nextLine)) {
20894               break;
20895             }
20896
20897             // End list item if found start of new heading
20898             if (headingBeginRegex.test(nextLine)) {
20899               break;
20900             }
20901
20902             // End list item if found start of new bullet
20903             if (nextBulletRegex.test(nextLine)) {
20904               break;
20905             }
20906
20907             // Horizontal rule found
20908             if (hrRegex.test(src)) {
20909               break;
20910             }
20911             if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) {
20912               // Dedent if possible
20913               itemContents += '\n' + nextLine.slice(indent);
20914             } else {
20915               // not enough indentation
20916               if (blankLine) {
20917                 break;
20918               }
20919
20920               // paragraph continuation unless last line was a different block level element
20921               if (line.search(/[^ ]/) >= 4) {
20922                 // indented code block
20923                 break;
20924               }
20925               if (fencesBeginRegex.test(line)) {
20926                 break;
20927               }
20928               if (headingBeginRegex.test(line)) {
20929                 break;
20930               }
20931               if (hrRegex.test(line)) {
20932                 break;
20933               }
20934               itemContents += '\n' + nextLine;
20935             }
20936             if (!blankLine && !nextLine.trim()) {
20937               // Check if current line is blank
20938               blankLine = true;
20939             }
20940             raw += rawLine + '\n';
20941             src = src.substring(rawLine.length + 1);
20942             line = nextLine.slice(indent);
20943           }
20944         }
20945         if (!list.loose) {
20946           // If the previous item ended with a blank line, the list is loose
20947           if (endsWithBlankLine) {
20948             list.loose = true;
20949           } else if (/\n *\n *$/.test(raw)) {
20950             endsWithBlankLine = true;
20951           }
20952         }
20953
20954         // Check for task list items
20955         if (this.options.gfm) {
20956           istask = /^\[[ xX]\] /.exec(itemContents);
20957           if (istask) {
20958             ischecked = istask[0] !== '[ ] ';
20959             itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
20960           }
20961         }
20962         list.items.push({
20963           type: 'list_item',
20964           raw: raw,
20965           task: !!istask,
20966           checked: ischecked,
20967           loose: false,
20968           text: itemContents
20969         });
20970         list.raw += raw;
20971       }
20972
20973       // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
20974       list.items[list.items.length - 1].raw = raw.trimRight();
20975       list.items[list.items.length - 1].text = itemContents.trimRight();
20976       list.raw = list.raw.trimRight();
20977       var l = list.items.length;
20978
20979       // Item child tokens handled here at end because we needed to have the final item to trim it first
20980       for (i = 0; i < l; i++) {
20981         this.lexer.state.top = false;
20982         list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
20983         if (!list.loose) {
20984           // Check if list should be loose
20985           var spacers = list.items[i].tokens.filter(function (t) {
20986             return t.type === 'space';
20987           });
20988           var hasMultipleLineBreaks = spacers.length > 0 && spacers.some(function (t) {
20989             return /\n.*\n/.test(t.raw);
20990           });
20991           list.loose = hasMultipleLineBreaks;
20992         }
20993       }
20994
20995       // Set all items to loose if list is loose
20996       if (list.loose) {
20997         for (i = 0; i < l; i++) {
20998           list.items[i].loose = true;
20999         }
21000       }
21001       return list;
21002     }
21003   };
21004   _proto.html = function html(src) {
21005     var cap = this.rules.block.html.exec(src);
21006     if (cap) {
21007       var token = {
21008         type: 'html',
21009         raw: cap[0],
21010         pre: !this.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
21011         text: cap[0]
21012       };
21013       if (this.options.sanitize) {
21014         var text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
21015         token.type = 'paragraph';
21016         token.text = text;
21017         token.tokens = this.lexer.inline(text);
21018       }
21019       return token;
21020     }
21021   };
21022   _proto.def = function def(src) {
21023     var cap = this.rules.block.def.exec(src);
21024     if (cap) {
21025       var tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
21026       var href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';
21027       var title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];
21028       return {
21029         type: 'def',
21030         tag: tag,
21031         raw: cap[0],
21032         href: href,
21033         title: title
21034       };
21035     }
21036   };
21037   _proto.table = function table(src) {
21038     var cap = this.rules.block.table.exec(src);
21039     if (cap) {
21040       var item = {
21041         type: 'table',
21042         header: splitCells(cap[1]).map(function (c) {
21043           return {
21044             text: c
21045           };
21046         }),
21047         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
21048         rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
21049       };
21050       if (item.header.length === item.align.length) {
21051         item.raw = cap[0];
21052         var l = item.align.length;
21053         var i, j, k, row;
21054         for (i = 0; i < l; i++) {
21055           if (/^ *-+: *$/.test(item.align[i])) {
21056             item.align[i] = 'right';
21057           } else if (/^ *:-+: *$/.test(item.align[i])) {
21058             item.align[i] = 'center';
21059           } else if (/^ *:-+ *$/.test(item.align[i])) {
21060             item.align[i] = 'left';
21061           } else {
21062             item.align[i] = null;
21063           }
21064         }
21065         l = item.rows.length;
21066         for (i = 0; i < l; i++) {
21067           item.rows[i] = splitCells(item.rows[i], item.header.length).map(function (c) {
21068             return {
21069               text: c
21070             };
21071           });
21072         }
21073
21074         // parse child tokens inside headers and cells
21075
21076         // header child tokens
21077         l = item.header.length;
21078         for (j = 0; j < l; j++) {
21079           item.header[j].tokens = this.lexer.inline(item.header[j].text);
21080         }
21081
21082         // cell child tokens
21083         l = item.rows.length;
21084         for (j = 0; j < l; j++) {
21085           row = item.rows[j];
21086           for (k = 0; k < row.length; k++) {
21087             row[k].tokens = this.lexer.inline(row[k].text);
21088           }
21089         }
21090         return item;
21091       }
21092     }
21093   };
21094   _proto.lheading = function lheading(src) {
21095     var cap = this.rules.block.lheading.exec(src);
21096     if (cap) {
21097       return {
21098         type: 'heading',
21099         raw: cap[0],
21100         depth: cap[2].charAt(0) === '=' ? 1 : 2,
21101         text: cap[1],
21102         tokens: this.lexer.inline(cap[1])
21103       };
21104     }
21105   };
21106   _proto.paragraph = function paragraph(src) {
21107     var cap = this.rules.block.paragraph.exec(src);
21108     if (cap) {
21109       var text = cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1];
21110       return {
21111         type: 'paragraph',
21112         raw: cap[0],
21113         text: text,
21114         tokens: this.lexer.inline(text)
21115       };
21116     }
21117   };
21118   _proto.text = function text(src) {
21119     var cap = this.rules.block.text.exec(src);
21120     if (cap) {
21121       return {
21122         type: 'text',
21123         raw: cap[0],
21124         text: cap[0],
21125         tokens: this.lexer.inline(cap[0])
21126       };
21127     }
21128   };
21129   _proto.escape = function escape$1(src) {
21130     var cap = this.rules.inline.escape.exec(src);
21131     if (cap) {
21132       return {
21133         type: 'escape',
21134         raw: cap[0],
21135         text: escape(cap[1])
21136       };
21137     }
21138   };
21139   _proto.tag = function tag(src) {
21140     var cap = this.rules.inline.tag.exec(src);
21141     if (cap) {
21142       if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
21143         this.lexer.state.inLink = true;
21144       } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
21145         this.lexer.state.inLink = false;
21146       }
21147       if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
21148         this.lexer.state.inRawBlock = true;
21149       } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
21150         this.lexer.state.inRawBlock = false;
21151       }
21152       return {
21153         type: this.options.sanitize ? 'text' : 'html',
21154         raw: cap[0],
21155         inLink: this.lexer.state.inLink,
21156         inRawBlock: this.lexer.state.inRawBlock,
21157         text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]
21158       };
21159     }
21160   };
21161   _proto.link = function link(src) {
21162     var cap = this.rules.inline.link.exec(src);
21163     if (cap) {
21164       var trimmedUrl = cap[2].trim();
21165       if (!this.options.pedantic && /^</.test(trimmedUrl)) {
21166         // commonmark requires matching angle brackets
21167         if (!/>$/.test(trimmedUrl)) {
21168           return;
21169         }
21170
21171         // ending angle bracket cannot be escaped
21172         var rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
21173         if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
21174           return;
21175         }
21176       } else {
21177         // find closing parenthesis
21178         var lastParenIndex = findClosingBracket(cap[2], '()');
21179         if (lastParenIndex > -1) {
21180           var start = cap[0].indexOf('!') === 0 ? 5 : 4;
21181           var linkLen = start + cap[1].length + lastParenIndex;
21182           cap[2] = cap[2].substring(0, lastParenIndex);
21183           cap[0] = cap[0].substring(0, linkLen).trim();
21184           cap[3] = '';
21185         }
21186       }
21187       var href = cap[2];
21188       var title = '';
21189       if (this.options.pedantic) {
21190         // split pedantic href and title
21191         var link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
21192         if (link) {
21193           href = link[1];
21194           title = link[3];
21195         }
21196       } else {
21197         title = cap[3] ? cap[3].slice(1, -1) : '';
21198       }
21199       href = href.trim();
21200       if (/^</.test(href)) {
21201         if (this.options.pedantic && !/>$/.test(trimmedUrl)) {
21202           // pedantic allows starting angle bracket without ending angle bracket
21203           href = href.slice(1);
21204         } else {
21205           href = href.slice(1, -1);
21206         }
21207       }
21208       return outputLink(cap, {
21209         href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
21210         title: title ? title.replace(this.rules.inline._escapes, '$1') : title
21211       }, cap[0], this.lexer);
21212     }
21213   };
21214   _proto.reflink = function reflink(src, links) {
21215     var cap;
21216     if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
21217       var link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
21218       link = links[link.toLowerCase()];
21219       if (!link) {
21220         var text = cap[0].charAt(0);
21221         return {
21222           type: 'text',
21223           raw: text,
21224           text: text
21225         };
21226       }
21227       return outputLink(cap, link, cap[0], this.lexer);
21228     }
21229   };
21230   _proto.emStrong = function emStrong(src, maskedSrc, prevChar) {
21231     if (prevChar === void 0) {
21232       prevChar = '';
21233     }
21234     var match = this.rules.inline.emStrong.lDelim.exec(src);
21235     if (!match) return;
21236
21237     // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
21238     if (match[3] && prevChar.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/)) return;
21239     var nextChar = match[1] || match[2] || '';
21240     if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) {
21241       var lLength = match[0].length - 1;
21242       var rDelim,
21243         rLength,
21244         delimTotal = lLength,
21245         midDelimTotal = 0;
21246       var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
21247       endReg.lastIndex = 0;
21248
21249       // Clip maskedSrc to same section of string as src (move to lexer?)
21250       maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
21251       while ((match = endReg.exec(maskedSrc)) != null) {
21252         rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
21253         if (!rDelim) continue; // skip single * in __abc*abc__
21254
21255         rLength = rDelim.length;
21256         if (match[3] || match[4]) {
21257           // found another Left Delim
21258           delimTotal += rLength;
21259           continue;
21260         } else if (match[5] || match[6]) {
21261           // either Left or Right Delim
21262           if (lLength % 3 && !((lLength + rLength) % 3)) {
21263             midDelimTotal += rLength;
21264             continue; // CommonMark Emphasis Rules 9-10
21265           }
21266         }
21267
21268         delimTotal -= rLength;
21269         if (delimTotal > 0) continue; // Haven't found enough closing delimiters
21270
21271         // Remove extra characters. *a*** -> *a*
21272         rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
21273         var raw = src.slice(0, lLength + match.index + (match[0].length - rDelim.length) + rLength);
21274
21275         // Create `em` if smallest delimiter has odd char count. *a***
21276         if (Math.min(lLength, rLength) % 2) {
21277           var _text = raw.slice(1, -1);
21278           return {
21279             type: 'em',
21280             raw: raw,
21281             text: _text,
21282             tokens: this.lexer.inlineTokens(_text)
21283           };
21284         }
21285
21286         // Create 'strong' if smallest delimiter has even char count. **a***
21287         var text = raw.slice(2, -2);
21288         return {
21289           type: 'strong',
21290           raw: raw,
21291           text: text,
21292           tokens: this.lexer.inlineTokens(text)
21293         };
21294       }
21295     }
21296   };
21297   _proto.codespan = function codespan(src) {
21298     var cap = this.rules.inline.code.exec(src);
21299     if (cap) {
21300       var text = cap[2].replace(/\n/g, ' ');
21301       var hasNonSpaceChars = /[^ ]/.test(text);
21302       var hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
21303       if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
21304         text = text.substring(1, text.length - 1);
21305       }
21306       text = escape(text, true);
21307       return {
21308         type: 'codespan',
21309         raw: cap[0],
21310         text: text
21311       };
21312     }
21313   };
21314   _proto.br = function br(src) {
21315     var cap = this.rules.inline.br.exec(src);
21316     if (cap) {
21317       return {
21318         type: 'br',
21319         raw: cap[0]
21320       };
21321     }
21322   };
21323   _proto.del = function del(src) {
21324     var cap = this.rules.inline.del.exec(src);
21325     if (cap) {
21326       return {
21327         type: 'del',
21328         raw: cap[0],
21329         text: cap[2],
21330         tokens: this.lexer.inlineTokens(cap[2])
21331       };
21332     }
21333   };
21334   _proto.autolink = function autolink(src, mangle) {
21335     var cap = this.rules.inline.autolink.exec(src);
21336     if (cap) {
21337       var text, href;
21338       if (cap[2] === '@') {
21339         text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
21340         href = 'mailto:' + text;
21341       } else {
21342         text = escape(cap[1]);
21343         href = text;
21344       }
21345       return {
21346         type: 'link',
21347         raw: cap[0],
21348         text: text,
21349         href: href,
21350         tokens: [{
21351           type: 'text',
21352           raw: text,
21353           text: text
21354         }]
21355       };
21356     }
21357   };
21358   _proto.url = function url(src, mangle) {
21359     var cap;
21360     if (cap = this.rules.inline.url.exec(src)) {
21361       var text, href;
21362       if (cap[2] === '@') {
21363         text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
21364         href = 'mailto:' + text;
21365       } else {
21366         // do extended autolink path validation
21367         var prevCapZero;
21368         do {
21369           prevCapZero = cap[0];
21370           cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
21371         } while (prevCapZero !== cap[0]);
21372         text = escape(cap[0]);
21373         if (cap[1] === 'www.') {
21374           href = 'http://' + cap[0];
21375         } else {
21376           href = cap[0];
21377         }
21378       }
21379       return {
21380         type: 'link',
21381         raw: cap[0],
21382         text: text,
21383         href: href,
21384         tokens: [{
21385           type: 'text',
21386           raw: text,
21387           text: text
21388         }]
21389       };
21390     }
21391   };
21392   _proto.inlineText = function inlineText(src, smartypants) {
21393     var cap = this.rules.inline.text.exec(src);
21394     if (cap) {
21395       var text;
21396       if (this.lexer.state.inRawBlock) {
21397         text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0];
21398       } else {
21399         text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
21400       }
21401       return {
21402         type: 'text',
21403         raw: cap[0],
21404         text: text
21405       };
21406     }
21407   };
21408   return Tokenizer;
21409 }();
21410
21411 /**
21412  * Block-Level Grammar
21413  */
21414 var block = {
21415   newline: /^(?: *(?:\n|$))+/,
21416   code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
21417   fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
21418   hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
21419   heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
21420   blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
21421   list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
21422   html: '^ {0,3}(?:' // optional indentation
21423   + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
21424   + '|comment[^\\n]*(\\n+|$)' // (2)
21425   + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
21426   + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
21427   + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
21428   + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
21429   + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
21430   + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
21431   + ')',
21432   def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
21433   table: noopTest,
21434   lheading: /^((?:.|\n(?!\n))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
21435   // regex template, placeholders will be replaced according to different paragraph
21436   // interruption rules of commonmark and the original markdown spec:
21437   _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
21438   text: /^[^\n]+/
21439 };
21440 block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
21441 block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
21442 block.def = edit(block.def).replace('label', block._label).replace('title', block._title).getRegex();
21443 block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
21444 block.listItemStart = edit(/^( *)(bull) */).replace('bull', block.bullet).getRegex();
21445 block.list = edit(block.list).replace(/bull/g, block.bullet).replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))').replace('def', '\\n+(?=' + block.def.source + ')').getRegex();
21446 block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul';
21447 block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
21448 block.html = edit(block.html, 'i').replace('comment', block._comment).replace('tag', block._tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
21449 block.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
21450 .replace('|table', '').replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
21451 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
21452 .getRegex();
21453 block.blockquote = edit(block.blockquote).replace('paragraph', block.paragraph).getRegex();
21454
21455 /**
21456  * Normal Block Grammar
21457  */
21458
21459 block.normal = merge({}, block);
21460
21461 /**
21462  * GFM Block Grammar
21463  */
21464
21465 block.gfm = merge({}, block.normal, {
21466   table: '^ *([^\\n ].*\\|.*)\\n' // Header
21467   + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
21468   + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
21469 });
21470
21471 block.gfm.table = edit(block.gfm.table).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('blockquote', ' {0,3}>').replace('code', ' {4}[^\\n]').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
21472 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
21473 .getRegex();
21474 block.gfm.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
21475 .replace('table', block.gfm.table) // interrupt paragraphs with table
21476 .replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
21477 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
21478 .getRegex();
21479 /**
21480  * Pedantic grammar (original John Gruber's loose markdown specification)
21481  */
21482
21483 block.pedantic = merge({}, block.normal, {
21484   html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
21485   + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))').replace('comment', block._comment).replace(/tag/g, '(?!(?:' + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b').getRegex(),
21486   def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
21487   heading: /^(#{1,6})(.*)(?:\n+|$)/,
21488   fences: noopTest,
21489   // fences not supported
21490   lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
21491   paragraph: edit(block.normal._paragraph).replace('hr', block.hr).replace('heading', ' *#{1,6} *[^\n]').replace('lheading', block.lheading).replace('blockquote', ' {0,3}>').replace('|fences', '').replace('|list', '').replace('|html', '').getRegex()
21492 });
21493
21494 /**
21495  * Inline-Level Grammar
21496  */
21497 var inline = {
21498   escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
21499   autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
21500   url: noopTest,
21501   tag: '^comment' + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
21502   + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
21503   + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
21504   + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
21505   + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
21506   // CDATA section
21507   link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
21508   reflink: /^!?\[(label)\]\[(ref)\]/,
21509   nolink: /^!?\[(ref)\](?:\[\])?/,
21510   reflinkSearch: 'reflink|nolink(?!\\()',
21511   emStrong: {
21512     lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
21513     //        (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left.  (5) and (6) can be either Left or Right.
21514     //          () Skip orphan inside strong                                      () Consume to delim     (1) #***                (2) a***#, a***                             (3) #***a, ***a                 (4) ***#              (5) #***#                 (6) a***a
21515     rDelimAst: /^(?:[^_*\\]|\\.)*?\_\_(?:[^_*\\]|\\.)*?\*(?:[^_*\\]|\\.)*?(?=\_\_)|(?:[^*\\]|\\.)+(?=[^*])|[punct_](\*+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|(?:[^punct*_\s\\]|\\.)(\*+)(?=[^punct*_\s])/,
21516     rDelimUnd: /^(?:[^_*\\]|\\.)*?\*\*(?:[^_*\\]|\\.)*?\_(?:[^_*\\]|\\.)*?(?=\*\*)|(?:[^_\\]|\\.)+(?=[^_])|[punct*](\_+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
21517   },
21518
21519   code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
21520   br: /^( {2,}|\\)\n(?!\s*$)/,
21521   del: noopTest,
21522   text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
21523   punctuation: /^([\spunctuation])/
21524 };
21525
21526 // list of punctuation marks from CommonMark spec
21527 // without * and _ to handle the different emphasis markers * and _
21528 inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
21529 inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
21530
21531 // sequences em should skip over [title](link), `code`, <html>
21532 inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
21533 // lookbehind is not available on Safari as of version 16
21534 // inline.escapedEmSt = /(?<=(?:^|[^\\)(?:\\[^])*)\\[*_]/g;
21535 inline.escapedEmSt = /(?:^|[^\\])(?:\\\\)*\\[*_]/g;
21536 inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
21537 inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex();
21538 inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g').replace(/punct/g, inline._punctuation).getRegex();
21539 inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g').replace(/punct/g, inline._punctuation).getRegex();
21540 inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
21541 inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
21542 inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
21543 inline.autolink = edit(inline.autolink).replace('scheme', inline._scheme).replace('email', inline._email).getRegex();
21544 inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
21545 inline.tag = edit(inline.tag).replace('comment', inline._comment).replace('attribute', inline._attribute).getRegex();
21546 inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
21547 inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
21548 inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
21549 inline.link = edit(inline.link).replace('label', inline._label).replace('href', inline._href).replace('title', inline._title).getRegex();
21550 inline.reflink = edit(inline.reflink).replace('label', inline._label).replace('ref', block._label).getRegex();
21551 inline.nolink = edit(inline.nolink).replace('ref', block._label).getRegex();
21552 inline.reflinkSearch = edit(inline.reflinkSearch, 'g').replace('reflink', inline.reflink).replace('nolink', inline.nolink).getRegex();
21553
21554 /**
21555  * Normal Inline Grammar
21556  */
21557
21558 inline.normal = merge({}, inline);
21559
21560 /**
21561  * Pedantic Inline Grammar
21562  */
21563
21564 inline.pedantic = merge({}, inline.normal, {
21565   strong: {
21566     start: /^__|\*\*/,
21567     middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
21568     endAst: /\*\*(?!\*)/g,
21569     endUnd: /__(?!_)/g
21570   },
21571   em: {
21572     start: /^_|\*/,
21573     middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
21574     endAst: /\*(?!\*)/g,
21575     endUnd: /_(?!_)/g
21576   },
21577   link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', inline._label).getRegex(),
21578   reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', inline._label).getRegex()
21579 });
21580
21581 /**
21582  * GFM Inline Grammar
21583  */
21584
21585 inline.gfm = merge({}, inline.normal, {
21586   escape: edit(inline.escape).replace('])', '~|])').getRegex(),
21587   _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
21588   url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
21589   _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
21590   del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
21591   text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
21592 });
21593 inline.gfm.url = edit(inline.gfm.url, 'i').replace('email', inline.gfm._extended_email).getRegex();
21594 /**
21595  * GFM + Line Breaks Inline Grammar
21596  */
21597
21598 inline.breaks = merge({}, inline.gfm, {
21599   br: edit(inline.br).replace('{2,}', '*').getRegex(),
21600   text: edit(inline.gfm.text).replace('\\b_', '\\b_| {2,}\\n').replace(/\{2,\}/g, '*').getRegex()
21601 });
21602
21603 /**
21604  * smartypants text replacement
21605  * @param {string} text
21606  */
21607 function smartypants(text) {
21608   return text
21609   // em-dashes
21610   .replace(/---/g, "\u2014")
21611   // en-dashes
21612   .replace(/--/g, "\u2013")
21613   // opening singles
21614   .replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018")
21615   // closing singles & apostrophes
21616   .replace(/'/g, "\u2019")
21617   // opening doubles
21618   .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C")
21619   // closing doubles
21620   .replace(/"/g, "\u201D")
21621   // ellipses
21622   .replace(/\.{3}/g, "\u2026");
21623 }
21624
21625 /**
21626  * mangle email addresses
21627  * @param {string} text
21628  */
21629 function mangle(text) {
21630   var out = '',
21631     i,
21632     ch;
21633   var l = text.length;
21634   for (i = 0; i < l; i++) {
21635     ch = text.charCodeAt(i);
21636     if (Math.random() > 0.5) {
21637       ch = 'x' + ch.toString(16);
21638     }
21639     out += '&#' + ch + ';';
21640   }
21641   return out;
21642 }
21643
21644 /**
21645  * Block Lexer
21646  */
21647 var Lexer = /*#__PURE__*/function () {
21648   function Lexer(options) {
21649     this.tokens = [];
21650     this.tokens.links = Object.create(null);
21651     this.options = options || exports.defaults;
21652     this.options.tokenizer = this.options.tokenizer || new Tokenizer();
21653     this.tokenizer = this.options.tokenizer;
21654     this.tokenizer.options = this.options;
21655     this.tokenizer.lexer = this;
21656     this.inlineQueue = [];
21657     this.state = {
21658       inLink: false,
21659       inRawBlock: false,
21660       top: true
21661     };
21662     var rules = {
21663       block: block.normal,
21664       inline: inline.normal
21665     };
21666     if (this.options.pedantic) {
21667       rules.block = block.pedantic;
21668       rules.inline = inline.pedantic;
21669     } else if (this.options.gfm) {
21670       rules.block = block.gfm;
21671       if (this.options.breaks) {
21672         rules.inline = inline.breaks;
21673       } else {
21674         rules.inline = inline.gfm;
21675       }
21676     }
21677     this.tokenizer.rules = rules;
21678   }
21679
21680   /**
21681    * Expose Rules
21682    */
21683   /**
21684    * Static Lex Method
21685    */
21686   Lexer.lex = function lex(src, options) {
21687     var lexer = new Lexer(options);
21688     return lexer.lex(src);
21689   }
21690
21691   /**
21692    * Static Lex Inline Method
21693    */;
21694   Lexer.lexInline = function lexInline(src, options) {
21695     var lexer = new Lexer(options);
21696     return lexer.inlineTokens(src);
21697   }
21698
21699   /**
21700    * Preprocessing
21701    */;
21702   var _proto = Lexer.prototype;
21703   _proto.lex = function lex(src) {
21704     src = src.replace(/\r\n|\r/g, '\n');
21705     this.blockTokens(src, this.tokens);
21706     var next;
21707     while (next = this.inlineQueue.shift()) {
21708       this.inlineTokens(next.src, next.tokens);
21709     }
21710     return this.tokens;
21711   }
21712
21713   /**
21714    * Lexing
21715    */;
21716   _proto.blockTokens = function blockTokens(src, tokens) {
21717     var _this = this;
21718     if (tokens === void 0) {
21719       tokens = [];
21720     }
21721     if (this.options.pedantic) {
21722       src = src.replace(/\t/g, '    ').replace(/^ +$/gm, '');
21723     } else {
21724       src = src.replace(/^( *)(\t+)/gm, function (_, leading, tabs) {
21725         return leading + '    '.repeat(tabs.length);
21726       });
21727     }
21728     var token, lastToken, cutSrc, lastParagraphClipped;
21729     while (src) {
21730       if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some(function (extTokenizer) {
21731         if (token = extTokenizer.call({
21732           lexer: _this
21733         }, src, tokens)) {
21734           src = src.substring(token.raw.length);
21735           tokens.push(token);
21736           return true;
21737         }
21738         return false;
21739       })) {
21740         continue;
21741       }
21742
21743       // newline
21744       if (token = this.tokenizer.space(src)) {
21745         src = src.substring(token.raw.length);
21746         if (token.raw.length === 1 && tokens.length > 0) {
21747           // if there's a single \n as a spacer, it's terminating the last line,
21748           // so move it there so that we don't get unecessary paragraph tags
21749           tokens[tokens.length - 1].raw += '\n';
21750         } else {
21751           tokens.push(token);
21752         }
21753         continue;
21754       }
21755
21756       // code
21757       if (token = this.tokenizer.code(src)) {
21758         src = src.substring(token.raw.length);
21759         lastToken = tokens[tokens.length - 1];
21760         // An indented code block cannot interrupt a paragraph.
21761         if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
21762           lastToken.raw += '\n' + token.raw;
21763           lastToken.text += '\n' + token.text;
21764           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21765         } else {
21766           tokens.push(token);
21767         }
21768         continue;
21769       }
21770
21771       // fences
21772       if (token = this.tokenizer.fences(src)) {
21773         src = src.substring(token.raw.length);
21774         tokens.push(token);
21775         continue;
21776       }
21777
21778       // heading
21779       if (token = this.tokenizer.heading(src)) {
21780         src = src.substring(token.raw.length);
21781         tokens.push(token);
21782         continue;
21783       }
21784
21785       // hr
21786       if (token = this.tokenizer.hr(src)) {
21787         src = src.substring(token.raw.length);
21788         tokens.push(token);
21789         continue;
21790       }
21791
21792       // blockquote
21793       if (token = this.tokenizer.blockquote(src)) {
21794         src = src.substring(token.raw.length);
21795         tokens.push(token);
21796         continue;
21797       }
21798
21799       // list
21800       if (token = this.tokenizer.list(src)) {
21801         src = src.substring(token.raw.length);
21802         tokens.push(token);
21803         continue;
21804       }
21805
21806       // html
21807       if (token = this.tokenizer.html(src)) {
21808         src = src.substring(token.raw.length);
21809         tokens.push(token);
21810         continue;
21811       }
21812
21813       // def
21814       if (token = this.tokenizer.def(src)) {
21815         src = src.substring(token.raw.length);
21816         lastToken = tokens[tokens.length - 1];
21817         if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
21818           lastToken.raw += '\n' + token.raw;
21819           lastToken.text += '\n' + token.raw;
21820           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21821         } else if (!this.tokens.links[token.tag]) {
21822           this.tokens.links[token.tag] = {
21823             href: token.href,
21824             title: token.title
21825           };
21826         }
21827         continue;
21828       }
21829
21830       // table (gfm)
21831       if (token = this.tokenizer.table(src)) {
21832         src = src.substring(token.raw.length);
21833         tokens.push(token);
21834         continue;
21835       }
21836
21837       // lheading
21838       if (token = this.tokenizer.lheading(src)) {
21839         src = src.substring(token.raw.length);
21840         tokens.push(token);
21841         continue;
21842       }
21843
21844       // top-level paragraph
21845       // prevent paragraph consuming extensions by clipping 'src' to extension start
21846       cutSrc = src;
21847       if (this.options.extensions && this.options.extensions.startBlock) {
21848         (function () {
21849           var startIndex = Infinity;
21850           var tempSrc = src.slice(1);
21851           var tempStart = void 0;
21852           _this.options.extensions.startBlock.forEach(function (getStartIndex) {
21853             tempStart = getStartIndex.call({
21854               lexer: this
21855             }, tempSrc);
21856             if (typeof tempStart === 'number' && tempStart >= 0) {
21857               startIndex = Math.min(startIndex, tempStart);
21858             }
21859           });
21860           if (startIndex < Infinity && startIndex >= 0) {
21861             cutSrc = src.substring(0, startIndex + 1);
21862           }
21863         })();
21864       }
21865       if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
21866         lastToken = tokens[tokens.length - 1];
21867         if (lastParagraphClipped && lastToken.type === 'paragraph') {
21868           lastToken.raw += '\n' + token.raw;
21869           lastToken.text += '\n' + token.text;
21870           this.inlineQueue.pop();
21871           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21872         } else {
21873           tokens.push(token);
21874         }
21875         lastParagraphClipped = cutSrc.length !== src.length;
21876         src = src.substring(token.raw.length);
21877         continue;
21878       }
21879
21880       // text
21881       if (token = this.tokenizer.text(src)) {
21882         src = src.substring(token.raw.length);
21883         lastToken = tokens[tokens.length - 1];
21884         if (lastToken && lastToken.type === 'text') {
21885           lastToken.raw += '\n' + token.raw;
21886           lastToken.text += '\n' + token.text;
21887           this.inlineQueue.pop();
21888           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21889         } else {
21890           tokens.push(token);
21891         }
21892         continue;
21893       }
21894       if (src) {
21895         var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
21896         if (this.options.silent) {
21897           console.error(errMsg);
21898           break;
21899         } else {
21900           throw new Error(errMsg);
21901         }
21902       }
21903     }
21904     this.state.top = true;
21905     return tokens;
21906   };
21907   _proto.inline = function inline(src, tokens) {
21908     if (tokens === void 0) {
21909       tokens = [];
21910     }
21911     this.inlineQueue.push({
21912       src: src,
21913       tokens: tokens
21914     });
21915     return tokens;
21916   }
21917
21918   /**
21919    * Lexing/Compiling
21920    */;
21921   _proto.inlineTokens = function inlineTokens(src, tokens) {
21922     var _this2 = this;
21923     if (tokens === void 0) {
21924       tokens = [];
21925     }
21926     var token, lastToken, cutSrc;
21927
21928     // String with links masked to avoid interference with em and strong
21929     var maskedSrc = src;
21930     var match;
21931     var keepPrevChar, prevChar;
21932
21933     // Mask out reflinks
21934     if (this.tokens.links) {
21935       var links = Object.keys(this.tokens.links);
21936       if (links.length > 0) {
21937         while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
21938           if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
21939             maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
21940           }
21941         }
21942       }
21943     }
21944     // Mask out other blocks
21945     while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
21946       maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
21947     }
21948
21949     // Mask out escaped em & strong delimiters
21950     while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
21951       maskedSrc = maskedSrc.slice(0, match.index + match[0].length - 2) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
21952       this.tokenizer.rules.inline.escapedEmSt.lastIndex--;
21953     }
21954     while (src) {
21955       if (!keepPrevChar) {
21956         prevChar = '';
21957       }
21958       keepPrevChar = false;
21959
21960       // extensions
21961       if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some(function (extTokenizer) {
21962         if (token = extTokenizer.call({
21963           lexer: _this2
21964         }, src, tokens)) {
21965           src = src.substring(token.raw.length);
21966           tokens.push(token);
21967           return true;
21968         }
21969         return false;
21970       })) {
21971         continue;
21972       }
21973
21974       // escape
21975       if (token = this.tokenizer.escape(src)) {
21976         src = src.substring(token.raw.length);
21977         tokens.push(token);
21978         continue;
21979       }
21980
21981       // tag
21982       if (token = this.tokenizer.tag(src)) {
21983         src = src.substring(token.raw.length);
21984         lastToken = tokens[tokens.length - 1];
21985         if (lastToken && token.type === 'text' && lastToken.type === 'text') {
21986           lastToken.raw += token.raw;
21987           lastToken.text += token.text;
21988         } else {
21989           tokens.push(token);
21990         }
21991         continue;
21992       }
21993
21994       // link
21995       if (token = this.tokenizer.link(src)) {
21996         src = src.substring(token.raw.length);
21997         tokens.push(token);
21998         continue;
21999       }
22000
22001       // reflink, nolink
22002       if (token = this.tokenizer.reflink(src, this.tokens.links)) {
22003         src = src.substring(token.raw.length);
22004         lastToken = tokens[tokens.length - 1];
22005         if (lastToken && token.type === 'text' && lastToken.type === 'text') {
22006           lastToken.raw += token.raw;
22007           lastToken.text += token.text;
22008         } else {
22009           tokens.push(token);
22010         }
22011         continue;
22012       }
22013
22014       // em & strong
22015       if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
22016         src = src.substring(token.raw.length);
22017         tokens.push(token);
22018         continue;
22019       }
22020
22021       // code
22022       if (token = this.tokenizer.codespan(src)) {
22023         src = src.substring(token.raw.length);
22024         tokens.push(token);
22025         continue;
22026       }
22027
22028       // br
22029       if (token = this.tokenizer.br(src)) {
22030         src = src.substring(token.raw.length);
22031         tokens.push(token);
22032         continue;
22033       }
22034
22035       // del (gfm)
22036       if (token = this.tokenizer.del(src)) {
22037         src = src.substring(token.raw.length);
22038         tokens.push(token);
22039         continue;
22040       }
22041
22042       // autolink
22043       if (token = this.tokenizer.autolink(src, mangle)) {
22044         src = src.substring(token.raw.length);
22045         tokens.push(token);
22046         continue;
22047       }
22048
22049       // url (gfm)
22050       if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
22051         src = src.substring(token.raw.length);
22052         tokens.push(token);
22053         continue;
22054       }
22055
22056       // text
22057       // prevent inlineText consuming extensions by clipping 'src' to extension start
22058       cutSrc = src;
22059       if (this.options.extensions && this.options.extensions.startInline) {
22060         (function () {
22061           var startIndex = Infinity;
22062           var tempSrc = src.slice(1);
22063           var tempStart = void 0;
22064           _this2.options.extensions.startInline.forEach(function (getStartIndex) {
22065             tempStart = getStartIndex.call({
22066               lexer: this
22067             }, tempSrc);
22068             if (typeof tempStart === 'number' && tempStart >= 0) {
22069               startIndex = Math.min(startIndex, tempStart);
22070             }
22071           });
22072           if (startIndex < Infinity && startIndex >= 0) {
22073             cutSrc = src.substring(0, startIndex + 1);
22074           }
22075         })();
22076       }
22077       if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
22078         src = src.substring(token.raw.length);
22079         if (token.raw.slice(-1) !== '_') {
22080           // Track prevChar before string of ____ started
22081           prevChar = token.raw.slice(-1);
22082         }
22083         keepPrevChar = true;
22084         lastToken = tokens[tokens.length - 1];
22085         if (lastToken && lastToken.type === 'text') {
22086           lastToken.raw += token.raw;
22087           lastToken.text += token.text;
22088         } else {
22089           tokens.push(token);
22090         }
22091         continue;
22092       }
22093       if (src) {
22094         var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
22095         if (this.options.silent) {
22096           console.error(errMsg);
22097           break;
22098         } else {
22099           throw new Error(errMsg);
22100         }
22101       }
22102     }
22103     return tokens;
22104   };
22105   _createClass(Lexer, null, [{
22106     key: "rules",
22107     get: function get() {
22108       return {
22109         block: block,
22110         inline: inline
22111       };
22112     }
22113   }]);
22114   return Lexer;
22115 }();
22116
22117 /**
22118  * Renderer
22119  */
22120 var Renderer = /*#__PURE__*/function () {
22121   function Renderer(options) {
22122     this.options = options || exports.defaults;
22123   }
22124   var _proto = Renderer.prototype;
22125   _proto.code = function code(_code, infostring, escaped) {
22126     var lang = (infostring || '').match(/\S*/)[0];
22127     if (this.options.highlight) {
22128       var out = this.options.highlight(_code, lang);
22129       if (out != null && out !== _code) {
22130         escaped = true;
22131         _code = out;
22132       }
22133     }
22134     _code = _code.replace(/\n$/, '') + '\n';
22135     if (!lang) {
22136       return '<pre><code>' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n';
22137     }
22138     return '<pre><code class="' + this.options.langPrefix + escape(lang) + '">' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n';
22139   }
22140
22141   /**
22142    * @param {string} quote
22143    */;
22144   _proto.blockquote = function blockquote(quote) {
22145     return "<blockquote>\n" + quote + "</blockquote>\n";
22146   };
22147   _proto.html = function html(_html) {
22148     return _html;
22149   }
22150
22151   /**
22152    * @param {string} text
22153    * @param {string} level
22154    * @param {string} raw
22155    * @param {any} slugger
22156    */;
22157   _proto.heading = function heading(text, level, raw, slugger) {
22158     if (this.options.headerIds) {
22159       var id = this.options.headerPrefix + slugger.slug(raw);
22160       return "<h" + level + " id=\"" + id + "\">" + text + "</h" + level + ">\n";
22161     }
22162
22163     // ignore IDs
22164     return "<h" + level + ">" + text + "</h" + level + ">\n";
22165   };
22166   _proto.hr = function hr() {
22167     return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
22168   };
22169   _proto.list = function list(body, ordered, start) {
22170     var type = ordered ? 'ol' : 'ul',
22171       startatt = ordered && start !== 1 ? ' start="' + start + '"' : '';
22172     return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
22173   }
22174
22175   /**
22176    * @param {string} text
22177    */;
22178   _proto.listitem = function listitem(text) {
22179     return "<li>" + text + "</li>\n";
22180   };
22181   _proto.checkbox = function checkbox(checked) {
22182     return '<input ' + (checked ? 'checked="" ' : '') + 'disabled="" type="checkbox"' + (this.options.xhtml ? ' /' : '') + '> ';
22183   }
22184
22185   /**
22186    * @param {string} text
22187    */;
22188   _proto.paragraph = function paragraph(text) {
22189     return "<p>" + text + "</p>\n";
22190   }
22191
22192   /**
22193    * @param {string} header
22194    * @param {string} body
22195    */;
22196   _proto.table = function table(header, body) {
22197     if (body) body = "<tbody>" + body + "</tbody>";
22198     return '<table>\n' + '<thead>\n' + header + '</thead>\n' + body + '</table>\n';
22199   }
22200
22201   /**
22202    * @param {string} content
22203    */;
22204   _proto.tablerow = function tablerow(content) {
22205     return "<tr>\n" + content + "</tr>\n";
22206   };
22207   _proto.tablecell = function tablecell(content, flags) {
22208     var type = flags.header ? 'th' : 'td';
22209     var tag = flags.align ? "<" + type + " align=\"" + flags.align + "\">" : "<" + type + ">";
22210     return tag + content + ("</" + type + ">\n");
22211   }
22212
22213   /**
22214    * span level renderer
22215    * @param {string} text
22216    */;
22217   _proto.strong = function strong(text) {
22218     return "<strong>" + text + "</strong>";
22219   }
22220
22221   /**
22222    * @param {string} text
22223    */;
22224   _proto.em = function em(text) {
22225     return "<em>" + text + "</em>";
22226   }
22227
22228   /**
22229    * @param {string} text
22230    */;
22231   _proto.codespan = function codespan(text) {
22232     return "<code>" + text + "</code>";
22233   };
22234   _proto.br = function br() {
22235     return this.options.xhtml ? '<br/>' : '<br>';
22236   }
22237
22238   /**
22239    * @param {string} text
22240    */;
22241   _proto.del = function del(text) {
22242     return "<del>" + text + "</del>";
22243   }
22244
22245   /**
22246    * @param {string} href
22247    * @param {string} title
22248    * @param {string} text
22249    */;
22250   _proto.link = function link(href, title, text) {
22251     href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
22252     if (href === null) {
22253       return text;
22254     }
22255     var out = '<a href="' + href + '"';
22256     if (title) {
22257       out += ' title="' + title + '"';
22258     }
22259     out += '>' + text + '</a>';
22260     return out;
22261   }
22262
22263   /**
22264    * @param {string} href
22265    * @param {string} title
22266    * @param {string} text
22267    */;
22268   _proto.image = function image(href, title, text) {
22269     href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
22270     if (href === null) {
22271       return text;
22272     }
22273     var out = "<img src=\"" + href + "\" alt=\"" + text + "\"";
22274     if (title) {
22275       out += " title=\"" + title + "\"";
22276     }
22277     out += this.options.xhtml ? '/>' : '>';
22278     return out;
22279   };
22280   _proto.text = function text(_text) {
22281     return _text;
22282   };
22283   return Renderer;
22284 }();
22285
22286 /**
22287  * TextRenderer
22288  * returns only the textual part of the token
22289  */
22290 var TextRenderer = /*#__PURE__*/function () {
22291   function TextRenderer() {}
22292   var _proto = TextRenderer.prototype;
22293   // no need for block level renderers
22294   _proto.strong = function strong(text) {
22295     return text;
22296   };
22297   _proto.em = function em(text) {
22298     return text;
22299   };
22300   _proto.codespan = function codespan(text) {
22301     return text;
22302   };
22303   _proto.del = function del(text) {
22304     return text;
22305   };
22306   _proto.html = function html(text) {
22307     return text;
22308   };
22309   _proto.text = function text(_text) {
22310     return _text;
22311   };
22312   _proto.link = function link(href, title, text) {
22313     return '' + text;
22314   };
22315   _proto.image = function image(href, title, text) {
22316     return '' + text;
22317   };
22318   _proto.br = function br() {
22319     return '';
22320   };
22321   return TextRenderer;
22322 }();
22323
22324 /**
22325  * Slugger generates header id
22326  */
22327 var Slugger = /*#__PURE__*/function () {
22328   function Slugger() {
22329     this.seen = {};
22330   }
22331
22332   /**
22333    * @param {string} value
22334    */
22335   var _proto = Slugger.prototype;
22336   _proto.serialize = function serialize(value) {
22337     return value.toLowerCase().trim()
22338     // remove html tags
22339     .replace(/<[!\/a-z].*?>/ig, '')
22340     // remove unwanted chars
22341     .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '').replace(/\s/g, '-');
22342   }
22343
22344   /**
22345    * Finds the next safe (unique) slug to use
22346    * @param {string} originalSlug
22347    * @param {boolean} isDryRun
22348    */;
22349   _proto.getNextSafeSlug = function getNextSafeSlug(originalSlug, isDryRun) {
22350     var slug = originalSlug;
22351     var occurenceAccumulator = 0;
22352     if (this.seen.hasOwnProperty(slug)) {
22353       occurenceAccumulator = this.seen[originalSlug];
22354       do {
22355         occurenceAccumulator++;
22356         slug = originalSlug + '-' + occurenceAccumulator;
22357       } while (this.seen.hasOwnProperty(slug));
22358     }
22359     if (!isDryRun) {
22360       this.seen[originalSlug] = occurenceAccumulator;
22361       this.seen[slug] = 0;
22362     }
22363     return slug;
22364   }
22365
22366   /**
22367    * Convert string to unique id
22368    * @param {object} [options]
22369    * @param {boolean} [options.dryrun] Generates the next unique slug without
22370    * updating the internal accumulator.
22371    */;
22372   _proto.slug = function slug(value, options) {
22373     if (options === void 0) {
22374       options = {};
22375     }
22376     var slug = this.serialize(value);
22377     return this.getNextSafeSlug(slug, options.dryrun);
22378   };
22379   return Slugger;
22380 }();
22381
22382 /**
22383  * Parsing & Compiling
22384  */
22385 var Parser = /*#__PURE__*/function () {
22386   function Parser(options) {
22387     this.options = options || exports.defaults;
22388     this.options.renderer = this.options.renderer || new Renderer();
22389     this.renderer = this.options.renderer;
22390     this.renderer.options = this.options;
22391     this.textRenderer = new TextRenderer();
22392     this.slugger = new Slugger();
22393   }
22394
22395   /**
22396    * Static Parse Method
22397    */
22398   Parser.parse = function parse(tokens, options) {
22399     var parser = new Parser(options);
22400     return parser.parse(tokens);
22401   }
22402
22403   /**
22404    * Static Parse Inline Method
22405    */;
22406   Parser.parseInline = function parseInline(tokens, options) {
22407     var parser = new Parser(options);
22408     return parser.parseInline(tokens);
22409   }
22410
22411   /**
22412    * Parse Loop
22413    */;
22414   var _proto = Parser.prototype;
22415   _proto.parse = function parse(tokens, top) {
22416     if (top === void 0) {
22417       top = true;
22418     }
22419     var out = '',
22420       i,
22421       j,
22422       k,
22423       l2,
22424       l3,
22425       row,
22426       cell,
22427       header,
22428       body,
22429       token,
22430       ordered,
22431       start,
22432       loose,
22433       itemBody,
22434       item,
22435       checked,
22436       task,
22437       checkbox,
22438       ret;
22439     var l = tokens.length;
22440     for (i = 0; i < l; i++) {
22441       token = tokens[i];
22442
22443       // Run any renderer extensions
22444       if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
22445         ret = this.options.extensions.renderers[token.type].call({
22446           parser: this
22447         }, token);
22448         if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
22449           out += ret || '';
22450           continue;
22451         }
22452       }
22453       switch (token.type) {
22454         case 'space':
22455           {
22456             continue;
22457           }
22458         case 'hr':
22459           {
22460             out += this.renderer.hr();
22461             continue;
22462           }
22463         case 'heading':
22464           {
22465             out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger);
22466             continue;
22467           }
22468         case 'code':
22469           {
22470             out += this.renderer.code(token.text, token.lang, token.escaped);
22471             continue;
22472           }
22473         case 'table':
22474           {
22475             header = '';
22476
22477             // header
22478             cell = '';
22479             l2 = token.header.length;
22480             for (j = 0; j < l2; j++) {
22481               cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), {
22482                 header: true,
22483                 align: token.align[j]
22484               });
22485             }
22486             header += this.renderer.tablerow(cell);
22487             body = '';
22488             l2 = token.rows.length;
22489             for (j = 0; j < l2; j++) {
22490               row = token.rows[j];
22491               cell = '';
22492               l3 = row.length;
22493               for (k = 0; k < l3; k++) {
22494                 cell += this.renderer.tablecell(this.parseInline(row[k].tokens), {
22495                   header: false,
22496                   align: token.align[k]
22497                 });
22498               }
22499               body += this.renderer.tablerow(cell);
22500             }
22501             out += this.renderer.table(header, body);
22502             continue;
22503           }
22504         case 'blockquote':
22505           {
22506             body = this.parse(token.tokens);
22507             out += this.renderer.blockquote(body);
22508             continue;
22509           }
22510         case 'list':
22511           {
22512             ordered = token.ordered;
22513             start = token.start;
22514             loose = token.loose;
22515             l2 = token.items.length;
22516             body = '';
22517             for (j = 0; j < l2; j++) {
22518               item = token.items[j];
22519               checked = item.checked;
22520               task = item.task;
22521               itemBody = '';
22522               if (item.task) {
22523                 checkbox = this.renderer.checkbox(checked);
22524                 if (loose) {
22525                   if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
22526                     item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
22527                     if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
22528                       item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
22529                     }
22530                   } else {
22531                     item.tokens.unshift({
22532                       type: 'text',
22533                       text: checkbox
22534                     });
22535                   }
22536                 } else {
22537                   itemBody += checkbox;
22538                 }
22539               }
22540               itemBody += this.parse(item.tokens, loose);
22541               body += this.renderer.listitem(itemBody, task, checked);
22542             }
22543             out += this.renderer.list(body, ordered, start);
22544             continue;
22545           }
22546         case 'html':
22547           {
22548             // TODO parse inline content if parameter markdown=1
22549             out += this.renderer.html(token.text);
22550             continue;
22551           }
22552         case 'paragraph':
22553           {
22554             out += this.renderer.paragraph(this.parseInline(token.tokens));
22555             continue;
22556           }
22557         case 'text':
22558           {
22559             body = token.tokens ? this.parseInline(token.tokens) : token.text;
22560             while (i + 1 < l && tokens[i + 1].type === 'text') {
22561               token = tokens[++i];
22562               body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
22563             }
22564             out += top ? this.renderer.paragraph(body) : body;
22565             continue;
22566           }
22567         default:
22568           {
22569             var errMsg = 'Token with "' + token.type + '" type was not found.';
22570             if (this.options.silent) {
22571               console.error(errMsg);
22572               return;
22573             } else {
22574               throw new Error(errMsg);
22575             }
22576           }
22577       }
22578     }
22579     return out;
22580   }
22581
22582   /**
22583    * Parse Inline Tokens
22584    */;
22585   _proto.parseInline = function parseInline(tokens, renderer) {
22586     renderer = renderer || this.renderer;
22587     var out = '',
22588       i,
22589       token,
22590       ret;
22591     var l = tokens.length;
22592     for (i = 0; i < l; i++) {
22593       token = tokens[i];
22594
22595       // Run any renderer extensions
22596       if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
22597         ret = this.options.extensions.renderers[token.type].call({
22598           parser: this
22599         }, token);
22600         if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
22601           out += ret || '';
22602           continue;
22603         }
22604       }
22605       switch (token.type) {
22606         case 'escape':
22607           {
22608             out += renderer.text(token.text);
22609             break;
22610           }
22611         case 'html':
22612           {
22613             out += renderer.html(token.text);
22614             break;
22615           }
22616         case 'link':
22617           {
22618             out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
22619             break;
22620           }
22621         case 'image':
22622           {
22623             out += renderer.image(token.href, token.title, token.text);
22624             break;
22625           }
22626         case 'strong':
22627           {
22628             out += renderer.strong(this.parseInline(token.tokens, renderer));
22629             break;
22630           }
22631         case 'em':
22632           {
22633             out += renderer.em(this.parseInline(token.tokens, renderer));
22634             break;
22635           }
22636         case 'codespan':
22637           {
22638             out += renderer.codespan(token.text);
22639             break;
22640           }
22641         case 'br':
22642           {
22643             out += renderer.br();
22644             break;
22645           }
22646         case 'del':
22647           {
22648             out += renderer.del(this.parseInline(token.tokens, renderer));
22649             break;
22650           }
22651         case 'text':
22652           {
22653             out += renderer.text(token.text);
22654             break;
22655           }
22656         default:
22657           {
22658             var errMsg = 'Token with "' + token.type + '" type was not found.';
22659             if (this.options.silent) {
22660               console.error(errMsg);
22661               return;
22662             } else {
22663               throw new Error(errMsg);
22664             }
22665           }
22666       }
22667     }
22668     return out;
22669   };
22670   return Parser;
22671 }();
22672
22673 /**
22674  * Marked
22675  */
22676 function marked(src, opt, callback) {
22677   // throw error in case of non string input
22678   if (typeof src === 'undefined' || src === null) {
22679     throw new Error('marked(): input parameter is undefined or null');
22680   }
22681   if (typeof src !== 'string') {
22682     throw new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected');
22683   }
22684   if (typeof opt === 'function') {
22685     callback = opt;
22686     opt = null;
22687   }
22688   opt = merge({}, marked.defaults, opt || {});
22689   checkSanitizeDeprecation(opt);
22690   if (callback) {
22691     var highlight = opt.highlight;
22692     var tokens;
22693     try {
22694       tokens = Lexer.lex(src, opt);
22695     } catch (e) {
22696       return callback(e);
22697     }
22698     var done = function done(err) {
22699       var out;
22700       if (!err) {
22701         try {
22702           if (opt.walkTokens) {
22703             marked.walkTokens(tokens, opt.walkTokens);
22704           }
22705           out = Parser.parse(tokens, opt);
22706         } catch (e) {
22707           err = e;
22708         }
22709       }
22710       opt.highlight = highlight;
22711       return err ? callback(err) : callback(null, out);
22712     };
22713     if (!highlight || highlight.length < 3) {
22714       return done();
22715     }
22716     delete opt.highlight;
22717     if (!tokens.length) return done();
22718     var pending = 0;
22719     marked.walkTokens(tokens, function (token) {
22720       if (token.type === 'code') {
22721         pending++;
22722         setTimeout(function () {
22723           highlight(token.text, token.lang, function (err, code) {
22724             if (err) {
22725               return done(err);
22726             }
22727             if (code != null && code !== token.text) {
22728               token.text = code;
22729               token.escaped = true;
22730             }
22731             pending--;
22732             if (pending === 0) {
22733               done();
22734             }
22735           });
22736         }, 0);
22737       }
22738     });
22739     if (pending === 0) {
22740       done();
22741     }
22742     return;
22743   }
22744   function onError(e) {
22745     e.message += '\nPlease report this to https://github.com/markedjs/marked.';
22746     if (opt.silent) {
22747       return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>';
22748     }
22749     throw e;
22750   }
22751   try {
22752     var _tokens = Lexer.lex(src, opt);
22753     if (opt.walkTokens) {
22754       if (opt.async) {
22755         return Promise.all(marked.walkTokens(_tokens, opt.walkTokens)).then(function () {
22756           return Parser.parse(_tokens, opt);
22757         })["catch"](onError);
22758       }
22759       marked.walkTokens(_tokens, opt.walkTokens);
22760     }
22761     return Parser.parse(_tokens, opt);
22762   } catch (e) {
22763     onError(e);
22764   }
22765 }
22766
22767 /**
22768  * Options
22769  */
22770
22771 marked.options = marked.setOptions = function (opt) {
22772   merge(marked.defaults, opt);
22773   changeDefaults(marked.defaults);
22774   return marked;
22775 };
22776 marked.getDefaults = getDefaults;
22777 marked.defaults = exports.defaults;
22778
22779 /**
22780  * Use Extension
22781  */
22782
22783 marked.use = function () {
22784   var extensions = marked.defaults.extensions || {
22785     renderers: {},
22786     childTokens: {}
22787   };
22788   for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
22789     args[_key] = arguments[_key];
22790   }
22791   args.forEach(function (pack) {
22792     // copy options to new object
22793     var opts = merge({}, pack);
22794
22795     // set async to true if it was set to true before
22796     opts.async = marked.defaults.async || opts.async;
22797
22798     // ==-- Parse "addon" extensions --== //
22799     if (pack.extensions) {
22800       pack.extensions.forEach(function (ext) {
22801         if (!ext.name) {
22802           throw new Error('extension name required');
22803         }
22804         if (ext.renderer) {
22805           // Renderer extensions
22806           var prevRenderer = extensions.renderers[ext.name];
22807           if (prevRenderer) {
22808             // Replace extension with func to run new extension but fall back if false
22809             extensions.renderers[ext.name] = function () {
22810               for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22811                 args[_key2] = arguments[_key2];
22812               }
22813               var ret = ext.renderer.apply(this, args);
22814               if (ret === false) {
22815                 ret = prevRenderer.apply(this, args);
22816               }
22817               return ret;
22818             };
22819           } else {
22820             extensions.renderers[ext.name] = ext.renderer;
22821           }
22822         }
22823         if (ext.tokenizer) {
22824           // Tokenizer Extensions
22825           if (!ext.level || ext.level !== 'block' && ext.level !== 'inline') {
22826             throw new Error("extension level must be 'block' or 'inline'");
22827           }
22828           if (extensions[ext.level]) {
22829             extensions[ext.level].unshift(ext.tokenizer);
22830           } else {
22831             extensions[ext.level] = [ext.tokenizer];
22832           }
22833           if (ext.start) {
22834             // Function to check for start of token
22835             if (ext.level === 'block') {
22836               if (extensions.startBlock) {
22837                 extensions.startBlock.push(ext.start);
22838               } else {
22839                 extensions.startBlock = [ext.start];
22840               }
22841             } else if (ext.level === 'inline') {
22842               if (extensions.startInline) {
22843                 extensions.startInline.push(ext.start);
22844               } else {
22845                 extensions.startInline = [ext.start];
22846               }
22847             }
22848           }
22849         }
22850         if (ext.childTokens) {
22851           // Child tokens to be visited by walkTokens
22852           extensions.childTokens[ext.name] = ext.childTokens;
22853         }
22854       });
22855       opts.extensions = extensions;
22856     }
22857
22858     // ==-- Parse "overwrite" extensions --== //
22859     if (pack.renderer) {
22860       (function () {
22861         var renderer = marked.defaults.renderer || new Renderer();
22862         var _loop = function _loop(prop) {
22863           var prevRenderer = renderer[prop];
22864           // Replace renderer with func to run extension, but fall back if false
22865           renderer[prop] = function () {
22866             for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
22867               args[_key3] = arguments[_key3];
22868             }
22869             var ret = pack.renderer[prop].apply(renderer, args);
22870             if (ret === false) {
22871               ret = prevRenderer.apply(renderer, args);
22872             }
22873             return ret;
22874           };
22875         };
22876         for (var prop in pack.renderer) {
22877           _loop(prop);
22878         }
22879         opts.renderer = renderer;
22880       })();
22881     }
22882     if (pack.tokenizer) {
22883       (function () {
22884         var tokenizer = marked.defaults.tokenizer || new Tokenizer();
22885         var _loop2 = function _loop2(prop) {
22886           var prevTokenizer = tokenizer[prop];
22887           // Replace tokenizer with func to run extension, but fall back if false
22888           tokenizer[prop] = function () {
22889             for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
22890               args[_key4] = arguments[_key4];
22891             }
22892             var ret = pack.tokenizer[prop].apply(tokenizer, args);
22893             if (ret === false) {
22894               ret = prevTokenizer.apply(tokenizer, args);
22895             }
22896             return ret;
22897           };
22898         };
22899         for (var prop in pack.tokenizer) {
22900           _loop2(prop);
22901         }
22902         opts.tokenizer = tokenizer;
22903       })();
22904     }
22905
22906     // ==-- Parse WalkTokens extensions --== //
22907     if (pack.walkTokens) {
22908       var _walkTokens = marked.defaults.walkTokens;
22909       opts.walkTokens = function (token) {
22910         var values = [];
22911         values.push(pack.walkTokens.call(this, token));
22912         if (_walkTokens) {
22913           values = values.concat(_walkTokens.call(this, token));
22914         }
22915         return values;
22916       };
22917     }
22918     marked.setOptions(opts);
22919   });
22920 };
22921
22922 /**
22923  * Run callback for every token
22924  */
22925
22926 marked.walkTokens = function (tokens, callback) {
22927   var values = [];
22928   var _loop3 = function _loop3() {
22929     var token = _step.value;
22930     values = values.concat(callback.call(marked, token));
22931     switch (token.type) {
22932       case 'table':
22933         {
22934           for (var _iterator2 = _createForOfIteratorHelperLoose(token.header), _step2; !(_step2 = _iterator2()).done;) {
22935             var cell = _step2.value;
22936             values = values.concat(marked.walkTokens(cell.tokens, callback));
22937           }
22938           for (var _iterator3 = _createForOfIteratorHelperLoose(token.rows), _step3; !(_step3 = _iterator3()).done;) {
22939             var row = _step3.value;
22940             for (var _iterator4 = _createForOfIteratorHelperLoose(row), _step4; !(_step4 = _iterator4()).done;) {
22941               var _cell = _step4.value;
22942               values = values.concat(marked.walkTokens(_cell.tokens, callback));
22943             }
22944           }
22945           break;
22946         }
22947       case 'list':
22948         {
22949           values = values.concat(marked.walkTokens(token.items, callback));
22950           break;
22951         }
22952       default:
22953         {
22954           if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) {
22955             // Walk any extensions
22956             marked.defaults.extensions.childTokens[token.type].forEach(function (childTokens) {
22957               values = values.concat(marked.walkTokens(token[childTokens], callback));
22958             });
22959           } else if (token.tokens) {
22960             values = values.concat(marked.walkTokens(token.tokens, callback));
22961           }
22962         }
22963     }
22964   };
22965   for (var _iterator = _createForOfIteratorHelperLoose(tokens), _step; !(_step = _iterator()).done;) {
22966     _loop3();
22967   }
22968   return values;
22969 };
22970
22971 /**
22972  * Parse Inline
22973  * @param {string} src
22974  */
22975 marked.parseInline = function (src, opt) {
22976   // throw error in case of non string input
22977   if (typeof src === 'undefined' || src === null) {
22978     throw new Error('marked.parseInline(): input parameter is undefined or null');
22979   }
22980   if (typeof src !== 'string') {
22981     throw new Error('marked.parseInline(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected');
22982   }
22983   opt = merge({}, marked.defaults, opt || {});
22984   checkSanitizeDeprecation(opt);
22985   try {
22986     var tokens = Lexer.lexInline(src, opt);
22987     if (opt.walkTokens) {
22988       marked.walkTokens(tokens, opt.walkTokens);
22989     }
22990     return Parser.parseInline(tokens, opt);
22991   } catch (e) {
22992     e.message += '\nPlease report this to https://github.com/markedjs/marked.';
22993     if (opt.silent) {
22994       return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>';
22995     }
22996     throw e;
22997   }
22998 };
22999
23000 /**
23001  * Expose
23002  */
23003 marked.Parser = Parser;
23004 marked.parser = Parser.parse;
23005 marked.Renderer = Renderer;
23006 marked.TextRenderer = TextRenderer;
23007 marked.Lexer = Lexer;
23008 marked.lexer = Lexer.lex;
23009 marked.Tokenizer = Tokenizer;
23010 marked.Slugger = Slugger;
23011 marked.parse = marked;
23012 var options = marked.options;
23013 var setOptions = marked.setOptions;
23014 var use = marked.use;
23015 var walkTokens = marked.walkTokens;
23016 var parseInline = marked.parseInline;
23017 var parse = marked;
23018 var parser = Parser.parse;
23019 var lexer = Lexer.lex;
23020
23021 exports.Lexer = Lexer;
23022 exports.Parser = Parser;
23023 exports.Renderer = Renderer;
23024 exports.Slugger = Slugger;
23025 exports.TextRenderer = TextRenderer;
23026 exports.Tokenizer = Tokenizer;
23027 exports.getDefaults = getDefaults;
23028 exports.lexer = lexer;
23029 exports.marked = marked;
23030 exports.options = options;
23031 exports.parse = parse;
23032 exports.parseInline = parseInline;
23033 exports.parser = parser;
23034 exports.setOptions = setOptions;
23035 exports.use = use;
23036 exports.walkTokens = walkTokens;
23037
23038
23039 /***/ }),
23040
23041 /***/ "./src/test-data.json":
23042 /*!****************************!*\
23043   !*** ./src/test-data.json ***!
23044   \****************************/
23045 /***/ ((module) => {
23046
23047 "use strict";
23048 module.exports = JSON.parse('{"id":"000000","name":"Sample","created":"1674409747467","tree":{"id":"000000","collapsed":false,"children":[{"id":"000001","collapsed":false,"children":[]},{"id":"1dc4c363-7440-4661-bbc5-7e995dc6ba71","collapsed":false,"children":[]},{"id":"e067419d-85c3-422d-b8c4-41690be4450d","collapsed":false,"children":[{"id":"6addd61d-d12f-4a27-a471-513becfff006","children":[],"collapsed":false}]},{"id":"2ab706de-fea9-42a0-a900-e88b2950ceb3","collapsed":false,"children":[{"id":"27c14755-ff26-4931-a676-b48cd958b781","children":[{"id":"116f8e0f-ab62-450f-914e-5ca0956a457f","children":[],"collapsed":false}],"collapsed":true},{"id":"d69efd32-fbf5-4b80-8a36-af1cb2af7b80","children":[{"id":"b5a55548-f65d-496a-8bea-6b6ba8296e21","children":[],"collapsed":false}],"collapsed":true},{"id":"2f67d730-c71b-4823-a986-fa510d9408e1","children":[{"id":"40194ea5-9c28-4adb-bffe-4f59e7eca666","children":[],"collapsed":false}],"collapsed":true}]},{"id":"21df5e96-d770-43f0-8bd1-1b01ab4626f9","collapsed":false,"children":[]},{"id":"89c3267b-0114-4138-98a8-443b28d2e679","collapsed":false,"children":[{"id":"6b457d6b-0228-41b7-bbba-6c0ba3b54f4d","collapsed":false,"children":[{"id":"bad021fc-24d1-4560-8321-042c28d438a8","collapsed":false,"children":[]}]},{"id":"9690699a-cb7d-4123-8fa5-f7a58a191a08","children":[{"id":"2831a7aa-7291-4ebc-997f-5572e767f5c0","children":[],"collapsed":false}],"collapsed":false},{"id":"88d336be-4910-4d74-b79a-441894af956d","collapsed":false,"children":[{"id":"eb7fd6d7-b3fe-46e5-814c-655a6eec2ba4","children":[],"collapsed":false}]},{"id":"51b2f235-b979-4d74-ad83-3e8b6152bb4a","collapsed":false,"children":[{"id":"9c576012-7e8f-4d2b-b58b-1886eba43341","children":[],"collapsed":false}]}]},{"id":"ef04ea02-aed6-4295-9117-2dcc45506f3a","collapsed":false,"children":[{"id":"255bfdfc-9260-4cb1-9dcd-15f2c9eca2b2","children":[{"id":"40b53a6f-0f43-40c2-b6d3-486982fc9d48","children":[{"id":"724d0e33-fe2c-459e-9e75-e3311809ba36","children":[],"collapsed":false},{"id":"588a65fd-69dd-4bb4-a819-f8c7f05a1d69","collapsed":false,"children":[]},{"id":"13ea01fb-339d-4e65-9fad-123d72830efb","collapsed":false,"children":[]},{"id":"a941538b-6834-4a65-b297-50036b89a41f","collapsed":false,"children":[]}],"collapsed":false},{"id":"80b86062-a197-4adf-baa4-56a5953e0a77","collapsed":false,"children":[{"id":"c09a5876-f825-4cb0-9a56-2916e28f9d02","children":[],"collapsed":false}]}],"collapsed":false}]}]},"contentNodes":{"000001":{"id":"000001","created":1674409747467,"type":"text","content":"**Welcome to my Outliner**<br>"},"e067419d-85c3-422d-b8c4-41690be4450d":{"id":"e067419d-85c3-422d-b8c4-41690be4450d","created":1674412571215,"type":"text","content":"This is my attempt to build a \\"home base\\" piece of software for myself. The goal is to be able to use this tool to serve as a way to write long-form content, manage my website, and keep notes + references. <br>"},"21df5e96-d770-43f0-8bd1-1b01ab4626f9":{"id":"21df5e96-d770-43f0-8bd1-1b01ab4626f9","created":1674412689419,"type":"text","content":"---"},"89c3267b-0114-4138-98a8-443b28d2e679":{"id":"89c3267b-0114-4138-98a8-443b28d2e679","created":1674412690374,"type":"text","content":"**FAQ**"},"9690699a-cb7d-4123-8fa5-f7a58a191a08":{"id":"9690699a-cb7d-4123-8fa5-f7a58a191a08","created":1674412696214,"type":"text","content":"**Why should I use this?**<br>"},"2831a7aa-7291-4ebc-997f-5572e767f5c0":{"id":"2831a7aa-7291-4ebc-997f-5572e767f5c0","created":1674412702948,"type":"text","content":"You shouldn\'t. This isn\'t a piece of software for you - it\'s for me. You may find some use for it, but you also may not. Along the way features will be introduced that likely break things for you.<br>"},"51b2f235-b979-4d74-ad83-3e8b6152bb4a":{"id":"51b2f235-b979-4d74-ad83-3e8b6152bb4a","created":1674412786944,"type":"text","content":"**Ok I used it, but my data is trapped?**<br>"},"9c576012-7e8f-4d2b-b58b-1886eba43341":{"id":"9c576012-7e8f-4d2b-b58b-1886eba43341","created":1674412794788,"type":"text","content":"I\'ll be adding the ability to export the entire thing as OPML, so that there\'s some interop between this and all of [Dave Winer\'s](https://scripting.com) tooling. Hopefully that\'s enough. At some point I\'m going to also introduce support for [RemoteStorage](https://remotestorage.io) which is a project that I\'ve previous contributed to in the past, but have mostly been neglecting lately. I\'m hoping between those two options that\'ll be enough for \\"backups\\" of data.<br>"},"88d336be-4910-4d74-b79a-441894af956d":{"id":"88d336be-4910-4d74-b79a-441894af956d","created":1674412890012,"type":"text","content":"**If I use this, does this mean you have access to all my data?**<br>"},"eb7fd6d7-b3fe-46e5-814c-655a6eec2ba4":{"id":"eb7fd6d7-b3fe-46e5-814c-655a6eec2ba4","created":1674412907752,"type":"text","content":"No. I\'m trying to keep this entirely \\"static\\" and \\"offline first\\". You should be able to use this without concern that I\'ll be watching what you type. Like I said - this is primarily a tool for me, and I already have access to all of my content.<br>"},"bad021fc-24d1-4560-8321-042c28d438a8":{"id":"bad021fc-24d1-4560-8321-042c28d438a8","created":1674491030563,"type":"text","content":"An outliner is simply a tool that allows for \\"infinite\\" hierarchy. You can create nested nodes, move them around, and generally treat it like a big old bulleted list. It seem silly, but being able to sort your list whenever you feel like is a huge deal. <br>"},"1dc4c363-7440-4661-bbc5-7e995dc6ba71":{"id":"1dc4c363-7440-4661-bbc5-7e995dc6ba71","created":1674491120429,"type":"text","content":"I\'ve long been a user of [Dave Winer\'s](https://scripting.com) outliner tools for the last decade since I first discovered Outliners. They\'ve been a massive benefit to me as I attempt to organize my thoughts across a variety of subjects. I\'ve also always struggled to adopt existing tooling as I found that they were ALMOST what I wanted.<br>"},"6addd61d-d12f-4a27-a471-513becfff006":{"id":"6addd61d-d12f-4a27-a471-513becfff006","created":1674491272253,"type":"text","content":"![Thumbs Up](http://www.tmsauto.com/wp-content/uploads/3-thumbs-up.jpg)<br>"},"ef04ea02-aed6-4295-9117-2dcc45506f3a":{"id":"ef04ea02-aed6-4295-9117-2dcc45506f3a","created":1674494561538,"type":"text","content":"**Changelog**"},"255bfdfc-9260-4cb1-9dcd-15f2c9eca2b2":{"id":"255bfdfc-9260-4cb1-9dcd-15f2c9eca2b2","created":1674494572205,"type":"text","content":"**2023-01-23 - Initial Release**<br>"},"40b53a6f-0f43-40c2-b6d3-486982fc9d48":{"id":"40b53a6f-0f43-40c2-b6d3-486982fc9d48","created":1674494588998,"type":"text","content":"The outliner supports all standard outliner functionality<br>"},"850bac59-c64f-4884-a24c-a10cad6b38c2":{"id":"850bac59-c64f-4884-a24c-a10cad6b38c2","created":1674494607269,"type":"text","content":"---"},"cccd8044-92b6-4e89-887c-2f979f4e0cab":{"id":"cccd8044-92b6-4e89-887c-2f979f4e0cab","created":1674494607378,"type":"text","content":"---"},"724d0e33-fe2c-459e-9e75-e3311809ba36":{"id":"724d0e33-fe2c-459e-9e75-e3311809ba36","created":1674496047585,"type":"text","content":"Ability to create/remove nodes at the same level or as children of the selected node<br>"},"588a65fd-69dd-4bb4-a819-f8c7f05a1d69":{"id":"588a65fd-69dd-4bb4-a819-f8c7f05a1d69","created":1674496066859,"type":"text","content":"Ability to move nodes up and down within the same level<br>"},"13ea01fb-339d-4e65-9fad-123d72830efb":{"id":"13ea01fb-339d-4e65-9fad-123d72830efb","created":1674496078557,"type":"text","content":"Ability to lift/lower nodes in the hierarchy<br>"},"80b86062-a197-4adf-baa4-56a5953e0a77":{"id":"80b86062-a197-4adf-baa4-56a5953e0a77","created":1674496103163,"type":"text","content":"**Known Issues**<br>"},"c09a5876-f825-4cb0-9a56-2916e28f9d02":{"id":"c09a5876-f825-4cb0-9a56-2916e28f9d02","created":1674496115316,"type":"text","content":"The `findNodeInTree` method seems to jump through the list multiple times and needs to be properly terminated. There\'s a hack in place right now that stops it from triggering the handler multiple times, but it would be good to get that fixed<br>"},"a941538b-6834-4a65-b297-50036b89a41f":{"id":"a941538b-6834-4a65-b297-50036b89a41f","created":1674496226731,"type":"text","content":"Ability to fold/unfold nodes to hide/display nested content<br>"},"6b457d6b-0228-41b7-bbba-6c0ba3b54f4d":{"id":"6b457d6b-0228-41b7-bbba-6c0ba3b54f4d","created":1674499489509,"type":"text","content":"**What is an outliner?**<br>"},"2ab706de-fea9-42a0-a900-e88b2950ceb3":{"id":"2ab706de-fea9-42a0-a900-e88b2950ceb3","created":1674504320041,"type":"text","content":"**Features**<br>"},"27c14755-ff26-4931-a676-b48cd958b781":{"id":"27c14755-ff26-4931-a676-b48cd958b781","created":1674504328945,"type":"text","content":"- [x] A simple keyboard-navigated outliner where each node supports Markdown<br>"},"116f8e0f-ab62-450f-914e-5ca0956a457f":{"id":"116f8e0f-ab62-450f-914e-5ca0956a457f","created":1674504343967,"type":"text","content":"This is probably the single biggest difference from other outliners - and it really is a simple change. The text nodes are all markdown - so by default it supports anything that would render via [marked.js](https://marked.js.org/). <br>"},"974ebeda-2d49-4a31-9bcc-666c6b910702":{"id":"974ebeda-2d49-4a31-9bcc-666c6b910702","created":1674504414730,"type":"text","content":"Roadmap<br>"},"b00509a3-694a-4159-b9f0-fdc11e1e04e3":{"id":"b00509a3-694a-4159-b9f0-fdc11e1e04e3","created":1674504415116,"type":"text","content":"---"},"3c51e000-8bf7-469d-94e5-4480b980993c":{"id":"3c51e000-8bf7-469d-94e5-4480b980993c","created":1674504438403,"type":"text","content":"---"},"0da3090a-9a6f-4b3f-9607-0e97bd4318f5":{"id":"0da3090a-9a6f-4b3f-9607-0e97bd4318f5","created":1674504442196,"type":"text","content":"Current"},"d69efd32-fbf5-4b80-8a36-af1cb2af7b80":{"id":"d69efd32-fbf5-4b80-8a36-af1cb2af7b80","created":1674504453605,"type":"text","content":"- [ ] Search!"},"b5a55548-f65d-496a-8bea-6b6ba8296e21":{"id":"b5a55548-f65d-496a-8bea-6b6ba8296e21","created":1674504458424,"type":"text","content":"This is the most important one. The ability to fuzzy search across the entirety of the document and jump to any node possible. When I was working with Fargo + Little Outliner, I tried building extensions that would allow me to do this - but they never quite worked as I envisioned. I\'m hoping to provide a full fuzzy-text search system<br>"},"315c3870-a6c2-49b6-89b1-8c9e0a950b4c":{"id":"315c3870-a6c2-49b6-89b1-8c9e0a950b4c","created":1674504522443,"type":"text","content":"---"},"4f84fa9b-bc13-43fa-9e31-cf4a0c976d27":{"id":"4f84fa9b-bc13-43fa-9e31-cf4a0c976d27","created":1674504522958,"type":"text","content":"---"},"2f67d730-c71b-4823-a986-fa510d9408e1":{"id":"2f67d730-c71b-4823-a986-fa510d9408e1","created":1674504531115,"type":"text","content":"- [ ] Export Data<br>"},"bb64c043-b69f-49f8-bde4-9018822d929b":{"id":"bb64c043-b69f-49f8-bde4-9018822d929b","created":1674504546666,"type":"text","content":"Being able to \\"publish\\" a node and <br>"},"40194ea5-9c28-4adb-bffe-4f59e7eca666":{"id":"40194ea5-9c28-4adb-bffe-4f59e7eca666","created":1674504558701,"type":"text","content":"Being able to export the data to OPML at any point will go a long way to ensuring that the tool never locks me in if I decide to leave<br>"},"82956c9c-33d1-44e1-aca7-298cdfc4c72c":{"id":"82956c9c-33d1-44e1-aca7-298cdfc4c72c","created":1674504834120,"type":"text","content":"---"},"a1f74891-c98b-4fc2-a7ce-c18b2ad2b8d0":{"id":"a1f74891-c98b-4fc2-a7ce-c18b2ad2b8d0","created":1674504838755,"type":"text","content":"---"},"e1e60a99-74da-436c-b140-ce8c10832889":{"id":"e1e60a99-74da-436c-b140-ce8c10832889","created":1674504891810,"type":"text","content":"---"},"de5fd362-402e-4769-8429-9fecab882da0":{"id":"de5fd362-402e-4769-8429-9fecab882da0","created":1674504894934,"type":"text","content":"---"},"de9ca950-e7c0-4f10-b65e-a5cf9000a618":{"id":"de9ca950-e7c0-4f10-b65e-a5cf9000a618","created":1674504899904,"type":"text","content":"---"},"8f1a787f-01b5-4b72-8308-8a3fe0a96383":{"id":"8f1a787f-01b5-4b72-8308-8a3fe0a96383","created":1674504923176,"type":"text","content":"eys"}}}');
23049
23050 /***/ })
23051
23052 /******/        });
23053 /************************************************************************/
23054 /******/        // The module cache
23055 /******/        var __webpack_module_cache__ = {};
23056 /******/        
23057 /******/        // The require function
23058 /******/        function __webpack_require__(moduleId) {
23059 /******/                // Check if module is in cache
23060 /******/                var cachedModule = __webpack_module_cache__[moduleId];
23061 /******/                if (cachedModule !== undefined) {
23062 /******/                        return cachedModule.exports;
23063 /******/                }
23064 /******/                // Create a new module (and put it into the cache)
23065 /******/                var module = __webpack_module_cache__[moduleId] = {
23066 /******/                        id: moduleId,
23067 /******/                        loaded: false,
23068 /******/                        exports: {}
23069 /******/                };
23070 /******/        
23071 /******/                // Execute the module function
23072 /******/                __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
23073 /******/        
23074 /******/                // Flag the module as loaded
23075 /******/                module.loaded = true;
23076 /******/        
23077 /******/                // Return the exports of the module
23078 /******/                return module.exports;
23079 /******/        }
23080 /******/        
23081 /******/        // expose the modules object (__webpack_modules__)
23082 /******/        __webpack_require__.m = __webpack_modules__;
23083 /******/        
23084 /************************************************************************/
23085 /******/        /* webpack/runtime/define property getters */
23086 /******/        (() => {
23087 /******/                // define getter functions for harmony exports
23088 /******/                __webpack_require__.d = (exports, definition) => {
23089 /******/                        for(var key in definition) {
23090 /******/                                if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
23091 /******/                                        Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
23092 /******/                                }
23093 /******/                        }
23094 /******/                };
23095 /******/        })();
23096 /******/        
23097 /******/        /* webpack/runtime/ensure chunk */
23098 /******/        (() => {
23099 /******/                __webpack_require__.f = {};
23100 /******/                // This file contains only the entry chunk.
23101 /******/                // The chunk loading function for additional chunks
23102 /******/                __webpack_require__.e = (chunkId) => {
23103 /******/                        return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
23104 /******/                                __webpack_require__.f[key](chunkId, promises);
23105 /******/                                return promises;
23106 /******/                        }, []));
23107 /******/                };
23108 /******/        })();
23109 /******/        
23110 /******/        /* webpack/runtime/get javascript chunk filename */
23111 /******/        (() => {
23112 /******/                // This function allow to reference async chunks
23113 /******/                __webpack_require__.u = (chunkId) => {
23114 /******/                        // return url for filenames based on template
23115 /******/                        return "" + chunkId + ".bundle.js";
23116 /******/                };
23117 /******/        })();
23118 /******/        
23119 /******/        /* webpack/runtime/global */
23120 /******/        (() => {
23121 /******/                __webpack_require__.g = (function() {
23122 /******/                        if (typeof globalThis === 'object') return globalThis;
23123 /******/                        try {
23124 /******/                                return this || new Function('return this')();
23125 /******/                        } catch (e) {
23126 /******/                                if (typeof window === 'object') return window;
23127 /******/                        }
23128 /******/                })();
23129 /******/        })();
23130 /******/        
23131 /******/        /* webpack/runtime/hasOwnProperty shorthand */
23132 /******/        (() => {
23133 /******/                __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
23134 /******/        })();
23135 /******/        
23136 /******/        /* webpack/runtime/load script */
23137 /******/        (() => {
23138 /******/                var inProgress = {};
23139 /******/                var dataWebpackPrefix = "outline-browser:";
23140 /******/                // loadScript function to load a script via script tag
23141 /******/                __webpack_require__.l = (url, done, key, chunkId) => {
23142 /******/                        if(inProgress[url]) { inProgress[url].push(done); return; }
23143 /******/                        var script, needAttach;
23144 /******/                        if(key !== undefined) {
23145 /******/                                var scripts = document.getElementsByTagName("script");
23146 /******/                                for(var i = 0; i < scripts.length; i++) {
23147 /******/                                        var s = scripts[i];
23148 /******/                                        if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; }
23149 /******/                                }
23150 /******/                        }
23151 /******/                        if(!script) {
23152 /******/                                needAttach = true;
23153 /******/                                script = document.createElement('script');
23154 /******/                
23155 /******/                                script.charset = 'utf-8';
23156 /******/                                script.timeout = 120;
23157 /******/                                if (__webpack_require__.nc) {
23158 /******/                                        script.setAttribute("nonce", __webpack_require__.nc);
23159 /******/                                }
23160 /******/                                script.setAttribute("data-webpack", dataWebpackPrefix + key);
23161 /******/                                script.src = url;
23162 /******/                        }
23163 /******/                        inProgress[url] = [done];
23164 /******/                        var onScriptComplete = (prev, event) => {
23165 /******/                                // avoid mem leaks in IE.
23166 /******/                                script.onerror = script.onload = null;
23167 /******/                                clearTimeout(timeout);
23168 /******/                                var doneFns = inProgress[url];
23169 /******/                                delete inProgress[url];
23170 /******/                                script.parentNode && script.parentNode.removeChild(script);
23171 /******/                                doneFns && doneFns.forEach((fn) => (fn(event)));
23172 /******/                                if(prev) return prev(event);
23173 /******/                        };
23174 /******/                        var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
23175 /******/                        script.onerror = onScriptComplete.bind(null, script.onerror);
23176 /******/                        script.onload = onScriptComplete.bind(null, script.onload);
23177 /******/                        needAttach && document.head.appendChild(script);
23178 /******/                };
23179 /******/        })();
23180 /******/        
23181 /******/        /* webpack/runtime/make namespace object */
23182 /******/        (() => {
23183 /******/                // define __esModule on exports
23184 /******/                __webpack_require__.r = (exports) => {
23185 /******/                        if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
23186 /******/                                Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
23187 /******/                        }
23188 /******/                        Object.defineProperty(exports, '__esModule', { value: true });
23189 /******/                };
23190 /******/        })();
23191 /******/        
23192 /******/        /* webpack/runtime/node module decorator */
23193 /******/        (() => {
23194 /******/                __webpack_require__.nmd = (module) => {
23195 /******/                        module.paths = [];
23196 /******/                        if (!module.children) module.children = [];
23197 /******/                        return module;
23198 /******/                };
23199 /******/        })();
23200 /******/        
23201 /******/        /* webpack/runtime/publicPath */
23202 /******/        (() => {
23203 /******/                var scriptUrl;
23204 /******/                if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
23205 /******/                var document = __webpack_require__.g.document;
23206 /******/                if (!scriptUrl && document) {
23207 /******/                        if (document.currentScript)
23208 /******/                                scriptUrl = document.currentScript.src
23209 /******/                        if (!scriptUrl) {
23210 /******/                                var scripts = document.getElementsByTagName("script");
23211 /******/                                if(scripts.length) scriptUrl = scripts[scripts.length - 1].src
23212 /******/                        }
23213 /******/                }
23214 /******/                // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
23215 /******/                // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
23216 /******/                if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
23217 /******/                scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
23218 /******/                __webpack_require__.p = scriptUrl;
23219 /******/        })();
23220 /******/        
23221 /******/        /* webpack/runtime/jsonp chunk loading */
23222 /******/        (() => {
23223 /******/                // no baseURI
23224 /******/                
23225 /******/                // object to store loaded and loading chunks
23226 /******/                // undefined = chunk not loaded, null = chunk preloaded/prefetched
23227 /******/                // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
23228 /******/                var installedChunks = {
23229 /******/                        "main": 0
23230 /******/                };
23231 /******/                
23232 /******/                __webpack_require__.f.j = (chunkId, promises) => {
23233 /******/                                // JSONP chunk loading for javascript
23234 /******/                                var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
23235 /******/                                if(installedChunkData !== 0) { // 0 means "already installed".
23236 /******/                
23237 /******/                                        // a Promise means "currently loading".
23238 /******/                                        if(installedChunkData) {
23239 /******/                                                promises.push(installedChunkData[2]);
23240 /******/                                        } else {
23241 /******/                                                if(true) { // all chunks have JS
23242 /******/                                                        // setup Promise in chunk cache
23243 /******/                                                        var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
23244 /******/                                                        promises.push(installedChunkData[2] = promise);
23245 /******/                
23246 /******/                                                        // start chunk loading
23247 /******/                                                        var url = __webpack_require__.p + __webpack_require__.u(chunkId);
23248 /******/                                                        // create error before stack unwound to get useful stacktrace later
23249 /******/                                                        var error = new Error();
23250 /******/                                                        var loadingEnded = (event) => {
23251 /******/                                                                if(__webpack_require__.o(installedChunks, chunkId)) {
23252 /******/                                                                        installedChunkData = installedChunks[chunkId];
23253 /******/                                                                        if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
23254 /******/                                                                        if(installedChunkData) {
23255 /******/                                                                                var errorType = event && (event.type === 'load' ? 'missing' : event.type);
23256 /******/                                                                                var realSrc = event && event.target && event.target.src;
23257 /******/                                                                                error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
23258 /******/                                                                                error.name = 'ChunkLoadError';
23259 /******/                                                                                error.type = errorType;
23260 /******/                                                                                error.request = realSrc;
23261 /******/                                                                                installedChunkData[1](error);
23262 /******/                                                                        }
23263 /******/                                                                }
23264 /******/                                                        };
23265 /******/                                                        __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
23266 /******/                                                } else installedChunks[chunkId] = 0;
23267 /******/                                        }
23268 /******/                                }
23269 /******/                };
23270 /******/                
23271 /******/                // no prefetching
23272 /******/                
23273 /******/                // no preloaded
23274 /******/                
23275 /******/                // no HMR
23276 /******/                
23277 /******/                // no HMR manifest
23278 /******/                
23279 /******/                // no on chunks loaded
23280 /******/                
23281 /******/                // install a JSONP callback for chunk loading
23282 /******/                var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
23283 /******/                        var [chunkIds, moreModules, runtime] = data;
23284 /******/                        // add "moreModules" to the modules object,
23285 /******/                        // then flag all "chunkIds" as loaded and fire callback
23286 /******/                        var moduleId, chunkId, i = 0;
23287 /******/                        if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
23288 /******/                                for(moduleId in moreModules) {
23289 /******/                                        if(__webpack_require__.o(moreModules, moduleId)) {
23290 /******/                                                __webpack_require__.m[moduleId] = moreModules[moduleId];
23291 /******/                                        }
23292 /******/                                }
23293 /******/                                if(runtime) var result = runtime(__webpack_require__);
23294 /******/                        }
23295 /******/                        if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
23296 /******/                        for(;i < chunkIds.length; i++) {
23297 /******/                                chunkId = chunkIds[i];
23298 /******/                                if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
23299 /******/                                        installedChunks[chunkId][0]();
23300 /******/                                }
23301 /******/                                installedChunks[chunkId] = 0;
23302 /******/                        }
23303 /******/                
23304 /******/                }
23305 /******/                
23306 /******/                var chunkLoadingGlobal = self["webpackChunkoutline_browser"] = self["webpackChunkoutline_browser"] || [];
23307 /******/                chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
23308 /******/                chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
23309 /******/        })();
23310 /******/        
23311 /************************************************************************/
23312 /******/        
23313 /******/        // startup
23314 /******/        // Load entry module and return exports
23315 /******/        // This entry module is referenced by other modules so it can't be inlined
23316 /******/        var __webpack_exports__ = __webpack_require__("./src/client.ts");
23317 /******/        
23318 /******/ })()
23319 ;
23320 //# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQix3QkFBd0I7QUFDbEQ7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHlCQUF5Qiw2QkFBNkI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEVBQTBFLHFCQUFNLG1CQUFtQixxQkFBTTs7QUFFekc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLFVBQVU7OztBQUdWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQSwwQkFBMEIsNkJBQTZCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsNEJBQTRCLHNCQUFzQjtBQUNsRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCLCtCQUErQjtBQUM5RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdCQUF3QiwyQkFBMkI7QUFDbkQ7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7O0FBRUEsd0JBQXdCLG1DQUFtQztBQUMzRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1EOztBQUVuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkM7O0FBRTNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlEOztBQUVqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDOztBQUV0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJFQUEyRTtBQUMzRSw2RUFBNkU7QUFDN0U7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07OztBQUdOLDJCQUEyQixlQUFlO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNOzs7QUFHTjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQSx5REFBeUQ7QUFDekQ7QUFDQTtBQUNBO0FBQ0EsK0lBQStJOztBQUUvSTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQztBQUNELDJDQUEyQyxjQUFjOzs7Ozs7Ozs7Ozs7QUNsa0N6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJDQUEyQztBQUMzQztBQUNBLDJEQUEyRDs7QUFFM0Q7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyw0QkFBNEI7QUFDOUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCO0FBQ0EsUUFBUTtBQUNSLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1FQUFtRTtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLEdBQUc7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLEdBQUc7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsR0FBRztBQUNwQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixHQUFHO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFD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QTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsT0FBTztBQUN0QixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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Q0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFVBQVU7QUFDekIsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7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QTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVEsV0FBVztBQUNsQyxlQUFlLFNBQVM7QUFDeEI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQSxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLG1EQUFtRCxpQkFBaUI7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsTUFBTTtBQUNyQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxNQUFNO0FBQ3JCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsMEJBQTBCO0FBQ3pDO0FBQ0EsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsZUFBZSxNQUFNO0FBQ3JCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLE1BQU07QUFDckIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLHNCQUFzQjtBQUNyQyxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUSxXQUFXO0FBQ2xDLGVBQWUsU0FBUztBQUN4QjtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCxtQkFBbUI7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLHFDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLFFBQVE7QUFDN0IsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsR0FBRztBQUNwQjtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUSxJQUFJLFFBQVE7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsR0FBRztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsR0FBRztBQUNwQjtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUSxJQUFJLFFBQVE7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLEdBQUc7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBLDhCQUE4QixtQkFBbUIsaUJBQWlCO0FBQ2xFO0FBQ0E7QUFDQSw4QkFBOEIsbUJBQW1CLGlCQUFpQjtBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QixxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLG1CQUFtQjtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELG1CQUFtQjtBQUN0RTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtB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QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFNBQVM7QUFDeEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDLEtBQUs7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsZUFBZTtBQUM5QixlQUFlLGlCQUFpQjtBQUNoQyxpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxlQUFlO0FBQzlCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVEsV0FBVztBQUNsQyxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixnQkFBZ0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7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QTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBLHdCQUF3QixRQUFRLElBQUksUUFBUSxJQUFJLFFBQVEsSUFBSSxRQUFRO0FBQ3BFO0FBQ0Esc0NBQXNDLGFBQWE7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxLQUFLLE9BQU8sZ0JBQWdCOztBQUU1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQywyREFBMkQ7QUFDL0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHdDQUF3QztBQUN0RTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNLElBQTBFO0FBQ2hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUksbUNBQU87QUFDWDtBQUNBLEtBQUs7QUFBQSxrR0FBQztBQUNOO0FBQ0E7QUFDQSxPQUFPLEVBU0o7QUFDSCxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDeHpoQkQsMkVBQWdEO0FBQ2hELHdFQUFrQztBQUNsQywwSEFBb0M7QUFDcEMscUdBQStDO0FBQy9DLGdFQUE4QjtBQUM5Qix3RUFBa0M7QUFFbEMsSUFBSSxXQUFXLEdBQUcsVUFBVSxDQUFDO0FBQzdCLElBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRTtJQUN4QyxNQUFNLFNBQVMsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3hELFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztDQUMzRDtBQUVELE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxFQUFlLENBQUM7QUFDckMsTUFBTSxPQUFPLEdBQUcsSUFBSSxpQkFBTyxDQUFDLFdBQW9DLENBQUMsQ0FBQztBQUNsRSxRQUFRLEVBQUUsQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBRXhDLE1BQU0sTUFBTSxHQUFHLElBQUksZUFBTSxFQUFFLENBQUM7QUFFNUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUVwQixNQUFNLE1BQU0sR0FBRyxJQUFJLGVBQU0sRUFBRSxDQUFDO0FBRTVCLFNBQVMsUUFBUTtJQUNmLE9BQU8sUUFBUSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUM3QyxDQUFDO0FBRUQsUUFBUSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUU7SUFDcEUsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ25CLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUVwQixtQkFBUSxHQUFFLENBQUM7QUFDYixDQUFDLENBQUMsQ0FBQztBQUdILG9CQUFVLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUU7SUFDeEMsb0JBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO1FBR3ZCLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQztRQUVoRCxJQUFHLE9BQU8sRUFBRTtZQUNWLElBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRTtnQkFFYixNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7Z0JBQ2xFLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUVoRCxJQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxLQUFLLFFBQVEsRUFBRTtvQkFDakMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2lCQUM3QztxQkFDSTtvQkFDSCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7aUJBQzdDO2dCQUVELE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksRUFBRSxDQUFDO2FBQ1I7aUJBQ0k7Z0JBQ0gsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3REO1NBQ0Y7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUdILG9CQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsRUFBRTtRQUMvQixtQkFBUSxHQUFFLENBQUM7SUFDYixDQUFDLENBQUMsQ0FBQztJQUVILG9CQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtRQUd2QixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsc0JBQXNCLENBQUM7UUFFcEQsSUFBRyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRTtZQUN4RCxJQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUU7Z0JBRWIsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO2dCQUV0RSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFFaEQsSUFBRyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxRQUFRLEVBQUU7b0JBQ2pDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztpQkFDN0M7cUJBQ0k7b0JBQ0gsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2lCQUM3QztnQkFFRCxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLEVBQUUsQ0FBQzthQUNSO2lCQUNJO2dCQUNILE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxPQUFPLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUN0RDtTQUNGO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxvQkFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7UUFFdkIsSUFBRyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFDM0IsT0FBTztTQUNSO1FBQ0QsSUFBRyxDQUFDLENBQUMsUUFBUSxFQUFFO1lBQ2IsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQzNELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBRW5ELElBQUcsR0FBRyxDQUFDLGFBQWEsQ0FBQyxFQUFFLEtBQUssUUFBUSxFQUFFO2dCQUNwQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7YUFDN0M7aUJBQ0k7Z0JBQ0gsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2FBQzdDO1lBQ0QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztTQUN4QzthQUNJO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyRCxJQUFHLFFBQVEsRUFBRTtnQkFDWCxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sUUFBUSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDdkQ7U0FDRjtJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsb0JBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO1FBQ3ZCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUM7UUFDMUMsSUFBRyxNQUFNLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDOUMsSUFBRyxDQUFDLENBQUMsUUFBUSxFQUFFO2dCQUNiLElBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUU7b0JBRTNFLE9BQU87aUJBQ1I7Z0JBQ0QsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO2dCQUUzRCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFFaEQsSUFBRyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxRQUFRLEVBQUU7b0JBQ2pDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7aUJBQzNEO3FCQUNJO29CQUNILE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7aUJBQzNEO2dCQUVELE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksRUFBRSxDQUFDO2FBQ1I7aUJBQ0k7Z0JBQ0gsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLE1BQU0sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3JEO1NBQ0Y7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILG9CQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtRQUV2QixJQUFHLE1BQU0sQ0FBQyxjQUFjLEVBQUUsRUFBRTtZQUMxQixNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEIsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztTQUNwQzthQUNJLElBQUcsTUFBTSxDQUFDLGVBQWUsRUFBRSxFQUFFO1lBQ2hDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQixPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1NBQ3RDO1FBQ0QsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLENBQUMsQ0FBQztJQUVILG9CQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsRUFBRTtRQUMvQixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7UUFFbkIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDNUMsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQWdCLENBQUM7UUFHOUUsV0FBVyxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDaEYsV0FBVyxDQUFDLGVBQWUsR0FBRyxNQUFNLENBQUM7UUFFckMsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3JDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN0QyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRCLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN4QyxTQUFTLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDNUIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUUxQixXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDcEIsb0JBQVUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxvQkFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7UUFDdkIsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBRW5CLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFnQixDQUFDO1FBRzlFLFdBQVcsQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDO1FBQ2hGLFdBQVcsQ0FBQyxlQUFlLEdBQUcsTUFBTSxDQUFDO1FBQ3JDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNwQixvQkFBVSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNuQyxDQUFDLENBQUMsQ0FBQztJQUVILG9CQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsRUFBRTtRQUMvQixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7UUFFbkIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDL0MsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2pILElBQUksRUFBRSxDQUFDO0lBQ1QsQ0FBQyxDQUFDLENBQUM7SUFFSCxvQkFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUU7UUFDekIsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBRW5CLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDMUQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFaEQsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFFOUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQyxJQUFJLEVBQUUsQ0FBQztJQUNULENBQUMsQ0FBQyxDQUFDO0lBRUgsb0JBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFO1FBRTNCLElBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRTtZQUNiLE9BQU87U0FDUjtRQUNELENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNuQixDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFbEIsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBRTVELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2hELElBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEtBQUssUUFBUSxFQUFFO1lBQ2pDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztTQUM3QzthQUNJO1lBQ0gsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1NBQzdDO1FBRUQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQyxJQUFJLEVBQUUsQ0FBQztJQUNULENBQUMsQ0FBQyxDQUFDO0lBRUgsb0JBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFO1FBRXZCLElBQUcsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO1lBQ2QsT0FBTztTQUNSO1FBRUQsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNyRCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUVoRCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsc0JBQXNCLENBQUM7UUFDeEQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFDO1FBQ3BELElBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEtBQUssUUFBUSxFQUFFO1lBQ2pDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztTQUM3QzthQUNJO1lBQ0gsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1NBQzdDO1FBRUQsSUFBRyxXQUFXLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQ3RDLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxXQUFXLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUMxRDthQUNJLElBQUcsV0FBVyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUMzQyxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sV0FBVyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDMUQ7YUFDSTtZQUNILE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMvQixNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQ3hDO1FBRUQsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsb0JBQVUsQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtJQUNyQyxvQkFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRTtRQUNwQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUUvQyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBZ0IsQ0FBQztRQUU5RSxXQUFXLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQztRQUN0QyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbkIsb0JBQVUsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFcEMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLEVBQUUsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRTFFLFdBQVcsQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNwRSxJQUFJLEVBQUUsQ0FBQztJQUNULENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUM7QUFFSCxvQkFBVSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUVwQyxNQUFNLENBQUMsV0FBVyxDQUFDO0lBQ2pCLEVBQUUsRUFBRSxRQUFRO0lBQ1osT0FBTyxFQUFFLFFBQVE7SUFDakIsSUFBSSxFQUFFLFFBQVE7SUFDZCxPQUFPLEVBQUUsUUFBUTtJQUNqQixhQUFhLEVBQUUsU0FBUztDQUN6QixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQVMsRUFBRTtJQUNqQixNQUFNLE1BQU0sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNuRCxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7QUFDdEIsQ0FBQyxFQUFDLENBQUM7QUFFSCxTQUFTLGlCQUFpQixDQUFDLEtBQWtCO0lBQzNDLElBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDbkMsSUFBRyxLQUFLLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUN4QyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNwQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNoQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztTQUMvQztRQUVELElBQUcsS0FBSyxDQUFDLGFBQWEsRUFBRTtZQUN0QixpQkFBaUIsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDO1NBQ3ZDO0tBQ0Y7QUFDSCxDQUFDO0FBRUQsTUFBTSxDQUFDLGVBQWUsR0FBRyxDQUFDLEtBQWEsRUFBRSxFQUFFO0lBSXpDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxLQUFLLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3hFLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBRTNCLElBQUksRUFBRSxDQUFDO0FBQ1QsQ0FBQyxDQUFDO0FBRUYsU0FBUyxhQUFhO0lBQ3BCLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNwRSxZQUFZLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZELE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0QyxLQUFLLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQzlCLENBQUM7QUFFRCxTQUFTLElBQUk7SUFDWCxJQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBRTtRQUM1QixLQUFLLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7S0FDM0Q7QUFDSCxDQUFDO0FBR0QsSUFBSSxFQUFFLENBQUM7Ozs7Ozs7Ozs7Ozs7OztBQ3BWUCw2REFBOEI7QUFFOUIsTUFBYSxNQUFNO0lBQ2pCO0lBRUEsQ0FBQztJQUVELEdBQUc7UUFDRCxPQUFPLFFBQVEsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVELFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELEtBQUs7UUFDSCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBRyxFQUFFLEVBQUU7WUFDTCxFQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUMvQjtJQUNILENBQUM7SUFFRCxHQUFHLENBQUMsU0FBaUI7UUFDbkIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2IsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQWdCLENBQUM7UUFFNUQsSUFBRyxFQUFFLEVBQUU7WUFDTCxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMzQixJQUFHLENBQUMsbUJBQVMsRUFBQyxFQUFFLENBQUMsRUFBRTtnQkFDakIsRUFBRSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUN6QjtTQUNGO0lBQ0gsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxlQUFlO1FBQ2IsT0FBTyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsY0FBYztRQUNaLE9BQU8sSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbkQsQ0FBQztDQUNGO0FBakRELHdCQWlEQzs7Ozs7Ozs7Ozs7Ozs7O0FDbkRELFNBQWdCLFNBQVMsQ0FBQyxPQUFvQjtJQUMxQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUM3QyxPQUFPLENBQ0gsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ2IsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDO1FBQ2QsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLElBQUksUUFBUSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUM7UUFDekUsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLElBQUksUUFBUSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FDNUUsQ0FBQztBQUNOLENBQUM7QUFSRCw4QkFRQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDUkQsMEhBQW9DO0FBQ3BDLHNGQUE2QjtBQUU3QixNQUFNLGdCQUFnQixHQUFHO0lBQ3ZCLEdBQUcsRUFBRSwyREFBMkQ7SUFDaEUsR0FBRyxFQUFFLGdFQUFnRTtJQUNyRSxHQUFHLEVBQUUseURBQXlEO0lBQzlELEdBQUcsRUFBRSw2REFBNkQ7SUFDbEUsT0FBTyxFQUFFLGlEQUFpRDtJQUMxRCxLQUFLLEVBQUUsaURBQWlEO0lBQ3hELFdBQVcsRUFBRSw4Q0FBOEM7SUFDM0QsV0FBVyxFQUFFLHNEQUFzRDtJQUNuRSxXQUFXLEVBQUUsMERBQTBEO0lBQ3ZFLFdBQVcsRUFBRSxtRUFBbUU7SUFDaEYsV0FBVyxFQUFFLHlCQUF5QjtJQUN0QyxXQUFXLEVBQUUsdUJBQXVCO0lBQ3BDLEdBQUcsRUFBRSw4RUFBOEU7SUFDbkYsR0FBRyxFQUFFLDRFQUE0RTtJQUNqRixRQUFRLEVBQUUsdURBQXVEO0lBQ2pFLEdBQUcsRUFBRSw0QkFBNEI7Q0FDbEMsQ0FBQztBQUVGLE1BQU0sU0FBUyxHQUFHOzs7Ozs7Ozs7Ozs7TUFZWixnQkFBRyxFQUFDLGdCQUFnQixFQUFFLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxFQUFFO0lBQ3BDLE9BQU87OztpQkFHSSxHQUFHOzs7WUFHUixJQUFJOzs7T0FHVDtBQUNILENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Ozs7O0NBS2hCO0FBRUQsU0FBZ0IsUUFBUTtJQUN0QixRQUFRLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsSUFBSSxTQUFTLENBQUM7SUFDdEQsb0JBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDaEMsQ0FBQztBQUhELDRCQUdDO0FBRUQsb0JBQVUsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRTtJQUNsQyxvQkFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLEVBQUU7UUFDNUIsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUMxQyxvQkFBVSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzlESCw2RkFBNEI7QUFDNUIscUdBQWtDO0FBQ2xDLDJGQUFnQztBQXNCL0IsQ0FBQztBQUVGLE1BQWEsT0FBTztJQUdsQixZQUFZLFdBQXVCO1FBQ2pDLElBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDO0lBQzFCLENBQUM7SUFFRCxjQUFjLENBQUMsSUFBaUIsRUFBRSxFQUFVLEVBQUUsTUFBd0QsRUFBRSxXQUFvQixLQUFLO1FBQy9ILElBQUksR0FBRyxHQUFHLFFBQVEsQ0FBQztRQUNuQixJQUFHLEdBQUcsRUFBRTtZQUNOLE9BQU87U0FDUjtRQUNELENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUN2QyxJQUFHLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFO2dCQUN0QixNQUFNLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUN4QixHQUFHLEdBQUcsSUFBSSxDQUFDO2dCQUNYLE9BQU8sS0FBSyxDQUFDO2FBQ2Q7aUJBQ0ksSUFBRyxTQUFTLENBQUMsUUFBUSxFQUFFO2dCQUMxQixJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO2FBQ2pEO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsSUFBSSxDQUFDLE1BQWM7UUFDakIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDakQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDeEIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsTUFBTSxDQUFDLE1BQWM7UUFDbkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDakQsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDekIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsMEJBQTBCLENBQUMsSUFBaUI7UUFDMUMsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsTUFBYztRQUM3QixJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUM7UUFDaEIsSUFBSSxVQUF1QixFQUFFLFVBQXVCLENBQUM7UUFDckQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDM0QsVUFBVSxHQUFHLEtBQUssQ0FBQztZQUNuQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxhQUFhLEVBQUUsRUFBRTtnQkFBRSxDQUFDO2dCQUNuRixJQUFHLEdBQUcsRUFBRTtvQkFDTixPQUFPO2lCQUNSO2dCQUNELFVBQVUsR0FBRyxhQUFhLENBQUM7Z0JBQzNCLEdBQUcsR0FBRyxJQUFJLENBQUM7Z0JBRVgsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBRXJELE1BQU0sb0JBQW9CLEdBQUcsa0JBQWtCLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUMvRixNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUU5RCxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUU1RCxhQUFhLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUN0RSxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTztZQUNMLFVBQVU7WUFDVixVQUFVO1NBQ1g7SUFDSCxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsTUFBYztRQUM3QixJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUM7UUFHaEIsSUFBSSxVQUF1QixFQUFFLGFBQTBCLEVBQUUsYUFBMEIsQ0FBQztRQUNwRixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUMzRCxJQUFHLEdBQUcsRUFBRTtnQkFDTixPQUFPO2FBQ1I7WUFDRCxHQUFHLEdBQUksSUFBSSxDQUFDO1lBQ1osVUFBVSxHQUFHLEtBQUssQ0FBQztZQUVuQixJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUUzQyxJQUFHLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUN0QixPQUFPO2FBQ1I7WUFFRCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMvQyxNQUFNLG1CQUFtQixHQUFHLFFBQVEsR0FBRyxDQUFDLENBQUM7WUFFekMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUN0RSxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFbkMsYUFBYSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsQ0FBQztZQUNwRCxhQUFhLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTztZQUNMLFVBQVU7WUFDVixhQUFhO1lBQ2IsYUFBYTtTQUNkO0lBQ0gsQ0FBQztJQUVELHVCQUF1QixDQUFDLE1BQWM7UUFDcEMsSUFBSSxVQUF1QixFQUFFLFVBQXVCLENBQUM7UUFDckQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDekQsVUFBVSxHQUFHLEtBQUssQ0FBQztZQUNuQixVQUFVLEdBQUcsS0FBSyxDQUFDO1lBQ25CLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2xELE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBRW5ELElBQUcsWUFBWSxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRTtnQkFFdkMsT0FBTzthQUNSO1lBR0QsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzVDLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFlBQVksR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2hFLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTztZQUNMLFVBQVU7WUFDVixVQUFVO1NBQ1g7SUFDSCxDQUFDO0lBRUQsMkJBQTJCLENBQUMsTUFBYztRQUN4QyxJQUFJLFVBQXVCLEVBQUUsVUFBdUIsQ0FBQztRQUNyRCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUN6RCxVQUFVLEdBQUcsS0FBSyxDQUFDO1lBQ25CLFVBQVUsR0FBRyxLQUFLLENBQUM7WUFDbkIsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDbEQsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFbkQsSUFBRyxZQUFZLEtBQUssQ0FBQyxFQUFFO2dCQUVyQixPQUFPO2FBQ1I7WUFHRCxVQUFVLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDNUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsWUFBWSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPO1lBQ0wsVUFBVTtZQUNWLFVBQVU7U0FDWDtJQUNILENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxVQUFrQixFQUFFLFFBQXNCO1FBQzFELE1BQU0sV0FBVyxHQUFnQixRQUFRLElBQUk7WUFDM0MsRUFBRSxFQUFFLGFBQUksR0FBRTtZQUNWLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ25CLElBQUksRUFBRSxNQUFNO1lBQ1osT0FBTyxFQUFFLEtBQUs7WUFDZCxhQUFhLEVBQUUsS0FBSztTQUNyQixDQUFDO1FBRUYsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQztRQUVyRCxJQUFJLFVBQXVCLENBQUM7UUFFNUIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDL0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BFLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFO2dCQUN0QyxFQUFFLEVBQUUsV0FBVyxDQUFDLEVBQUU7Z0JBQ2xCLFNBQVMsRUFBRSxLQUFLO2dCQUNoQixRQUFRLEVBQUUsRUFBRTthQUNiLENBQUMsQ0FBQztZQUVILFVBQVUsR0FBRyxNQUFNLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPO1lBQ0wsSUFBSSxFQUFFLFdBQVc7WUFDakIsVUFBVTtTQUNYO0lBQ0gsQ0FBQztJQUVELGVBQWUsQ0FBQyxXQUFtQixFQUFFLE1BQWU7UUFDbEQsTUFBTSxJQUFJLEdBQWdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNuRTtnQkFDRSxFQUFFLEVBQUUsYUFBSSxHQUFFO2dCQUNWLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUNuQixJQUFJLEVBQUUsTUFBTTtnQkFDWixPQUFPLEVBQUUsS0FBSztnQkFDZCxhQUFhLEVBQUUsS0FBSzthQUNyQixDQUFDO1FBRUYsSUFBRyxDQUFDLE1BQU0sRUFBRTtZQUNWLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7U0FDeEM7UUFFRCxJQUFJLFVBQXVCLENBQUM7UUFFNUIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ3pCLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtnQkFDWCxRQUFRLEVBQUUsRUFBRTtnQkFDWixTQUFTLEVBQUUsS0FBSzthQUNqQixDQUFDLENBQUM7WUFFSCxVQUFVLEdBQUcsU0FBUyxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTztZQUNMLElBQUk7WUFDSixVQUFVO1NBQ1g7SUFDSCxDQUFDO0lBRUQsVUFBVSxDQUFDLE1BQWM7UUFDdkIsSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDO1FBQ2hCLElBQUksV0FBd0IsRUFBRSxVQUF1QixDQUFDO1FBQ3RELElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQzNELElBQUcsR0FBRyxFQUFFO2dCQUNOLE9BQU87YUFDUjtZQUNELEdBQUcsR0FBRyxJQUFJLENBQUM7WUFDWCxXQUFXLEdBQUcsS0FBSyxDQUFDO1lBQ3BCLFVBQVUsR0FBRyxLQUFLLENBQUM7WUFFbkIsSUFBSSxRQUFRLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUVwRSxVQUFVLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPO1lBQ0wsV0FBVztZQUNYLFVBQVU7U0FDWDtJQUNILENBQUM7SUFFRCxhQUFhLENBQUMsRUFBVSxFQUFFLE9BQWU7UUFDdkMsSUFBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQzlCLE1BQU0sSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7U0FDakM7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQy9DLENBQUM7SUFFRCxhQUFhLENBQUMsTUFBYztRQUMxQixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQyxJQUFJLE9BQWUsQ0FBQztRQUNwQixRQUFPLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDaEIsS0FBSyxNQUFNO2dCQUNULE9BQU8sR0FBRyxlQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDckMsTUFBTTtZQUNSO2dCQUNFLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUN2QixNQUFNO1NBQ1Q7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsVUFBVSxDQUFDLElBQWlCO1FBQzFCLElBQUcsSUFBSSxDQUFDLEVBQUUsS0FBSyxRQUFRLEVBQUU7WUFDdkIsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDdEI7UUFDRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUMsQ0FBQyxVQUFVLENBQUM7UUFDMUQsTUFBTSxPQUFPLEdBQWdCLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSTtZQUM5RCxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDWCxPQUFPLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLEVBQUUsTUFBTTtZQUNaLE9BQU8sRUFBRSxFQUFFO1lBQ1gsYUFBYSxFQUFFLEtBQUs7U0FDckIsQ0FBQztRQUVGLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRW5FLElBQUksSUFBSSxHQUFHLG9CQUFvQixRQUFRLElBQUksYUFBYSxjQUFjLElBQUksQ0FBQyxFQUFFLFlBQVksSUFBSSxDQUFDLEVBQUU7MENBQzFELE9BQU8sQ0FBQyxJQUFJO1FBQzlDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzs7TUFFN0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtXQUNsRjtRQUVQLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE1BQU07UUFNSixPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9FLENBQUM7Q0FDRjtBQW5TRCwwQkFtU0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzdURCxpSEFBdUU7QUFDdkUsc0ZBQTZCO0FBRTdCLDBIQUFvQztBQUNwQyw2REFBOEI7QUFFOUIsTUFBTSxXQUFXLEdBQUc7Ozs7Ozs7O0NBUW5CLENBQUM7QUFFRixNQUFhLE1BQU07SUFNakI7UUFDRSxJQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsQ0FBQztJQUMxQixDQUFDO0lBRUssV0FBVyxDQUFDLE1BQTJCOztZQUMzQyxJQUFJLENBQUMsRUFBRSxHQUFHLE1BQU0saUJBQU0sRUFBQztnQkFDckIsTUFBTTthQUNQLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLENBQUM7S0FBQTtJQUVELFVBQVU7UUFDUixvQkFBVSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFO1lBQ3BDLG9CQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsRUFBRTtnQkFDNUIsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDMUMsb0JBQVUsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDdEMsQ0FBQyxDQUFDLENBQUM7WUFFSCxvQkFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUU7Z0JBQzFCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDbkIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDL0MsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO2dCQUM3RCxJQUFHLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRTtvQkFDeEIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ2hDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUNoRCxJQUFHLENBQUMsbUJBQVMsRUFBQyxFQUFFLENBQUMsa0JBQWlDLENBQUMsRUFBRTt3QkFDbkQsRUFBRSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsRUFBRSxDQUFDO3FCQUN4QztpQkFDRjtZQUNILENBQUMsQ0FBQyxDQUFDO1lBRUgsb0JBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFO2dCQUN4QixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ25CLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMseUJBQXlCLENBQUMsQ0FBQztnQkFDN0QsSUFBRyxFQUFFLENBQUMsc0JBQXNCLEVBQUU7b0JBQzVCLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUNoQyxFQUFFLENBQUMsc0JBQXNCLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDcEQsSUFBRyxDQUFDLG1CQUFTLEVBQUMsRUFBRSxDQUFDLHNCQUFxQyxDQUFDLEVBQUU7d0JBQ3ZELEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxjQUFjLEVBQUUsQ0FBQztxQkFDNUM7aUJBQ0Y7WUFDSCxDQUFDLENBQUM7WUFFRixvQkFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUU7Z0JBQzNCLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMseUJBQXlCLENBQUMsQ0FBQztnQkFDN0QsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFekMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDMUMsb0JBQVUsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBRXBDLElBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRTtvQkFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDN0I7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsb0JBQVUsQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTtZQUN4QyxvQkFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLEVBQUU7Z0JBQy9CLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDbkIsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUVwQixRQUFRLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsSUFBSSxXQUFXLENBQUM7Z0JBQ3hELE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQ25ELEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWCxFQUFFLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQzdELG9CQUFVLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2xDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsY0FBYyxDQUFDLENBQWdCO1FBQzdCLElBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNoQixhQUFhLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQzlCO1FBRUQsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQTZCLENBQUM7UUFDM0MsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUV6QyxJQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUU7WUFDZixJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQzlCLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9CLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztTQUNUO0lBQ0gsQ0FBQztJQUVLLGFBQWEsQ0FBQyxLQUFhLEVBQUUsQ0FBZ0I7O1lBQ2pELElBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFO2dCQUNkLE9BQU87YUFDUjtZQUNELE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVyQyxNQUFNLGVBQWUsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFFbEUsSUFBRyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQ3hCLGVBQWUsQ0FBQyxTQUFTLEdBQUcsOEJBQThCLENBQUM7Z0JBQzNELE9BQU87YUFDUjtZQUVELE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO2dCQUNyQyxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDaEQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBRTFDLE9BQU87aUNBQ29CLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxjQUFjLEdBQUcsQ0FBQyxFQUFFLEtBQUssT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFDLENBQUMsRUFBRTtPQUNuSSxDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7WUFFSCxlQUFlLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUMsQ0FBQztLQUFBO0lBRUQsUUFBUSxDQUFDLEdBQXdCO1FBQy9CLE9BQU8saUJBQU0sRUFBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQztJQUM3QixDQUFDO0lBRUQsVUFBVSxDQUFDLElBQWlDO1FBQzFDLE9BQU8sc0JBQVcsRUFBQyxJQUFJLENBQUMsRUFBRSxFQUFFLGdCQUFHLEVBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBVSxDQUFDLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQsTUFBTSxDQUFDLElBQVk7UUFDakIsT0FBTyxpQkFBTSxFQUFDLElBQUksQ0FBQyxFQUFFLEVBQUU7WUFDckIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDakIsVUFBVSxFQUFFLENBQUMsU0FBUyxDQUFDO1NBQ3hCLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQWxJRCx3QkFrSUM7Ozs7Ozs7Ozs7OztBQ2xKWTs7QUFFYiw4Q0FBNkM7QUFDN0M7QUFDQSxDQUFDLEVBQUM7QUFDRix1Q0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUM7QUFDRix5Q0FBd0M7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUM7QUFDRiw2Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUM7QUFDRixzQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUM7QUFDRixzQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUM7QUFDRixzQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUM7QUFDRixzQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUM7QUFDRiw0Q0FBMkM7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUM7QUFDRiwyQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUM7O0FBRUYsZ0NBQWdDLG1CQUFPLENBQUMsZ0VBQVM7O0FBRWpELGlDQUFpQyxtQkFBTyxDQUFDLGdFQUFTOztBQUVsRCxpQ0FBaUMsbUJBQU8sQ0FBQyxnRUFBUzs7QUFFbEQsaUNBQWlDLG1CQUFPLENBQUMsZ0VBQVM7O0FBRWxELGtDQUFrQyxtQkFBTyxDQUFDLGtFQUFVOztBQUVwRCxzQ0FBc0MsbUJBQU8sQ0FBQywwRUFBYzs7QUFFNUQsdUNBQXVDLG1CQUFPLENBQUMsNEVBQWU7O0FBRTlELHdDQUF3QyxtQkFBTyxDQUFDLDhFQUFnQjs7QUFFaEUsb0NBQW9DLG1CQUFPLENBQUMsc0VBQVk7O0FBRXhELHVDQUF1Qyx1Q0FBdUM7Ozs7Ozs7Ozs7O0FDOUVqRTs7QUFFYiw4Q0FBNkM7QUFDN0M7QUFDQSxDQUFDLEVBQUM7QUFDRixrQkFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRDs7QUFFckQ7O0FBRUEsb0JBQW9CLGdCQUFnQjtBQUNwQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0JBQWtCLGNBQWM7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixjQUFjO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQkFBa0IsYUFBYTtBQUMvQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWU7Ozs7Ozs7Ozs7O0FDOU5GOztBQUViLDhDQUE2QztBQUM3QztBQUNBLENBQUMsRUFBQztBQUNGLGtCQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBZTs7Ozs7Ozs7Ozs7QUNWRjs7QUFFYiw4Q0FBNkM7QUFDN0M7QUFDQSxDQUFDLEVBQUM7QUFDRixrQkFBZTtBQUNmO0FBQ0Esa0JBQWU7Ozs7Ozs7Ozs7O0FDUEY7O0FBRWIsOENBQTZDO0FBQzdDO0FBQ0EsQ0FBQyxFQUFDO0FBQ0Ysa0JBQWU7O0FBRWYsdUNBQXVDLG1CQUFPLENBQUMsNEVBQWU7O0FBRTlELHVDQUF1Qyx1Q0FBdUM7O0FBRTlFO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0NBQWtDOztBQUVsQztBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7O0FBRXJCO0FBQ0EscUJBQXFCOztBQUVyQjtBQUNBLHFCQUFxQjs7QUFFckI7QUFDQSxxQkFBcUI7QUFDckI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFlOzs7Ozs7Ozs7OztBQzVDRjs7QUFFYiw4Q0FBNkM7QUFDN0M7QUFDQSxDQUFDLEVBQUM7QUFDRixrQkFBZTtBQUNmLDZCQUE2QixFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxHQUFHO0FBQzNGLGtCQUFlOzs7Ozs7Ozs7OztBQ1BGOztBQUViLDhDQUE2QztBQUM3QztBQUNBLENBQUMsRUFBQztBQUNGLGtCQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7O0FDeEJhOztBQUViLDhDQUE2QztBQUM3QztBQUNBLENBQUMsRUFBQztBQUNGLGtCQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHFEQUFxRDs7QUFFckQ7O0FBRUEsb0JBQW9CLGdCQUFnQjtBQUNwQztBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0IsT0FBTztBQUN6Qjs7QUFFQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixPQUFPO0FBQ3pCOztBQUVBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7O0FBRUEscUJBQXFCLFFBQVE7QUFDN0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBZTs7Ozs7Ozs7Ozs7QUN2R0Y7O0FBRWIsOENBQTZDO0FBQzdDO0FBQ0EsQ0FBQyxFQUFDO0FBQ0Ysa0JBQWU7QUFDZix1QkFBdUI7O0FBRXZCLHVDQUF1QyxtQkFBTyxDQUFDLDRFQUFlOztBQUU5RCx1Q0FBdUMsdUNBQXVDOztBQUU5RTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFlOzs7Ozs7Ozs7OztBQzNDRjs7QUFFYiw4Q0FBNkM7QUFDN0M7QUFDQSxDQUFDLEVBQUM7QUFDRixrQkFBZTs7QUFFZixrQ0FBa0MsbUJBQU8sQ0FBQyxrRUFBVTs7QUFFcEQsaUJBQWlCLG1CQUFPLENBQUMsOEVBQWdCOztBQUV6Qyx1Q0FBdUMsdUNBQXVDOztBQUU5RTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGVBQWU7OztBQUdmO0FBQ0Esb0JBQW9COztBQUVwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0ZBQWdGO0FBQ2hGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7OztBQUdBLHdFQUF3RTtBQUN4RTs7QUFFQSw0RUFBNEU7O0FBRTVFLGdFQUFnRTs7QUFFaEU7QUFDQTtBQUNBLElBQUk7QUFDSjs7O0FBR0E7QUFDQTtBQUNBLElBQUk7OztBQUdKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCOztBQUV4QiwyQkFBMkI7O0FBRTNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCOztBQUV0QjtBQUNBO0FBQ0EsdUJBQXVCOztBQUV2QixvQ0FBb0M7O0FBRXBDLDhCQUE4Qjs7QUFFOUIsa0NBQWtDOztBQUVsQyw0QkFBNEI7O0FBRTVCLGtCQUFrQixPQUFPO0FBQ3pCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFlOzs7Ozs7Ozs7OztBQzFHRjs7QUFFYiw4Q0FBNkM7QUFDN0M7QUFDQSxDQUFDLEVBQUM7QUFDRixrQkFBZTs7QUFFZixnQ0FBZ0MsbUJBQU8sQ0FBQyxrRUFBVTs7QUFFbEQsaUNBQWlDLG1CQUFPLENBQUMsa0VBQVU7O0FBRW5ELHVDQUF1Qyx1Q0FBdUM7O0FBRTlFO0FBQ0E7QUFDQSxrQkFBZTs7Ozs7Ozs7Ozs7QUNmRjs7QUFFYiw4Q0FBNkM7QUFDN0M7QUFDQSxDQUFDLEVBQUM7QUFDRixXQUFXLEdBQUcsV0FBVztBQUN6QixrQkFBZTs7QUFFZixpQkFBaUIsbUJBQU8sQ0FBQyw4RUFBZ0I7O0FBRXpDLG9DQUFvQyxtQkFBTyxDQUFDLHNFQUFZOztBQUV4RCx1Q0FBdUMsdUNBQXVDOztBQUU5RTtBQUNBLDJDQUEyQzs7QUFFM0M7O0FBRUEsa0JBQWtCLGdCQUFnQjtBQUNsQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxXQUFXO0FBQ1g7QUFDQSxXQUFXOztBQUVYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsc0JBQXNCLFFBQVE7QUFDOUI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTs7O0FBR0o7QUFDQSw4QkFBOEI7QUFDOUIsSUFBSSxlQUFlOzs7QUFHbkI7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7O0FDL0VhOztBQUViLDhDQUE2QztBQUM3QztBQUNBLENBQUMsRUFBQztBQUNGLGtCQUFlOztBQUVmLHFDQUFxQyxtQkFBTyxDQUFDLHdFQUFhOztBQUUxRCxrQ0FBa0MsbUJBQU8sQ0FBQyxrRUFBVTs7QUFFcEQsaUJBQWlCLG1CQUFPLENBQUMsOEVBQWdCOztBQUV6Qyx1Q0FBdUMsdUNBQXVDOztBQUU5RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxrRUFBa0U7OztBQUdsRTtBQUNBLG1DQUFtQzs7QUFFbkM7QUFDQTs7QUFFQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtCQUFlOzs7Ozs7Ozs7OztBQzFDRjs7QUFFYiw4Q0FBNkM7QUFDN0M7QUFDQSxDQUFDLEVBQUM7QUFDRixrQkFBZTs7QUFFZixnQ0FBZ0MsbUJBQU8sQ0FBQyxrRUFBVTs7QUFFbEQsa0NBQWtDLG1CQUFPLENBQUMsb0VBQVc7O0FBRXJELHVDQUF1Qyx1Q0FBdUM7O0FBRTlFO0FBQ0E7QUFDQSxrQkFBZTs7Ozs7Ozs7Ozs7QUNmRjs7QUFFYiw4Q0FBNkM7QUFDN0M7QUFDQSxDQUFDLEVBQUM7QUFDRixrQkFBZTs7QUFFZixvQ0FBb0MsbUJBQU8sQ0FBQyxzRUFBWTs7QUFFeEQsdUNBQXVDLHVDQUF1Qzs7QUFFOUU7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWU7Ozs7Ozs7Ozs7O0FDaEJGOztBQUViLDhDQUE2QztBQUM3QztBQUNBLENBQUMsRUFBQztBQUNGLGtCQUFlOztBQUVmLHVDQUF1QyxtQkFBTyxDQUFDLDRFQUFlOztBQUU5RCx1Q0FBdUMsdUNBQXVDOztBQUU5RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWU7Ozs7Ozs7Ozs7O0FDcEJGO0FBQ2IsOENBQTZDO0FBQzdDO0FBQ0EsQ0FBQyxFQUFDO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQixtWEFBOEI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLDZYQUE4QjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsNlhBQThCO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQiw2WEFBOEI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLDJjQUE4QjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsbWRBQThCO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQixnT0FBNEI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGdPQUE0QjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSw4Z0JBQXFCO0FBQ3pCOztBQUVBOzs7Ozs7Ozs7OztBQ3pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVhOztBQUViO0FBQ0Esa0JBQWtCLGtCQUFrQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDLFNBQVM7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBLEVBQUUsZ0JBQWdCO0FBQ2xCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEMsSUFBSSxrQkFBa0IsSUFBSSxNQUFNO0FBQzFFO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsWUFBWTtBQUNaLFlBQVk7QUFDWixjQUFjO0FBQ2QsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyREFBMkQ7O0FBRTNEO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQSxXQUFXLGlCQUFpQjtBQUM1QixXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFdBQVcsU0FBUztBQUNwQixXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLHNCQUFzQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLGtCQUFrQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQixXQUFXLFNBQVM7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLE9BQU87QUFDaEI7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLElBQUk7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixJQUFJO0FBQ2xDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHNDQUFzQyxJQUFJOztBQUUxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWLDBDQUEwQztBQUMxQyw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQyxrQ0FBa0MsYUFBYSxJQUFJO0FBQ2xHLHVDQUF1QyxrQ0FBa0MsU0FBUyxHQUFHLFNBQVMsR0FBRyxXQUFXLEdBQUc7QUFDL0csZ0RBQWdELGtDQUFrQztBQUNsRixpREFBaUQsa0NBQWtDOztBQUVuRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOENBQThDLElBQUksTUFBTSxFQUFFO0FBQzFEOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBa0IsT0FBTztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixPQUFPO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixPQUFPO0FBQzNCO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxZQUFZO0FBQ1o7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsT0FBTztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLE9BQU87QUFDM0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLE9BQU87QUFDM0I7QUFDQSxzQkFBc0IsZ0JBQWdCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnREFBZ0QsRUFBRSxHQUFHLEdBQUc7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7O0FBRS9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQSxzQ0FBc0M7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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SUFBSTtBQUM5RSxDQUFDOztBQUVEO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0EsZUFBZSxFQUFFO0FBQ2pCOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQixhQUFhLFFBQVE7QUFDckIsYUFBYSxLQUFLO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELFdBQVcsRUFBRTtBQUN4RTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQixhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLE9BQU87QUFDdkI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLFFBQVE7QUFDaEM7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLFFBQVE7QUFDaEM7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLFFBQVE7QUFDbEM7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLFFBQVE7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsT0FBTztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQiw0QkFBNEI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFD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O1dBQ0E7V0FDQTtXQUNBO1dBQ0E7V0FDQTtXQUNBO1dBQ0E7V0FDQTtXQUNBO1dBQ0E7V0FDQTtXQUNBLE1BQU0scUJBQXFCO1dBQzNCO1dBQ0E7V0FDQTtXQUNBO1dBQ0E7V0FDQTs7V0FFQTs7V0FFQTtXQUNBO1dBQ0E7Ozs7O1VFckZBO1VBQ0E7VUFDQTtVQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL2tleWJvYXJkanMvZGlzdC9rZXlib2FyZC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvbG9kYXNoL2xvZGFzaC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9zcmMvY2xpZW50LnRzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL3NyYy9jdXJzb3IudHMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vc3JjL2RvbS50cyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9zcmMvaGVscC50cyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9zcmMvb3V0bGluZS50cyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9zcmMvc2VhcmNoLnRzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9pbmRleC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvbWQ1LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9uYXRpdmUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL25pbC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvcGFyc2UuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3JlZ2V4LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9ybmcuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3NoYTEuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3N0cmluZ2lmeS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvdjEuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3YzLmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci92MzUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3Y0LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci92NS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvdmFsaWRhdGUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3ZlcnNpb24uanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL0BseXJhc2VhcmNoL2x5cmEvZGlzdC9janMvaW5kZXguY2pzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy9tYXJrZWQvbGliL21hcmtlZC5janMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svcnVudGltZS9lbnN1cmUgY2h1bmsiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svcnVudGltZS9nZXQgamF2YXNjcmlwdCBjaHVuayBmaWxlbmFtZSIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9ydW50aW1lL2dsb2JhbCIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9ydW50aW1lL2xvYWQgc2NyaXB0Iiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci93ZWJwYWNrL3J1bnRpbWUvbm9kZSBtb2R1bGUgZGVjb3JhdG9yIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci93ZWJwYWNrL3J1bnRpbWUvcHVibGljUGF0aCIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9ydW50aW1lL2pzb25wIGNodW5rIGxvYWRpbmciLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svYmVmb3JlLXN0YXJ0dXAiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svc3RhcnR1cCIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9hZnRlci1zdGFydHVwIl0sInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpIDpcbiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgKGdsb2JhbCA9IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwua2V5Ym9hcmRKUyA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICBmdW5jdGlvbiBfdHlwZW9mKG9iaikge1xuICAgIFwiQGJhYmVsL2hlbHBlcnMgLSB0eXBlb2ZcIjtcblxuICAgIGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikge1xuICAgICAgX3R5cGVvZiA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvYmo7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBfdHlwZW9mID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIF90eXBlb2Yob2JqKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHtcbiAgICBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTtcbiAgICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTtcbiAgICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTtcbiAgICAgIGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gX2NyZWF0ZUNsYXNzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykge1xuICAgIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICAgIGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTtcbiAgICByZXR1cm4gQ29uc3RydWN0b3I7XG4gIH1cblxuICBmdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7XG4gICAgcmV0dXJuIF9hcnJheVdpdGhvdXRIb2xlcyhhcnIpIHx8IF9pdGVyYWJsZVRvQXJyYXkoYXJyKSB8fCBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkoYXJyKSB8fCBfbm9uSXRlcmFibGVTcHJlYWQoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9hcnJheVdpdGhvdXRIb2xlcyhhcnIpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkoYXJyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXkoaXRlcikge1xuICAgIGlmICh0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIFN5bWJvbC5pdGVyYXRvciBpbiBPYmplY3QoaXRlcikpIHJldHVybiBBcnJheS5mcm9tKGl0ZXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikge1xuICAgIGlmICghbykgcmV0dXJuO1xuICAgIGlmICh0eXBlb2YgbyA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7XG4gICAgdmFyIG4gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobykuc2xpY2UoOCwgLTEpO1xuICAgIGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7XG4gICAgaWYgKG4gPT09IFwiQXJndW1lbnRzXCIgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QobikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xuICB9XG5cbiAgZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHtcbiAgICBpZiAobGVuID09IG51bGwgfHwgbGVuID4gYXJyLmxlbmd0aCkgbGVuID0gYXJyLmxlbmd0aDtcblxuICAgIGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgYXJyMltpXSA9IGFycltpXTtcblxuICAgIHJldHVybiBhcnIyO1xuICB9XG5cbiAgZnVuY3Rpb24gX25vbkl0ZXJhYmxlU3ByZWFkKCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gc3ByZWFkIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xuICB9XG5cbiAgdmFyIEtleUNvbWJvID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBLZXlDb21ibyhrZXlDb21ib1N0cikge1xuICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEtleUNvbWJvKTtcblxuICAgICAgdGhpcy5zb3VyY2VTdHIgPSBrZXlDb21ib1N0cjtcbiAgICAgIHRoaXMuc3ViQ29tYm9zID0gS2V5Q29tYm8ucGFyc2VDb21ib1N0cihrZXlDb21ib1N0cik7XG4gICAgICB0aGlzLmtleU5hbWVzID0gdGhpcy5zdWJDb21ib3MucmVkdWNlKGZ1bmN0aW9uIChtZW1vLCBuZXh0U3ViQ29tYm8pIHtcbiAgICAgICAgcmV0dXJuIG1lbW8uY29uY2F0KG5leHRTdWJDb21ibyk7XG4gICAgICB9LCBbXSk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNsYXNzKEtleUNvbWJvLCBbe1xuICAgICAga2V5OiBcImNoZWNrXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gY2hlY2socHJlc3NlZEtleU5hbWVzKSB7XG4gICAgICAgIHZhciBzdGFydGluZ0tleU5hbWVJbmRleCA9IDA7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIHN0YXJ0aW5nS2V5TmFtZUluZGV4ID0gdGhpcy5fY2hlY2tTdWJDb21ibyh0aGlzLnN1YkNvbWJvc1tpXSwgc3RhcnRpbmdLZXlOYW1lSW5kZXgsIHByZXNzZWRLZXlOYW1lcyk7XG5cbiAgICAgICAgICBpZiAoc3RhcnRpbmdLZXlOYW1lSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcImlzRXF1YWxcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBpc0VxdWFsKG90aGVyS2V5Q29tYm8pIHtcbiAgICAgICAgaWYgKCFvdGhlcktleUNvbWJvIHx8IHR5cGVvZiBvdGhlcktleUNvbWJvICE9PSAnc3RyaW5nJyAmJiBfdHlwZW9mKG90aGVyS2V5Q29tYm8pICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2Ygb3RoZXJLZXlDb21ibyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBvdGhlcktleUNvbWJvID0gbmV3IEtleUNvbWJvKG90aGVyS2V5Q29tYm8pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3ViQ29tYm9zLmxlbmd0aCAhPT0gb3RoZXJLZXlDb21iby5zdWJDb21ib3MubGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIGlmICh0aGlzLnN1YkNvbWJvc1tpXS5sZW5ndGggIT09IG90aGVyS2V5Q29tYm8uc3ViQ29tYm9zW2ldLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IF9pICs9IDEpIHtcbiAgICAgICAgICB2YXIgc3ViQ29tYm8gPSB0aGlzLnN1YkNvbWJvc1tfaV07XG5cbiAgICAgICAgICB2YXIgb3RoZXJTdWJDb21ibyA9IG90aGVyS2V5Q29tYm8uc3ViQ29tYm9zW19pXS5zbGljZSgwKTtcblxuICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3ViQ29tYm8ubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAgIHZhciBrZXlOYW1lID0gc3ViQ29tYm9bal07XG4gICAgICAgICAgICB2YXIgaW5kZXggPSBvdGhlclN1YkNvbWJvLmluZGV4T2Yoa2V5TmFtZSk7XG5cbiAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgIG90aGVyU3ViQ29tYm8uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAob3RoZXJTdWJDb21iby5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiX2NoZWNrU3ViQ29tYm9cIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBfY2hlY2tTdWJDb21ibyhzdWJDb21ibywgc3RhcnRpbmdLZXlOYW1lSW5kZXgsIHByZXNzZWRLZXlOYW1lcykge1xuICAgICAgICBzdWJDb21ibyA9IHN1YkNvbWJvLnNsaWNlKDApO1xuICAgICAgICBwcmVzc2VkS2V5TmFtZXMgPSBwcmVzc2VkS2V5TmFtZXMuc2xpY2Uoc3RhcnRpbmdLZXlOYW1lSW5kZXgpO1xuICAgICAgICB2YXIgZW5kSW5kZXggPSBzdGFydGluZ0tleU5hbWVJbmRleDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN1YkNvbWJvLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgdmFyIGtleU5hbWUgPSBzdWJDb21ib1tpXTtcblxuICAgICAgICAgIGlmIChrZXlOYW1lWzBdID09PSAnXFxcXCcpIHtcbiAgICAgICAgICAgIHZhciBlc2NhcGVkS2V5TmFtZSA9IGtleU5hbWUuc2xpY2UoMSk7XG5cbiAgICAgICAgICAgIGlmIChlc2NhcGVkS2V5TmFtZSA9PT0gS2V5Q29tYm8uY29tYm9EZWxpbWluYXRvciB8fCBlc2NhcGVkS2V5TmFtZSA9PT0gS2V5Q29tYm8ua2V5RGVsaW1pbmF0b3IpIHtcbiAgICAgICAgICAgICAga2V5TmFtZSA9IGVzY2FwZWRLZXlOYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBpbmRleCA9IHByZXNzZWRLZXlOYW1lcy5pbmRleE9mKGtleU5hbWUpO1xuXG4gICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIHN1YkNvbWJvLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIGkgLT0gMTtcblxuICAgICAgICAgICAgaWYgKGluZGV4ID4gZW5kSW5kZXgpIHtcbiAgICAgICAgICAgICAgZW5kSW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN1YkNvbWJvLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICByZXR1cm4gZW5kSW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBLZXlDb21ibztcbiAgfSgpO1xuICBLZXlDb21iby5jb21ib0RlbGltaW5hdG9yID0gJz4nO1xuICBLZXlDb21iby5rZXlEZWxpbWluYXRvciA9ICcrJztcblxuICBLZXlDb21iby5wYXJzZUNvbWJvU3RyID0gZnVuY3Rpb24gKGtleUNvbWJvU3RyKSB7XG4gICAgdmFyIHN1YkNvbWJvU3RycyA9IEtleUNvbWJvLl9zcGxpdFN0cihrZXlDb21ib1N0ciwgS2V5Q29tYm8uY29tYm9EZWxpbWluYXRvcik7XG5cbiAgICB2YXIgY29tYm8gPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3ViQ29tYm9TdHJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb21iby5wdXNoKEtleUNvbWJvLl9zcGxpdFN0cihzdWJDb21ib1N0cnNbaV0sIEtleUNvbWJvLmtleURlbGltaW5hdG9yKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbWJvO1xuICB9O1xuXG4gIEtleUNvbWJvLl9zcGxpdFN0ciA9IGZ1bmN0aW9uIChzdHIsIGRlbGltaW5hdG9yKSB7XG4gICAgdmFyIHMgPSBzdHI7XG4gICAgdmFyIGQgPSBkZWxpbWluYXRvcjtcbiAgICB2YXIgYyA9ICcnO1xuICAgIHZhciBjYSA9IFtdO1xuXG4gICAgZm9yICh2YXIgY2kgPSAwOyBjaSA8IHMubGVuZ3RoOyBjaSArPSAxKSB7XG4gICAgICBpZiAoY2kgPiAwICYmIHNbY2ldID09PSBkICYmIHNbY2kgLSAxXSAhPT0gJ1xcXFwnKSB7XG4gICAgICAgIGNhLnB1c2goYy50cmltKCkpO1xuICAgICAgICBjID0gJyc7XG4gICAgICAgIGNpICs9IDE7XG4gICAgICB9XG5cbiAgICAgIGMgKz0gc1tjaV07XG4gICAgfVxuXG4gICAgaWYgKGMpIHtcbiAgICAgIGNhLnB1c2goYy50cmltKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBjYTtcbiAgfTtcblxuICB2YXIgTG9jYWxlID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBMb2NhbGUobmFtZSkge1xuICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIExvY2FsZSk7XG5cbiAgICAgIHRoaXMubG9jYWxlTmFtZSA9IG5hbWU7XG4gICAgICB0aGlzLmFjdGl2ZVRhcmdldEtleXMgPSBbXTtcbiAgICAgIHRoaXMucHJlc3NlZEtleXMgPSBbXTtcbiAgICAgIHRoaXMuX2FwcGxpZWRNYWNyb3MgPSBbXTtcbiAgICAgIHRoaXMuX2tleU1hcCA9IHt9O1xuICAgICAgdGhpcy5fa2lsbEtleUNvZGVzID0gW107XG4gICAgICB0aGlzLl9tYWNyb3MgPSBbXTtcbiAgICB9XG5cbiAgICBfY3JlYXRlQ2xhc3MoTG9jYWxlLCBbe1xuICAgICAga2V5OiBcImJpbmRLZXlDb2RlXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gYmluZEtleUNvZGUoa2V5Q29kZSwga2V5TmFtZXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBrZXlOYW1lcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBrZXlOYW1lcyA9IFtrZXlOYW1lc107XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9rZXlNYXBba2V5Q29kZV0gPSBrZXlOYW1lcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiYmluZE1hY3JvXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gYmluZE1hY3JvKGtleUNvbWJvU3RyLCBrZXlOYW1lcykge1xuICAgICAgICBpZiAodHlwZW9mIGtleU5hbWVzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGtleU5hbWVzID0gW2tleU5hbWVzXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBoYW5kbGVyID0gbnVsbDtcblxuICAgICAgICBpZiAodHlwZW9mIGtleU5hbWVzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgaGFuZGxlciA9IGtleU5hbWVzO1xuICAgICAgICAgIGtleU5hbWVzID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtYWNybyA9IHtcbiAgICAgICAgICBrZXlDb21ibzogbmV3IEtleUNvbWJvKGtleUNvbWJvU3RyKSxcbiAgICAgICAgICBrZXlOYW1lczoga2V5TmFtZXMsXG4gICAgICAgICAgaGFuZGxlcjogaGFuZGxlclxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX21hY3Jvcy5wdXNoKG1hY3JvKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiZ2V0S2V5Q29kZXNcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRLZXlDb2RlcyhrZXlOYW1lKSB7XG4gICAgICAgIHZhciBrZXlDb2RlcyA9IFtdO1xuXG4gICAgICAgIGZvciAodmFyIGtleUNvZGUgaW4gdGhpcy5fa2V5TWFwKSB7XG4gICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fa2V5TWFwW2tleUNvZGVdLmluZGV4T2Yoa2V5TmFtZSk7XG5cbiAgICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAga2V5Q29kZXMucHVzaChrZXlDb2RlIHwgMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGtleUNvZGVzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJnZXRLZXlOYW1lc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldEtleU5hbWVzKGtleUNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2tleU1hcFtrZXlDb2RlXSB8fCBbXTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwic2V0S2lsbEtleVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldEtpbGxLZXkoa2V5Q29kZSkge1xuICAgICAgICBpZiAodHlwZW9mIGtleUNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdmFyIGtleUNvZGVzID0gdGhpcy5nZXRLZXlDb2RlcyhrZXlDb2RlKTtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Q29kZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0S2lsbEtleShrZXlDb2Rlc1tpXSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fa2lsbEtleUNvZGVzLnB1c2goa2V5Q29kZSk7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInByZXNzS2V5XCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gcHJlc3NLZXkoa2V5Q29kZSkge1xuICAgICAgICBpZiAodHlwZW9mIGtleUNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdmFyIGtleUNvZGVzID0gdGhpcy5nZXRLZXlDb2RlcyhrZXlDb2RlKTtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Q29kZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMucHJlc3NLZXkoa2V5Q29kZXNbaV0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYWN0aXZlVGFyZ2V0S2V5cy5sZW5ndGggPSAwO1xuICAgICAgICB2YXIga2V5TmFtZXMgPSB0aGlzLmdldEtleU5hbWVzKGtleUNvZGUpO1xuXG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBrZXlOYW1lcy5sZW5ndGg7IF9pICs9IDEpIHtcbiAgICAgICAgICB0aGlzLmFjdGl2ZVRhcmdldEtleXMucHVzaChrZXlOYW1lc1tfaV0pO1xuXG4gICAgICAgICAgaWYgKHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihrZXlOYW1lc1tfaV0pID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5wcmVzc2VkS2V5cy5wdXNoKGtleU5hbWVzW19pXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fYXBwbHlNYWNyb3MoKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicmVsZWFzZUtleVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbGVhc2VLZXkoa2V5Q29kZSkge1xuICAgICAgICBpZiAodHlwZW9mIGtleUNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdmFyIGtleUNvZGVzID0gdGhpcy5nZXRLZXlDb2RlcyhrZXlDb2RlKTtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Q29kZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMucmVsZWFzZUtleShrZXlDb2Rlc1tpXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBrZXlOYW1lcyA9IHRoaXMuZ2V0S2V5TmFtZXMoa2V5Q29kZSk7XG5cbiAgICAgICAgICB2YXIga2lsbEtleUNvZGVJbmRleCA9IHRoaXMuX2tpbGxLZXlDb2Rlcy5pbmRleE9mKGtleUNvZGUpO1xuXG4gICAgICAgICAgaWYgKGtpbGxLZXlDb2RlSW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnByZXNzZWRLZXlzLmxlbmd0aCA9IDA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvciAodmFyIF9pMiA9IDA7IF9pMiA8IGtleU5hbWVzLmxlbmd0aDsgX2kyICs9IDEpIHtcbiAgICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5wcmVzc2VkS2V5cy5pbmRleE9mKGtleU5hbWVzW19pMl0pO1xuXG4gICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVzc2VkS2V5cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5hY3RpdmVUYXJnZXRLZXlzLmxlbmd0aCA9IDA7XG5cbiAgICAgICAgICB0aGlzLl9jbGVhck1hY3JvcygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcIl9hcHBseU1hY3Jvc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9hcHBseU1hY3JvcygpIHtcbiAgICAgICAgdmFyIG1hY3JvcyA9IHRoaXMuX21hY3Jvcy5zbGljZSgwKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hY3Jvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIHZhciBtYWNybyA9IG1hY3Jvc1tpXTtcblxuICAgICAgICAgIGlmIChtYWNyby5rZXlDb21iby5jaGVjayh0aGlzLnByZXNzZWRLZXlzKSkge1xuICAgICAgICAgICAgaWYgKG1hY3JvLmhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgbWFjcm8ua2V5TmFtZXMgPSBtYWNyby5oYW5kbGVyKHRoaXMucHJlc3NlZEtleXMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1hY3JvLmtleU5hbWVzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLnByZXNzZWRLZXlzLmluZGV4T2YobWFjcm8ua2V5TmFtZXNbal0pID09PSAtMSkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJlc3NlZEtleXMucHVzaChtYWNyby5rZXlOYW1lc1tqXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fYXBwbGllZE1hY3Jvcy5wdXNoKG1hY3JvKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiX2NsZWFyTWFjcm9zXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gX2NsZWFyTWFjcm9zKCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2FwcGxpZWRNYWNyb3MubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICB2YXIgbWFjcm8gPSB0aGlzLl9hcHBsaWVkTWFjcm9zW2ldO1xuXG4gICAgICAgICAgaWYgKCFtYWNyby5rZXlDb21iby5jaGVjayh0aGlzLnByZXNzZWRLZXlzKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYWNyby5rZXlOYW1lcy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLnByZXNzZWRLZXlzLmluZGV4T2YobWFjcm8ua2V5TmFtZXNbal0pO1xuXG4gICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVzc2VkS2V5cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtYWNyby5oYW5kbGVyKSB7XG4gICAgICAgICAgICAgIG1hY3JvLmtleU5hbWVzID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fYXBwbGllZE1hY3Jvcy5zcGxpY2UoaSwgMSk7XG5cbiAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gTG9jYWxlO1xuICB9KCk7XG5cbiAgdmFyIEtleWJvYXJkID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBLZXlib2FyZCh0YXJnZXRXaW5kb3csIHRhcmdldEVsZW1lbnQsIHRhcmdldFBsYXRmb3JtLCB0YXJnZXRVc2VyQWdlbnQpIHtcbiAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBLZXlib2FyZCk7XG5cbiAgICAgIHRoaXMuX2xvY2FsZSA9IG51bGw7XG4gICAgICB0aGlzLl9jdXJyZW50Q29udGV4dCA9ICcnO1xuICAgICAgdGhpcy5fY29udGV4dHMgPSB7fTtcbiAgICAgIHRoaXMuX2xpc3RlbmVycyA9IFtdO1xuICAgICAgdGhpcy5fYXBwbGllZExpc3RlbmVycyA9IFtdO1xuICAgICAgdGhpcy5fbG9jYWxlcyA9IHt9O1xuICAgICAgdGhpcy5fdGFyZ2V0RWxlbWVudCA9IG51bGw7XG4gICAgICB0aGlzLl90YXJnZXRXaW5kb3cgPSBudWxsO1xuICAgICAgdGhpcy5fdGFyZ2V0UGxhdGZvcm0gPSAnJztcbiAgICAgIHRoaXMuX3RhcmdldFVzZXJBZ2VudCA9ICcnO1xuICAgICAgdGhpcy5faXNNb2Rlcm5Ccm93c2VyID0gZmFsc2U7XG4gICAgICB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyA9IG51bGw7XG4gICAgICB0aGlzLl90YXJnZXRLZXlVcEJpbmRpbmcgPSBudWxsO1xuICAgICAgdGhpcy5fdGFyZ2V0UmVzZXRCaW5kaW5nID0gbnVsbDtcbiAgICAgIHRoaXMuX3BhdXNlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5fY29udGV4dHMuZ2xvYmFsID0ge1xuICAgICAgICBsaXN0ZW5lcnM6IHRoaXMuX2xpc3RlbmVycyxcbiAgICAgICAgdGFyZ2V0V2luZG93OiB0YXJnZXRXaW5kb3csXG4gICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdldEVsZW1lbnQsXG4gICAgICAgIHRhcmdldFBsYXRmb3JtOiB0YXJnZXRQbGF0Zm9ybSxcbiAgICAgICAgdGFyZ2V0VXNlckFnZW50OiB0YXJnZXRVc2VyQWdlbnRcbiAgICAgIH07XG4gICAgICB0aGlzLnNldENvbnRleHQoJ2dsb2JhbCcpO1xuICAgIH1cblxuICAgIF9jcmVhdGVDbGFzcyhLZXlib2FyZCwgW3tcbiAgICAgIGtleTogXCJzZXRMb2NhbGVcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRMb2NhbGUobG9jYWxlTmFtZSwgbG9jYWxlQnVpbGRlcikge1xuICAgICAgICB2YXIgbG9jYWxlID0gbnVsbDtcblxuICAgICAgICBpZiAodHlwZW9mIGxvY2FsZU5hbWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgaWYgKGxvY2FsZUJ1aWxkZXIpIHtcbiAgICAgICAgICAgIGxvY2FsZSA9IG5ldyBMb2NhbGUobG9jYWxlTmFtZSk7XG4gICAgICAgICAgICBsb2NhbGVCdWlsZGVyKGxvY2FsZSwgdGhpcy5fdGFyZ2V0UGxhdGZvcm0sIHRoaXMuX3RhcmdldFVzZXJBZ2VudCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvY2FsZSA9IHRoaXMuX2xvY2FsZXNbbG9jYWxlTmFtZV0gfHwgbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG9jYWxlID0gbG9jYWxlTmFtZTtcbiAgICAgICAgICBsb2NhbGVOYW1lID0gbG9jYWxlLl9sb2NhbGVOYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlID0gbG9jYWxlO1xuICAgICAgICB0aGlzLl9sb2NhbGVzW2xvY2FsZU5hbWVdID0gbG9jYWxlO1xuXG4gICAgICAgIGlmIChsb2NhbGUpIHtcbiAgICAgICAgICB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMgPSBsb2NhbGUucHJlc3NlZEtleXM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiZ2V0TG9jYWxlXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0TG9jYWxlKGxvY2FsTmFtZSkge1xuICAgICAgICBsb2NhbE5hbWUgfHwgKGxvY2FsTmFtZSA9IHRoaXMuX2xvY2FsZS5sb2NhbGVOYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvY2FsZXNbbG9jYWxOYW1lXSB8fCBudWxsO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJiaW5kXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgICAgICBpZiAoa2V5Q29tYm9TdHIgPT09IG51bGwgfHwgdHlwZW9mIGtleUNvbWJvU3RyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCA9IHJlbGVhc2VIYW5kbGVyO1xuICAgICAgICAgIHJlbGVhc2VIYW5kbGVyID0gcHJlc3NIYW5kbGVyO1xuICAgICAgICAgIHByZXNzSGFuZGxlciA9IGtleUNvbWJvU3RyO1xuICAgICAgICAgIGtleUNvbWJvU3RyID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZXlDb21ib1N0ciAmJiBfdHlwZW9mKGtleUNvbWJvU3RyKSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGtleUNvbWJvU3RyLmxlbmd0aCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleUNvbWJvU3RyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmJpbmQoa2V5Q29tYm9TdHJbaV0sIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzLnB1c2goe1xuICAgICAgICAgIGtleUNvbWJvOiBrZXlDb21ib1N0ciA/IG5ldyBLZXlDb21ibyhrZXlDb21ib1N0cikgOiBudWxsLFxuICAgICAgICAgIHByZXNzSGFuZGxlcjogcHJlc3NIYW5kbGVyIHx8IG51bGwsXG4gICAgICAgICAgcmVsZWFzZUhhbmRsZXI6IHJlbGVhc2VIYW5kbGVyIHx8IG51bGwsXG4gICAgICAgICAgcHJldmVudFJlcGVhdDogZmFsc2UsXG4gICAgICAgICAgcHJldmVudFJlcGVhdEJ5RGVmYXVsdDogcHJldmVudFJlcGVhdEJ5RGVmYXVsdCB8fCBmYWxzZSxcbiAgICAgICAgICBleGVjdXRpbmdIYW5kbGVyOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiYWRkTGlzdGVuZXJcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRMaXN0ZW5lcihrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwib25cIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBvbihrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiYmluZFByZXNzXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gYmluZFByZXNzKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCBudWxsLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiYmluZFJlbGVhc2VcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBiaW5kUmVsZWFzZShrZXlDb21ib1N0ciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmluZChrZXlDb21ib1N0ciwgbnVsbCwgcmVsZWFzZUhhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJ1bmJpbmRcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiB1bmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgaWYgKGtleUNvbWJvU3RyID09PSBudWxsIHx8IHR5cGVvZiBrZXlDb21ib1N0ciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHJlbGVhc2VIYW5kbGVyID0gcHJlc3NIYW5kbGVyO1xuICAgICAgICAgIHByZXNzSGFuZGxlciA9IGtleUNvbWJvU3RyO1xuICAgICAgICAgIGtleUNvbWJvU3RyID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZXlDb21ib1N0ciAmJiBfdHlwZW9mKGtleUNvbWJvU3RyKSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGtleUNvbWJvU3RyLmxlbmd0aCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleUNvbWJvU3RyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLnVuYmluZChrZXlDb21ib1N0cltpXSwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgdGhpcy5fbGlzdGVuZXJzLmxlbmd0aDsgX2kgKz0gMSkge1xuICAgICAgICAgIHZhciBsaXN0ZW5lciA9IHRoaXMuX2xpc3RlbmVyc1tfaV07XG4gICAgICAgICAgdmFyIGNvbWJvTWF0Y2hlcyA9ICFrZXlDb21ib1N0ciAmJiAhbGlzdGVuZXIua2V5Q29tYm8gfHwgbGlzdGVuZXIua2V5Q29tYm8gJiYgbGlzdGVuZXIua2V5Q29tYm8uaXNFcXVhbChrZXlDb21ib1N0cik7XG4gICAgICAgICAgdmFyIHByZXNzSGFuZGxlck1hdGNoZXMgPSAhcHJlc3NIYW5kbGVyICYmICFyZWxlYXNlSGFuZGxlciB8fCAhcHJlc3NIYW5kbGVyICYmICFsaXN0ZW5lci5wcmVzc0hhbmRsZXIgfHwgcHJlc3NIYW5kbGVyID09PSBsaXN0ZW5lci5wcmVzc0hhbmRsZXI7XG4gICAgICAgICAgdmFyIHJlbGVhc2VIYW5kbGVyTWF0Y2hlcyA9ICFwcmVzc0hhbmRsZXIgJiYgIXJlbGVhc2VIYW5kbGVyIHx8ICFyZWxlYXNlSGFuZGxlciAmJiAhbGlzdGVuZXIucmVsZWFzZUhhbmRsZXIgfHwgcmVsZWFzZUhhbmRsZXIgPT09IGxpc3RlbmVyLnJlbGVhc2VIYW5kbGVyO1xuXG4gICAgICAgICAgaWYgKGNvbWJvTWF0Y2hlcyAmJiBwcmVzc0hhbmRsZXJNYXRjaGVzICYmIHJlbGVhc2VIYW5kbGVyTWF0Y2hlcykge1xuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzLnNwbGljZShfaSwgMSk7XG5cbiAgICAgICAgICAgIF9pIC09IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInJlbW92ZUxpc3RlbmVyXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudW5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwib2ZmXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gb2ZmKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnVuYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcik7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInNldENvbnRleHRcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRDb250ZXh0KGNvbnRleHROYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9sb2NhbGUpIHtcbiAgICAgICAgICB0aGlzLnJlbGVhc2VBbGxLZXlzKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2NvbnRleHRzW2NvbnRleHROYW1lXSkge1xuICAgICAgICAgIHZhciBnbG9iYWxDb250ZXh0ID0gdGhpcy5fY29udGV4dHMuZ2xvYmFsO1xuICAgICAgICAgIHRoaXMuX2NvbnRleHRzW2NvbnRleHROYW1lXSA9IHtcbiAgICAgICAgICAgIGxpc3RlbmVyczogW10sXG4gICAgICAgICAgICB0YXJnZXRXaW5kb3c6IGdsb2JhbENvbnRleHQudGFyZ2V0V2luZG93LFxuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogZ2xvYmFsQ29udGV4dC50YXJnZXRFbGVtZW50LFxuICAgICAgICAgICAgdGFyZ2V0UGxhdGZvcm06IGdsb2JhbENvbnRleHQudGFyZ2V0UGxhdGZvcm0sXG4gICAgICAgICAgICB0YXJnZXRVc2VyQWdlbnQ6IGdsb2JhbENvbnRleHQudGFyZ2V0VXNlckFnZW50XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdO1xuICAgICAgICB0aGlzLl9jdXJyZW50Q29udGV4dCA9IGNvbnRleHROYW1lO1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSBjb250ZXh0Lmxpc3RlbmVycztcbiAgICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICAgIHRoaXMud2F0Y2goY29udGV4dC50YXJnZXRXaW5kb3csIGNvbnRleHQudGFyZ2V0RWxlbWVudCwgY29udGV4dC50YXJnZXRQbGF0Zm9ybSwgY29udGV4dC50YXJnZXRVc2VyQWdlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiZ2V0Q29udGV4dFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldENvbnRleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50Q29udGV4dDtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwid2l0aENvbnRleHRcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiB3aXRoQ29udGV4dChjb250ZXh0TmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHByZXZpb3VzQ29udGV4dE5hbWUgPSB0aGlzLmdldENvbnRleHQoKTtcbiAgICAgICAgdGhpcy5zZXRDb250ZXh0KGNvbnRleHROYW1lKTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgdGhpcy5zZXRDb250ZXh0KHByZXZpb3VzQ29udGV4dE5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwid2F0Y2hcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiB3YXRjaCh0YXJnZXRXaW5kb3csIHRhcmdldEVsZW1lbnQsIHRhcmdldFBsYXRmb3JtLCB0YXJnZXRVc2VyQWdlbnQpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB0aGlzLnN0b3AoKTtcbiAgICAgICAgdmFyIHdpbiA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDoge307XG5cbiAgICAgICAgaWYgKCF0YXJnZXRXaW5kb3cpIHtcbiAgICAgICAgICBpZiAoIXdpbi5hZGRFdmVudExpc3RlbmVyICYmICF3aW4uYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICAgIC8vIFRoaXMgd2FzIGFkZGVkIHNvIHdoZW4gdXNpbmcgdGhpbmdzIGxpa2UgSlNET00gd2F0Y2ggY2FuIGJlIHVzZWQgdG8gY29uZmlndXJlIHdhdGNoXG4gICAgICAgICAgICAvLyBmb3IgdGhlIGdsb2JhbCBuYW1lc3BhY2UgbWFudWFsbHkuXG4gICAgICAgICAgICBpZiAodGhpcy5fY3VycmVudENvbnRleHQgPT09ICdnbG9iYWwnKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZmluZCB3aW5kb3cgZnVuY3Rpb25zIGFkZEV2ZW50TGlzdGVuZXIgb3IgYXR0YWNoRXZlbnQuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGFyZ2V0V2luZG93ID0gd2luO1xuICAgICAgICB9IC8vIEhhbmRsZSBlbGVtZW50IGJpbmRpbmdzIHdoZXJlIGEgdGFyZ2V0IHdpbmRvdyBpcyBub3QgcGFzc2VkXG5cblxuICAgICAgICBpZiAodHlwZW9mIHRhcmdldFdpbmRvdy5ub2RlVHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICB0YXJnZXRVc2VyQWdlbnQgPSB0YXJnZXRQbGF0Zm9ybTtcbiAgICAgICAgICB0YXJnZXRQbGF0Zm9ybSA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgICAgdGFyZ2V0RWxlbWVudCA9IHRhcmdldFdpbmRvdztcbiAgICAgICAgICB0YXJnZXRXaW5kb3cgPSB3aW47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRhcmdldFdpbmRvdy5hZGRFdmVudExpc3RlbmVyICYmICF0YXJnZXRXaW5kb3cuYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIGFkZEV2ZW50TGlzdGVuZXIgb3IgYXR0YWNoRXZlbnQgbWV0aG9kcyBvbiB0YXJnZXRXaW5kb3cuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9pc01vZGVybkJyb3dzZXIgPSAhIXRhcmdldFdpbmRvdy5hZGRFdmVudExpc3RlbmVyO1xuICAgICAgICB2YXIgdXNlckFnZW50ID0gdGFyZ2V0V2luZG93Lm5hdmlnYXRvciAmJiB0YXJnZXRXaW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCB8fCAnJztcbiAgICAgICAgdmFyIHBsYXRmb3JtID0gdGFyZ2V0V2luZG93Lm5hdmlnYXRvciAmJiB0YXJnZXRXaW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtIHx8ICcnO1xuICAgICAgICB0YXJnZXRFbGVtZW50ICYmIHRhcmdldEVsZW1lbnQgIT09IG51bGwgfHwgKHRhcmdldEVsZW1lbnQgPSB0YXJnZXRXaW5kb3cuZG9jdW1lbnQpO1xuICAgICAgICB0YXJnZXRQbGF0Zm9ybSAmJiB0YXJnZXRQbGF0Zm9ybSAhPT0gbnVsbCB8fCAodGFyZ2V0UGxhdGZvcm0gPSBwbGF0Zm9ybSk7XG4gICAgICAgIHRhcmdldFVzZXJBZ2VudCAmJiB0YXJnZXRVc2VyQWdlbnQgIT09IG51bGwgfHwgKHRhcmdldFVzZXJBZ2VudCA9IHVzZXJBZ2VudCk7XG5cbiAgICAgICAgdGhpcy5fdGFyZ2V0S2V5RG93bkJpbmRpbmcgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICBfdGhpcy5wcmVzc0tleShldmVudC5rZXlDb2RlLCBldmVudCk7XG5cbiAgICAgICAgICBfdGhpcy5faGFuZGxlQ29tbWFuZEJ1ZyhldmVudCwgcGxhdGZvcm0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX3RhcmdldEtleVVwQmluZGluZyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIF90aGlzLnJlbGVhc2VLZXkoZXZlbnQua2V5Q29kZSwgZXZlbnQpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIF90aGlzLnJlbGVhc2VBbGxLZXlzKGV2ZW50KTtcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgJ2tleWRvd24nLCB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fYmluZEV2ZW50KHRhcmdldEVsZW1lbnQsICdrZXl1cCcsIHRoaXMuX3RhcmdldEtleVVwQmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fYmluZEV2ZW50KHRhcmdldFdpbmRvdywgJ2ZvY3VzJywgdGhpcy5fdGFyZ2V0UmVzZXRCaW5kaW5nKTtcblxuICAgICAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0V2luZG93LCAnYmx1cicsIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fdGFyZ2V0RWxlbWVudCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuX3RhcmdldFdpbmRvdyA9IHRhcmdldFdpbmRvdztcbiAgICAgICAgdGhpcy5fdGFyZ2V0UGxhdGZvcm0gPSB0YXJnZXRQbGF0Zm9ybTtcbiAgICAgICAgdGhpcy5fdGFyZ2V0VXNlckFnZW50ID0gdGFyZ2V0VXNlckFnZW50O1xuICAgICAgICB2YXIgY3VycmVudENvbnRleHQgPSB0aGlzLl9jb250ZXh0c1t0aGlzLl9jdXJyZW50Q29udGV4dF07XG4gICAgICAgIGN1cnJlbnRDb250ZXh0LnRhcmdldFdpbmRvdyA9IHRoaXMuX3RhcmdldFdpbmRvdztcbiAgICAgICAgY3VycmVudENvbnRleHQudGFyZ2V0RWxlbWVudCA9IHRoaXMuX3RhcmdldEVsZW1lbnQ7XG4gICAgICAgIGN1cnJlbnRDb250ZXh0LnRhcmdldFBsYXRmb3JtID0gdGhpcy5fdGFyZ2V0UGxhdGZvcm07XG4gICAgICAgIGN1cnJlbnRDb250ZXh0LnRhcmdldFVzZXJBZ2VudCA9IHRoaXMuX3RhcmdldFVzZXJBZ2VudDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInN0b3BcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBzdG9wKCkge1xuICAgICAgICBpZiAoIXRoaXMuX3RhcmdldEVsZW1lbnQgfHwgIXRoaXMuX3RhcmdldFdpbmRvdykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3VuYmluZEV2ZW50KHRoaXMuX3RhcmdldEVsZW1lbnQsICdrZXlkb3duJywgdGhpcy5fdGFyZ2V0S2V5RG93bkJpbmRpbmcpO1xuXG4gICAgICAgIHRoaXMuX3VuYmluZEV2ZW50KHRoaXMuX3RhcmdldEVsZW1lbnQsICdrZXl1cCcsIHRoaXMuX3RhcmdldEtleVVwQmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fdW5iaW5kRXZlbnQodGhpcy5fdGFyZ2V0V2luZG93LCAnZm9jdXMnLCB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcpO1xuXG4gICAgICAgIHRoaXMuX3VuYmluZEV2ZW50KHRoaXMuX3RhcmdldFdpbmRvdywgJ2JsdXInLCB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcpO1xuXG4gICAgICAgIHRoaXMuX3RhcmdldFdpbmRvdyA9IG51bGw7XG4gICAgICAgIHRoaXMuX3RhcmdldEVsZW1lbnQgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicHJlc3NLZXlcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBwcmVzc0tleShrZXlDb2RlLCBldmVudCkge1xuICAgICAgICBpZiAodGhpcy5fcGF1c2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2xvY2FsZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTG9jYWxlIG5vdCBzZXQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2xvY2FsZS5wcmVzc0tleShrZXlDb2RlKTtcblxuICAgICAgICB0aGlzLl9hcHBseUJpbmRpbmdzKGV2ZW50KTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicmVsZWFzZUtleVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbGVhc2VLZXkoa2V5Q29kZSwgZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX3BhdXNlZCkge1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLl9sb2NhbGUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvY2FsZSBub3Qgc2V0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb2NhbGUucmVsZWFzZUtleShrZXlDb2RlKTtcblxuICAgICAgICB0aGlzLl9jbGVhckJpbmRpbmdzKGV2ZW50KTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicmVsZWFzZUFsbEtleXNcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWxlYXNlQWxsS2V5cyhldmVudCkge1xuICAgICAgICBpZiAodGhpcy5fcGF1c2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2xvY2FsZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTG9jYWxlIG5vdCBzZXQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2xvY2FsZS5wcmVzc2VkS2V5cy5sZW5ndGggPSAwO1xuXG4gICAgICAgIHRoaXMuX2NsZWFyQmluZGluZ3MoZXZlbnQpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJwYXVzZVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHBhdXNlKCkge1xuICAgICAgICBpZiAodGhpcy5fcGF1c2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fbG9jYWxlKSB7XG4gICAgICAgICAgdGhpcy5yZWxlYXNlQWxsS2V5cygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcGF1c2VkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInJlc3VtZVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlc3VtZSgpIHtcbiAgICAgICAgdGhpcy5fcGF1c2VkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJyZXNldFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgICAgICB0aGlzLnJlbGVhc2VBbGxLZXlzKCk7XG4gICAgICAgIHRoaXMuX2xpc3RlbmVycy5sZW5ndGggPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiX2JpbmRFdmVudFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc01vZGVybkJyb3dzZXIgPyB0YXJnZXRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSkgOiB0YXJnZXRFbGVtZW50LmF0dGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWUsIGhhbmRsZXIpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfdW5iaW5kRXZlbnRcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBfdW5iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc01vZGVybkJyb3dzZXIgPyB0YXJnZXRFbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSkgOiB0YXJnZXRFbGVtZW50LmRldGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWUsIGhhbmRsZXIpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfZ2V0R3JvdXBlZExpc3RlbmVyc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRHcm91cGVkTGlzdGVuZXJzKCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJHcm91cHMgPSBbXTtcbiAgICAgICAgdmFyIGxpc3RlbmVyR3JvdXBNYXAgPSBbXTtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycztcblxuICAgICAgICBpZiAodGhpcy5fY3VycmVudENvbnRleHQgIT09ICdnbG9iYWwnKSB7XG4gICAgICAgICAgbGlzdGVuZXJzID0gW10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShsaXN0ZW5lcnMpLCBfdG9Db25zdW1hYmxlQXJyYXkodGhpcy5fY29udGV4dHMuZ2xvYmFsLmxpc3RlbmVycykpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGlzdGVuZXJzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICByZXR1cm4gKGIua2V5Q29tYm8gPyBiLmtleUNvbWJvLmtleU5hbWVzLmxlbmd0aCA6IDApIC0gKGEua2V5Q29tYm8gPyBhLmtleUNvbWJvLmtleU5hbWVzLmxlbmd0aCA6IDApO1xuICAgICAgICB9KS5mb3JFYWNoKGZ1bmN0aW9uIChsKSB7XG4gICAgICAgICAgdmFyIG1hcEluZGV4ID0gLTE7XG5cbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVyR3JvdXBNYXAubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lckdyb3VwTWFwW2ldID09PSBudWxsICYmIGwua2V5Q29tYm8gPT09IG51bGwgfHwgbGlzdGVuZXJHcm91cE1hcFtpXSAhPT0gbnVsbCAmJiBsaXN0ZW5lckdyb3VwTWFwW2ldLmlzRXF1YWwobC5rZXlDb21ibykpIHtcbiAgICAgICAgICAgICAgbWFwSW5kZXggPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChtYXBJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIG1hcEluZGV4ID0gbGlzdGVuZXJHcm91cE1hcC5sZW5ndGg7XG4gICAgICAgICAgICBsaXN0ZW5lckdyb3VwTWFwLnB1c2gobC5rZXlDb21ibyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFsaXN0ZW5lckdyb3Vwc1ttYXBJbmRleF0pIHtcbiAgICAgICAgICAgIGxpc3RlbmVyR3JvdXBzW21hcEluZGV4XSA9IFtdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxpc3RlbmVyR3JvdXBzW21hcEluZGV4XS5wdXNoKGwpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyR3JvdXBzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfYXBwbHlCaW5kaW5nc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9hcHBseUJpbmRpbmdzKGV2ZW50KSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciBwcmV2ZW50UmVwZWF0ID0gZmFsc2U7XG4gICAgICAgIGV2ZW50IHx8IChldmVudCA9IHt9KTtcblxuICAgICAgICBldmVudC5wcmV2ZW50UmVwZWF0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHByZXZlbnRSZXBlYXQgPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIGV2ZW50LnByZXNzZWRLZXlzID0gdGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzLnNsaWNlKDApO1xuICAgICAgICB2YXIgYWN0aXZlVGFyZ2V0S2V5cyA9IHRoaXMuX2xvY2FsZS5hY3RpdmVUYXJnZXRLZXlzO1xuXG4gICAgICAgIHZhciBwcmVzc2VkS2V5cyA9IHRoaXMuX2xvY2FsZS5wcmVzc2VkS2V5cy5zbGljZSgwKTtcblxuICAgICAgICB2YXIgbGlzdGVuZXJHcm91cHMgPSB0aGlzLl9nZXRHcm91cGVkTGlzdGVuZXJzKCk7XG5cbiAgICAgICAgdmFyIF9sb29wID0gZnVuY3Rpb24gX2xvb3AoaSkge1xuICAgICAgICAgIHZhciBsaXN0ZW5lcnMgPSBsaXN0ZW5lckdyb3Vwc1tpXTtcbiAgICAgICAgICB2YXIga2V5Q29tYm8gPSBsaXN0ZW5lcnNbMF0ua2V5Q29tYm87XG5cbiAgICAgICAgICBpZiAoa2V5Q29tYm8gPT09IG51bGwgfHwga2V5Q29tYm8uY2hlY2socHJlc3NlZEtleXMpICYmIGFjdGl2ZVRhcmdldEtleXMuc29tZShmdW5jdGlvbiAoaykge1xuICAgICAgICAgICAgcmV0dXJuIGtleUNvbWJvLmtleU5hbWVzLmluY2x1ZGVzKGspO1xuICAgICAgICAgIH0pKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxpc3RlbmVycy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbal07XG5cbiAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyICYmIGxpc3RlbmVyLnByZXNzSGFuZGxlciAmJiAhbGlzdGVuZXIucHJldmVudFJlcGVhdCkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyLnByZXNzSGFuZGxlci5jYWxsKF90aGlzMiwgZXZlbnQpO1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIGlmIChwcmV2ZW50UmVwZWF0IHx8IGxpc3RlbmVyLnByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLnByZXZlbnRSZXBlYXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgcHJldmVudFJlcGVhdCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChfdGhpczIuX2FwcGxpZWRMaXN0ZW5lcnMuaW5kZXhPZihsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMyLl9hcHBsaWVkTGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChrZXlDb21ibykge1xuICAgICAgICAgICAgICBmb3IgKHZhciBfaiA9IDA7IF9qIDwga2V5Q29tYm8ua2V5TmFtZXMubGVuZ3RoOyBfaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gcHJlc3NlZEtleXMuaW5kZXhPZihrZXlDb21iby5rZXlOYW1lc1tfal0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgcHJlc3NlZEtleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAgIF9qIC09IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJHcm91cHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBfbG9vcChpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfY2xlYXJCaW5kaW5nc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9jbGVhckJpbmRpbmdzKGV2ZW50KSB7XG4gICAgICAgIGV2ZW50IHx8IChldmVudCA9IHt9KTtcbiAgICAgICAgZXZlbnQucHJlc3NlZEtleXMgPSB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMuc2xpY2UoMCk7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9hcHBsaWVkTGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgdmFyIGxpc3RlbmVyID0gdGhpcy5fYXBwbGllZExpc3RlbmVyc1tpXTtcbiAgICAgICAgICB2YXIga2V5Q29tYm8gPSBsaXN0ZW5lci5rZXlDb21ibztcblxuICAgICAgICAgIGlmIChrZXlDb21ibyA9PT0gbnVsbCB8fCAha2V5Q29tYm8uY2hlY2sodGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzKSkge1xuICAgICAgICAgICAgbGlzdGVuZXIucHJldmVudFJlcGVhdCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoa2V5Q29tYm8gIT09IG51bGwgfHwgZXZlbnQucHJlc3NlZEtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIHRoaXMuX2FwcGxpZWRMaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuXG4gICAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyICYmIGxpc3RlbmVyLnJlbGVhc2VIYW5kbGVyKSB7XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgPSB0cnVlO1xuICAgICAgICAgICAgICBsaXN0ZW5lci5yZWxlYXNlSGFuZGxlci5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICAgICAgbGlzdGVuZXIuZXhlY3V0aW5nSGFuZGxlciA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfaGFuZGxlQ29tbWFuZEJ1Z1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9oYW5kbGVDb21tYW5kQnVnKGV2ZW50LCBwbGF0Zm9ybSkge1xuICAgICAgICAvLyBPbiBNYWMgd2hlbiB0aGUgY29tbWFuZCBrZXkgaXMga2VwdCBwcmVzc2VkLCBrZXl1cCBpcyBub3QgdHJpZ2dlcmVkIGZvciBhbnkgb3RoZXIga2V5LlxuICAgICAgICAvLyBJbiB0aGlzIGNhc2UgZm9yY2UgYSBrZXl1cCBmb3Igbm9uLW1vZGlmaWVyIGtleXMgZGlyZWN0bHkgYWZ0ZXIgdGhlIGtleXByZXNzLlxuICAgICAgICB2YXIgbW9kaWZpZXJLZXlzID0gW1wic2hpZnRcIiwgXCJjdHJsXCIsIFwiYWx0XCIsIFwiY2Fwc2xvY2tcIiwgXCJ0YWJcIiwgXCJjb21tYW5kXCJdO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5tYXRjaChcIk1hY1wiKSAmJiB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMuaW5jbHVkZXMoXCJjb21tYW5kXCIpICYmICFtb2RpZmllcktleXMuaW5jbHVkZXModGhpcy5fbG9jYWxlLmdldEtleU5hbWVzKGV2ZW50LmtleUNvZGUpWzBdKSkge1xuICAgICAgICAgIHRoaXMuX3RhcmdldEtleVVwQmluZGluZyhldmVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gS2V5Ym9hcmQ7XG4gIH0oKTtcblxuICBmdW5jdGlvbiB1cyhsb2NhbGUsIHBsYXRmb3JtLCB1c2VyQWdlbnQpIHtcbiAgICAvLyBnZW5lcmFsXG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDMsIFsnY2FuY2VsJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg4LCBbJ2JhY2tzcGFjZSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoOSwgWyd0YWInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyLCBbJ2NsZWFyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMywgWydlbnRlciddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTYsIFsnc2hpZnQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE3LCBbJ2N0cmwnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE4LCBbJ2FsdCcsICdtZW51J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxOSwgWydwYXVzZScsICdicmVhayddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMjAsIFsnY2Fwc2xvY2snXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDI3LCBbJ2VzY2FwZScsICdlc2MnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDMyLCBbJ3NwYWNlJywgJ3NwYWNlYmFyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgzMywgWydwYWdldXAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM0LCBbJ3BhZ2Vkb3duJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgzNSwgWydlbmQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM2LCBbJ2hvbWUnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM3LCBbJ2xlZnQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM4LCBbJ3VwJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgzOSwgWydyaWdodCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDAsIFsnZG93biddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDEsIFsnc2VsZWN0J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg0MiwgWydwcmludHNjcmVlbiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDMsIFsnZXhlY3V0ZSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDQsIFsnc25hcHNob3QnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ1LCBbJ2luc2VydCcsICdpbnMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ2LCBbJ2RlbGV0ZScsICdkZWwnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ3LCBbJ2hlbHAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE0NSwgWydzY3JvbGxsb2NrJywgJ3Njcm9sbCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTg4LCBbJ2NvbW1hJywgJywnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE5MCwgWydwZXJpb2QnLCAnLiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTkxLCBbJ3NsYXNoJywgJ2ZvcndhcmRzbGFzaCcsICcvJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxOTIsIFsnZ3JhdmVhY2NlbnQnLCAnYCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMjE5LCBbJ29wZW5icmFja2V0JywgJ1snXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDIyMCwgWydiYWNrc2xhc2gnLCAnXFxcXCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMjIxLCBbJ2Nsb3NlYnJhY2tldCcsICddJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgyMjIsIFsnYXBvc3Ryb3BoZScsICdcXCcnXSk7IC8vIDAtOVxuXG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ4LCBbJ3plcm8nLCAnMCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDksIFsnb25lJywgJzEnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDUwLCBbJ3R3bycsICcyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg1MSwgWyd0aHJlZScsICczJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg1MiwgWydmb3VyJywgJzQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDUzLCBbJ2ZpdmUnLCAnNSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNTQsIFsnc2l4JywgJzYnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDU1LCBbJ3NldmVuJywgJzcnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDU2LCBbJ2VpZ2h0JywgJzgnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDU3LCBbJ25pbmUnLCAnOSddKTsgLy8gbnVtcGFkXG5cbiAgICBsb2NhbGUuYmluZEtleUNvZGUoOTYsIFsnbnVtemVybycsICdudW0wJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg5NywgWydudW1vbmUnLCAnbnVtMSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoOTgsIFsnbnVtdHdvJywgJ251bTInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDk5LCBbJ251bXRocmVlJywgJ251bTMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwMCwgWydudW1mb3VyJywgJ251bTQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwMSwgWydudW1maXZlJywgJ251bTUnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwMiwgWydudW1zaXgnLCAnbnVtNiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTAzLCBbJ251bXNldmVuJywgJ251bTcnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwNCwgWydudW1laWdodCcsICdudW04J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDUsIFsnbnVtbmluZScsICdudW05J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDYsIFsnbnVtbXVsdGlwbHknLCAnbnVtKiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTA3LCBbJ251bWFkZCcsICdudW0rJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDgsIFsnbnVtZW50ZXInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwOSwgWydudW1zdWJ0cmFjdCcsICdudW0tJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTAsIFsnbnVtZGVjaW1hbCcsICdudW0uJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTEsIFsnbnVtZGl2aWRlJywgJ251bS8nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE0NCwgWydudW1sb2NrJywgJ251bSddKTsgLy8gZnVuY3Rpb24ga2V5c1xuXG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExMiwgWydmMSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTEzLCBbJ2YyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTQsIFsnZjMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNSwgWydmNCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTE2LCBbJ2Y1J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTcsIFsnZjYnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExOCwgWydmNyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTE5LCBbJ2Y4J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMjAsIFsnZjknXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMSwgWydmMTAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMiwgWydmMTEnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMywgWydmMTInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNCwgWydmMTMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNSwgWydmMTQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNiwgWydmMTUnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNywgWydmMTYnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyOCwgWydmMTcnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyOSwgWydmMTgnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMCwgWydmMTknXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMSwgWydmMjAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMiwgWydmMjEnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMywgWydmMjInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzNCwgWydmMjMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzNSwgWydmMjQnXSk7IC8vIHNlY29uZGFyeSBrZXkgc3ltYm9sc1xuXG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyBgJywgWyd0aWxkZScsICd+J10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgMScsIFsnZXhjbGFtYXRpb24nLCAnZXhjbGFtYXRpb25wb2ludCcsICchJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgMicsIFsnYXQnLCAnQCddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDMnLCBbJ251bWJlcicsICcjJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgNCcsIFsnZG9sbGFyJywgJ2RvbGxhcnMnLCAnZG9sbGFyc2lnbicsICckJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgNScsIFsncGVyY2VudCcsICclJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgNicsIFsnY2FyZXQnLCAnXiddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDcnLCBbJ2FtcGVyc2FuZCcsICdhbmQnLCAnJiddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDgnLCBbJ2FzdGVyaXNrJywgJyonXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA5JywgWydvcGVucGFyZW4nLCAnKCddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDAnLCBbJ2Nsb3NlcGFyZW4nLCAnKSddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIC0nLCBbJ3VuZGVyc2NvcmUnLCAnXyddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArID0nLCBbJ3BsdXMnLCAnKyddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIFsnLCBbJ29wZW5jdXJseWJyYWNlJywgJ29wZW5jdXJseWJyYWNrZXQnLCAneyddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIF0nLCBbJ2Nsb3NlY3VybHlicmFjZScsICdjbG9zZWN1cmx5YnJhY2tldCcsICd9J10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgXFxcXCcsIFsndmVydGljYWxiYXInLCAnfCddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDsnLCBbJ2NvbG9uJywgJzonXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyBcXCcnLCBbJ3F1b3RhdGlvbm1hcmsnLCAnXFwnJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgISwnLCBbJ29wZW5hbmdsZWJyYWNrZXQnLCAnPCddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIC4nLCBbJ2Nsb3NlYW5nbGVicmFja2V0JywgJz4nXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAvJywgWydxdWVzdGlvbm1hcmsnLCAnPyddKTtcblxuICAgIGlmIChwbGF0Zm9ybS5tYXRjaCgnTWFjJykpIHtcbiAgICAgIGxvY2FsZS5iaW5kTWFjcm8oJ2NvbW1hbmQnLCBbJ21vZCcsICdtb2RpZmllciddKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9jYWxlLmJpbmRNYWNybygnY3RybCcsIFsnbW9kJywgJ21vZGlmaWVyJ10pO1xuICAgIH0gLy9hLXogYW5kIEEtWlxuXG5cbiAgICBmb3IgKHZhciBrZXlDb2RlID0gNjU7IGtleUNvZGUgPD0gOTA7IGtleUNvZGUgKz0gMSkge1xuICAgICAgdmFyIGtleU5hbWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGtleUNvZGUgKyAzMik7XG4gICAgICB2YXIgY2FwaXRhbEtleU5hbWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGtleUNvZGUpO1xuICAgICAgbG9jYWxlLmJpbmRLZXlDb2RlKGtleUNvZGUsIGtleU5hbWUpO1xuICAgICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAnICsga2V5TmFtZSwgY2FwaXRhbEtleU5hbWUpO1xuICAgICAgbG9jYWxlLmJpbmRNYWNybygnY2Fwc2xvY2sgKyAnICsga2V5TmFtZSwgY2FwaXRhbEtleU5hbWUpO1xuICAgIH0gLy8gYnJvd3NlciBjYXZlYXRzXG5cblxuICAgIHZhciBzZW1pY29sb25LZXlDb2RlID0gdXNlckFnZW50Lm1hdGNoKCdGaXJlZm94JykgPyA1OSA6IDE4NjtcbiAgICB2YXIgZGFzaEtleUNvZGUgPSB1c2VyQWdlbnQubWF0Y2goJ0ZpcmVmb3gnKSA/IDE3MyA6IDE4OTtcbiAgICB2YXIgZXF1YWxLZXlDb2RlID0gdXNlckFnZW50Lm1hdGNoKCdGaXJlZm94JykgPyA2MSA6IDE4NztcbiAgICB2YXIgbGVmdENvbW1hbmRLZXlDb2RlO1xuICAgIHZhciByaWdodENvbW1hbmRLZXlDb2RlO1xuXG4gICAgaWYgKHBsYXRmb3JtLm1hdGNoKCdNYWMnKSAmJiAodXNlckFnZW50Lm1hdGNoKCdTYWZhcmknKSB8fCB1c2VyQWdlbnQubWF0Y2goJ0Nocm9tZScpKSkge1xuICAgICAgbGVmdENvbW1hbmRLZXlDb2RlID0gOTE7XG4gICAgICByaWdodENvbW1hbmRLZXlDb2RlID0gOTM7XG4gICAgfSBlbHNlIGlmIChwbGF0Zm9ybS5tYXRjaCgnTWFjJykgJiYgdXNlckFnZW50Lm1hdGNoKCdPcGVyYScpKSB7XG4gICAgICBsZWZ0Q29tbWFuZEtleUNvZGUgPSAxNztcbiAgICAgIHJpZ2h0Q29tbWFuZEtleUNvZGUgPSAxNztcbiAgICB9IGVsc2UgaWYgKHBsYXRmb3JtLm1hdGNoKCdNYWMnKSAmJiB1c2VyQWdlbnQubWF0Y2goJ0ZpcmVmb3gnKSkge1xuICAgICAgbGVmdENvbW1hbmRLZXlDb2RlID0gMjI0O1xuICAgICAgcmlnaHRDb21tYW5kS2V5Q29kZSA9IDIyNDtcbiAgICB9XG5cbiAgICBsb2NhbGUuYmluZEtleUNvZGUoc2VtaWNvbG9uS2V5Q29kZSwgWydzZW1pY29sb24nLCAnOyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoZGFzaEtleUNvZGUsIFsnZGFzaCcsICctJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZShlcXVhbEtleUNvZGUsIFsnZXF1YWwnLCAnZXF1YWxzaWduJywgJz0nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKGxlZnRDb21tYW5kS2V5Q29kZSwgWydjb21tYW5kJywgJ3dpbmRvd3MnLCAnd2luJywgJ3N1cGVyJywgJ2xlZnRjb21tYW5kJywgJ2xlZnR3aW5kb3dzJywgJ2xlZnR3aW4nLCAnbGVmdHN1cGVyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZShyaWdodENvbW1hbmRLZXlDb2RlLCBbJ2NvbW1hbmQnLCAnd2luZG93cycsICd3aW4nLCAnc3VwZXInLCAncmlnaHRjb21tYW5kJywgJ3JpZ2h0d2luZG93cycsICdyaWdodHdpbicsICdyaWdodHN1cGVyJ10pOyAvLyBraWxsIGtleXNcblxuICAgIGxvY2FsZS5zZXRLaWxsS2V5KCdjb21tYW5kJyk7XG4gIH1cblxuICB2YXIga2V5Ym9hcmQgPSBuZXcgS2V5Ym9hcmQoKTtcbiAga2V5Ym9hcmQuc2V0TG9jYWxlKCd1cycsIHVzKTtcbiAga2V5Ym9hcmQuS2V5Ym9hcmQgPSBLZXlib2FyZDtcbiAga2V5Ym9hcmQuTG9jYWxlID0gTG9jYWxlO1xuICBrZXlib2FyZC5LZXlDb21ibyA9IEtleUNvbWJvO1xuXG4gIHJldHVybiBrZXlib2FyZDtcblxufSkpKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKbWFXeGxJam9pYTJWNVltOWhjbVF1YW5NaUxDSnpiM1Z5WTJWeklqcGJJaTR1TDJ4cFlpOXJaWGt0WTI5dFltOHVhbk1pTENJdUxpOXNhV0l2Ykc5allXeGxMbXB6SWl3aUxpNHZiR2xpTDJ0bGVXSnZZWEprTG1weklpd2lMaTR2Ykc5allXeGxjeTkxY3k1cWN5SXNJaTR1TDJsdVpHVjRMbXB6SWwwc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYklseHVaWGh3YjNKMElHTnNZWE56SUV0bGVVTnZiV0p2SUh0Y2JpQWdZMjl1YzNSeWRXTjBiM0lvYTJWNVEyOXRZbTlUZEhJcElIdGNiaUFnSUNCMGFHbHpMbk52ZFhKalpWTjBjaUE5SUd0bGVVTnZiV0p2VTNSeU8xeHVJQ0FnSUhSb2FYTXVjM1ZpUTI5dFltOXpJRDBnUzJWNVEyOXRZbTh1Y0dGeWMyVkRiMjFpYjFOMGNpaHJaWGxEYjIxaWIxTjBjaWs3WEc0Z0lDQWdkR2hwY3k1clpYbE9ZVzFsY3lBZ1BTQjBhR2x6TG5OMVlrTnZiV0p2Y3k1eVpXUjFZMlVvS0cxbGJXOHNJRzVsZUhSVGRXSkRiMjFpYnlrZ1BUNWNiaUFnSUNBZ0lHMWxiVzh1WTI5dVkyRjBLRzVsZUhSVGRXSkRiMjFpYnlrc0lGdGRLVHRjYmlBZ2ZWeHVYRzRnSUdOb1pXTnJLSEJ5WlhOelpXUkxaWGxPWVcxbGN5a2dlMXh1SUNBZ0lHeGxkQ0J6ZEdGeWRHbHVaMHRsZVU1aGJXVkpibVJsZUNBOUlEQTdYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FTQTlJREE3SUdrZ1BDQjBhR2x6TG5OMVlrTnZiV0p2Y3k1c1pXNW5kR2c3SUdrZ0t6MGdNU2tnZTF4dUlDQWdJQ0FnYzNSaGNuUnBibWRMWlhsT1lXMWxTVzVrWlhnZ1BTQjBhR2x6TGw5amFHVmphMU4xWWtOdmJXSnZLRnh1SUNBZ0lDQWdJQ0IwYUdsekxuTjFZa052YldKdmMxdHBYU3hjYmlBZ0lDQWdJQ0FnYzNSaGNuUnBibWRMWlhsT1lXMWxTVzVrWlhnc1hHNGdJQ0FnSUNBZ0lIQnlaWE56WldSTFpYbE9ZVzFsYzF4dUlDQWdJQ0FnS1R0Y2JpQWdJQ0FnSUdsbUlDaHpkR0Z5ZEdsdVowdGxlVTVoYldWSmJtUmxlQ0E5UFQwZ0xURXBJSHNnY21WMGRYSnVJR1poYkhObE95QjlYRzRnSUNBZ2ZWeHVJQ0FnSUhKbGRIVnliaUIwY25WbE8xeHVJQ0I5TzF4dVhHNGdJR2x6UlhGMVlXd29iM1JvWlhKTFpYbERiMjFpYnlrZ2UxeHVJQ0FnSUdsbUlDaGNiaUFnSUNBZ0lDRnZkR2hsY2t0bGVVTnZiV0p2SUh4OFhHNGdJQ0FnSUNCMGVYQmxiMllnYjNSb1pYSkxaWGxEYjIxaWJ5QWhQVDBnSjNOMGNtbHVaeWNnSmlaY2JpQWdJQ0FnSUhSNWNHVnZaaUJ2ZEdobGNrdGxlVU52YldKdklDRTlQU0FuYjJKcVpXTjBKMXh1SUNBZ0lDa2dleUJ5WlhSMWNtNGdabUZzYzJVN0lIMWNibHh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdiM1JvWlhKTFpYbERiMjFpYnlBOVBUMGdKM04wY21sdVp5Y3BJSHRjYmlBZ0lDQWdJRzkwYUdWeVMyVjVRMjl0WW04Z1BTQnVaWGNnUzJWNVEyOXRZbThvYjNSb1pYSkxaWGxEYjIxaWJ5azdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLSFJvYVhNdWMzVmlRMjl0WW05ekxteGxibWQwYUNBaFBUMGdiM1JvWlhKTFpYbERiMjFpYnk1emRXSkRiMjFpYjNNdWJHVnVaM1JvS1NCN1hHNGdJQ0FnSUNCeVpYUjFjbTRnWm1Gc2MyVTdYRzRnSUNBZ2ZWeHVJQ0FnSUdadmNpQW9iR1YwSUdrZ1BTQXdPeUJwSUR3Z2RHaHBjeTV6ZFdKRGIyMWliM011YkdWdVozUm9PeUJwSUNzOUlERXBJSHRjYmlBZ0lDQWdJR2xtSUNoMGFHbHpMbk4xWWtOdmJXSnZjMXRwWFM1c1pXNW5kR2dnSVQwOUlHOTBhR1Z5UzJWNVEyOXRZbTh1YzNWaVEyOXRZbTl6VzJsZExteGxibWQwYUNrZ2UxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1ptRnNjMlU3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmVnh1WEc0Z0lDQWdabTl5SUNoc1pYUWdhU0E5SURBN0lHa2dQQ0IwYUdsekxuTjFZa052YldKdmN5NXNaVzVuZEdnN0lHa2dLejBnTVNrZ2UxeHVJQ0FnSUNBZ1kyOXVjM1FnYzNWaVEyOXRZbThnSUNBZ0lDQTlJSFJvYVhNdWMzVmlRMjl0WW05elcybGRPMXh1SUNBZ0lDQWdZMjl1YzNRZ2IzUm9aWEpUZFdKRGIyMWlieUE5SUc5MGFHVnlTMlY1UTI5dFltOHVjM1ZpUTI5dFltOXpXMmxkTG5Oc2FXTmxLREFwTzF4dVhHNGdJQ0FnSUNCbWIzSWdLR3hsZENCcUlEMGdNRHNnYWlBOElITjFZa052YldKdkxteGxibWQwYURzZ2FpQXJQU0F4S1NCN1hHNGdJQ0FnSUNBZ0lHTnZibk4wSUd0bGVVNWhiV1VnUFNCemRXSkRiMjFpYjF0cVhUdGNiaUFnSUNBZ0lDQWdZMjl1YzNRZ2FXNWtaWGdnSUNBOUlHOTBhR1Z5VTNWaVEyOXRZbTh1YVc1a1pYaFBaaWhyWlhsT1lXMWxLVHRjYmx4dUlDQWdJQ0FnSUNCcFppQW9hVzVrWlhnZ1BpQXRNU2tnZTF4dUlDQWdJQ0FnSUNBZ0lHOTBhR1Z5VTNWaVEyOXRZbTh1YzNCc2FXTmxLR2x1WkdWNExDQXhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnYVdZZ0tHOTBhR1Z5VTNWaVEyOXRZbTh1YkdWdVozUm9JQ0U5UFNBd0tTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQm1ZV3h6WlR0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc1Y2JpQWdJQ0J5WlhSMWNtNGdkSEoxWlR0Y2JpQWdmVHRjYmx4dUlDQmZZMmhsWTJ0VGRXSkRiMjFpYnloemRXSkRiMjFpYnl3Z2MzUmhjblJwYm1kTFpYbE9ZVzFsU1c1a1pYZ3NJSEJ5WlhOelpXUkxaWGxPWVcxbGN5a2dlMXh1SUNBZ0lITjFZa052YldKdklEMGdjM1ZpUTI5dFltOHVjMnhwWTJVb01DazdYRzRnSUNBZ2NISmxjM05sWkV0bGVVNWhiV1Z6SUQwZ2NISmxjM05sWkV0bGVVNWhiV1Z6TG5Oc2FXTmxLSE4wWVhKMGFXNW5TMlY1VG1GdFpVbHVaR1Y0S1R0Y2JseHVJQ0FnSUd4bGRDQmxibVJKYm1SbGVDQTlJSE4wWVhKMGFXNW5TMlY1VG1GdFpVbHVaR1Y0TzF4dUlDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnYzNWaVEyOXRZbTh1YkdWdVozUm9PeUJwSUNzOUlERXBJSHRjYmx4dUlDQWdJQ0FnYkdWMElHdGxlVTVoYldVZ1BTQnpkV0pEYjIxaWIxdHBYVHRjYmlBZ0lDQWdJR2xtSUNoclpYbE9ZVzFsV3pCZElEMDlQU0FuWEZ4Y1hDY3BJSHRjYmlBZ0lDQWdJQ0FnWTI5dWMzUWdaWE5qWVhCbFpFdGxlVTVoYldVZ1BTQnJaWGxPWVcxbExuTnNhV05sS0RFcE8xeHVJQ0FnSUNBZ0lDQnBaaUFvWEc0Z0lDQWdJQ0FnSUNBZ1pYTmpZWEJsWkV0bGVVNWhiV1VnUFQwOUlFdGxlVU52YldKdkxtTnZiV0p2UkdWc2FXMXBibUYwYjNJZ2ZIeGNiaUFnSUNBZ0lDQWdJQ0JsYzJOaGNHVmtTMlY1VG1GdFpTQTlQVDBnUzJWNVEyOXRZbTh1YTJWNVJHVnNhVzFwYm1GMGIzSmNiaUFnSUNBZ0lDQWdLU0I3WEc0Z0lDQWdJQ0FnSUNBZ2EyVjVUbUZ0WlNBOUlHVnpZMkZ3WldSTFpYbE9ZVzFsTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNCOVhHNWNiaUFnSUNBZ0lHTnZibk4wSUdsdVpHVjRJRDBnY0hKbGMzTmxaRXRsZVU1aGJXVnpMbWx1WkdWNFQyWW9hMlY1VG1GdFpTazdYRzRnSUNBZ0lDQnBaaUFvYVc1a1pYZ2dQaUF0TVNrZ2UxeHVJQ0FnSUNBZ0lDQnpkV0pEYjIxaWJ5NXpjR3hwWTJVb2FTd2dNU2s3WEc0Z0lDQWdJQ0FnSUdrZ0xUMGdNVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHbHVaR1Y0SUQ0Z1pXNWtTVzVrWlhncElIdGNiaUFnSUNBZ0lDQWdJQ0JsYm1SSmJtUmxlQ0E5SUdsdVpHVjRPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUdsbUlDaHpkV0pEYjIxaWJ5NXNaVzVuZEdnZ1BUMDlJREFwSUh0Y2JpQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z1pXNWtTVzVrWlhnN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnY21WMGRYSnVJQzB4TzF4dUlDQjlPMXh1ZlZ4dVhHNUxaWGxEYjIxaWJ5NWpiMjFpYjBSbGJHbHRhVzVoZEc5eUlEMGdKejRuTzF4dVMyVjVRMjl0WW04dWEyVjVSR1ZzYVcxcGJtRjBiM0lnSUNBOUlDY3JKenRjYmx4dVMyVjVRMjl0WW04dWNHRnljMlZEYjIxaWIxTjBjaUE5SUdaMWJtTjBhVzl1S0d0bGVVTnZiV0p2VTNSeUtTQjdYRzRnSUdOdmJuTjBJSE4xWWtOdmJXSnZVM1J5Y3lBOUlFdGxlVU52YldKdkxsOXpjR3hwZEZOMGNpaHJaWGxEYjIxaWIxTjBjaXdnUzJWNVEyOXRZbTh1WTI5dFltOUVaV3hwYldsdVlYUnZjaWs3WEc0Z0lHTnZibk4wSUdOdmJXSnZJQ0FnSUNBZ0lDQTlJRnRkTzF4dVhHNGdJR1p2Y2lBb2JHVjBJR2tnUFNBd0lEc2dhU0E4SUhOMVlrTnZiV0p2VTNSeWN5NXNaVzVuZEdnN0lHa2dLejBnTVNrZ2UxeHVJQ0FnSUdOdmJXSnZMbkIxYzJnb1MyVjVRMjl0WW04dVgzTndiR2wwVTNSeUtITjFZa052YldKdlUzUnljMXRwWFN3Z1MyVjVRMjl0WW04dWEyVjVSR1ZzYVcxcGJtRjBiM0lwS1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnWTI5dFltODdYRzU5WEc1Y2JrdGxlVU52YldKdkxsOXpjR3hwZEZOMGNpQTlJR1oxYm1OMGFXOXVLSE4wY2l3Z1pHVnNhVzFwYm1GMGIzSXBJSHRjYmlBZ1kyOXVjM1FnY3lBZ1BTQnpkSEk3WEc0Z0lHTnZibk4wSUdRZ0lEMGdaR1ZzYVcxcGJtRjBiM0k3WEc0Z0lHeGxkQ0JqSUNBOUlDY25PMXh1SUNCamIyNXpkQ0JqWVNBOUlGdGRPMXh1WEc0Z0lHWnZjaUFvYkdWMElHTnBJRDBnTURzZ1kya2dQQ0J6TG14bGJtZDBhRHNnWTJrZ0t6MGdNU2tnZTF4dUlDQWdJR2xtSUNoamFTQStJREFnSmlZZ2MxdGphVjBnUFQwOUlHUWdKaVlnYzF0amFTQXRJREZkSUNFOVBTQW5YRnhjWENjcElIdGNiaUFnSUNBZ0lHTmhMbkIxYzJnb1l5NTBjbWx0S0NrcE8xeHVJQ0FnSUNBZ1l5QTlJQ2NuTzF4dUlDQWdJQ0FnWTJrZ0t6MGdNVHRjYmlBZ0lDQjlYRzRnSUNBZ1l5QXJQU0J6VzJOcFhUdGNiaUFnZlZ4dUlDQnBaaUFvWXlrZ2V5QmpZUzV3ZFhOb0tHTXVkSEpwYlNncEtUc2dmVnh1WEc0Z0lISmxkSFZ5YmlCallUdGNibjA3WEc0aUxDSnBiWEJ2Y25RZ2V5QkxaWGxEYjIxaWJ5QjlJR1p5YjIwZ0p5NHZhMlY1TFdOdmJXSnZKenRjYmx4dVhHNWxlSEJ2Y25RZ1kyeGhjM01nVEc5allXeGxJSHRjYmlBZ1kyOXVjM1J5ZFdOMGIzSW9ibUZ0WlNrZ2UxeHVJQ0FnSUhSb2FYTXViRzlqWVd4bFRtRnRaU0FnSUNBZ0lDQWdJQ0E5SUc1aGJXVTdYRzRnSUNBZ2RHaHBjeTVoWTNScGRtVlVZWEpuWlhSTFpYbHpJRDBnVzEwN1hHNGdJQ0FnZEdocGN5NXdjbVZ6YzJWa1MyVjVjeUFnSUNBZ0lDQWdJRDBnVzEwN1hHNGdJQ0FnZEdocGN5NWZZWEJ3YkdsbFpFMWhZM0p2Y3lBZ0lDQWdJRDBnVzEwN1hHNGdJQ0FnZEdocGN5NWZhMlY1VFdGd0lDQWdJQ0FnSUNBZ0lDQWdJRDBnZTMwN1hHNGdJQ0FnZEdocGN5NWZhMmxzYkV0bGVVTnZaR1Z6SUNBZ0lDQWdJRDBnVzEwN1hHNGdJQ0FnZEdocGN5NWZiV0ZqY205eklDQWdJQ0FnSUNBZ0lDQWdJRDBnVzEwN1hHNGdJSDFjYmx4dUlDQmlhVzVrUzJWNVEyOWtaU2hyWlhsRGIyUmxMQ0JyWlhsT1lXMWxjeWtnZTF4dUlDQWdJR2xtSUNoMGVYQmxiMllnYTJWNVRtRnRaWE1nUFQwOUlDZHpkSEpwYm1jbktTQjdYRzRnSUNBZ0lDQnJaWGxPWVcxbGN5QTlJRnRyWlhsT1lXMWxjMTA3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdkR2hwY3k1ZmEyVjVUV0Z3VzJ0bGVVTnZaR1ZkSUQwZ2EyVjVUbUZ0WlhNN1hHNGdJSDA3WEc1Y2JpQWdZbWx1WkUxaFkzSnZLR3RsZVVOdmJXSnZVM1J5TENCclpYbE9ZVzFsY3lrZ2UxeHVJQ0FnSUdsbUlDaDBlWEJsYjJZZ2EyVjVUbUZ0WlhNZ1BUMDlJQ2R6ZEhKcGJtY25LU0I3WEc0Z0lDQWdJQ0JyWlhsT1lXMWxjeUE5SUZzZ2EyVjVUbUZ0WlhNZ1hUdGNiaUFnSUNCOVhHNWNiaUFnSUNCc1pYUWdhR0Z1Wkd4bGNpQTlJRzUxYkd3N1hHNGdJQ0FnYVdZZ0tIUjVjR1Z2WmlCclpYbE9ZVzFsY3lBOVBUMGdKMloxYm1OMGFXOXVKeWtnZTF4dUlDQWdJQ0FnYUdGdVpHeGxjaUE5SUd0bGVVNWhiV1Z6TzF4dUlDQWdJQ0FnYTJWNVRtRnRaWE1nUFNCdWRXeHNPMXh1SUNBZ0lIMWNibHh1SUNBZ0lHTnZibk4wSUcxaFkzSnZJRDBnZTF4dUlDQWdJQ0FnYTJWNVEyOXRZbThnT2lCdVpYY2dTMlY1UTI5dFltOG9hMlY1UTI5dFltOVRkSElwTEZ4dUlDQWdJQ0FnYTJWNVRtRnRaWE1nT2lCclpYbE9ZVzFsY3l4Y2JpQWdJQ0FnSUdoaGJtUnNaWElnSURvZ2FHRnVaR3hsY2x4dUlDQWdJSDA3WEc1Y2JpQWdJQ0IwYUdsekxsOXRZV055YjNNdWNIVnphQ2h0WVdOeWJ5azdYRzRnSUgwN1hHNWNiaUFnWjJWMFMyVjVRMjlrWlhNb2EyVjVUbUZ0WlNrZ2UxeHVJQ0FnSUdOdmJuTjBJR3RsZVVOdlpHVnpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaGpiMjV6ZENCclpYbERiMlJsSUdsdUlIUm9hWE11WDJ0bGVVMWhjQ2tnZTF4dUlDQWdJQ0FnWTI5dWMzUWdhVzVrWlhnZ1BTQjBhR2x6TGw5clpYbE5ZWEJiYTJWNVEyOWtaVjB1YVc1a1pYaFBaaWhyWlhsT1lXMWxLVHRjYmlBZ0lDQWdJR2xtSUNocGJtUmxlQ0ErSUMweEtTQjdJR3RsZVVOdlpHVnpMbkIxYzJnb2EyVjVRMjlrWlh3d0tUc2dmVnh1SUNBZ0lIMWNiaUFnSUNCeVpYUjFjbTRnYTJWNVEyOWtaWE03WEc0Z0lIMDdYRzVjYmlBZ1oyVjBTMlY1VG1GdFpYTW9hMlY1UTI5a1pTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDlyWlhsTllYQmJhMlY1UTI5a1pWMGdmSHdnVzEwN1hHNGdJSDA3WEc1Y2JpQWdjMlYwUzJsc2JFdGxlU2hyWlhsRGIyUmxLU0I3WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJyWlhsRGIyUmxJRDA5UFNBbmMzUnlhVzVuSnlrZ2UxeHVJQ0FnSUNBZ1kyOXVjM1FnYTJWNVEyOWtaWE1nUFNCMGFHbHpMbWRsZEV0bGVVTnZaR1Z6S0d0bGVVTnZaR1VwTzF4dUlDQWdJQ0FnWm05eUlDaHNaWFFnYVNBOUlEQTdJR2tnUENCclpYbERiMlJsY3k1c1pXNW5kR2c3SUdrZ0t6MGdNU2tnZTF4dUlDQWdJQ0FnSUNCMGFHbHpMbk5sZEV0cGJHeExaWGtvYTJWNVEyOWtaWE5iYVYwcE8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJSDFjYmx4dUlDQWdJSFJvYVhNdVgydHBiR3hMWlhsRGIyUmxjeTV3ZFhOb0tHdGxlVU52WkdVcE8xeHVJQ0I5TzF4dVhHNGdJSEJ5WlhOelMyVjVLR3RsZVVOdlpHVXBJSHRjYmlBZ0lDQnBaaUFvZEhsd1pXOW1JR3RsZVVOdlpHVWdQVDA5SUNkemRISnBibWNuS1NCN1hHNGdJQ0FnSUNCamIyNXpkQ0JyWlhsRGIyUmxjeUE5SUhSb2FYTXVaMlYwUzJWNVEyOWtaWE1vYTJWNVEyOWtaU2s3WEc0Z0lDQWdJQ0JtYjNJZ0tHeGxkQ0JwSUQwZ01Ec2dhU0E4SUd0bGVVTnZaR1Z6TG14bGJtZDBhRHNnYVNBclBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVjSEpsYzNOTFpYa29hMlY1UTI5a1pYTmJhVjBwTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIUm9hWE11WVdOMGFYWmxWR0Z5WjJWMFMyVjVjeTVzWlc1bmRHZ2dQU0F3TzF4dUlDQWdJR052Ym5OMElHdGxlVTVoYldWeklEMGdkR2hwY3k1blpYUkxaWGxPWVcxbGN5aHJaWGxEYjJSbEtUdGNiaUFnSUNCbWIzSWdLR3hsZENCcElEMGdNRHNnYVNBOElHdGxlVTVoYldWekxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNCMGFHbHpMbUZqZEdsMlpWUmhjbWRsZEV0bGVYTXVjSFZ6YUNoclpYbE9ZVzFsYzF0cFhTazdYRzRnSUNBZ0lDQnBaaUFvZEdocGN5NXdjbVZ6YzJWa1MyVjVjeTVwYm1SbGVFOW1LR3RsZVU1aGJXVnpXMmxkS1NBOVBUMGdMVEVwSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV3Y21WemMyVmtTMlY1Y3k1d2RYTm9LR3RsZVU1aGJXVnpXMmxkS1R0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc1Y2JpQWdJQ0IwYUdsekxsOWhjSEJzZVUxaFkzSnZjeWdwTzF4dUlDQjlPMXh1WEc0Z0lISmxiR1ZoYzJWTFpYa29hMlY1UTI5a1pTa2dlMXh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdhMlY1UTI5a1pTQTlQVDBnSjNOMGNtbHVaeWNwSUh0Y2JpQWdJQ0FnSUdOdmJuTjBJR3RsZVVOdlpHVnpJRDBnZEdocGN5NW5aWFJMWlhsRGIyUmxjeWhyWlhsRGIyUmxLVHRjYmlBZ0lDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnYTJWNVEyOWtaWE11YkdWdVozUm9PeUJwSUNzOUlERXBJSHRjYmlBZ0lDQWdJQ0FnZEdocGN5NXlaV3hsWVhObFMyVjVLR3RsZVVOdlpHVnpXMmxkS1R0Y2JpQWdJQ0FnSUgxY2JseHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0JqYjI1emRDQnJaWGxPWVcxbGN5QWdJQ0FnSUNBZ0lEMGdkR2hwY3k1blpYUkxaWGxPWVcxbGN5aHJaWGxEYjJSbEtUdGNiaUFnSUNBZ0lHTnZibk4wSUd0cGJHeExaWGxEYjJSbFNXNWtaWGdnUFNCMGFHbHpMbDlyYVd4c1MyVjVRMjlrWlhNdWFXNWtaWGhQWmloclpYbERiMlJsS1R0Y2JseHVJQ0FnSUNBZ2FXWWdLR3RwYkd4TFpYbERiMlJsU1c1a1pYZ2dJVDA5SUMweEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWNISmxjM05sWkV0bGVYTXViR1Z1WjNSb0lEMGdNRHRjYmlBZ0lDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnYTJWNVRtRnRaWE11YkdWdVozUm9PeUJwSUNzOUlERXBJSHRjYmlBZ0lDQWdJQ0FnSUNCamIyNXpkQ0JwYm1SbGVDQTlJSFJvYVhNdWNISmxjM05sWkV0bGVYTXVhVzVrWlhoUFppaHJaWGxPWVcxbGMxdHBYU2s3WEc0Z0lDQWdJQ0FnSUNBZ2FXWWdLR2x1WkdWNElENGdMVEVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNdWNISmxjM05sWkV0bGVYTXVjM0JzYVdObEtHbHVaR1Y0TENBeEtUdGNiaUFnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ2RHaHBjeTVoWTNScGRtVlVZWEpuWlhSTFpYbHpMbXhsYm1kMGFDQTlJREE3WEc0Z0lDQWdJQ0IwYUdsekxsOWpiR1ZoY2sxaFkzSnZjeWdwTzF4dUlDQWdJSDFjYmlBZ2ZUdGNibHh1SUNCZllYQndiSGxOWVdOeWIzTW9LU0I3WEc0Z0lDQWdZMjl1YzNRZ2JXRmpjbTl6SUQwZ2RHaHBjeTVmYldGamNtOXpMbk5zYVdObEtEQXBPMXh1SUNBZ0lHWnZjaUFvYkdWMElHa2dQU0F3T3lCcElEd2diV0ZqY205ekxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNCamIyNXpkQ0J0WVdOeWJ5QTlJRzFoWTNKdmMxdHBYVHRjYmlBZ0lDQWdJR2xtSUNodFlXTnlieTVyWlhsRGIyMWlieTVqYUdWamF5aDBhR2x6TG5CeVpYTnpaV1JMWlhsektTa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2JXRmpjbTh1YUdGdVpHeGxjaWtnZTF4dUlDQWdJQ0FnSUNBZ0lHMWhZM0p2TG10bGVVNWhiV1Z6SUQwZ2JXRmpjbTh1YUdGdVpHeGxjaWgwYUdsekxuQnlaWE56WldSTFpYbHpLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCbWIzSWdLR3hsZENCcUlEMGdNRHNnYWlBOElHMWhZM0p2TG10bGVVNWhiV1Z6TG14bGJtZDBhRHNnYWlBclBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWNISmxjM05sWkV0bGVYTXVhVzVrWlhoUFppaHRZV055Ynk1clpYbE9ZVzFsYzF0cVhTa2dQVDA5SUMweEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMGFHbHpMbkJ5WlhOelpXUkxaWGx6TG5CMWMyZ29iV0ZqY204dWEyVjVUbUZ0WlhOYmFsMHBPMXh1SUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjBhR2x6TGw5aGNIQnNhV1ZrVFdGamNtOXpMbkIxYzJnb2JXRmpjbThwTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJSDFjYmlBZ2ZUdGNibHh1SUNCZlkyeGxZWEpOWVdOeWIzTW9LU0I3WEc0Z0lDQWdabTl5SUNoc1pYUWdhU0E5SURBN0lHa2dQQ0IwYUdsekxsOWhjSEJzYVdWa1RXRmpjbTl6TG14bGJtZDBhRHNnYVNBclBTQXhLU0I3WEc0Z0lDQWdJQ0JqYjI1emRDQnRZV055YnlBOUlIUm9hWE11WDJGd2NHeHBaV1JOWVdOeWIzTmJhVjA3WEc0Z0lDQWdJQ0JwWmlBb0lXMWhZM0p2TG10bGVVTnZiV0p2TG1Ob1pXTnJLSFJvYVhNdWNISmxjM05sWkV0bGVYTXBLU0I3WEc0Z0lDQWdJQ0FnSUdadmNpQW9iR1YwSUdvZ1BTQXdPeUJxSUR3Z2JXRmpjbTh1YTJWNVRtRnRaWE11YkdWdVozUm9PeUJxSUNzOUlERXBJSHRjYmlBZ0lDQWdJQ0FnSUNCamIyNXpkQ0JwYm1SbGVDQTlJSFJvYVhNdWNISmxjM05sWkV0bGVYTXVhVzVrWlhoUFppaHRZV055Ynk1clpYbE9ZVzFsYzF0cVhTazdYRzRnSUNBZ0lDQWdJQ0FnYVdZZ0tHbHVaR1Y0SUQ0Z0xURXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE11Y0hKbGMzTmxaRXRsZVhNdWMzQnNhV05sS0dsdVpHVjRMQ0F4S1R0Y2JpQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWhZM0p2TG1oaGJtUnNaWElwSUh0Y2JpQWdJQ0FnSUNBZ0lDQnRZV055Ynk1clpYbE9ZVzFsY3lBOUlHNTFiR3c3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2RHaHBjeTVmWVhCd2JHbGxaRTFoWTNKdmN5NXpjR3hwWTJVb2FTd2dNU2s3WEc0Z0lDQWdJQ0FnSUdrZ0xUMGdNVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUgxY2JuMWNiaUlzSW1sdGNHOXlkQ0I3SUV4dlkyRnNaU0I5SUdaeWIyMGdKeTR2Ykc5allXeGxKenRjYm1sdGNHOXlkQ0I3SUV0bGVVTnZiV0p2SUgwZ1puSnZiU0FuTGk5clpYa3RZMjl0WW04bk8xeHVYRzVjYm1WNGNHOXlkQ0JqYkdGemN5QkxaWGxpYjJGeVpDQjdYRzRnSUdOdmJuTjBjblZqZEc5eUtIUmhjbWRsZEZkcGJtUnZkeXdnZEdGeVoyVjBSV3hsYldWdWRDd2dkR0Z5WjJWMFVHeGhkR1p2Y20wc0lIUmhjbWRsZEZWelpYSkJaMlZ1ZENrZ2UxeHVJQ0FnSUhSb2FYTXVYMnh2WTJGc1pTQWdJQ0FnSUNBZ0lDQWdJQ0FnSUQwZ2JuVnNiRHRjYmlBZ0lDQjBhR2x6TGw5amRYSnlaVzUwUTI5dWRHVjRkQ0FnSUNBZ0lDQTlJQ2NuTzF4dUlDQWdJSFJvYVhNdVgyTnZiblJsZUhSeklDQWdJQ0FnSUNBZ0lDQWdJRDBnZTMwN1hHNGdJQ0FnZEdocGN5NWZiR2x6ZEdWdVpYSnpJQ0FnSUNBZ0lDQWdJQ0FnUFNCYlhUdGNiaUFnSUNCMGFHbHpMbDloY0hCc2FXVmtUR2x6ZEdWdVpYSnpJQ0FnSUNBOUlGdGRPMXh1SUNBZ0lIUm9hWE11WDJ4dlkyRnNaWE1nSUNBZ0lDQWdJQ0FnSUNBZ0lEMGdlMzA3WEc0Z0lDQWdkR2hwY3k1ZmRHRnlaMlYwUld4bGJXVnVkQ0FnSUNBZ0lDQWdQU0J1ZFd4c08xeHVJQ0FnSUhSb2FYTXVYM1JoY21kbGRGZHBibVJ2ZHlBZ0lDQWdJQ0FnSUQwZ2JuVnNiRHRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJRYkdGMFptOXliU0FnSUNBZ0lDQTlJQ2NuTzF4dUlDQWdJSFJvYVhNdVgzUmhjbWRsZEZWelpYSkJaMlZ1ZENBZ0lDQWdJRDBnSnljN1hHNGdJQ0FnZEdocGN5NWZhWE5OYjJSbGNtNUNjbTkzYzJWeUlDQWdJQ0FnUFNCbVlXeHpaVHRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJMWlhsRWIzZHVRbWx1WkdsdVp5QTlJRzUxYkd3N1hHNGdJQ0FnZEdocGN5NWZkR0Z5WjJWMFMyVjVWWEJDYVc1a2FXNW5JQ0FnUFNCdWRXeHNPMXh1SUNBZ0lIUm9hWE11WDNSaGNtZGxkRkpsYzJWMFFtbHVaR2x1WnlBZ0lEMGdiblZzYkR0Y2JpQWdJQ0IwYUdsekxsOXdZWFZ6WldRZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0E5SUdaaGJITmxPMXh1WEc0Z0lDQWdkR2hwY3k1ZlkyOXVkR1Y0ZEhNdVoyeHZZbUZzSUQwZ2UxeHVJQ0FnSUNBZ2JHbHpkR1Z1WlhKek9pQjBhR2x6TGw5c2FYTjBaVzVsY25Nc1hHNGdJQ0FnSUNCMFlYSm5aWFJYYVc1a2IzY3NYRzRnSUNBZ0lDQjBZWEpuWlhSRmJHVnRaVzUwTEZ4dUlDQWdJQ0FnZEdGeVoyVjBVR3hoZEdadmNtMHNYRzRnSUNBZ0lDQjBZWEpuWlhSVmMyVnlRV2RsYm5SY2JpQWdJQ0I5TzF4dVhHNGdJQ0FnZEdocGN5NXpaWFJEYjI1MFpYaDBLQ2RuYkc5aVlXd25LVHRjYmlBZ2ZWeHVYRzRnSUhObGRFeHZZMkZzWlNoc2IyTmhiR1ZPWVcxbExDQnNiMk5oYkdWQ2RXbHNaR1Z5S1NCN1hHNGdJQ0FnYkdWMElHeHZZMkZzWlNBOUlHNTFiR3c3WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJzYjJOaGJHVk9ZVzFsSUQwOVBTQW5jM1J5YVc1bkp5a2dlMXh1WEc0Z0lDQWdJQ0JwWmlBb2JHOWpZV3hsUW5WcGJHUmxjaWtnZTF4dUlDQWdJQ0FnSUNCc2IyTmhiR1VnUFNCdVpYY2dURzlqWVd4bEtHeHZZMkZzWlU1aGJXVXBPMXh1SUNBZ0lDQWdJQ0JzYjJOaGJHVkNkV2xzWkdWeUtHeHZZMkZzWlN3Z2RHaHBjeTVmZEdGeVoyVjBVR3hoZEdadmNtMHNJSFJvYVhNdVgzUmhjbWRsZEZWelpYSkJaMlZ1ZENrN1hHNGdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNCc2IyTmhiR1VnUFNCMGFHbHpMbDlzYjJOaGJHVnpXMnh2WTJGc1pVNWhiV1ZkSUh4OElHNTFiR3c3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lHeHZZMkZzWlNBZ0lDQWdQU0JzYjJOaGJHVk9ZVzFsTzF4dUlDQWdJQ0FnYkc5allXeGxUbUZ0WlNBOUlHeHZZMkZzWlM1ZmJHOWpZV3hsVG1GdFpUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMGFHbHpMbDlzYjJOaGJHVWdJQ0FnSUNBZ0lDQWdJQ0FnSUQwZ2JHOWpZV3hsTzF4dUlDQWdJSFJvYVhNdVgyeHZZMkZzWlhOYmJHOWpZV3hsVG1GdFpWMGdQU0JzYjJOaGJHVTdYRzRnSUNBZ2FXWWdLR3h2WTJGc1pTa2dlMXh1SUNBZ0lDQWdkR2hwY3k1ZmJHOWpZV3hsTG5CeVpYTnpaV1JMWlhseklEMGdiRzlqWVd4bExuQnlaWE56WldSTFpYbHpPMXh1SUNBZ0lIMWNibHh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNCOVhHNWNiaUFnWjJWMFRHOWpZV3hsS0d4dlkyRnNUbUZ0WlNrZ2UxeHVJQ0FnSUd4dlkyRnNUbUZ0WlNCOGZDQW9iRzlqWVd4T1lXMWxJRDBnZEdocGN5NWZiRzlqWVd4bExteHZZMkZzWlU1aGJXVXBPMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDlzYjJOaGJHVnpXMnh2WTJGc1RtRnRaVjBnZkh3Z2JuVnNiRHRjYmlBZ2ZWeHVYRzRnSUdKcGJtUW9hMlY1UTI5dFltOVRkSElzSUhCeVpYTnpTR0Z1Wkd4bGNpd2djbVZzWldGelpVaGhibVJzWlhJc0lIQnlaWFpsYm5SU1pYQmxZWFJDZVVSbFptRjFiSFFwSUh0Y2JpQWdJQ0JwWmlBb2EyVjVRMjl0WW05VGRISWdQVDA5SUc1MWJHd2dmSHdnZEhsd1pXOW1JR3RsZVVOdmJXSnZVM1J5SUQwOVBTQW5ablZ1WTNScGIyNG5LU0I3WEc0Z0lDQWdJQ0J3Y21WMlpXNTBVbVZ3WldGMFFubEVaV1poZFd4MElEMGdjbVZzWldGelpVaGhibVJzWlhJN1hHNGdJQ0FnSUNCeVpXeGxZWE5sU0dGdVpHeGxjaUFnSUNBZ0lDQWdJRDBnY0hKbGMzTklZVzVrYkdWeU8xeHVJQ0FnSUNBZ2NISmxjM05JWVc1a2JHVnlJQ0FnSUNBZ0lDQWdJQ0E5SUd0bGVVTnZiV0p2VTNSeU8xeHVJQ0FnSUNBZ2EyVjVRMjl0WW05VGRISWdJQ0FnSUNBZ0lDQWdJQ0E5SUc1MWJHdzdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLRnh1SUNBZ0lDQWdhMlY1UTI5dFltOVRkSElnSmlaY2JpQWdJQ0FnSUhSNWNHVnZaaUJyWlhsRGIyMWliMU4wY2lBOVBUMGdKMjlpYW1WamRDY2dKaVpjYmlBZ0lDQWdJSFI1Y0dWdlppQnJaWGxEYjIxaWIxTjBjaTVzWlc1bmRHZ2dQVDA5SUNkdWRXMWlaWEluWEc0Z0lDQWdLU0I3WEc0Z0lDQWdJQ0JtYjNJZ0tHeGxkQ0JwSUQwZ01Ec2dhU0E4SUd0bGVVTnZiV0p2VTNSeUxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11WW1sdVpDaHJaWGxEYjIxaWIxTjBjbHRwWFN3Z2NISmxjM05JWVc1a2JHVnlMQ0J5Wld4bFlYTmxTR0Z1Wkd4bGNpazdYRzRnSUNBZ0lDQjlYRzRnSUNBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjBhR2x6TGw5c2FYTjBaVzVsY25NdWNIVnphQ2g3WEc0Z0lDQWdJQ0JyWlhsRGIyMWlieUFnSUNBZ0lDQWdJQ0FnSUNBZ09pQnJaWGxEYjIxaWIxTjBjaUEvSUc1bGR5QkxaWGxEYjIxaWJ5aHJaWGxEYjIxaWIxTjBjaWtnT2lCdWRXeHNMRnh1SUNBZ0lDQWdjSEpsYzNOSVlXNWtiR1Z5SUNBZ0lDQWdJQ0FnSURvZ2NISmxjM05JWVc1a2JHVnlJQ0FnSUNBZ0lDQWdJQ0I4ZkNCdWRXeHNMRnh1SUNBZ0lDQWdjbVZzWldGelpVaGhibVJzWlhJZ0lDQWdJQ0FnSURvZ2NtVnNaV0Z6WlVoaGJtUnNaWElnSUNBZ0lDQWdJQ0I4ZkNCdWRXeHNMRnh1SUNBZ0lDQWdjSEpsZG1WdWRGSmxjR1ZoZENBZ0lDQWdJQ0FnSURvZ1ptRnNjMlVzWEc0Z0lDQWdJQ0J3Y21WMlpXNTBVbVZ3WldGMFFubEVaV1poZFd4ME9pQndjbVYyWlc1MFVtVndaV0YwUW5sRVpXWmhkV3gwSUh4OElHWmhiSE5sTEZ4dUlDQWdJQ0FnWlhobFkzVjBhVzVuU0dGdVpHeGxjaUFnSUNBZ0lEb2dabUZzYzJWY2JpQWdJQ0I5S1R0Y2JseHVJQ0FnSUhKbGRIVnliaUIwYUdsek8xeHVJQ0I5WEc1Y2JpQWdZV1JrVEdsemRHVnVaWElvYTJWNVEyOXRZbTlUZEhJc0lIQnlaWE56U0dGdVpHeGxjaXdnY21Wc1pXRnpaVWhoYm1Sc1pYSXNJSEJ5WlhabGJuUlNaWEJsWVhSQ2VVUmxabUYxYkhRcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWlhVzVrS0d0bGVVTnZiV0p2VTNSeUxDQndjbVZ6YzBoaGJtUnNaWElzSUhKbGJHVmhjMlZJWVc1a2JHVnlMQ0J3Y21WMlpXNTBVbVZ3WldGMFFubEVaV1poZFd4MEtUdGNiaUFnZlZ4dVhHNGdJRzl1S0d0bGVVTnZiV0p2VTNSeUxDQndjbVZ6YzBoaGJtUnNaWElzSUhKbGJHVmhjMlZJWVc1a2JHVnlMQ0J3Y21WMlpXNTBVbVZ3WldGMFFubEVaV1poZFd4MEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVZbWx1WkNoclpYbERiMjFpYjFOMGNpd2djSEpsYzNOSVlXNWtiR1Z5TENCeVpXeGxZWE5sU0dGdVpHeGxjaXdnY0hKbGRtVnVkRkpsY0dWaGRFSjVSR1ZtWVhWc2RDazdYRzRnSUgxY2JseHVJQ0JpYVc1a1VISmxjM01vYTJWNVEyOXRZbTlUZEhJc0lIQnlaWE56U0dGdVpHeGxjaXdnY0hKbGRtVnVkRkpsY0dWaGRFSjVSR1ZtWVhWc2RDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbUpwYm1Rb2EyVjVRMjl0WW05VGRISXNJSEJ5WlhOelNHRnVaR3hsY2l3Z2JuVnNiQ3dnY0hKbGRtVnVkRkpsY0dWaGRFSjVSR1ZtWVhWc2RDazdYRzRnSUgxY2JseHVJQ0JpYVc1a1VtVnNaV0Z6WlNoclpYbERiMjFpYjFOMGNpd2djbVZzWldGelpVaGhibVJzWlhJcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWlhVzVrS0d0bGVVTnZiV0p2VTNSeUxDQnVkV3hzTENCeVpXeGxZWE5sU0dGdVpHeGxjaXdnY0hKbGRtVnVkRkpsY0dWaGRFSjVSR1ZtWVhWc2RDazdYRzRnSUgxY2JseHVJQ0IxYm1KcGJtUW9hMlY1UTI5dFltOVRkSElzSUhCeVpYTnpTR0Z1Wkd4bGNpd2djbVZzWldGelpVaGhibVJzWlhJcElIdGNiaUFnSUNCcFppQW9hMlY1UTI5dFltOVRkSElnUFQwOUlHNTFiR3dnZkh3Z2RIbHdaVzltSUd0bGVVTnZiV0p2VTNSeUlEMDlQU0FuWm5WdVkzUnBiMjRuS1NCN1hHNGdJQ0FnSUNCeVpXeGxZWE5sU0dGdVpHeGxjaUE5SUhCeVpYTnpTR0Z1Wkd4bGNqdGNiaUFnSUNBZ0lIQnlaWE56U0dGdVpHeGxjaUFnSUQwZ2EyVjVRMjl0WW05VGRISTdYRzRnSUNBZ0lDQnJaWGxEYjIxaWIxTjBjaUE5SUc1MWJHdzdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLRnh1SUNBZ0lDQWdhMlY1UTI5dFltOVRkSElnSmlaY2JpQWdJQ0FnSUhSNWNHVnZaaUJyWlhsRGIyMWliMU4wY2lBOVBUMGdKMjlpYW1WamRDY2dKaVpjYmlBZ0lDQWdJSFI1Y0dWdlppQnJaWGxEYjIxaWIxTjBjaTVzWlc1bmRHZ2dQVDA5SUNkdWRXMWlaWEluWEc0Z0lDQWdLU0I3WEc0Z0lDQWdJQ0JtYjNJZ0tHeGxkQ0JwSUQwZ01Ec2dhU0E4SUd0bGVVTnZiV0p2VTNSeUxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZFc1aWFXNWtLR3RsZVVOdmJXSnZVM1J5VzJsZExDQndjbVZ6YzBoaGJtUnNaWElzSUhKbGJHVmhjMlZJWVc1a2JHVnlLVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQWdJSDFjYmx4dUlDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnZEdocGN5NWZiR2x6ZEdWdVpYSnpMbXhsYm1kMGFEc2dhU0FyUFNBeEtTQjdYRzRnSUNBZ0lDQmpiMjV6ZENCc2FYTjBaVzVsY2lBOUlIUm9hWE11WDJ4cGMzUmxibVZ5YzF0cFhUdGNibHh1SUNBZ0lDQWdZMjl1YzNRZ1kyOXRZbTlOWVhSamFHVnpJQ0FnSUNBZ0lDQWdJRDBnSVd0bGVVTnZiV0p2VTNSeUlDWW1JQ0ZzYVhOMFpXNWxjaTVyWlhsRGIyMWlieUI4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUd4cGMzUmxibVZ5TG10bGVVTnZiV0p2SUNZbUlHeHBjM1JsYm1WeUxtdGxlVU52YldKdkxtbHpSWEYxWVd3b2EyVjVRMjl0WW05VGRISXBPMXh1SUNBZ0lDQWdZMjl1YzNRZ2NISmxjM05JWVc1a2JHVnlUV0YwWTJobGN5QWdJRDBnSVhCeVpYTnpTR0Z1Wkd4bGNpQW1KaUFoY21Wc1pXRnpaVWhoYm1Sc1pYSWdmSHhjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FoY0hKbGMzTklZVzVrYkdWeUlDWW1JQ0ZzYVhOMFpXNWxjaTV3Y21WemMwaGhibVJzWlhJZ2ZIeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQndjbVZ6YzBoaGJtUnNaWElnUFQwOUlHeHBjM1JsYm1WeUxuQnlaWE56U0dGdVpHeGxjanRjYmlBZ0lDQWdJR052Ym5OMElISmxiR1ZoYzJWSVlXNWtiR1Z5VFdGMFkyaGxjeUE5SUNGd2NtVnpjMGhoYm1Sc1pYSWdKaVlnSVhKbGJHVmhjMlZJWVc1a2JHVnlJSHg4WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSVhKbGJHVmhjMlZJWVc1a2JHVnlJQ1ltSUNGc2FYTjBaVzVsY2k1eVpXeGxZWE5sU0dGdVpHeGxjaUI4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGJHVmhjMlZJWVc1a2JHVnlJRDA5UFNCc2FYTjBaVzVsY2k1eVpXeGxZWE5sU0dGdVpHeGxjanRjYmx4dUlDQWdJQ0FnYVdZZ0tHTnZiV0p2VFdGMFkyaGxjeUFtSmlCd2NtVnpjMGhoYm1Sc1pYSk5ZWFJqYUdWeklDWW1JSEpsYkdWaGMyVklZVzVrYkdWeVRXRjBZMmhsY3lrZ2UxeHVJQ0FnSUNBZ0lDQjBhR2x6TGw5c2FYTjBaVzVsY25NdWMzQnNhV05sS0drc0lERXBPMXh1SUNBZ0lDQWdJQ0JwSUMwOUlERTdYRzRnSUNBZ0lDQjlYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTTdYRzRnSUgxY2JseHVJQ0J5WlcxdmRtVk1hWE4wWlc1bGNpaHJaWGxEYjIxaWIxTjBjaXdnY0hKbGMzTklZVzVrYkdWeUxDQnlaV3hsWVhObFNHRnVaR3hsY2lrZ2UxeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxuVnVZbWx1WkNoclpYbERiMjFpYjFOMGNpd2djSEpsYzNOSVlXNWtiR1Z5TENCeVpXeGxZWE5sU0dGdVpHeGxjaWs3WEc0Z0lIMWNibHh1SUNCdlptWW9hMlY1UTI5dFltOVRkSElzSUhCeVpYTnpTR0Z1Wkd4bGNpd2djbVZzWldGelpVaGhibVJzWlhJcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NTFibUpwYm1Rb2EyVjVRMjl0WW05VGRISXNJSEJ5WlhOelNHRnVaR3hsY2l3Z2NtVnNaV0Z6WlVoaGJtUnNaWElwTzF4dUlDQjlYRzVjYmlBZ2MyVjBRMjl1ZEdWNGRDaGpiMjUwWlhoMFRtRnRaU2tnZTF4dUlDQWdJR2xtS0hSb2FYTXVYMnh2WTJGc1pTa2dleUIwYUdsekxuSmxiR1ZoYzJWQmJHeExaWGx6S0NrN0lIMWNibHh1SUNBZ0lHbG1JQ2doZEdocGN5NWZZMjl1ZEdWNGRITmJZMjl1ZEdWNGRFNWhiV1ZkS1NCN1hHNGdJQ0FnSUNCamIyNXpkQ0JuYkc5aVlXeERiMjUwWlhoMElEMGdkR2hwY3k1ZlkyOXVkR1Y0ZEhNdVoyeHZZbUZzTzF4dUlDQWdJQ0FnZEdocGN5NWZZMjl1ZEdWNGRITmJZMjl1ZEdWNGRFNWhiV1ZkSUQwZ2UxeHVJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNuTWdJQ0FnSUNBNklGdGRMRnh1SUNBZ0lDQWdJQ0IwWVhKblpYUlhhVzVrYjNjZ0lDQTZJR2RzYjJKaGJFTnZiblJsZUhRdWRHRnlaMlYwVjJsdVpHOTNMRnh1SUNBZ0lDQWdJQ0IwWVhKblpYUkZiR1Z0Wlc1MElDQTZJR2RzYjJKaGJFTnZiblJsZUhRdWRHRnlaMlYwUld4bGJXVnVkQ3hjYmlBZ0lDQWdJQ0FnZEdGeVoyVjBVR3hoZEdadmNtMGdPaUJuYkc5aVlXeERiMjUwWlhoMExuUmhjbWRsZEZCc1lYUm1iM0p0TEZ4dUlDQWdJQ0FnSUNCMFlYSm5aWFJWYzJWeVFXZGxiblE2SUdkc2IySmhiRU52Ym5SbGVIUXVkR0Z5WjJWMFZYTmxja0ZuWlc1MFhHNGdJQ0FnSUNCOU8xeHVJQ0FnSUgxY2JseHVJQ0FnSUdOdmJuTjBJR052Ym5SbGVIUWdJQ0FnSUNBZ0lEMGdkR2hwY3k1ZlkyOXVkR1Y0ZEhOYlkyOXVkR1Y0ZEU1aGJXVmRPMXh1SUNBZ0lIUm9hWE11WDJOMWNuSmxiblJEYjI1MFpYaDBJRDBnWTI5dWRHVjRkRTVoYldVN1hHNGdJQ0FnZEdocGN5NWZiR2x6ZEdWdVpYSnpJQ0FnSUNBZ1BTQmpiMjUwWlhoMExteHBjM1JsYm1WeWN6dGNibHh1SUNBZ0lIUm9hWE11YzNSdmNDZ3BPMXh1SUNBZ0lIUm9hWE11ZDJGMFkyZ29YRzRnSUNBZ0lDQmpiMjUwWlhoMExuUmhjbWRsZEZkcGJtUnZkeXhjYmlBZ0lDQWdJR052Ym5SbGVIUXVkR0Z5WjJWMFJXeGxiV1Z1ZEN4Y2JpQWdJQ0FnSUdOdmJuUmxlSFF1ZEdGeVoyVjBVR3hoZEdadmNtMHNYRzRnSUNBZ0lDQmpiMjUwWlhoMExuUmhjbWRsZEZWelpYSkJaMlZ1ZEZ4dUlDQWdJQ2s3WEc1Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3p0Y2JpQWdmVnh1WEc0Z0lHZGxkRU52Ym5SbGVIUW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WDJOMWNuSmxiblJEYjI1MFpYaDBPMXh1SUNCOVhHNWNiaUFnZDJsMGFFTnZiblJsZUhRb1kyOXVkR1Y0ZEU1aGJXVXNJR05oYkd4aVlXTnJLU0I3WEc0Z0lDQWdZMjl1YzNRZ2NISmxkbWx2ZFhORGIyNTBaWGgwVG1GdFpTQTlJSFJvYVhNdVoyVjBRMjl1ZEdWNGRDZ3BPMXh1SUNBZ0lIUm9hWE11YzJWMFEyOXVkR1Y0ZENoamIyNTBaWGgwVG1GdFpTazdYRzVjYmlBZ0lDQmpZV3hzWW1GamF5Z3BPMXh1WEc0Z0lDQWdkR2hwY3k1elpYUkRiMjUwWlhoMEtIQnlaWFpwYjNWelEyOXVkR1Y0ZEU1aGJXVXBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE03WEc0Z0lIMWNibHh1SUNCM1lYUmphQ2gwWVhKblpYUlhhVzVrYjNjc0lIUmhjbWRsZEVWc1pXMWxiblFzSUhSaGNtZGxkRkJzWVhSbWIzSnRMQ0IwWVhKblpYUlZjMlZ5UVdkbGJuUXBJSHRjYmlBZ0lDQjBhR2x6TG5OMGIzQW9LVHRjYmx4dUlDQWdJR052Ym5OMElIZHBiaUE5SUhSNWNHVnZaaUJuYkc5aVlXeFVhR2x6SUNFOVBTQW5kVzVrWldacGJtVmtKeUEvSUdkc2IySmhiRlJvYVhNZ09seHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUjVjR1Z2WmlCbmJHOWlZV3dnSVQwOUlDZDFibVJsWm1sdVpXUW5JRDhnWjJ4dlltRnNJRHBjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwZVhCbGIyWWdkMmx1Wkc5M0lDRTlQU0FuZFc1a1pXWnBibVZrSnlBL0lIZHBibVJ2ZHlBNlhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2UzMDdYRzVjYmlBZ0lDQnBaaUFvSVhSaGNtZGxkRmRwYm1SdmR5a2dlMXh1SUNBZ0lDQWdhV1lnS0NGM2FXNHVZV1JrUlhabGJuUk1hWE4wWlc1bGNpQW1KaUFoZDJsdUxtRjBkR0ZqYUVWMlpXNTBLU0I3WEc0Z0lDQWdJQ0FnSUM4dklGUm9hWE1nZDJGeklHRmtaR1ZrSUhOdklIZG9aVzRnZFhOcGJtY2dkR2hwYm1keklHeHBhMlVnU2xORVQwMGdkMkYwWTJnZ1kyRnVJR0psSUhWelpXUWdkRzhnWTI5dVptbG5kWEpsSUhkaGRHTm9YRzRnSUNBZ0lDQWdJQzh2SUdadmNpQjBhR1VnWjJ4dlltRnNJRzVoYldWemNHRmpaU0J0WVc1MVlXeHNlUzVjYmlBZ0lDQWdJQ0FnYVdZZ0tIUm9hWE11WDJOMWNuSmxiblJEYjI1MFpYaDBJRDA5UFNBbloyeHZZbUZzSnlrZ2UxeHVJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJseHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ25RMkZ1Ym05MElHWnBibVFnZDJsdVpHOTNJR1oxYm1OMGFXOXVjeUJoWkdSRmRtVnVkRXhwYzNSbGJtVnlJRzl5SUdGMGRHRmphRVYyWlc1MExpY3BPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdkR0Z5WjJWMFYybHVaRzkzSUQwZ2QybHVPMXh1SUNBZ0lIMWNibHh1SUNBZ0lDOHZJRWhoYm1Sc1pTQmxiR1Z0Wlc1MElHSnBibVJwYm1keklIZG9aWEpsSUdFZ2RHRnlaMlYwSUhkcGJtUnZkeUJwY3lCdWIzUWdjR0Z6YzJWa1hHNGdJQ0FnYVdZZ0tIUjVjR1Z2WmlCMFlYSm5aWFJYYVc1a2IzY3VibTlrWlZSNWNHVWdQVDA5SUNkdWRXMWlaWEluS1NCN1hHNGdJQ0FnSUNCMFlYSm5aWFJWYzJWeVFXZGxiblFnUFNCMFlYSm5aWFJRYkdGMFptOXliVHRjYmlBZ0lDQWdJSFJoY21kbGRGQnNZWFJtYjNKdElDQTlJSFJoY21kbGRFVnNaVzFsYm5RN1hHNGdJQ0FnSUNCMFlYSm5aWFJGYkdWdFpXNTBJQ0FnUFNCMFlYSm5aWFJYYVc1a2IzYzdYRzRnSUNBZ0lDQjBZWEpuWlhSWGFXNWtiM2NnSUNBZ1BTQjNhVzQ3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdhV1lnS0NGMFlYSm5aWFJYYVc1a2IzY3VZV1JrUlhabGJuUk1hWE4wWlc1bGNpQW1KaUFoZEdGeVoyVjBWMmx1Wkc5M0xtRjBkR0ZqYUVWMlpXNTBLU0I3WEc0Z0lDQWdJQ0IwYUhKdmR5QnVaWGNnUlhKeWIzSW9KME5oYm01dmRDQm1hVzVrSUdGa1pFVjJaVzUwVEdsemRHVnVaWElnYjNJZ1lYUjBZV05vUlhabGJuUWdiV1YwYUc5a2N5QnZiaUIwWVhKblpYUlhhVzVrYjNjdUp5azdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2RHaHBjeTVmYVhOTmIyUmxjbTVDY205M2MyVnlJRDBnSVNGMFlYSm5aWFJYYVc1a2IzY3VZV1JrUlhabGJuUk1hWE4wWlc1bGNqdGNibHh1SUNBZ0lHTnZibk4wSUhWelpYSkJaMlZ1ZENBOUlIUmhjbWRsZEZkcGJtUnZkeTV1WVhacFoyRjBiM0lnSmlZZ2RHRnlaMlYwVjJsdVpHOTNMbTVoZG1sbllYUnZjaTUxYzJWeVFXZGxiblFnZkh3Z0p5YzdYRzRnSUNBZ1kyOXVjM1FnY0d4aGRHWnZjbTBnSUQwZ2RHRnlaMlYwVjJsdVpHOTNMbTVoZG1sbllYUnZjaUFtSmlCMFlYSm5aWFJYYVc1a2IzY3VibUYyYVdkaGRHOXlMbkJzWVhSbWIzSnRJQ0I4ZkNBbkp6dGNibHh1SUNBZ0lIUmhjbWRsZEVWc1pXMWxiblFnSUNBbUppQjBZWEpuWlhSRmJHVnRaVzUwSUNBZ0lUMDlJRzUxYkd3Z2ZId2dLSFJoY21kbGRFVnNaVzFsYm5RZ0lDQTlJSFJoY21kbGRGZHBibVJ2ZHk1a2IyTjFiV1Z1ZENrN1hHNGdJQ0FnZEdGeVoyVjBVR3hoZEdadmNtMGdJQ1ltSUhSaGNtZGxkRkJzWVhSbWIzSnRJQ0FoUFQwZ2JuVnNiQ0I4ZkNBb2RHRnlaMlYwVUd4aGRHWnZjbTBnSUQwZ2NHeGhkR1p2Y20wcE8xeHVJQ0FnSUhSaGNtZGxkRlZ6WlhKQloyVnVkQ0FtSmlCMFlYSm5aWFJWYzJWeVFXZGxiblFnSVQwOUlHNTFiR3dnZkh3Z0tIUmhjbWRsZEZWelpYSkJaMlZ1ZENBOUlIVnpaWEpCWjJWdWRDazdYRzVjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJMWlhsRWIzZHVRbWx1WkdsdVp5QTlJQ2hsZG1WdWRDa2dQVDRnZTF4dUlDQWdJQ0FnZEdocGN5NXdjbVZ6YzB0bGVTaGxkbVZ1ZEM1clpYbERiMlJsTENCbGRtVnVkQ2s3WEc0Z0lDQWdJQ0IwYUdsekxsOW9ZVzVrYkdWRGIyMXRZVzVrUW5WbktHVjJaVzUwTENCd2JHRjBabTl5YlNrN1hHNGdJQ0FnZlR0Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSTFpYbFZjRUpwYm1ScGJtY2dQU0FvWlhabGJuUXBJRDArSUh0Y2JpQWdJQ0FnSUhSb2FYTXVjbVZzWldGelpVdGxlU2hsZG1WdWRDNXJaWGxEYjJSbExDQmxkbVZ1ZENrN1hHNGdJQ0FnZlR0Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSU1pYTmxkRUpwYm1ScGJtY2dQU0FvWlhabGJuUXBJRDArSUh0Y2JpQWdJQ0FnSUhSb2FYTXVjbVZzWldGelpVRnNiRXRsZVhNb1pYWmxiblFwTzF4dUlDQWdJSDA3WEc1Y2JpQWdJQ0IwYUdsekxsOWlhVzVrUlhabGJuUW9kR0Z5WjJWMFJXeGxiV1Z1ZEN3Z0oydGxlV1J2ZDI0bkxDQjBhR2x6TGw5MFlYSm5aWFJMWlhsRWIzZHVRbWx1WkdsdVp5azdYRzRnSUNBZ2RHaHBjeTVmWW1sdVpFVjJaVzUwS0hSaGNtZGxkRVZzWlcxbGJuUXNJQ2RyWlhsMWNDY3NJQ0FnZEdocGN5NWZkR0Z5WjJWMFMyVjVWWEJDYVc1a2FXNW5LVHRjYmlBZ0lDQjBhR2x6TGw5aWFXNWtSWFpsYm5Rb2RHRnlaMlYwVjJsdVpHOTNMQ0FnSjJadlkzVnpKeXdnSUNCMGFHbHpMbDkwWVhKblpYUlNaWE5sZEVKcGJtUnBibWNwTzF4dUlDQWdJSFJvYVhNdVgySnBibVJGZG1WdWRDaDBZWEpuWlhSWGFXNWtiM2NzSUNBbllteDFjaWNzSUNBZ0lIUm9hWE11WDNSaGNtZGxkRkpsYzJWMFFtbHVaR2x1WnlrN1hHNWNiaUFnSUNCMGFHbHpMbDkwWVhKblpYUkZiR1Z0Wlc1MElDQWdQU0IwWVhKblpYUkZiR1Z0Wlc1ME8xeHVJQ0FnSUhSb2FYTXVYM1JoY21kbGRGZHBibVJ2ZHlBZ0lDQTlJSFJoY21kbGRGZHBibVJ2ZHp0Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSUWJHRjBabTl5YlNBZ1BTQjBZWEpuWlhSUWJHRjBabTl5YlR0Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSVmMyVnlRV2RsYm5RZ1BTQjBZWEpuWlhSVmMyVnlRV2RsYm5RN1hHNWNiaUFnSUNCamIyNXpkQ0JqZFhKeVpXNTBRMjl1ZEdWNGRDQWdJQ0FnSUNBZ0lDQWdQU0IwYUdsekxsOWpiMjUwWlhoMGMxdDBhR2x6TGw5amRYSnlaVzUwUTI5dWRHVjRkRjA3WEc0Z0lDQWdZM1Z5Y21WdWRFTnZiblJsZUhRdWRHRnlaMlYwVjJsdVpHOTNJQ0FnSUQwZ2RHaHBjeTVmZEdGeVoyVjBWMmx1Wkc5M08xeHVJQ0FnSUdOMWNuSmxiblJEYjI1MFpYaDBMblJoY21kbGRFVnNaVzFsYm5RZ0lDQTlJSFJvYVhNdVgzUmhjbWRsZEVWc1pXMWxiblE3WEc0Z0lDQWdZM1Z5Y21WdWRFTnZiblJsZUhRdWRHRnlaMlYwVUd4aGRHWnZjbTBnSUQwZ2RHaHBjeTVmZEdGeVoyVjBVR3hoZEdadmNtMDdYRzRnSUNBZ1kzVnljbVZ1ZEVOdmJuUmxlSFF1ZEdGeVoyVjBWWE5sY2tGblpXNTBJRDBnZEdocGN5NWZkR0Z5WjJWMFZYTmxja0ZuWlc1ME8xeHVYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTTdYRzRnSUgxY2JseHVJQ0J6ZEc5d0tDa2dlMXh1SUNBZ0lHbG1JQ2doZEdocGN5NWZkR0Z5WjJWMFJXeGxiV1Z1ZENCOGZDQWhkR2hwY3k1ZmRHRnlaMlYwVjJsdVpHOTNLU0I3SUhKbGRIVnlianNnZlZ4dVhHNGdJQ0FnZEdocGN5NWZkVzVpYVc1a1JYWmxiblFvZEdocGN5NWZkR0Z5WjJWMFJXeGxiV1Z1ZEN3Z0oydGxlV1J2ZDI0bkxDQjBhR2x6TGw5MFlYSm5aWFJMWlhsRWIzZHVRbWx1WkdsdVp5azdYRzRnSUNBZ2RHaHBjeTVmZFc1aWFXNWtSWFpsYm5Rb2RHaHBjeTVmZEdGeVoyVjBSV3hsYldWdWRDd2dKMnRsZVhWd0p5d2dJQ0IwYUdsekxsOTBZWEpuWlhSTFpYbFZjRUpwYm1ScGJtY3BPMXh1SUNBZ0lIUm9hWE11WDNWdVltbHVaRVYyWlc1MEtIUm9hWE11WDNSaGNtZGxkRmRwYm1SdmR5d2dJQ2RtYjJOMWN5Y3NJQ0FnZEdocGN5NWZkR0Z5WjJWMFVtVnpaWFJDYVc1a2FXNW5LVHRjYmlBZ0lDQjBhR2x6TGw5MWJtSnBibVJGZG1WdWRDaDBhR2x6TGw5MFlYSm5aWFJYYVc1a2IzY3NJQ0FuWW14MWNpY3NJQ0FnSUhSb2FYTXVYM1JoY21kbGRGSmxjMlYwUW1sdVpHbHVaeWs3WEc1Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSWGFXNWtiM2NnSUQwZ2JuVnNiRHRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJGYkdWdFpXNTBJRDBnYm5Wc2JEdGNibHh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNCOVhHNWNiaUFnY0hKbGMzTkxaWGtvYTJWNVEyOWtaU3dnWlhabGJuUXBJSHRjYmlBZ0lDQnBaaUFvZEdocGN5NWZjR0YxYzJWa0tTQjdJSEpsZEhWeWJpQjBhR2x6T3lCOVhHNGdJQ0FnYVdZZ0tDRjBhR2x6TGw5c2IyTmhiR1VwSUhzZ2RHaHliM2NnYm1WM0lFVnljbTl5S0NkTWIyTmhiR1VnYm05MElITmxkQ2NwT3lCOVhHNWNiaUFnSUNCMGFHbHpMbDlzYjJOaGJHVXVjSEpsYzNOTFpYa29hMlY1UTI5a1pTazdYRzRnSUNBZ2RHaHBjeTVmWVhCd2JIbENhVzVrYVc1bmN5aGxkbVZ1ZENrN1hHNWNiaUFnSUNCeVpYUjFjbTRnZEdocGN6dGNiaUFnZlZ4dVhHNGdJSEpsYkdWaGMyVkxaWGtvYTJWNVEyOWtaU3dnWlhabGJuUXBJSHRjYmlBZ0lDQnBaaUFvZEdocGN5NWZjR0YxYzJWa0tTQjdJSEpsZEhWeWJpQjBhR2x6T3lCOVhHNGdJQ0FnYVdZZ0tDRjBhR2x6TGw5c2IyTmhiR1VwSUhzZ2RHaHliM2NnYm1WM0lFVnljbTl5S0NkTWIyTmhiR1VnYm05MElITmxkQ2NwT3lCOVhHNWNiaUFnSUNCMGFHbHpMbDlzYjJOaGJHVXVjbVZzWldGelpVdGxlU2hyWlhsRGIyUmxLVHRjYmlBZ0lDQjBhR2x6TGw5amJHVmhja0pwYm1ScGJtZHpLR1YyWlc1MEtUdGNibHh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNCOVhHNWNiaUFnY21Wc1pXRnpaVUZzYkV0bGVYTW9aWFpsYm5RcElIdGNiaUFnSUNCcFppQW9kR2hwY3k1ZmNHRjFjMlZrS1NCN0lISmxkSFZ5YmlCMGFHbHpPeUI5WEc0Z0lDQWdhV1lnS0NGMGFHbHpMbDlzYjJOaGJHVXBJSHNnZEdoeWIzY2dibVYzSUVWeWNtOXlLQ2RNYjJOaGJHVWdibTkwSUhObGRDY3BPeUI5WEc1Y2JpQWdJQ0IwYUdsekxsOXNiMk5oYkdVdWNISmxjM05sWkV0bGVYTXViR1Z1WjNSb0lEMGdNRHRjYmlBZ0lDQjBhR2x6TGw5amJHVmhja0pwYm1ScGJtZHpLR1YyWlc1MEtUdGNibHh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNCOVhHNWNiaUFnY0dGMWMyVW9LU0I3WEc0Z0lDQWdhV1lnS0hSb2FYTXVYM0JoZFhObFpDa2dleUJ5WlhSMWNtNGdkR2hwY3pzZ2ZWeHVJQ0FnSUdsbUlDaDBhR2x6TGw5c2IyTmhiR1VwSUhzZ2RHaHBjeTV5Wld4bFlYTmxRV3hzUzJWNWN5Z3BPeUI5WEc0Z0lDQWdkR2hwY3k1ZmNHRjFjMlZrSUQwZ2RISjFaVHRjYmx4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQjlYRzVjYmlBZ2NtVnpkVzFsS0NrZ2UxeHVJQ0FnSUhSb2FYTXVYM0JoZFhObFpDQTlJR1poYkhObE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTTdYRzRnSUgxY2JseHVJQ0J5WlhObGRDZ3BJSHRjYmlBZ0lDQjBhR2x6TG5KbGJHVmhjMlZCYkd4TFpYbHpLQ2s3WEc0Z0lDQWdkR2hwY3k1ZmJHbHpkR1Z1WlhKekxteGxibWQwYUNBOUlEQTdYRzVjYmlBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ2ZWeHVYRzRnSUY5aWFXNWtSWFpsYm5Rb2RHRnlaMlYwUld4bGJXVnVkQ3dnWlhabGJuUk9ZVzFsTENCb1lXNWtiR1Z5S1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVgybHpUVzlrWlhKdVFuSnZkM05sY2lBL1hHNGdJQ0FnSUNCMFlYSm5aWFJGYkdWdFpXNTBMbUZrWkVWMlpXNTBUR2x6ZEdWdVpYSW9aWFpsYm5ST1lXMWxMQ0JvWVc1a2JHVnlMQ0JtWVd4elpTa2dPbHh1SUNBZ0lDQWdkR0Z5WjJWMFJXeGxiV1Z1ZEM1aGRIUmhZMmhGZG1WdWRDZ25iMjRuSUNzZ1pYWmxiblJPWVcxbExDQm9ZVzVrYkdWeUtUdGNiaUFnZlZ4dVhHNGdJRjkxYm1KcGJtUkZkbVZ1ZENoMFlYSm5aWFJGYkdWdFpXNTBMQ0JsZG1WdWRFNWhiV1VzSUdoaGJtUnNaWElwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1ZmFYTk5iMlJsY201Q2NtOTNjMlZ5SUQ5Y2JpQWdJQ0FnSUhSaGNtZGxkRVZzWlcxbGJuUXVjbVZ0YjNabFJYWmxiblJNYVhOMFpXNWxjaWhsZG1WdWRFNWhiV1VzSUdoaGJtUnNaWElzSUdaaGJITmxLU0E2WEc0Z0lDQWdJQ0IwWVhKblpYUkZiR1Z0Wlc1MExtUmxkR0ZqYUVWMlpXNTBLQ2R2YmljZ0t5QmxkbVZ1ZEU1aGJXVXNJR2hoYm1Sc1pYSXBPMXh1SUNCOVhHNWNiaUFnWDJkbGRFZHliM1Z3WldSTWFYTjBaVzVsY25Nb0tTQjdYRzRnSUNBZ1kyOXVjM1FnYkdsemRHVnVaWEpIY205MWNITWdJQ0E5SUZ0ZE8xeHVJQ0FnSUdOdmJuTjBJR3hwYzNSbGJtVnlSM0p2ZFhCTllYQWdQU0JiWFR0Y2JseHVJQ0FnSUd4bGRDQnNhWE4wWlc1bGNuTWdQU0IwYUdsekxsOXNhWE4wWlc1bGNuTTdYRzRnSUNBZ2FXWWdLSFJvYVhNdVgyTjFjbkpsYm5SRGIyNTBaWGgwSUNFOVBTQW5aMnh2WW1Gc0p5a2dlMXh1SUNBZ0lDQWdiR2x6ZEdWdVpYSnpJRDBnV3k0dUxteHBjM1JsYm1WeWN5d2dMaTR1ZEdocGN5NWZZMjl1ZEdWNGRITXVaMnh2WW1Gc0xteHBjM1JsYm1WeWMxMDdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2JHbHpkR1Z1WlhKekxuTnZjblFvWEc0Z0lDQWdJQ0FvWVN3Z1lpa2dQVDVjYmlBZ0lDQWdJQ0FnS0dJdWEyVjVRMjl0WW04Z1B5QmlMbXRsZVVOdmJXSnZMbXRsZVU1aGJXVnpMbXhsYm1kMGFDQTZJREFwSUMxY2JpQWdJQ0FnSUNBZ0tHRXVhMlY1UTI5dFltOGdQeUJoTG10bGVVTnZiV0p2TG10bGVVNWhiV1Z6TG14bGJtZDBhQ0E2SURBcFhHNGdJQ0FnS1M1bWIzSkZZV05vS0Noc0tTQTlQaUI3WEc0Z0lDQWdJQ0JzWlhRZ2JXRndTVzVrWlhnZ1BTQXRNVHRjYmlBZ0lDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnYkdsemRHVnVaWEpIY205MWNFMWhjQzVzWlc1bmRHZzdJR2tnS3owZ01Ta2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2JHbHpkR1Z1WlhKSGNtOTFjRTFoY0Z0cFhTQTlQVDBnYm5Wc2JDQW1KaUJzTG10bGVVTnZiV0p2SUQwOVBTQnVkV3hzSUh4OFhHNGdJQ0FnSUNBZ0lDQWdJQ0JzYVhOMFpXNWxja2R5YjNWd1RXRndXMmxkSUNFOVBTQnVkV3hzSUNZbUlHeHBjM1JsYm1WeVIzSnZkWEJOWVhCYmFWMHVhWE5GY1hWaGJDaHNMbXRsZVVOdmJXSnZLU2tnZTF4dUlDQWdJQ0FnSUNBZ0lHMWhjRWx1WkdWNElEMGdhVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnYVdZZ0tHMWhjRWx1WkdWNElEMDlQU0F0TVNrZ2UxeHVJQ0FnSUNBZ0lDQnRZWEJKYm1SbGVDQTlJR3hwYzNSbGJtVnlSM0p2ZFhCTllYQXViR1Z1WjNSb08xeHVJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNrZHliM1Z3VFdGd0xuQjFjMmdvYkM1clpYbERiMjFpYnlrN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnSUNCcFppQW9JV3hwYzNSbGJtVnlSM0p2ZFhCelcyMWhjRWx1WkdWNFhTa2dlMXh1SUNBZ0lDQWdJQ0JzYVhOMFpXNWxja2R5YjNWd2MxdHRZWEJKYm1SbGVGMGdQU0JiWFR0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0FnSUd4cGMzUmxibVZ5UjNKdmRYQnpXMjFoY0VsdVpHVjRYUzV3ZFhOb0tHd3BPMXh1SUNBZ0lIMHBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHeHBjM1JsYm1WeVIzSnZkWEJ6TzF4dUlDQjlYRzVjYmlBZ1gyRndjR3g1UW1sdVpHbHVaM01vWlhabGJuUXBJSHRjYmlBZ0lDQnNaWFFnY0hKbGRtVnVkRkpsY0dWaGRDQTlJR1poYkhObE8xeHVYRzRnSUNBZ1pYWmxiblFnZkh3Z0tHVjJaVzUwSUQwZ2UzMHBPMXh1SUNBZ0lHVjJaVzUwTG5CeVpYWmxiblJTWlhCbFlYUWdQU0FvS1NBOVBpQjdJSEJ5WlhabGJuUlNaWEJsWVhRZ1BTQjBjblZsT3lCOU8xeHVJQ0FnSUdWMlpXNTBMbkJ5WlhOelpXUkxaWGx6SUNBZ1BTQjBhR2x6TGw5c2IyTmhiR1V1Y0hKbGMzTmxaRXRsZVhNdWMyeHBZMlVvTUNrN1hHNWNiaUFnSUNCamIyNXpkQ0JoWTNScGRtVlVZWEpuWlhSTFpYbHpJRDBnZEdocGN5NWZiRzlqWVd4bExtRmpkR2wyWlZSaGNtZGxkRXRsZVhNN1hHNGdJQ0FnWTI5dWMzUWdjSEpsYzNObFpFdGxlWE1nSUNBZ0lDQTlJSFJvYVhNdVgyeHZZMkZzWlM1d2NtVnpjMlZrUzJWNWN5NXpiR2xqWlNnd0tUdGNiaUFnSUNCamIyNXpkQ0JzYVhOMFpXNWxja2R5YjNWd2N5QWdJRDBnZEdocGN5NWZaMlYwUjNKdmRYQmxaRXhwYzNSbGJtVnljeWdwTzF4dVhHNGdJQ0FnWm05eUlDaHNaWFFnYVNBOUlEQTdJR2tnUENCc2FYTjBaVzVsY2tkeWIzVndjeTVzWlc1bmRHZzdJR2tnS3owZ01Ta2dlMXh1SUNBZ0lDQWdZMjl1YzNRZ2JHbHpkR1Z1WlhKeklEMGdiR2x6ZEdWdVpYSkhjbTkxY0hOYmFWMDdYRzRnSUNBZ0lDQmpiMjV6ZENCclpYbERiMjFpYnlBZ1BTQnNhWE4wWlc1bGNuTmJNRjB1YTJWNVEyOXRZbTg3WEc1Y2JpQWdJQ0FnSUdsbUlDaGNiaUFnSUNBZ0lDQWdhMlY1UTI5dFltOGdQVDA5SUc1MWJHd2dmSHhjYmlBZ0lDQWdJQ0FnYTJWNVEyOXRZbTh1WTJobFkyc29jSEpsYzNObFpFdGxlWE1wSUNZbVhHNGdJQ0FnSUNBZ0lHRmpkR2wyWlZSaGNtZGxkRXRsZVhNdWMyOXRaU2hySUQwK0lHdGxlVU52YldKdkxtdGxlVTVoYldWekxtbHVZMngxWkdWektHc3BLVnh1SUNBZ0lDQWdLU0I3WEc0Z0lDQWdJQ0FnSUdadmNpQW9iR1YwSUdvZ1BTQXdPeUJxSUR3Z2JHbHpkR1Z1WlhKekxteGxibWQwYURzZ2FpQXJQU0F4S1NCN1hHNGdJQ0FnSUNBZ0lDQWdiR1YwSUd4cGMzUmxibVZ5SUQwZ2JHbHpkR1Z1WlhKelcycGRPMXh1WEc0Z0lDQWdJQ0FnSUNBZ2FXWWdLQ0ZzYVhOMFpXNWxjaTVsZUdWamRYUnBibWRJWVc1a2JHVnlJQ1ltSUd4cGMzUmxibVZ5TG5CeVpYTnpTR0Z1Wkd4bGNpQW1KaUFoYkdsemRHVnVaWEl1Y0hKbGRtVnVkRkpsY0dWaGRDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2JHbHpkR1Z1WlhJdVpYaGxZM1YwYVc1blNHRnVaR3hsY2lBOUlIUnlkV1U3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNpNXdjbVZ6YzBoaGJtUnNaWEl1WTJGc2JDaDBhR2x6TENCbGRtVnVkQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNpNWxlR1ZqZFhScGJtZElZVzVrYkdWeUlEMGdabUZzYzJVN1hHNWNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaHdjbVYyWlc1MFVtVndaV0YwSUh4OElHeHBjM1JsYm1WeUxuQnlaWFpsYm5SU1pYQmxZWFJDZVVSbFptRjFiSFFwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnYkdsemRHVnVaWEl1Y0hKbGRtVnVkRkpsY0dWaGRDQTlJSFJ5ZFdVN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUhCeVpYWmxiblJTWlhCbFlYUWdJQ0FnSUNBZ0lDQWdQU0JtWVd4elpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnSUNCcFppQW9kR2hwY3k1ZllYQndiR2xsWkV4cGMzUmxibVZ5Y3k1cGJtUmxlRTltS0d4cGMzUmxibVZ5S1NBOVBUMGdMVEVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNdVgyRndjR3hwWldSTWFYTjBaVzVsY25NdWNIVnphQ2hzYVhOMFpXNWxjaWs3WEc0Z0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnYVdZZ0tHdGxlVU52YldKdktTQjdYRzRnSUNBZ0lDQWdJQ0FnWm05eUlDaHNaWFFnYWlBOUlEQTdJR29nUENCclpYbERiMjFpYnk1clpYbE9ZVzFsY3k1c1pXNW5kR2c3SUdvZ0t6MGdNU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdZMjl1YzNRZ2FXNWtaWGdnUFNCd2NtVnpjMlZrUzJWNWN5NXBibVJsZUU5bUtHdGxlVU52YldKdkxtdGxlVTVoYldWelcycGRLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hwYm1SbGVDQWhQVDBnTFRFcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ2NISmxjM05sWkV0bGVYTXVjM0JzYVdObEtHbHVaR1Y0TENBeEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ2FpQXRQU0F4TzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JpQWdmVnh1WEc0Z0lGOWpiR1ZoY2tKcGJtUnBibWR6S0dWMlpXNTBLU0I3WEc0Z0lDQWdaWFpsYm5RZ2ZId2dLR1YyWlc1MElEMGdlMzBwTzF4dUlDQWdJR1YyWlc1MExuQnlaWE56WldSTFpYbHpJRDBnZEdocGN5NWZiRzlqWVd4bExuQnlaWE56WldSTFpYbHpMbk5zYVdObEtEQXBPMXh1WEc0Z0lDQWdabTl5SUNoc1pYUWdhU0E5SURBN0lHa2dQQ0IwYUdsekxsOWhjSEJzYVdWa1RHbHpkR1Z1WlhKekxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNCamIyNXpkQ0JzYVhOMFpXNWxjaUE5SUhSb2FYTXVYMkZ3Y0d4cFpXUk1hWE4wWlc1bGNuTmJhVjA3WEc0Z0lDQWdJQ0JqYjI1emRDQnJaWGxEYjIxaWJ5QTlJR3hwYzNSbGJtVnlMbXRsZVVOdmJXSnZPMXh1SUNBZ0lDQWdhV1lnS0d0bGVVTnZiV0p2SUQwOVBTQnVkV3hzSUh4OElDRnJaWGxEYjIxaWJ5NWphR1ZqYXloMGFHbHpMbDlzYjJOaGJHVXVjSEpsYzNObFpFdGxlWE1wS1NCN1hHNGdJQ0FnSUNBZ0lHeHBjM1JsYm1WeUxuQnlaWFpsYm5SU1pYQmxZWFFnUFNCbVlXeHpaVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHdGxlVU52YldKdklDRTlQU0J1ZFd4c0lIeDhJR1YyWlc1MExuQnlaWE56WldSTFpYbHpMbXhsYm1kMGFDQTlQVDBnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJSFJvYVhNdVgyRndjR3hwWldSTWFYTjBaVzVsY25NdWMzQnNhV05sS0drc0lERXBPMXh1SUNBZ0lDQWdJQ0FnSUdrZ0xUMGdNVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCcFppQW9JV3hwYzNSbGJtVnlMbVY0WldOMWRHbHVaMGhoYm1Sc1pYSWdKaVlnYkdsemRHVnVaWEl1Y21Wc1pXRnpaVWhoYm1Sc1pYSXBJSHRjYmlBZ0lDQWdJQ0FnSUNCc2FYTjBaVzVsY2k1bGVHVmpkWFJwYm1kSVlXNWtiR1Z5SUQwZ2RISjFaVHRjYmlBZ0lDQWdJQ0FnSUNCc2FYTjBaVzVsY2k1eVpXeGxZWE5sU0dGdVpHeGxjaTVqWVd4c0tIUm9hWE1zSUdWMlpXNTBLVHRjYmlBZ0lDQWdJQ0FnSUNCc2FYTjBaVzVsY2k1bGVHVmpkWFJwYm1kSVlXNWtiR1Z5SUQwZ1ptRnNjMlU3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNCZmFHRnVaR3hsUTI5dGJXRnVaRUoxWnlobGRtVnVkQ3dnY0d4aGRHWnZjbTBwSUh0Y2JpQWdJQ0F2THlCUGJpQk5ZV01nZDJobGJpQjBhR1VnWTI5dGJXRnVaQ0JyWlhrZ2FYTWdhMlZ3ZENCd2NtVnpjMlZrTENCclpYbDFjQ0JwY3lCdWIzUWdkSEpwWjJkbGNtVmtJR1p2Y2lCaGJua2diM1JvWlhJZ2EyVjVMbHh1SUNBZ0lDOHZJRWx1SUhSb2FYTWdZMkZ6WlNCbWIzSmpaU0JoSUd0bGVYVndJR1p2Y2lCdWIyNHRiVzlrYVdacFpYSWdhMlY1Y3lCa2FYSmxZM1JzZVNCaFpuUmxjaUIwYUdVZ2EyVjVjSEpsYzNNdVhHNGdJQ0FnWTI5dWMzUWdiVzlrYVdacFpYSkxaWGx6SUQwZ1cxd2ljMmhwWm5SY0lpd2dYQ0pqZEhKc1hDSXNJRndpWVd4MFhDSXNJRndpWTJGd2MyeHZZMnRjSWl3Z1hDSjBZV0pjSWl3Z1hDSmpiMjF0WVc1a1hDSmRPMXh1SUNBZ0lHbG1JQ2h3YkdGMFptOXliUzV0WVhSamFDaGNJazFoWTF3aUtTQW1KaUIwYUdsekxsOXNiMk5oYkdVdWNISmxjM05sWkV0bGVYTXVhVzVqYkhWa1pYTW9YQ0pqYjIxdFlXNWtYQ0lwSUNZbVhHNGdJQ0FnSUNBZ0lDRnRiMlJwWm1sbGNrdGxlWE11YVc1amJIVmtaWE1vZEdocGN5NWZiRzlqWVd4bExtZGxkRXRsZVU1aGJXVnpLR1YyWlc1MExtdGxlVU52WkdVcFd6QmRLU2tnZTF4dUlDQWdJQ0FnZEdocGN5NWZkR0Z5WjJWMFMyVjVWWEJDYVc1a2FXNW5LR1YyWlc1MEtUdGNiaUFnSUNCOVhHNGdJSDFjYm4xY2JpSXNJbHh1Wlhod2IzSjBJR1oxYm1OMGFXOXVJSFZ6S0d4dlkyRnNaU3dnY0d4aGRHWnZjbTBzSUhWelpYSkJaMlZ1ZENrZ2UxeHVYRzRnSUM4dklHZGxibVZ5WVd4Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLRE1zSUNBZ1d5ZGpZVzVqWld3blhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnNExDQWdJRnNuWW1GamEzTndZV05sSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvT1N3Z0lDQmJKM1JoWWlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeUxDQWdXeWRqYkdWaGNpZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERXpMQ0FnV3lkbGJuUmxjaWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREUyTENBZ1d5ZHphR2xtZENkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFM0xDQWdXeWRqZEhKc0oxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UZ3NJQ0JiSjJGc2RDY3NJQ2R0Wlc1MUoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01Ua3NJQ0JiSjNCaGRYTmxKeXdnSjJKeVpXRnJKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NakFzSUNCYkoyTmhjSE5zYjJOckoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01qY3NJQ0JiSjJWelkyRndaU2NzSUNkbGMyTW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3pNaXdnSUZzbmMzQmhZMlVuTENBbmMzQmhZMlZpWVhJblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnek15d2dJRnNuY0dGblpYVndKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NelFzSUNCYkozQmhaMlZrYjNkdUoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb016VXNJQ0JiSjJWdVpDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtETTJMQ0FnV3lkb2IyMWxKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NemNzSUNCYkoyeGxablFuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d6T0N3Z0lGc25kWEFuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d6T1N3Z0lGc25jbWxuYUhRblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnME1Dd2dJRnNuWkc5M2JpZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEUXhMQ0FnV3lkelpXeGxZM1FuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2cwTWl3Z0lGc25jSEpwYm5SelkzSmxaVzRuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2cwTXl3Z0lGc25aWGhsWTNWMFpTZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEUTBMQ0FnV3lkemJtRndjMmh2ZENkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RRMUxDQWdXeWRwYm5ObGNuUW5MQ0FuYVc1ekoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb05EWXNJQ0JiSjJSbGJHVjBaU2NzSUNka1pXd25YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZzBOeXdnSUZzbmFHVnNjQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREUwTlN3Z1d5ZHpZM0p2Ykd4c2IyTnJKeXdnSjNOamNtOXNiQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREU0T0N3Z1d5ZGpiMjF0WVNjc0lDY3NKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVGt3TENCYkozQmxjbWx2WkNjc0lDY3VKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVGt4TENCYkozTnNZWE5vSnl3Z0oyWnZjbmRoY21SemJHRnphQ2NzSUNjdkoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01Ua3lMQ0JiSjJkeVlYWmxZV05qWlc1MEp5d2dKMkFuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d5TVRrc0lGc25iM0JsYm1KeVlXTnJaWFFuTENBbld5ZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtESXlNQ3dnV3lkaVlXTnJjMnhoYzJnbkxDQW5YRnhjWENkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RJeU1Td2dXeWRqYkc5elpXSnlZV05yWlhRbkxDQW5YU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREl5TWl3Z1d5ZGhjRzl6ZEhKdmNHaGxKeXdnSjF4Y0p5ZGRLVHRjYmx4dUlDQXZMeUF3TFRsY2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLRFE0TENCYkozcGxjbThuTENBbk1DZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEUTVMQ0JiSjI5dVpTY3NJQ2N4SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTlRBc0lGc25kSGR2Snl3Z0p6SW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZzFNU3dnV3lkMGFISmxaU2NzSUNjekoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb05USXNJRnNuWm05MWNpY3NJQ2MwSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTlRNc0lGc25abWwyWlNjc0lDYzFKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9OVFFzSUZzbmMybDRKeXdnSnpZblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnMU5Td2dXeWR6WlhabGJpY3NJQ2MzSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTlRZc0lGc25aV2xuYUhRbkxDQW5PQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLRFUzTENCYkoyNXBibVVuTENBbk9TZGRLVHRjYmx4dUlDQXZMeUJ1ZFcxd1lXUmNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RrMkxDQmJKMjUxYlhwbGNtOG5MQ0FuYm5WdE1DZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEazNMQ0JiSjI1MWJXOXVaU2NzSUNkdWRXMHhKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9PVGdzSUZzbmJuVnRkSGR2Snl3Z0oyNTFiVEluWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2c1T1N3Z1d5ZHVkVzEwYUhKbFpTY3NJQ2R1ZFcwekoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UQXdMQ0JiSjI1MWJXWnZkWEluTENBbmJuVnROQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV3TVN3Z1d5ZHVkVzFtYVhabEp5d2dKMjUxYlRVblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNneE1ESXNJRnNuYm5WdGMybDRKeXdnSjI1MWJUWW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3hNRE1zSUZzbmJuVnRjMlYyWlc0bkxDQW5iblZ0TnlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFd05Dd2dXeWR1ZFcxbGFXZG9kQ2NzSUNkdWRXMDRKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVEExTENCYkoyNTFiVzVwYm1VbkxDQW5iblZ0T1NkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFd05pd2dXeWR1ZFcxdGRXeDBhWEJzZVNjc0lDZHVkVzBxSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRBM0xDQmJKMjUxYldGa1pDY3NJQ2R1ZFcwckoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UQTRMQ0JiSjI1MWJXVnVkR1Z5SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRBNUxDQmJKMjUxYlhOMVluUnlZV04wSnl3Z0oyNTFiUzBuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d4TVRBc0lGc25iblZ0WkdWamFXMWhiQ2NzSUNkdWRXMHVKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVEV4TENCYkoyNTFiV1JwZG1sa1pTY3NJQ2R1ZFcwdkoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UUTBMQ0JiSjI1MWJXeHZZMnNuTENBbmJuVnRKMTBwTzF4dVhHNGdJQzh2SUdaMWJtTjBhVzl1SUd0bGVYTmNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE1pd2dXeWRtTVNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE15d2dXeWRtTWlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE5Dd2dXeWRtTXlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE5Td2dXeWRtTkNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE5pd2dXeWRtTlNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE55d2dXeWRtTmlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE9Dd2dXeWRtTnlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE9Td2dXeWRtT0NkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeU1Dd2dXeWRtT1NkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeU1Td2dXeWRtTVRBblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNneE1qSXNJRnNuWmpFeEoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01USXpMQ0JiSjJZeE1pZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERXlOQ3dnV3lkbU1UTW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3hNalVzSUZzblpqRTBKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVEkyTENCYkoyWXhOU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV5Tnl3Z1d5ZG1NVFluWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d4TWpnc0lGc25aakUzSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRJNUxDQmJKMll4T0NkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFek1Dd2dXeWRtTVRrblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNneE16RXNJRnNuWmpJd0oxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UTXlMQ0JiSjJZeU1TZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERXpNeXdnV3lkbU1qSW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3hNelFzSUZzblpqSXpKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVE0xTENCYkoyWXlOQ2RkS1R0Y2JseHVJQ0F2THlCelpXTnZibVJoY25rZ2EyVjVJSE41YldKdmJITmNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUJnSnl3Z1d5ZDBhV3hrWlNjc0lDZCtKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZHphR2xtZENBcklERW5MQ0JiSjJWNFkyeGhiV0YwYVc5dUp5d2dKMlY0WTJ4aGJXRjBhVzl1Y0c5cGJuUW5MQ0FuSVNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUF5Snl3Z1d5ZGhkQ2NzSUNkQUoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFMWhZM0p2S0NkemFHbG1kQ0FySURNbkxDQmJKMjUxYldKbGNpY3NJQ2NqSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkUxaFkzSnZLQ2R6YUdsbWRDQXJJRFFuTENCYkoyUnZiR3hoY2ljc0lDZGtiMnhzWVhKekp5d2dKMlJ2Ykd4aGNuTnBaMjRuTENBbkpDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBMUp5d2dXeWR3WlhKalpXNTBKeXdnSnlVblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1RXRmpjbThvSjNOb2FXWjBJQ3NnTmljc0lGc25ZMkZ5WlhRbkxDQW5YaWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJOWVdOeWJ5Z25jMmhwWm5RZ0t5QTNKeXdnV3lkaGJYQmxjbk5oYm1RbkxDQW5ZVzVrSnl3Z0p5WW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtUV0ZqY204b0ozTm9hV1owSUNzZ09DY3NJRnNuWVhOMFpYSnBjMnNuTENBbktpZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBNUp5d2dXeWR2Y0dWdWNHRnlaVzRuTENBbktDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBd0p5d2dXeWRqYkc5elpYQmhjbVZ1Snl3Z0p5a25YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtUV0ZqY204b0ozTm9hV1owSUNzZ0xTY3NJRnNuZFc1a1pYSnpZMjl5WlNjc0lDZGZKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZHphR2xtZENBcklEMG5MQ0JiSjNCc2RYTW5MQ0FuS3lkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUJiSnl3Z1d5ZHZjR1Z1WTNWeWJIbGljbUZqWlNjc0lDZHZjR1Z1WTNWeWJIbGljbUZqYTJWMEp5d2dKM3NuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrVFdGamNtOG9KM05vYVdaMElDc2dYU2NzSUZzblkyeHZjMlZqZFhKc2VXSnlZV05sSnl3Z0oyTnNiM05sWTNWeWJIbGljbUZqYTJWMEp5d2dKMzBuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrVFdGamNtOG9KM05vYVdaMElDc2dYRnhjWENjc0lGc25kbVZ5ZEdsallXeGlZWEluTENBbmZDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBN0p5d2dXeWRqYjJ4dmJpY3NJQ2M2SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkUxaFkzSnZLQ2R6YUdsbWRDQXJJRnhjSnljc0lGc25jWFZ2ZEdGMGFXOXViV0Z5YXljc0lDZGNYQ2NuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrVFdGamNtOG9KM05vYVdaMElDc2dJU3duTENCYkoyOXdaVzVoYm1kc1pXSnlZV05yWlhRbkxDQW5QQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJOWVdOeWJ5Z25jMmhwWm5RZ0t5QXVKeXdnV3lkamJHOXpaV0Z1WjJ4bFluSmhZMnRsZENjc0lDYytKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZHphR2xtZENBcklDOG5MQ0JiSjNGMVpYTjBhVzl1YldGeWF5Y3NJQ2MvSjEwcE8xeHVYRzRnSUdsbUlDaHdiR0YwWm05eWJTNXRZWFJqYUNnblRXRmpKeWtwSUh0Y2JpQWdJQ0JzYjJOaGJHVXVZbWx1WkUxaFkzSnZLQ2RqYjIxdFlXNWtKeXdnV3lkdGIyUW5MQ0FuYlc5a2FXWnBaWEluWFNrN1hHNGdJSDBnWld4elpTQjdYRzRnSUNBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnblkzUnliQ2NzSUZzbmJXOWtKeXdnSjIxdlpHbG1hV1Z5SjEwcE8xeHVJQ0I5WEc1Y2JpQWdMeTloTFhvZ1lXNWtJRUV0V2x4dUlDQm1iM0lnS0d4bGRDQnJaWGxEYjJSbElEMGdOalU3SUd0bGVVTnZaR1VnUEQwZ09UQTdJR3RsZVVOdlpHVWdLejBnTVNrZ2UxeHVJQ0FnSUhaaGNpQnJaWGxPWVcxbElEMGdVM1J5YVc1bkxtWnliMjFEYUdGeVEyOWtaU2hyWlhsRGIyUmxJQ3NnTXpJcE8xeHVJQ0FnSUhaaGNpQmpZWEJwZEdGc1MyVjVUbUZ0WlNBOUlGTjBjbWx1Wnk1bWNtOXRRMmhoY2tOdlpHVW9hMlY1UTI5a1pTazdYRzRnSUZ4MGJHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtHdGxlVU52WkdVc0lHdGxlVTVoYldVcE8xeHVJQ0JjZEd4dlkyRnNaUzVpYVc1a1RXRmpjbThvSjNOb2FXWjBJQ3NnSnlBcklHdGxlVTVoYldVc0lHTmhjR2wwWVd4TFpYbE9ZVzFsS1R0Y2JpQWdYSFJzYjJOaGJHVXVZbWx1WkUxaFkzSnZLQ2RqWVhCemJHOWpheUFySUNjZ0t5QnJaWGxPWVcxbExDQmpZWEJwZEdGc1MyVjVUbUZ0WlNrN1hHNGdJSDFjYmx4dUlDQXZMeUJpY205M2MyVnlJR05oZG1WaGRITmNiaUFnWTI5dWMzUWdjMlZ0YVdOdmJHOXVTMlY1UTI5a1pTQTlJSFZ6WlhKQloyVnVkQzV0WVhSamFDZ25SbWx5WldadmVDY3BJRDhnTlRrZ0lEb2dNVGcyTzF4dUlDQmpiMjV6ZENCa1lYTm9TMlY1UTI5a1pTQWdJQ0FnSUQwZ2RYTmxja0ZuWlc1MExtMWhkR05vS0NkR2FYSmxabTk0SnlrZ1B5QXhOek1nT2lBeE9EazdYRzRnSUdOdmJuTjBJR1Z4ZFdGc1MyVjVRMjlrWlNBZ0lDQWdQU0IxYzJWeVFXZGxiblF1YldGMFkyZ29KMFpwY21WbWIzZ25LU0EvSURZeElDQTZJREU0Tnp0Y2JpQWdiR1YwSUd4bFpuUkRiMjF0WVc1a1MyVjVRMjlrWlR0Y2JpQWdiR1YwSUhKcFoyaDBRMjl0YldGdVpFdGxlVU52WkdVN1hHNGdJR2xtSUNod2JHRjBabTl5YlM1dFlYUmphQ2duVFdGakp5a2dKaVlnS0hWelpYSkJaMlZ1ZEM1dFlYUmphQ2duVTJGbVlYSnBKeWtnZkh3Z2RYTmxja0ZuWlc1MExtMWhkR05vS0NkRGFISnZiV1VuS1NrcElIdGNiaUFnSUNCc1pXWjBRMjl0YldGdVpFdGxlVU52WkdVZ0lEMGdPVEU3WEc0Z0lDQWdjbWxuYUhSRGIyMXRZVzVrUzJWNVEyOWtaU0E5SURrek8xeHVJQ0I5SUdWc2MyVWdhV1lvY0d4aGRHWnZjbTB1YldGMFkyZ29KMDFoWXljcElDWW1JSFZ6WlhKQloyVnVkQzV0WVhSamFDZ25UM0JsY21FbktTa2dlMXh1SUNBZ0lHeGxablJEYjIxdFlXNWtTMlY1UTI5a1pTQWdQU0F4Tnp0Y2JpQWdJQ0J5YVdkb2RFTnZiVzFoYm1STFpYbERiMlJsSUQwZ01UYzdYRzRnSUgwZ1pXeHpaU0JwWmlod2JHRjBabTl5YlM1dFlYUmphQ2duVFdGakp5a2dKaVlnZFhObGNrRm5aVzUwTG0xaGRHTm9LQ2RHYVhKbFptOTRKeWtwSUh0Y2JpQWdJQ0JzWldaMFEyOXRiV0Z1WkV0bGVVTnZaR1VnSUQwZ01qSTBPMXh1SUNBZ0lISnBaMmgwUTI5dGJXRnVaRXRsZVVOdlpHVWdQU0F5TWpRN1hHNGdJSDFjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtITmxiV2xqYjJ4dmJrdGxlVU52WkdVc0lDQWdJRnNuYzJWdGFXTnZiRzl1Snl3Z0p6c25YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTaGtZWE5vUzJWNVEyOWtaU3dnSUNBZ0lDQWdJQ0JiSjJSaGMyZ25MQ0FuTFNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0dWeGRXRnNTMlY1UTI5a1pTd2dJQ0FnSUNBZ0lGc25aWEYxWVd3bkxDQW5aWEYxWVd4emFXZHVKeXdnSnowblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNoc1pXWjBRMjl0YldGdVpFdGxlVU52WkdVc0lDQmJKMk52YlcxaGJtUW5MQ0FuZDJsdVpHOTNjeWNzSUNkM2FXNG5MQ0FuYzNWd1pYSW5MQ0FuYkdWbWRHTnZiVzFoYm1RbkxDQW5iR1ZtZEhkcGJtUnZkM01uTENBbmJHVm1kSGRwYmljc0lDZHNaV1owYzNWd1pYSW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTaHlhV2RvZEVOdmJXMWhibVJMWlhsRGIyUmxMQ0JiSjJOdmJXMWhibVFuTENBbmQybHVaRzkzY3ljc0lDZDNhVzRuTENBbmMzVndaWEluTENBbmNtbG5hSFJqYjIxdFlXNWtKeXdnSjNKcFoyaDBkMmx1Wkc5M2N5Y3NJQ2R5YVdkb2RIZHBiaWNzSUNkeWFXZG9kSE4xY0dWeUoxMHBPMXh1WEc0Z0lDOHZJR3RwYkd3Z2EyVjVjMXh1SUNCc2IyTmhiR1V1YzJWMFMybHNiRXRsZVNnblkyOXRiV0Z1WkNjcE8xeHVmVHRjYmlJc0ltbHRjRzl5ZENCN0lFdGxlV0p2WVhKa0lIMGdabkp2YlNBbkxpOXNhV0l2YTJWNVltOWhjbVFuTzF4dWFXMXdiM0owSUhzZ1RHOWpZV3hsSUgwZ1puSnZiU0FuTGk5c2FXSXZiRzlqWVd4bEp6dGNibWx0Y0c5eWRDQjdJRXRsZVVOdmJXSnZJSDBnWm5KdmJTQW5MaTlzYVdJdmEyVjVMV052YldKdkp6dGNibWx0Y0c5eWRDQjdJSFZ6SUgwZ1puSnZiU0FuTGk5c2IyTmhiR1Z6TDNWekp6dGNibHh1WTI5dWMzUWdhMlY1WW05aGNtUWdQU0J1WlhjZ1MyVjVZbTloY21Rb0tUdGNibHh1YTJWNVltOWhjbVF1YzJWMFRHOWpZV3hsS0NkMWN5Y3NJSFZ6S1R0Y2JseHVhMlY1WW05aGNtUXVTMlY1WW05aGNtUWdQU0JMWlhsaWIyRnlaRHRjYm10bGVXSnZZWEprTGt4dlkyRnNaU0E5SUV4dlkyRnNaVHRjYm10bGVXSnZZWEprTGt0bGVVTnZiV0p2SUQwZ1MyVjVRMjl0WW04N1hHNWNibVY0Y0c5eWRDQmtaV1poZFd4MElHdGxlV0p2WVhKa08xeHVJbDBzSW01aGJXVnpJanBiSWt0bGVVTnZiV0p2SWl3aWEyVjVRMjl0WW05VGRISWlMQ0p6YjNWeVkyVlRkSElpTENKemRXSkRiMjFpYjNNaUxDSndZWEp6WlVOdmJXSnZVM1J5SWl3aWEyVjVUbUZ0WlhNaUxDSnlaV1IxWTJVaUxDSnRaVzF2SWl3aWJtVjRkRk4xWWtOdmJXSnZJaXdpWTI5dVkyRjBJaXdpY0hKbGMzTmxaRXRsZVU1aGJXVnpJaXdpYzNSaGNuUnBibWRMWlhsT1lXMWxTVzVrWlhnaUxDSnBJaXdpYkdWdVozUm9JaXdpWDJOb1pXTnJVM1ZpUTI5dFltOGlMQ0p2ZEdobGNrdGxlVU52YldKdklpd2ljM1ZpUTI5dFltOGlMQ0p2ZEdobGNsTjFZa052YldKdklpd2ljMnhwWTJVaUxDSnFJaXdpYTJWNVRtRnRaU0lzSW1sdVpHVjRJaXdpYVc1a1pYaFBaaUlzSW5Od2JHbGpaU0lzSW1WdVpFbHVaR1Y0SWl3aVpYTmpZWEJsWkV0bGVVNWhiV1VpTENKamIyMWliMFJsYkdsdGFXNWhkRzl5SWl3aWEyVjVSR1ZzYVcxcGJtRjBiM0lpTENKemRXSkRiMjFpYjFOMGNuTWlMQ0pmYzNCc2FYUlRkSElpTENKamIyMWlieUlzSW5CMWMyZ2lMQ0p6ZEhJaUxDSmtaV3hwYldsdVlYUnZjaUlzSW5NaUxDSmtJaXdpWXlJc0ltTmhJaXdpWTJraUxDSjBjbWx0SWl3aVRHOWpZV3hsSWl3aWJtRnRaU0lzSW14dlkyRnNaVTVoYldVaUxDSmhZM1JwZG1WVVlYSm5aWFJMWlhseklpd2ljSEpsYzNObFpFdGxlWE1pTENKZllYQndiR2xsWkUxaFkzSnZjeUlzSWw5clpYbE5ZWEFpTENKZmEybHNiRXRsZVVOdlpHVnpJaXdpWDIxaFkzSnZjeUlzSW10bGVVTnZaR1VpTENKb1lXNWtiR1Z5SWl3aWJXRmpjbThpTENKclpYbERiMjFpYnlJc0ltdGxlVU52WkdWeklpd2laMlYwUzJWNVEyOWtaWE1pTENKelpYUkxhV3hzUzJWNUlpd2ljSEpsYzNOTFpYa2lMQ0puWlhSTFpYbE9ZVzFsY3lJc0lsOWhjSEJzZVUxaFkzSnZjeUlzSW5KbGJHVmhjMlZMWlhraUxDSnJhV3hzUzJWNVEyOWtaVWx1WkdWNElpd2lYMk5zWldGeVRXRmpjbTl6SWl3aWJXRmpjbTl6SWl3aVkyaGxZMnNpTENKTFpYbGliMkZ5WkNJc0luUmhjbWRsZEZkcGJtUnZkeUlzSW5SaGNtZGxkRVZzWlcxbGJuUWlMQ0owWVhKblpYUlFiR0YwWm05eWJTSXNJblJoY21kbGRGVnpaWEpCWjJWdWRDSXNJbDlzYjJOaGJHVWlMQ0pmWTNWeWNtVnVkRU52Ym5SbGVIUWlMQ0pmWTI5dWRHVjRkSE1pTENKZmJHbHpkR1Z1WlhKeklpd2lYMkZ3Y0d4cFpXUk1hWE4wWlc1bGNuTWlMQ0pmYkc5allXeGxjeUlzSWw5MFlYSm5aWFJGYkdWdFpXNTBJaXdpWDNSaGNtZGxkRmRwYm1SdmR5SXNJbDkwWVhKblpYUlFiR0YwWm05eWJTSXNJbDkwWVhKblpYUlZjMlZ5UVdkbGJuUWlMQ0pmYVhOTmIyUmxjbTVDY205M2MyVnlJaXdpWDNSaGNtZGxkRXRsZVVSdmQyNUNhVzVrYVc1bklpd2lYM1JoY21kbGRFdGxlVlZ3UW1sdVpHbHVaeUlzSWw5MFlYSm5aWFJTWlhObGRFSnBibVJwYm1jaUxDSmZjR0YxYzJWa0lpd2laMnh2WW1Gc0lpd2liR2x6ZEdWdVpYSnpJaXdpYzJWMFEyOXVkR1Y0ZENJc0lteHZZMkZzWlVKMWFXeGtaWElpTENKc2IyTmhiR1VpTENKZmJHOWpZV3hsVG1GdFpTSXNJbXh2WTJGc1RtRnRaU0lzSW5CeVpYTnpTR0Z1Wkd4bGNpSXNJbkpsYkdWaGMyVklZVzVrYkdWeUlpd2ljSEpsZG1WdWRGSmxjR1ZoZEVKNVJHVm1ZWFZzZENJc0ltSnBibVFpTENKd2NtVjJaVzUwVW1Wd1pXRjBJaXdpWlhobFkzVjBhVzVuU0dGdVpHeGxjaUlzSW5WdVltbHVaQ0lzSW14cGMzUmxibVZ5SWl3aVkyOXRZbTlOWVhSamFHVnpJaXdpYVhORmNYVmhiQ0lzSW5CeVpYTnpTR0Z1Wkd4bGNrMWhkR05vWlhNaUxDSnlaV3hsWVhObFNHRnVaR3hsY2sxaGRHTm9aWE1pTENKamIyNTBaWGgwVG1GdFpTSXNJbkpsYkdWaGMyVkJiR3hMWlhseklpd2laMnh2WW1Gc1EyOXVkR1Y0ZENJc0ltTnZiblJsZUhRaUxDSnpkRzl3SWl3aWQyRjBZMmdpTENKallXeHNZbUZqYXlJc0luQnlaWFpwYjNWelEyOXVkR1Y0ZEU1aGJXVWlMQ0puWlhSRGIyNTBaWGgwSWl3aWQybHVJaXdpWjJ4dlltRnNWR2hwY3lJc0luZHBibVJ2ZHlJc0ltRmtaRVYyWlc1MFRHbHpkR1Z1WlhJaUxDSmhkSFJoWTJoRmRtVnVkQ0lzSWtWeWNtOXlJaXdpYm05a1pWUjVjR1VpTENKMWMyVnlRV2RsYm5RaUxDSnVZWFpwWjJGMGIzSWlMQ0p3YkdGMFptOXliU0lzSW1SdlkzVnRaVzUwSWl3aVpYWmxiblFpTENKZmFHRnVaR3hsUTI5dGJXRnVaRUoxWnlJc0lsOWlhVzVrUlhabGJuUWlMQ0pqZFhKeVpXNTBRMjl1ZEdWNGRDSXNJbDkxYm1KcGJtUkZkbVZ1ZENJc0lsOWhjSEJzZVVKcGJtUnBibWR6SWl3aVgyTnNaV0Z5UW1sdVpHbHVaM01pTENKbGRtVnVkRTVoYldVaUxDSnlaVzF2ZG1WRmRtVnVkRXhwYzNSbGJtVnlJaXdpWkdWMFlXTm9SWFpsYm5RaUxDSnNhWE4wWlc1bGNrZHliM1Z3Y3lJc0lteHBjM1JsYm1WeVIzSnZkWEJOWVhBaUxDSnpiM0owSWl3aVlTSXNJbUlpTENKbWIzSkZZV05vSWl3aWJDSXNJbTFoY0VsdVpHVjRJaXdpWDJkbGRFZHliM1Z3WldSTWFYTjBaVzVsY25NaUxDSnpiMjFsSWl3aWF5SXNJbWx1WTJ4MVpHVnpJaXdpWTJGc2JDSXNJbTF2WkdsbWFXVnlTMlY1Y3lJc0ltMWhkR05vSWl3aWRYTWlMQ0ppYVc1a1MyVjVRMjlrWlNJc0ltSnBibVJOWVdOeWJ5SXNJbE4wY21sdVp5SXNJbVp5YjIxRGFHRnlRMjlrWlNJc0ltTmhjR2wwWVd4TFpYbE9ZVzFsSWl3aWMyVnRhV052Ykc5dVMyVjVRMjlrWlNJc0ltUmhjMmhMWlhsRGIyUmxJaXdpWlhGMVlXeExaWGxEYjJSbElpd2liR1ZtZEVOdmJXMWhibVJMWlhsRGIyUmxJaXdpY21sbmFIUkRiMjF0WVc1a1MyVjVRMjlrWlNJc0ltdGxlV0p2WVhKa0lpd2ljMlYwVEc5allXeGxJbDBzSW0xaGNIQnBibWR6SWpvaU96czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenROUVVOaFFTeFJRVUZpTzBWQlEwVXNiMEpCUVZsRExGZEJRVm9zUlVGQmVVSTdSVUZCUVRzN1JVRkRka0lzVTBGQlMwTXNVMEZCVEN4SFFVRnBRa1FzVjBGQmFrSTdSVUZEUVN4VFFVRkxSU3hUUVVGTUxFZEJRV2xDU0N4UlFVRlJMRU5CUVVOSkxHRkJRVlFzUTBGQmRVSklMRmRCUVhaQ0xFTkJRV3BDTzBWQlEwRXNVMEZCUzBrc1VVRkJUQ3hIUVVGcFFpeExRVUZMUml4VFFVRk1MRU5CUVdWSExFMUJRV1lzUTBGQmMwSXNWVUZCUTBNc1NVRkJSQ3hGUVVGUFF5eFpRVUZRTzBWQlFVRXNZVUZEY2tORUxFbEJRVWtzUTBGQlEwVXNUVUZCVEN4RFFVRlpSQ3haUVVGYUxFTkJSSEZETzBWQlFVRXNTMEZCZEVJc1JVRkRXU3hGUVVSYUxFTkJRV3BDTzBWQlJVUTdPMFZCVGtnN1JVRkJRVHRGUVVGQkxEQkNRVkZSUlN4bFFWSlNMRVZCVVhsQ08wVkJRM0pDTEZWQlFVbERMRzlDUVVGdlFpeEhRVUZITEVOQlFUTkNPenRGUVVOQkxGZEJRVXNzU1VGQlNVTXNRMEZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVOQlFVTXNSMEZCUnl4TFFVRkxWQ3hUUVVGTUxFTkJRV1ZWTEUxQlFXNURMRVZCUVRKRFJDeERRVUZETEVsQlFVa3NRMEZCYUVRc1JVRkJiVVE3UlVGRGFrUkVMRkZCUVVGQkxHOUNRVUZ2UWl4SFFVRkhMRXRCUVV0SExHTkJRVXdzUTBGRGNrSXNTMEZCUzFnc1UwRkJUQ3hEUVVGbFV5eERRVUZtTEVOQlJIRkNMRVZCUlhKQ1JDeHZRa0ZHY1VJc1JVRkhja0pFTEdWQlNIRkNMRU5CUVhaQ096dEZRVXRCTEZsQlFVbERMRzlDUVVGdlFpeExRVUZMTEVOQlFVTXNRMEZCT1VJc1JVRkJhVU03UlVGQlJTeHBRa0ZCVHl4TFFVRlFPMFZCUVdVN1JVRkRia1E3TzBWQlEwUXNZVUZCVHl4SlFVRlFPMFZCUTBRN1JVRnVRa2c3UlVGQlFUdEZRVUZCTERSQ1FYRkNWVWtzWVVGeVFsWXNSVUZ4UW5sQ08wVkJRM0pDTEZWQlEwVXNRMEZCUTBFc1lVRkJSQ3hKUVVOQkxFOUJRVTlCTEdGQlFWQXNTMEZCZVVJc1VVRkJla0lzU1VGRFFTeFJRVUZQUVN4aFFVRlFMRTFCUVhsQ0xGRkJTRE5DTEVWQlNVVTdSVUZCUlN4bFFVRlBMRXRCUVZBN1JVRkJaVHM3UlVGRmJrSXNWVUZCU1N4UFFVRlBRU3hoUVVGUUxFdEJRWGxDTEZGQlFUZENMRVZCUVhWRE8wVkJRM0pEUVN4UlFVRkJRU3hoUVVGaExFZEJRVWNzU1VGQlNXWXNVVUZCU2l4RFFVRmhaU3hoUVVGaUxFTkJRV2hDTzBWQlEwUTdPMFZCUlVRc1ZVRkJTU3hMUVVGTFdpeFRRVUZNTEVOQlFXVlZMRTFCUVdZc1MwRkJNRUpGTEdGQlFXRXNRMEZCUTFvc1UwRkJaQ3hEUVVGM1FsVXNUVUZCZEVRc1JVRkJPRVE3UlVGRE5VUXNaVUZCVHl4TFFVRlFPMFZCUTBRN08wVkJRMFFzVjBGQlN5eEpRVUZKUkN4RFFVRkRMRWRCUVVjc1EwRkJZaXhGUVVGblFrRXNRMEZCUXl4SFFVRkhMRXRCUVV0VUxGTkJRVXdzUTBGQlpWVXNUVUZCYmtNc1JVRkJNa05FTEVOQlFVTXNTVUZCU1N4RFFVRm9SQ3hGUVVGdFJEdEZRVU5xUkN4WlFVRkpMRXRCUVV0VUxGTkJRVXdzUTBGQlpWTXNRMEZCWml4RlFVRnJRa01zVFVGQmJFSXNTMEZCTmtKRkxHRkJRV0VzUTBGQlExb3NVMEZCWkN4RFFVRjNRbE1zUTBGQmVFSXNSVUZCTWtKRExFMUJRVFZFTEVWQlFXOUZPMFZCUTJ4RkxHbENRVUZQTEV0QlFWQTdSVUZEUkR0RlFVTkdPenRGUVVWRUxGZEJRVXNzU1VGQlNVUXNSVUZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVWQlFVTXNSMEZCUnl4TFFVRkxWQ3hUUVVGTUxFTkJRV1ZWTEUxQlFXNURMRVZCUVRKRFJDeEZRVUZETEVsQlFVa3NRMEZCYUVRc1JVRkJiVVE3UlVGRGFrUXNXVUZCVFVrc1VVRkJVU3hIUVVGUkxFdEJRVXRpTEZOQlFVd3NRMEZCWlZNc1JVRkJaaXhEUVVGMFFqczdSVUZEUVN4WlFVRk5TeXhoUVVGaExFZEJRVWRHTEdGQlFXRXNRMEZCUTFvc1UwRkJaQ3hEUVVGM1FsTXNSVUZCZUVJc1JVRkJNa0pOTEV0QlFUTkNMRU5CUVdsRExFTkJRV3BETEVOQlFYUkNPenRGUVVWQkxHRkJRVXNzU1VGQlNVTXNRMEZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVOQlFVTXNSMEZCUjBnc1VVRkJVU3hEUVVGRFNDeE5RVUUzUWl4RlFVRnhRMDBzUTBGQlF5eEpRVUZKTEVOQlFURkRMRVZCUVRaRE8wVkJRek5ETEdOQlFVMURMRTlCUVU4c1IwRkJSMG9zVVVGQlVTeERRVUZEUnl4RFFVRkVMRU5CUVhoQ08wVkJRMEVzWTBGQlRVVXNTMEZCU3l4SFFVRkxTaXhoUVVGaExFTkJRVU5MTEU5QlFXUXNRMEZCYzBKR0xFOUJRWFJDTEVOQlFXaENPenRGUVVWQkxHTkJRVWxETEV0QlFVc3NSMEZCUnl4RFFVRkRMRU5CUVdJc1JVRkJaMEk3UlVGRFpFb3NXVUZCUVVFc1lVRkJZU3hEUVVGRFRTeE5RVUZrTEVOQlFYRkNSaXhMUVVGeVFpeEZRVUUwUWl4RFFVRTFRanRGUVVORU8wVkJRMFk3TzBWQlEwUXNXVUZCU1Vvc1lVRkJZU3hEUVVGRFNpeE5RVUZrTEV0QlFYbENMRU5CUVRkQ0xFVkJRV2RETzBWQlF6bENMR2xDUVVGUExFdEJRVkE3UlVGRFJEdEZRVU5HT3p0RlFVVkVMR0ZCUVU4c1NVRkJVRHRGUVVORU8wVkJNMFJJTzBWQlFVRTdSVUZCUVN4dFEwRTJSR2xDUnl4UlFUZEVha0lzUlVFMlJESkNUQ3h2UWtFM1JETkNMRVZCTmtScFJFUXNaVUUzUkdwRUxFVkJOa1JyUlR0RlFVTTVSRTBzVFVGQlFVRXNVVUZCVVN4SFFVRkhRU3hSUVVGUkxFTkJRVU5GTEV0QlFWUXNRMEZCWlN4RFFVRm1MRU5CUVZnN1JVRkRRVklzVFVGQlFVRXNaVUZCWlN4SFFVRkhRU3hsUVVGbExFTkJRVU5STEV0QlFXaENMRU5CUVhOQ1VDeHZRa0ZCZEVJc1EwRkJiRUk3UlVGRlFTeFZRVUZKWVN4UlFVRlJMRWRCUVVkaUxHOUNRVUZtT3p0RlFVTkJMRmRCUVVzc1NVRkJTVU1zUTBGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFTkJRVU1zUjBGQlIwa3NVVUZCVVN4RFFVRkRTQ3hOUVVFM1FpeEZRVUZ4UTBRc1EwRkJReXhKUVVGSkxFTkJRVEZETEVWQlFUWkRPMFZCUlRORExGbEJRVWxSTEU5QlFVOHNSMEZCUjBvc1VVRkJVU3hEUVVGRFNpeERRVUZFTEVOQlFYUkNPenRGUVVOQkxGbEJRVWxSTEU5QlFVOHNRMEZCUXl4RFFVRkVMRU5CUVZBc1MwRkJaU3hKUVVGdVFpeEZRVUY1UWp0RlFVTjJRaXhqUVVGTlN5eGpRVUZqTEVkQlFVZE1MRTlCUVU4c1EwRkJRMFlzUzBGQlVpeERRVUZqTEVOQlFXUXNRMEZCZGtJN08wVkJRMEVzWTBGRFJVOHNZMEZCWXl4TFFVRkxla0lzVVVGQlVTeERRVUZETUVJc1owSkJRVFZDTEVsQlEwRkVMR05CUVdNc1MwRkJTM3BDTEZGQlFWRXNRMEZCUXpKQ0xHTkJSamxDTEVWQlIwVTdSVUZEUVZBc1dVRkJRVUVzVDBGQlR5eEhRVUZIU3l4alFVRldPMFZCUTBRN1JVRkRSanM3UlVGRlJDeFpRVUZOU2l4TFFVRkxMRWRCUVVkWUxHVkJRV1VzUTBGQlExa3NUMEZCYUVJc1EwRkJkMEpHTEU5QlFYaENMRU5CUVdRN08wVkJRMEVzV1VGQlNVTXNTMEZCU3l4SFFVRkhMRU5CUVVNc1EwRkJZaXhGUVVGblFqdEZRVU5rVEN4VlFVRkJRU3hSUVVGUkxFTkJRVU5QTEUxQlFWUXNRMEZCWjBKWUxFTkJRV2hDTEVWQlFXMUNMRU5CUVc1Q08wVkJRMEZCTEZWQlFVRkJMRU5CUVVNc1NVRkJTU3hEUVVGTU96dEZRVU5CTEdOQlFVbFRMRXRCUVVzc1IwRkJSMGNzVVVGQldpeEZRVUZ6UWp0RlFVTndRa0VzV1VGQlFVRXNVVUZCVVN4SFFVRkhTQ3hMUVVGWU8wVkJRMFE3TzBWQlEwUXNZMEZCU1V3c1VVRkJVU3hEUVVGRFNDeE5RVUZVTEV0QlFXOUNMRU5CUVhoQ0xFVkJRVEpDTzBWQlEzcENMRzFDUVVGUFZ5eFJRVUZRTzBWQlEwUTdSVUZEUmp0RlFVTkdPenRGUVVORUxHRkJRVThzUTBGQlF5eERRVUZTTzBWQlEwUTdSVUUxUmtnN08wVkJRVUU3UlVGQlFUdEZRU3RHUVhoQ0xGRkJRVkVzUTBGQlF6QkNMR2RDUVVGVUxFZEJRVFJDTEVkQlFUVkNPMFZCUTBFeFFpeFJRVUZSTEVOQlFVTXlRaXhqUVVGVUxFZEJRVFJDTEVkQlFUVkNPenRGUVVWQk0wSXNVVUZCVVN4RFFVRkRTU3hoUVVGVUxFZEJRWGxDTEZWQlFWTklMRmRCUVZRc1JVRkJjMEk3UlVGRE4wTXNUVUZCVFRKQ0xGbEJRVmtzUjBGQlJ6VkNMRkZCUVZFc1EwRkJRelpDTEZOQlFWUXNRMEZCYlVJMVFpeFhRVUZ1UWl4RlFVRm5RMFFzVVVGQlVTeERRVUZETUVJc1owSkJRWHBETEVOQlFYSkNPenRGUVVOQkxFMUJRVTFKTEV0QlFVc3NSMEZCVlN4RlFVRnlRanM3UlVGRlFTeFBRVUZMTEVsQlFVbHNRaXhEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZwUWtFc1EwRkJReXhIUVVGSFowSXNXVUZCV1N4RFFVRkRaaXhOUVVGc1F5eEZRVUV3UTBRc1EwRkJReXhKUVVGSkxFTkJRUzlETEVWQlFXdEVPMFZCUTJoRWEwSXNTVUZCUVVFc1MwRkJTeXhEUVVGRFF5eEpRVUZPTEVOQlFWY3ZRaXhSUVVGUkxFTkJRVU0yUWl4VFFVRlVMRU5CUVcxQ1JDeFpRVUZaTEVOQlFVTm9RaXhEUVVGRUxFTkJRUzlDTEVWQlFXOURXaXhSUVVGUkxFTkJRVU15UWl4alFVRTNReXhEUVVGWU8wVkJRMFE3TzBWQlEwUXNVMEZCVDBjc1MwRkJVRHRGUVVORUxFTkJVa1E3TzBWQlZVRTVRaXhSUVVGUkxFTkJRVU0yUWl4VFFVRlVMRWRCUVhGQ0xGVkJRVk5ITEVkQlFWUXNSVUZCWTBNc1YwRkJaQ3hGUVVFeVFqdEZRVU01UXl4TlFVRk5ReXhEUVVGRExFZEJRVWxHTEVkQlFWZzdSVUZEUVN4TlFVRk5SeXhEUVVGRExFZEJRVWxHTEZkQlFWZzdSVUZEUVN4TlFVRkpSeXhEUVVGRExFZEJRVWtzUlVGQlZEdEZRVU5CTEUxQlFVMURMRVZCUVVVc1IwRkJSeXhGUVVGWU96dEZRVVZCTEU5QlFVc3NTVUZCU1VNc1JVRkJSU3hIUVVGSExFTkJRV1FzUlVGQmFVSkJMRVZCUVVVc1IwRkJSMG9zUTBGQlF5eERRVUZEY2tJc1RVRkJlRUlzUlVGQlowTjVRaXhGUVVGRkxFbEJRVWtzUTBGQmRFTXNSVUZCZVVNN1JVRkRka01zVVVGQlNVRXNSVUZCUlN4SFFVRkhMRU5CUVV3c1NVRkJWVW9zUTBGQlF5eERRVUZEU1N4RlFVRkVMRU5CUVVRc1MwRkJWVWdzUTBGQmNFSXNTVUZCZVVKRUxFTkJRVU1zUTBGQlEwa3NSVUZCUlN4SFFVRkhMRU5CUVU0c1EwRkJSQ3hMUVVGakxFbEJRVE5ETEVWQlFXbEVPMFZCUXk5RFJDeE5RVUZCUVN4RlFVRkZMRU5CUVVOT0xFbEJRVWdzUTBGQlVVc3NRMEZCUXl4RFFVRkRSeXhKUVVGR0xFVkJRVkk3UlVGRFFVZ3NUVUZCUVVFc1EwRkJReXhIUVVGSExFVkJRVW83UlVGRFFVVXNUVUZCUVVFc1JVRkJSU3hKUVVGSkxFTkJRVTQ3UlVGRFJEczdSVUZEUkVZc1NVRkJRVUVzUTBGQlF5eEpRVUZKUml4RFFVRkRMRU5CUVVOSkxFVkJRVVFzUTBGQlRqdEZRVU5FT3p0RlFVTkVMRTFCUVVsR0xFTkJRVW9zUlVGQlR6dEZRVUZGUXl4SlFVRkJRU3hGUVVGRkxFTkJRVU5PTEVsQlFVZ3NRMEZCVVVzc1EwRkJReXhEUVVGRFJ5eEpRVUZHTEVWQlFWSTdSVUZCYjBJN08wVkJSVGRDTEZOQlFVOUdMRVZCUVZBN1JVRkRSQ3hEUVdwQ1JEczdUVU14UjJGSExFMUJRV0k3UlVGRFJTeHJRa0ZCV1VNc1NVRkJXaXhGUVVGclFqdEZRVUZCT3p0RlFVTm9RaXhUUVVGTFF5eFZRVUZNTEVkQlFUSkNSQ3hKUVVFelFqdEZRVU5CTEZOQlFVdEZMR2RDUVVGTUxFZEJRWGRDTEVWQlFYaENPMFZCUTBFc1UwRkJTME1zVjBGQlRDeEhRVUV5UWl4RlFVRXpRanRGUVVOQkxGTkJRVXRETEdOQlFVd3NSMEZCTWtJc1JVRkJNMEk3UlVGRFFTeFRRVUZMUXl4UFFVRk1MRWRCUVRKQ0xFVkJRVE5DTzBWQlEwRXNVMEZCUzBNc1lVRkJUQ3hIUVVFeVFpeEZRVUV6UWp0RlFVTkJMRk5CUVV0RExFOUJRVXdzUjBGQk1rSXNSVUZCTTBJN1JVRkRSRHM3UlVGVVNEdEZRVUZCTzBWQlFVRXNaME5CVjJORExFOUJXR1FzUlVGWGRVSTFReXhSUVZoMlFpeEZRVmRwUXp0RlFVTTNRaXhWUVVGSkxFOUJRVTlCTEZGQlFWQXNTMEZCYjBJc1VVRkJlRUlzUlVGQmEwTTdSVUZEYUVOQkxGRkJRVUZCTEZGQlFWRXNSMEZCUnl4RFFVRkRRU3hSUVVGRUxFTkJRVmc3UlVGRFJEczdSVUZGUkN4WFFVRkxlVU1zVDBGQlRDeERRVUZoUnl4UFFVRmlMRWxCUVhkQ05VTXNVVUZCZUVJN1JVRkRSRHRGUVdwQ1NEdEZRVUZCTzBWQlFVRXNPRUpCYlVKWlNpeFhRVzVDV2l4RlFXMUNlVUpKTEZGQmJrSjZRaXhGUVcxQ2JVTTdSVUZETDBJc1ZVRkJTU3hQUVVGUFFTeFJRVUZRTEV0QlFXOUNMRkZCUVhoQ0xFVkJRV3RETzBWQlEyaERRU3hSUVVGQlFTeFJRVUZSTEVkQlFVY3NRMEZCUlVFc1VVRkJSaXhEUVVGWU8wVkJRMFE3TzBWQlJVUXNWVUZCU1RaRExFOUJRVThzUjBGQlJ5eEpRVUZrT3p0RlFVTkJMRlZCUVVrc1QwRkJUemRETEZGQlFWQXNTMEZCYjBJc1ZVRkJlRUlzUlVGQmIwTTdSVUZEYkVNMlF5eFJRVUZCUVN4UFFVRlBMRWRCUVVjM1F5eFJRVUZXTzBWQlEwRkJMRkZCUVVGQkxGRkJRVkVzUjBGQlJ5eEpRVUZZTzBWQlEwUTdPMFZCUlVRc1ZVRkJUVGhETEV0QlFVc3NSMEZCUnp0RlFVTmFReXhSUVVGQlFTeFJRVUZSTEVWQlFVY3NTVUZCU1hCRUxGRkJRVW9zUTBGQllVTXNWMEZCWWl4RFFVUkRPMFZCUlZwSkxGRkJRVUZCTEZGQlFWRXNSVUZCUjBFc1VVRkdRenRGUVVkYU5rTXNVVUZCUVVFc1QwRkJUeXhGUVVGSlFUdEZRVWhETEU5QlFXUTdPMFZCVFVFc1YwRkJTMFlzVDBGQlRDeERRVUZoYWtJc1NVRkJZaXhEUVVGclFtOUNMRXRCUVd4Q08wVkJRMFE3UlVGeVEwZzdSVUZCUVR0RlFVRkJMR2REUVhWRFl5OUNMRTlCZGtOa0xFVkJkVU4xUWp0RlFVTnVRaXhWUVVGTmFVTXNVVUZCVVN4SFFVRkhMRVZCUVdwQ096dEZRVU5CTEZkQlFVc3NTVUZCVFVvc1QwRkJXQ3hKUVVGelFpeExRVUZMU0N4UFFVRXpRaXhGUVVGdlF6dEZRVU5zUXl4WlFVRk5la0lzUzBGQlN5eEhRVUZITEV0QlFVdDVRaXhQUVVGTUxFTkJRV0ZITEU5QlFXSXNSVUZCYzBJelFpeFBRVUYwUWl4RFFVRTRRa1lzVDBGQk9VSXNRMEZCWkRzN1JVRkRRU3haUVVGSlF5eExRVUZMTEVkQlFVY3NRMEZCUXl4RFFVRmlMRVZCUVdkQ08wVkJRVVZuUXl4VlFVRkJRU3hSUVVGUkxFTkJRVU4wUWl4SlFVRlVMRU5CUVdOclFpeFBRVUZQTEVkQlFVTXNRMEZCZEVJN1JVRkJNa0k3UlVGRE9VTTdPMFZCUTBRc1lVRkJUMGtzVVVGQlVEdEZRVU5FTzBWQk9VTklPMFZCUVVFN1JVRkJRU3huUTBGblJHTktMRTlCYUVSa0xFVkJaMFIxUWp0RlFVTnVRaXhoUVVGUExFdEJRVXRJTEU5QlFVd3NRMEZCWVVjc1QwRkJZaXhMUVVGNVFpeEZRVUZvUXp0RlFVTkVPMFZCYkVSSU8wVkJRVUU3UlVGQlFTd3JRa0Z2UkdGQkxFOUJjRVJpTEVWQmIwUnpRanRGUVVOc1FpeFZRVUZKTEU5QlFVOUJMRTlCUVZBc1MwRkJiVUlzVVVGQmRrSXNSVUZCYVVNN1JVRkRMMElzV1VGQlRVa3NVVUZCVVN4SFFVRkhMRXRCUVV0RExGZEJRVXdzUTBGQmFVSk1MRTlCUVdwQ0xFTkJRV3BDT3p0RlFVTkJMR0ZCUVVzc1NVRkJTWEpETEVOQlFVTXNSMEZCUnl4RFFVRmlMRVZCUVdkQ1FTeERRVUZETEVkQlFVZDVReXhSUVVGUkxFTkJRVU40UXl4TlFVRTNRaXhGUVVGeFEwUXNRMEZCUXl4SlFVRkpMRU5CUVRGRExFVkJRVFpETzBWQlF6TkRMR1ZCUVVzeVF5eFZRVUZNTEVOQlFXZENSaXhSUVVGUkxFTkJRVU42UXl4RFFVRkVMRU5CUVhoQ08wVkJRMFE3TzBWQlEwUTdSVUZEUkRzN1JVRkZSQ3hYUVVGTGJVTXNZVUZCVEN4RFFVRnRRbWhDTEVsQlFXNUNMRU5CUVhkQ2EwSXNUMEZCZUVJN1JVRkRSRHRGUVRsRVNEdEZRVUZCTzBWQlFVRXNOa0pCWjBWWFFTeFBRV2hGV0N4RlFXZEZiMEk3UlVGRGFFSXNWVUZCU1N4UFFVRlBRU3hQUVVGUUxFdEJRVzFDTEZGQlFYWkNMRVZCUVdsRE8wVkJReTlDTEZsQlFVMUpMRkZCUVZFc1IwRkJSeXhMUVVGTFF5eFhRVUZNTEVOQlFXbENUQ3hQUVVGcVFpeERRVUZxUWpzN1JVRkRRU3hoUVVGTExFbEJRVWx5UXl4RFFVRkRMRWRCUVVjc1EwRkJZaXhGUVVGblFrRXNRMEZCUXl4SFFVRkhlVU1zVVVGQlVTeERRVUZEZUVNc1RVRkJOMElzUlVGQmNVTkVMRU5CUVVNc1NVRkJTU3hEUVVFeFF5eEZRVUUyUXp0RlFVTXpReXhsUVVGTE5FTXNVVUZCVEN4RFFVRmpTQ3hSUVVGUkxFTkJRVU42UXl4RFFVRkVMRU5CUVhSQ08wVkJRMFE3TzBWQlEwUTdSVUZEUkRzN1JVRkZSQ3hYUVVGTEswSXNaMEpCUVV3c1EwRkJjMEk1UWl4TlFVRjBRaXhIUVVFclFpeERRVUV2UWp0RlFVTkJMRlZCUVUxU0xGRkJRVkVzUjBGQlJ5eExRVUZMYjBRc1YwRkJUQ3hEUVVGcFFsSXNUMEZCYWtJc1EwRkJha0k3TzBWQlEwRXNWMEZCU3l4SlFVRkpja01zUlVGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFVkJRVU1zUjBGQlIxQXNVVUZCVVN4RFFVRkRVU3hOUVVFM1FpeEZRVUZ4UTBRc1JVRkJReXhKUVVGSkxFTkJRVEZETEVWQlFUWkRPMFZCUXpORExHRkJRVXNyUWl4blFrRkJUQ3hEUVVGelFsb3NTVUZCZEVJc1EwRkJNa0l4UWl4UlFVRlJMRU5CUVVOUExFVkJRVVFzUTBGQmJrTTdPMFZCUTBFc1dVRkJTU3hMUVVGTFowTXNWMEZCVEN4RFFVRnBRblJDTEU5QlFXcENMRU5CUVhsQ2FrSXNVVUZCVVN4RFFVRkRUeXhGUVVGRUxFTkJRV3BETEUxQlFUQkRMRU5CUVVNc1EwRkJMME1zUlVGQmEwUTdSVUZEYUVRc1pVRkJTMmRETEZkQlFVd3NRMEZCYVVKaUxFbEJRV3BDTEVOQlFYTkNNVUlzVVVGQlVTeERRVUZEVHl4RlFVRkVMRU5CUVRsQ08wVkJRMFE3UlVGRFJqczdSVUZGUkN4WFFVRkxPRU1zV1VGQlREdEZRVU5FTzBWQmJrWklPMFZCUVVFN1JVRkJRU3dyUWtGeFJtRlVMRTlCY2taaUxFVkJjVVp6UWp0RlFVTnNRaXhWUVVGSkxFOUJRVTlCTEU5QlFWQXNTMEZCYlVJc1VVRkJka0lzUlVGQmFVTTdSVUZETDBJc1dVRkJUVWtzVVVGQlVTeEhRVUZITEV0QlFVdERMRmRCUVV3c1EwRkJhVUpNTEU5QlFXcENMRU5CUVdwQ096dEZRVU5CTEdGQlFVc3NTVUZCU1hKRExFTkJRVU1zUjBGQlJ5eERRVUZpTEVWQlFXZENRU3hEUVVGRExFZEJRVWQ1UXl4UlFVRlJMRU5CUVVONFF5eE5RVUUzUWl4RlFVRnhRMFFzUTBGQlF5eEpRVUZKTEVOQlFURkRMRVZCUVRaRE8wVkJRek5ETEdWQlFVc3JReXhWUVVGTUxFTkJRV2RDVGl4UlFVRlJMRU5CUVVONlF5eERRVUZFTEVOQlFYaENPMFZCUTBRN1JVRkZSaXhQUVU1RUxFMUJUVTg3UlVGRFRDeFpRVUZOVUN4UlFVRlJMRWRCUVZjc1MwRkJTMjlFTEZkQlFVd3NRMEZCYVVKU0xFOUJRV3BDTEVOQlFYcENPenRGUVVOQkxGbEJRVTFYTEdkQ1FVRm5RaXhIUVVGSExFdEJRVXRpTEdGQlFVd3NRMEZCYlVKNlFpeFBRVUZ1UWl4RFFVRXlRakpDTEU5QlFUTkNMRU5CUVhwQ096dEZRVVZCTEZsQlFVbFhMR2RDUVVGblFpeExRVUZMTEVOQlFVTXNRMEZCTVVJc1JVRkJOa0k3UlVGRE0wSXNaVUZCUzJoQ0xGZEJRVXdzUTBGQmFVSXZRaXhOUVVGcVFpeEhRVUV3UWl4RFFVRXhRanRGUVVORUxGTkJSa1FzVFVGRlR6dEZRVU5NTEdWQlFVc3NTVUZCU1VRc1IwRkJReXhIUVVGSExFTkJRV0lzUlVGQlowSkJMRWRCUVVNc1IwRkJSMUFzVVVGQlVTeERRVUZEVVN4TlFVRTNRaXhGUVVGeFEwUXNSMEZCUXl4SlFVRkpMRU5CUVRGRExFVkJRVFpETzBWQlF6TkRMR2RDUVVGTlV5eExRVUZMTEVkQlFVY3NTMEZCUzNWQ0xGZEJRVXdzUTBGQmFVSjBRaXhQUVVGcVFpeERRVUY1UW1wQ0xGRkJRVkVzUTBGQlEwOHNSMEZCUkN4RFFVRnFReXhEUVVGa096dEZRVU5CTEdkQ1FVRkpVeXhMUVVGTExFZEJRVWNzUTBGQlF5eERRVUZpTEVWQlFXZENPMFZCUTJRc2JVSkJRVXQxUWl4WFFVRk1MRU5CUVdsQ2NrSXNUVUZCYWtJc1EwRkJkMEpHTEV0QlFYaENMRVZCUVN0Q0xFTkJRUzlDTzBWQlEwUTdSVUZEUmp0RlFVTkdPenRGUVVWRUxHRkJRVXR6UWl4blFrRkJUQ3hEUVVGelFqbENMRTFCUVhSQ0xFZEJRU3RDTEVOQlFTOUNPenRGUVVOQkxHRkJRVXRuUkN4WlFVRk1PMFZCUTBRN1JVRkRSanRGUVRsSFNEdEZRVUZCTzBWQlFVRXNiVU5CWjBocFFqdEZRVU5pTEZWQlFVMURMRTFCUVUwc1IwRkJSeXhMUVVGTFpDeFBRVUZNTEVOQlFXRTVRaXhMUVVGaUxFTkJRVzFDTEVOQlFXNUNMRU5CUVdZN08wVkJRMEVzVjBGQlN5eEpRVUZKVGl4RFFVRkRMRWRCUVVjc1EwRkJZaXhGUVVGblFrRXNRMEZCUXl4SFFVRkhhMFFzVFVGQlRTeERRVUZEYWtRc1RVRkJNMElzUlVGQmJVTkVMRU5CUVVNc1NVRkJTU3hEUVVGNFF5eEZRVUV5UXp0RlFVTjZReXhaUVVGTmRVTXNTMEZCU3l4SFFVRkhWeXhOUVVGTkxFTkJRVU5zUkN4RFFVRkVMRU5CUVhCQ096dEZRVU5CTEZsQlFVbDFReXhMUVVGTExFTkJRVU5ETEZGQlFVNHNRMEZCWlZjc1MwRkJaaXhEUVVGeFFpeExRVUZMYmtJc1YwRkJNVUlzUTBGQlNpeEZRVUUwUXp0RlFVTXhReXhqUVVGSlR5eExRVUZMTEVOQlFVTkVMRTlCUVZZc1JVRkJiVUk3UlVGRGFrSkRMRmxCUVVGQkxFdEJRVXNzUTBGQlF6bERMRkZCUVU0c1IwRkJhVUk0UXl4TFFVRkxMRU5CUVVORUxFOUJRVTRzUTBGQll5eExRVUZMVGl4WFFVRnVRaXhEUVVGcVFqdEZRVU5FT3p0RlFVTkVMR1ZCUVVzc1NVRkJTWHBDTEVOQlFVTXNSMEZCUnl4RFFVRmlMRVZCUVdkQ1FTeERRVUZETEVkQlFVZG5ReXhMUVVGTExFTkJRVU01UXl4UlFVRk9MRU5CUVdWUkxFMUJRVzVETEVWQlFUSkRUU3hEUVVGRExFbEJRVWtzUTBGQmFFUXNSVUZCYlVRN1JVRkRha1FzWjBKQlFVa3NTMEZCUzNsQ0xGZEJRVXdzUTBGQmFVSjBRaXhQUVVGcVFpeERRVUY1UWpaQ0xFdEJRVXNzUTBGQlF6bERMRkZCUVU0c1EwRkJaV01zUTBGQlppeERRVUY2UWl4TlFVRm5SQ3hEUVVGRExFTkJRWEpFTEVWQlFYZEVPMFZCUTNSRUxHMUNRVUZMZVVJc1YwRkJUQ3hEUVVGcFFtSXNTVUZCYWtJc1EwRkJjMEp2UWl4TFFVRkxMRU5CUVVNNVF5eFJRVUZPTEVOQlFXVmpMRU5CUVdZc1EwRkJkRUk3UlVGRFJEdEZRVU5HT3p0RlFVTkVMR1ZCUVVzd1FpeGpRVUZNTEVOQlFXOUNaQ3hKUVVGd1FpeERRVUY1UW05Q0xFdEJRWHBDTzBWQlEwUTdSVUZEUmp0RlFVTkdPMFZCYUVsSU8wVkJRVUU3UlVGQlFTeHRRMEZyU1dsQ08wVkJRMklzVjBGQlN5eEpRVUZKZGtNc1EwRkJReXhIUVVGSExFTkJRV0lzUlVGQlowSkJMRU5CUVVNc1IwRkJSeXhMUVVGTGFVTXNZMEZCVEN4RFFVRnZRbWhETEUxQlFYaERMRVZCUVdkRVJDeERRVUZETEVsQlFVa3NRMEZCY2tRc1JVRkJkMFE3UlVGRGRFUXNXVUZCVFhWRExFdEJRVXNzUjBGQlJ5eExRVUZMVGl4alFVRk1MRU5CUVc5Q2FrTXNRMEZCY0VJc1EwRkJaRHM3UlVGRFFTeFpRVUZKTEVOQlFVTjFReXhMUVVGTExFTkJRVU5ETEZGQlFVNHNRMEZCWlZjc1MwRkJaaXhEUVVGeFFpeExRVUZMYmtJc1YwRkJNVUlzUTBGQlRDeEZRVUUyUXp0RlFVTXpReXhsUVVGTExFbEJRVWw2UWl4RFFVRkRMRWRCUVVjc1EwRkJZaXhGUVVGblFrRXNRMEZCUXl4SFFVRkhaME1zUzBGQlN5eERRVUZET1VNc1VVRkJUaXhEUVVGbFVTeE5RVUZ1UXl4RlFVRXlRMDBzUTBGQlF5eEpRVUZKTEVOQlFXaEVMRVZCUVcxRU8wVkJRMnBFTEdkQ1FVRk5SU3hMUVVGTExFZEJRVWNzUzBGQlMzVkNMRmRCUVV3c1EwRkJhVUowUWl4UFFVRnFRaXhEUVVGNVFqWkNMRXRCUVVzc1EwRkJRemxETEZGQlFVNHNRMEZCWldNc1EwRkJaaXhEUVVGNlFpeERRVUZrT3p0RlFVTkJMR2RDUVVGSlJTeExRVUZMTEVkQlFVY3NRMEZCUXl4RFFVRmlMRVZCUVdkQ08wVkJRMlFzYlVKQlFVdDFRaXhYUVVGTUxFTkJRV2xDY2tJc1RVRkJha0lzUTBGQmQwSkdMRXRCUVhoQ0xFVkJRU3RDTEVOQlFTOUNPMFZCUTBRN1JVRkRSanM3UlVGRFJDeGpRVUZKT0VJc1MwRkJTeXhEUVVGRFJDeFBRVUZXTEVWQlFXMUNPMFZCUTJwQ1F5eFpRVUZCUVN4TFFVRkxMRU5CUVVNNVF5eFJRVUZPTEVkQlFXbENMRWxCUVdwQ08wVkJRMFE3TzBWQlEwUXNaVUZCUzNkRExHTkJRVXdzUTBGQmIwSjBRaXhOUVVGd1FpeERRVUV5UWxnc1EwRkJNMElzUlVGQk9FSXNRMEZCT1VJN08wVkJRMEZCTEZWQlFVRkJMRU5CUVVNc1NVRkJTU3hEUVVGTU8wVkJRMFE3UlVGRFJqdEZRVU5HTzBWQmJrcElPenRGUVVGQk8wVkJRVUU3TzAxRFEyRnZSQ3hSUVVGaU8wVkJRMFVzYjBKQlFWbERMRmxCUVZvc1JVRkJNRUpETEdGQlFURkNMRVZCUVhsRFF5eGpRVUY2UXl4RlFVRjVSRU1zWlVGQmVrUXNSVUZCTUVVN1JVRkJRVHM3UlVGRGVFVXNVMEZCUzBNc1QwRkJUQ3hIUVVFMlFpeEpRVUUzUWp0RlFVTkJMRk5CUVV0RExHVkJRVXdzUjBGQk5rSXNSVUZCTjBJN1JVRkRRU3hUUVVGTFF5eFRRVUZNTEVkQlFUWkNMRVZCUVRkQ08wVkJRMEVzVTBGQlMwTXNWVUZCVEN4SFFVRTJRaXhGUVVFM1FqdEZRVU5CTEZOQlFVdERMR2xDUVVGTUxFZEJRVFpDTEVWQlFUZENPMFZCUTBFc1UwRkJTME1zVVVGQlRDeEhRVUUyUWl4RlFVRTNRanRGUVVOQkxGTkJRVXRETEdOQlFVd3NSMEZCTmtJc1NVRkJOMEk3UlVGRFFTeFRRVUZMUXl4aFFVRk1MRWRCUVRaQ0xFbEJRVGRDTzBWQlEwRXNVMEZCUzBNc1pVRkJUQ3hIUVVFMlFpeEZRVUUzUWp0RlFVTkJMRk5CUVV0RExHZENRVUZNTEVkQlFUWkNMRVZCUVRkQ08wVkJRMEVzVTBGQlMwTXNaMEpCUVV3c1IwRkJOa0lzUzBGQk4wSTdSVUZEUVN4VFFVRkxReXh4UWtGQlRDeEhRVUUyUWl4SlFVRTNRanRGUVVOQkxGTkJRVXRETEcxQ1FVRk1MRWRCUVRaQ0xFbEJRVGRDTzBWQlEwRXNVMEZCUzBNc2JVSkJRVXdzUjBGQk5rSXNTVUZCTjBJN1JVRkRRU3hUUVVGTFF5eFBRVUZNTEVkQlFUWkNMRXRCUVRkQ08wVkJSVUVzVTBGQlMxb3NVMEZCVEN4RFFVRmxZU3hOUVVGbUxFZEJRWGRDTzBWQlEzUkNReXhOUVVGQlFTeFRRVUZUTEVWQlFVVXNTMEZCUzJJc1ZVRkVUVHRGUVVWMFFsQXNUVUZCUVVFc1dVRkJXU3hGUVVGYVFTeFpRVVp6UWp0RlFVZDBRa01zVFVGQlFVRXNZVUZCWVN4RlFVRmlRU3hoUVVoelFqdEZRVWwwUWtNc1RVRkJRVUVzWTBGQll5eEZRVUZrUVN4alFVcHpRanRGUVV0MFFrTXNUVUZCUVVFc1pVRkJaU3hGUVVGbVFUdEZRVXh6UWl4TFFVRjRRanRGUVZGQkxGTkJRVXRyUWl4VlFVRk1MRU5CUVdkQ0xGRkJRV2hDTzBWQlEwUTdPMFZCTTBKSU8wVkJRVUU3UlVGQlFTdzRRa0UyUWxrMVF5eFZRVGRDV2l4RlFUWkNkMEkyUXl4aFFUZENlRUlzUlVFMlFuVkRPMFZCUTI1RExGVkJRVWxETEUxQlFVMHNSMEZCUnl4SlFVRmlPenRGUVVOQkxGVkJRVWtzVDBGQlR6bERMRlZCUVZBc1MwRkJjMElzVVVGQk1VSXNSVUZCYjBNN1JVRkZiRU1zV1VGQlNUWkRMR0ZCUVVvc1JVRkJiVUk3UlVGRGFrSkRMRlZCUVVGQkxFMUJRVTBzUjBGQlJ5eEpRVUZKYUVRc1RVRkJTaXhEUVVGWFJTeFZRVUZZTEVOQlFWUTdSVUZEUVRaRExGVkJRVUZCTEdGQlFXRXNRMEZCUTBNc1RVRkJSQ3hGUVVGVExFdEJRVXRZTEdWQlFXUXNSVUZCSzBJc1MwRkJTME1zWjBKQlFYQkRMRU5CUVdJN1JVRkRSQ3hUUVVoRUxFMUJSMDg3UlVGRFRGVXNWVUZCUVVFc1RVRkJUU3hIUVVGSExFdEJRVXRrTEZGQlFVd3NRMEZCWTJoRExGVkJRV1FzUzBGQk5rSXNTVUZCZEVNN1JVRkRSRHRGUVVOR0xFOUJVa1FzVFVGUlR6dEZRVU5NT0VNc1VVRkJRVUVzVFVGQlRTeEhRVUZQT1VNc1ZVRkJZanRGUVVOQlFTeFJRVUZCUVN4VlFVRlZMRWRCUVVjNFF5eE5RVUZOTEVOQlFVTkRMRmRCUVhCQ08wVkJRMFE3TzBWQlJVUXNWMEZCUzNCQ0xFOUJRVXdzUjBGQk5FSnRRaXhOUVVFMVFqdEZRVU5CTEZkQlFVdGtMRkZCUVV3c1EwRkJZMmhETEZWQlFXUXNTVUZCTkVJNFF5eE5RVUUxUWpzN1JVRkRRU3hWUVVGSlFTeE5RVUZLTEVWQlFWazdSVUZEVml4aFFVRkxia0lzVDBGQlRDeERRVUZoZWtJc1YwRkJZaXhIUVVFeVFqUkRMRTFCUVUwc1EwRkJRelZETEZkQlFXeERPMFZCUTBRN08wVkJSVVFzWVVGQlR5eEpRVUZRTzBWQlEwUTdSVUZ1UkVnN1JVRkJRVHRGUVVGQkxEaENRWEZFV1RoRExGTkJja1JhTEVWQmNVUjFRanRGUVVOdVFrRXNUVUZCUVVFc1UwRkJVeXhMUVVGTFFTeFRRVUZUTEVkQlFVY3NTMEZCUzNKQ0xFOUJRVXdzUTBGQllUTkNMRlZCUVRsQ0xFTkJRVlE3UlVGRFFTeGhRVUZQTEV0QlFVdG5ReXhSUVVGTUxFTkJRV05uUWl4VFFVRmtMRXRCUVRSQ0xFbEJRVzVETzBWQlEwUTdSVUY0UkVnN1JVRkJRVHRGUVVGQkxIbENRVEJFVDNwR0xGZEJNVVJRTEVWQk1FUnZRakJHTEZsQk1VUndRaXhGUVRCRWEwTkRMR05CTVVSc1F5eEZRVEJFYTBSRExITkNRVEZFYkVRc1JVRXdSREJGTzBWQlEzUkZMRlZCUVVrMVJpeFhRVUZYTEV0QlFVc3NTVUZCYUVJc1NVRkJkMElzVDBGQlQwRXNWMEZCVUN4TFFVRjFRaXhWUVVGdVJDeEZRVUVyUkR0RlFVTTNSRFJHTEZGQlFVRkJMSE5DUVVGelFpeEhRVUZIUkN4alFVRjZRanRGUVVOQlFTeFJRVUZCUVN4alFVRmpMRWRCUVZkRUxGbEJRWHBDTzBWQlEwRkJMRkZCUVVGQkxGbEJRVmtzUjBGQllURkdMRmRCUVhwQ08wVkJRMEZCTEZGQlFVRkJMRmRCUVZjc1IwRkJZeXhKUVVGNlFqdEZRVU5FT3p0RlFVVkVMRlZCUTBWQkxGZEJRVmNzU1VGRFdDeFJRVUZQUVN4WFFVRlFMRTFCUVhWQ0xGRkJSSFpDTEVsQlJVRXNUMEZCVDBFc1YwRkJWeXhEUVVGRFdTeE5RVUZ1UWl4TFFVRTRRaXhSUVVob1F5eEZRVWxGTzBWQlEwRXNZVUZCU3l4SlFVRkpSQ3hEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZuUWtFc1EwRkJReXhIUVVGSFdDeFhRVUZYTEVOQlFVTlpMRTFCUVdoRExFVkJRWGREUkN4RFFVRkRMRWxCUVVrc1EwRkJOME1zUlVGQlowUTdSVUZET1VNc1pVRkJTMnRHTEVsQlFVd3NRMEZCVlRkR0xGZEJRVmNzUTBGQlExY3NRMEZCUkN4RFFVRnlRaXhGUVVFd1FpdEZMRmxCUVRGQ0xFVkJRWGREUXl4alFVRjRRenRGUVVORU96dEZRVU5FTEdWQlFVOHNTVUZCVUR0RlFVTkVPenRGUVVWRUxGZEJRVXR3UWl4VlFVRk1MRU5CUVdkQ2VrTXNTVUZCYUVJc1EwRkJjVUk3UlVGRGJrSnhRaXhSUVVGQlFTeFJRVUZSTEVWQlFXZENia1FzVjBGQlZ5eEhRVUZITEVsQlFVbEVMRkZCUVVvc1EwRkJZVU1zVjBGQllpeERRVUZJTEVkQlFTdENMRWxCUkM5RE8wVkJSVzVDTUVZc1VVRkJRVUVzV1VGQldTeEZRVUZaUVN4WlFVRlpMRWxCUVdNc1NVRkdMMEk3UlVGSGJrSkRMRkZCUVVGQkxHTkJRV01zUlVGQlZVRXNZMEZCWXl4SlFVRlpMRWxCU0M5Q08wVkJTVzVDUnl4UlFVRkJRU3hoUVVGaExFVkJRVmNzUzBGS1REdEZRVXR1UWtZc1VVRkJRVUVzYzBKQlFYTkNMRVZCUVVWQkxITkNRVUZ6UWl4SlFVRkpMRXRCVEM5Q08wVkJUVzVDUnl4UlFVRkJRU3huUWtGQlowSXNSVUZCVVR0RlFVNU1MRTlCUVhKQ096dEZRVk5CTEdGQlFVOHNTVUZCVUR0RlFVTkVPMFZCZGtaSU8wVkJRVUU3UlVGQlFTeG5RMEY1Um1NdlJpeFhRWHBHWkN4RlFYbEdNa0l3Uml4WlFYcEdNMElzUlVGNVJubERReXhqUVhwR2VrTXNSVUY1Um5sRVF5eHpRa0Y2Um5wRUxFVkJlVVpwUmp0RlFVTTNSU3hoUVVGUExFdEJRVXRETEVsQlFVd3NRMEZCVlRkR0xGZEJRVllzUlVGQmRVSXdSaXhaUVVGMlFpeEZRVUZ4UTBNc1kwRkJja01zUlVGQmNVUkRMSE5DUVVGeVJDeERRVUZRTzBWQlEwUTdSVUV6UmtnN1JVRkJRVHRGUVVGQkxIVkNRVFpHU3pWR0xGZEJOMFpNTEVWQk5rWnJRakJHTEZsQk4wWnNRaXhGUVRaR1owTkRMR05CTjBab1F5eEZRVFpHWjBSRExITkNRVGRHYUVRc1JVRTJSbmRGTzBWQlEzQkZMR0ZCUVU4c1MwRkJTME1zU1VGQlRDeERRVUZWTjBZc1YwRkJWaXhGUVVGMVFqQkdMRmxCUVhaQ0xFVkJRWEZEUXl4alFVRnlReXhGUVVGeFJFTXNjMEpCUVhKRUxFTkJRVkE3UlVGRFJEdEZRUzlHU0R0RlFVRkJPMFZCUVVFc09FSkJhVWRaTlVZc1YwRnFSMW9zUlVGcFIzbENNRVlzV1VGcVIzcENMRVZCYVVkMVEwVXNjMEpCYWtkMlF5eEZRV2xISzBRN1JVRkRNMFFzWVVGQlR5eExRVUZMUXl4SlFVRk1MRU5CUVZVM1JpeFhRVUZXTEVWQlFYVkNNRVlzV1VGQmRrSXNSVUZCY1VNc1NVRkJja01zUlVGQk1rTkZMSE5DUVVFelF5eERRVUZRTzBWQlEwUTdSVUZ1UjBnN1JVRkJRVHRGUVVGQkxHZERRWEZIWXpWR0xGZEJja2RrTEVWQmNVY3lRakpHTEdOQmNrY3pRaXhGUVhGSE1rTTdSVUZEZGtNc1lVRkJUeXhMUVVGTFJTeEpRVUZNTEVOQlFWVTNSaXhYUVVGV0xFVkJRWFZDTEVsQlFYWkNMRVZCUVRaQ01rWXNZMEZCTjBJc1JVRkJOa05ETEhOQ1FVRTNReXhEUVVGUU8wVkJRMFE3UlVGMlIwZzdSVUZCUVR0RlFVRkJMREpDUVhsSFV6VkdMRmRCZWtkVUxFVkJlVWR6UWpCR0xGbEJla2QwUWl4RlFYbEhiME5ETEdOQmVrZHdReXhGUVhsSGIwUTdSVUZEYUVRc1ZVRkJTVE5HTEZkQlFWY3NTMEZCU3l4SlFVRm9RaXhKUVVGM1FpeFBRVUZQUVN4WFFVRlFMRXRCUVhWQ0xGVkJRVzVFTEVWQlFTdEVPMFZCUXpkRU1rWXNVVUZCUVVFc1kwRkJZeXhIUVVGSFJDeFpRVUZxUWp0RlFVTkJRU3hSUVVGQlFTeFpRVUZaTEVkQlFVc3hSaXhYUVVGcVFqdEZRVU5CUVN4UlFVRkJRU3hYUVVGWExFZEJRVWNzU1VGQlpEdEZRVU5FT3p0RlFVVkVMRlZCUTBWQkxGZEJRVmNzU1VGRFdDeFJRVUZQUVN4WFFVRlFMRTFCUVhWQ0xGRkJSSFpDTEVsQlJVRXNUMEZCVDBFc1YwRkJWeXhEUVVGRFdTeE5RVUZ1UWl4TFFVRTRRaXhSUVVob1F5eEZRVWxGTzBWQlEwRXNZVUZCU3l4SlFVRkpSQ3hEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZuUWtFc1EwRkJReXhIUVVGSFdDeFhRVUZYTEVOQlFVTlpMRTFCUVdoRExFVkJRWGREUkN4RFFVRkRMRWxCUVVrc1EwRkJOME1zUlVGQlowUTdSVUZET1VNc1pVRkJTM0ZHTEUxQlFVd3NRMEZCV1doSExGZEJRVmNzUTBGQlExY3NRMEZCUkN4RFFVRjJRaXhGUVVFMFFpdEZMRmxCUVRWQ0xFVkJRVEJEUXl4alFVRXhRenRGUVVORU96dEZRVU5FTEdWQlFVOHNTVUZCVUR0RlFVTkVPenRGUVVWRUxGZEJRVXNzU1VGQlNXaEdMRVZCUVVNc1IwRkJSeXhEUVVGaUxFVkJRV2RDUVN4RlFVRkRMRWRCUVVjc1MwRkJTelJFTEZWQlFVd3NRMEZCWjBJelJDeE5RVUZ3UXl4RlFVRTBRMFFzUlVGQlF5eEpRVUZKTEVOQlFXcEVMRVZCUVc5RU8wVkJRMnhFTEZsQlFVMXpSaXhSUVVGUkxFZEJRVWNzUzBGQlN6RkNMRlZCUVV3c1EwRkJaMEkxUkN4RlFVRm9RaXhEUVVGcVFqdEZRVVZCTEZsQlFVMTFSaXhaUVVGWkxFZEJRVmtzUTBGQlEyeEhMRmRCUVVRc1NVRkJaMElzUTBGQlEybEhMRkZCUVZFc1EwRkJRemxETEZGQlFURkNMRWxCUTBZNFF5eFJRVUZSTEVOQlFVTTVReXhSUVVGVUxFbEJRWEZDT0VNc1VVRkJVU3hEUVVGRE9VTXNVVUZCVkN4RFFVRnJRbWRFTEU5QlFXeENMRU5CUVRCQ2JrY3NWMEZCTVVJc1EwRkVha1E3UlVGRlFTeFpRVUZOYjBjc2JVSkJRVzFDTEVkQlFVc3NRMEZCUTFZc1dVRkJSQ3hKUVVGcFFpeERRVUZEUXl4alFVRnNRaXhKUVVOR0xFTkJRVU5FTEZsQlFVUXNTVUZCYVVJc1EwRkJRMDhzVVVGQlVTeERRVUZEVUN4WlFVUjZRaXhKUVVWR1FTeFpRVUZaTEV0QlFVdFBMRkZCUVZFc1EwRkJRMUFzV1VGR2RFUTdSVUZIUVN4WlFVRk5WeXh4UWtGQmNVSXNSMEZCUnl4RFFVRkRXQ3haUVVGRUxFbEJRV2xDTEVOQlFVTkRMR05CUVd4Q0xFbEJRMFlzUTBGQlEwRXNZMEZCUkN4SlFVRnRRaXhEUVVGRFRTeFJRVUZSTEVOQlFVTk9MR05CUkROQ0xFbEJSVVpCTEdOQlFXTXNTMEZCUzAwc1VVRkJVU3hEUVVGRFRpeGpRVVo0UkRzN1JVRkpRU3haUVVGSlR5eFpRVUZaTEVsQlFVbEZMRzFDUVVGb1FpeEpRVUYxUTBNc2NVSkJRVE5ETEVWQlFXdEZPMFZCUTJoRkxHVkJRVXM1UWl4VlFVRk1MRU5CUVdkQ2FrUXNUVUZCYUVJc1EwRkJkVUpZTEVWQlFYWkNMRVZCUVRCQ0xFTkJRVEZDT3p0RlFVTkJRU3hWUVVGQlFTeEZRVUZETEVsQlFVa3NRMEZCVER0RlFVTkVPMFZCUTBZN08wVkJSVVFzWVVGQlR5eEpRVUZRTzBWQlEwUTdSVUU1U1VnN1JVRkJRVHRGUVVGQkxHMURRV2RLYVVKWUxGZEJhRXBxUWl4RlFXZEtPRUl3Uml4WlFXaEtPVUlzUlVGblNqUkRReXhqUVdoS05VTXNSVUZuU2pSRU8wVkJRM2hFTEdGQlFVOHNTMEZCUzBzc1RVRkJUQ3hEUVVGWmFFY3NWMEZCV2l4RlFVRjVRakJHTEZsQlFYcENMRVZCUVhWRFF5eGpRVUYyUXl4RFFVRlFPMFZCUTBRN1JVRnNTa2c3UlVGQlFUdEZRVUZCTEhkQ1FXOUtUVE5HTEZkQmNFcE9MRVZCYjBwdFFqQkdMRmxCY0VwdVFpeEZRVzlLYVVORExHTkJjRXBxUXl4RlFXOUthVVE3UlVGRE4wTXNZVUZCVHl4TFFVRkxTeXhOUVVGTUxFTkJRVmxvUnl4WFFVRmFMRVZCUVhsQ01FWXNXVUZCZWtJc1JVRkJkVU5ETEdOQlFYWkRMRU5CUVZBN1JVRkRSRHRGUVhSS1NEdEZRVUZCTzBWQlFVRXNLMEpCZDBwaFZ5eFhRWGhLWWl4RlFYZEtNRUk3UlVGRGRFSXNWVUZCUnl4TFFVRkxiRU1zVDBGQlVpeEZRVUZwUWp0RlFVRkZMR0ZCUVV0dFF5eGpRVUZNTzBWQlFYZENPenRGUVVVelF5eFZRVUZKTEVOQlFVTXNTMEZCUzJwRExGTkJRVXdzUTBGQlpXZERMRmRCUVdZc1EwRkJUQ3hGUVVGclF6dEZRVU5vUXl4WlFVRk5SU3hoUVVGaExFZEJRVWNzUzBGQlMyeERMRk5CUVV3c1EwRkJaV0VzVFVGQmNrTTdSVUZEUVN4aFFVRkxZaXhUUVVGTUxFTkJRV1ZuUXl4WFFVRm1MRWxCUVRoQ08wVkJRelZDYkVJc1ZVRkJRVUVzVTBGQlV5eEZRVUZSTEVWQlJGYzdSVUZGTlVKd1FpeFZRVUZCUVN4WlFVRlpMRVZCUVV0M1F5eGhRVUZoTEVOQlFVTjRReXhaUVVaSU8wVkJSelZDUXl4VlFVRkJRU3hoUVVGaExFVkJRVWwxUXl4aFFVRmhMRU5CUVVOMlF5eGhRVWhJTzBWQlNUVkNReXhWUVVGQlFTeGpRVUZqTEVWQlFVZHpReXhoUVVGaExFTkJRVU4wUXl4alFVcElPMFZCU3pWQ1F5eFZRVUZCUVN4bFFVRmxMRVZCUVVWeFF5eGhRVUZoTEVOQlFVTnlRenRGUVV4SUxGTkJRVGxDTzBWQlQwUTdPMFZCUlVRc1ZVRkJUWE5ETEU5QlFVOHNSMEZCVlN4TFFVRkxia01zVTBGQlRDeERRVUZsWjBNc1YwRkJaaXhEUVVGMlFqdEZRVU5CTEZkQlFVdHFReXhsUVVGTUxFZEJRWFZDYVVNc1YwRkJka0k3UlVGRFFTeFhRVUZMTDBJc1ZVRkJUQ3hIUVVGMVFtdERMRTlCUVU4c1EwRkJRM0pDTEZOQlFTOUNPMFZCUlVFc1YwRkJTM05DTEVsQlFVdzdSVUZEUVN4WFFVRkxReXhMUVVGTUxFTkJRMFZHTEU5QlFVOHNRMEZCUTNwRExGbEJSRllzUlVGRlJYbERMRTlCUVU4c1EwRkJRM2hETEdGQlJsWXNSVUZIUlhkRExFOUJRVThzUTBGQlEzWkRMR05CU0ZZc1JVRkpSWFZETEU5QlFVOHNRMEZCUTNSRExHVkJTbFk3UlVGUFFTeGhRVUZQTEVsQlFWQTdSVUZEUkR0RlFXNU1TRHRGUVVGQk8wVkJRVUVzYVVOQmNVeGxPMFZCUTFnc1lVRkJUeXhMUVVGTFJTeGxRVUZhTzBWQlEwUTdSVUYyVEVnN1JVRkJRVHRGUVVGQkxHZERRWGxNWTJsRExGZEJla3hrTEVWQmVVd3lRazBzVVVGNlRETkNMRVZCZVV4eFF6dEZRVU5xUXl4VlFVRk5ReXh0UWtGQmJVSXNSMEZCUnl4TFFVRkxReXhWUVVGTUxFVkJRVFZDTzBWQlEwRXNWMEZCUzNwQ0xGVkJRVXdzUTBGQlowSnBRaXhYUVVGb1FqdEZRVVZCVFN4TlFVRkJRU3hSUVVGUk8wVkJSVklzVjBGQlMzWkNMRlZCUVV3c1EwRkJaMEozUWl4dFFrRkJhRUk3UlVGRlFTeGhRVUZQTEVsQlFWQTdSVUZEUkR0RlFXeE5TRHRGUVVGQk8wVkJRVUVzTUVKQmIwMVJOME1zV1VGd1RWSXNSVUZ2VFhOQ1F5eGhRWEJOZEVJc1JVRnZUWEZEUXl4alFYQk5ja01zUlVGdlRYRkVReXhsUVhCTmNrUXNSVUZ2VFhORk8wVkJRVUU3TzBWQlEyeEZMRmRCUVV0MVF5eEpRVUZNTzBWQlJVRXNWVUZCVFVzc1IwRkJSeXhIUVVGSExFOUJRVTlETEZWQlFWQXNTMEZCYzBJc1YwRkJkRUlzUjBGQmIwTkJMRlZCUVhCRExFZEJRMEVzVDBGQlR6ZENMRTFCUVZBc1MwRkJhMElzVjBGQmJFSXNSMEZCWjBOQkxFMUJRV2hETEVkQlEwRXNUMEZCVHpoQ0xFMUJRVkFzUzBGQmEwSXNWMEZCYkVJc1IwRkJaME5CTEUxQlFXaERMRWRCUTBFc1JVRklXanM3UlVGTFFTeFZRVUZKTEVOQlFVTnFSQ3haUVVGTUxFVkJRVzFDTzBWQlEycENMRmxCUVVrc1EwRkJReXRETEVkQlFVY3NRMEZCUTBjc1owSkJRVXdzU1VGQmVVSXNRMEZCUTBnc1IwRkJSeXhEUVVGRFNTeFhRVUZzUXl4RlFVRXJRenRGUVVNM1F6dEZRVU5CTzBWQlEwRXNZMEZCU1N4TFFVRkxPVU1zWlVGQlRDeExRVUY1UWl4UlFVRTNRaXhGUVVGMVF6dEZRVU55UXp0RlFVTkVPenRGUVVORUxHZENRVUZOTEVsQlFVa3JReXhMUVVGS0xFTkJRVlVzSzBSQlFWWXNRMEZCVGp0RlFVTkVPenRGUVVORWNFUXNVVUZCUVVFc1dVRkJXU3hIUVVGSEswTXNSMEZCWmp0RlFVTkVMRTlCYkVKcFJUczdPMFZCY1VKc1JTeFZRVUZKTEU5QlFVOHZReXhaUVVGWkxFTkJRVU54UkN4UlFVRndRaXhMUVVGcFF5eFJRVUZ5UXl4RlFVRXJRenRGUVVNM1EyeEVMRkZCUVVGQkxHVkJRV1VzUjBGQlIwUXNZMEZCYkVJN1JVRkRRVUVzVVVGQlFVRXNZMEZCWXl4SFFVRkpSQ3hoUVVGc1FqdEZRVU5CUVN4UlFVRkJRU3hoUVVGaExFZEJRVXRFTEZsQlFXeENPMFZCUTBGQkxGRkJRVUZCTEZsQlFWa3NSMEZCVFN0RExFZEJRV3hDTzBWQlEwUTdPMFZCUlVRc1ZVRkJTU3hEUVVGREwwTXNXVUZCV1N4RFFVRkRhMFFzWjBKQlFXUXNTVUZCYTBNc1EwRkJRMnhFTEZsQlFWa3NRMEZCUTIxRUxGZEJRWEJFTEVWQlFXbEZPMFZCUXk5RUxHTkJRVTBzU1VGQlNVTXNTMEZCU2l4RFFVRlZMSE5GUVVGV0xFTkJRVTQ3UlVGRFJEczdSVUZGUkN4WFFVRkxkRU1zWjBKQlFVd3NSMEZCZDBJc1EwRkJReXhEUVVGRFpDeFpRVUZaTEVOQlFVTnJSQ3huUWtGQmRrTTdSVUZGUVN4VlFVRk5TU3hUUVVGVExFZEJRVWQwUkN4WlFVRlpMRU5CUVVOMVJDeFRRVUZpTEVsQlFUQkNka1FzV1VGQldTeERRVUZEZFVRc1UwRkJZaXhEUVVGMVFrUXNVMEZCYWtRc1NVRkJPRVFzUlVGQmFFWTdSVUZEUVN4VlFVRk5SU3hSUVVGUkxFZEJRVWw0UkN4WlFVRlpMRU5CUVVOMVJDeFRRVUZpTEVsQlFUQkNka1FzV1VGQldTeERRVUZEZFVRc1UwRkJZaXhEUVVGMVFrTXNVVUZCYWtRc1NVRkJPRVFzUlVGQmFFWTdSVUZGUVhaRUxFMUJRVUZCTEdGQlFXRXNTVUZCVFVFc1lVRkJZU3hMUVVGUExFbEJRWFpETEV0QlFXZEVRU3hoUVVGaExFZEJRVXRFTEZsQlFWa3NRMEZCUTNsRUxGRkJRUzlGTzBWQlEwRjJSQ3hOUVVGQlFTeGpRVUZqTEVsQlFVdEJMR05CUVdNc1MwRkJUU3hKUVVGMlF5eExRVUZuUkVFc1kwRkJZeXhIUVVGSmMwUXNVVUZCYkVVN1JVRkRRWEpFTEUxQlFVRkJMR1ZCUVdVc1NVRkJTVUVzWlVGQlpTeExRVUZMTEVsQlFYWkRMRXRCUVdkRVFTeGxRVUZsTEVkQlFVZHRSQ3hUUVVGc1JUczdSVUZGUVN4WFFVRkxka01zY1VKQlFVd3NSMEZCTmtJc1ZVRkJRekpETEV0QlFVUXNSVUZCVnp0RlFVTjBReXhSUVVGQkxFdEJRVWtzUTBGQlEyNUZMRkZCUVV3c1EwRkJZMjFGTEV0QlFVc3NRMEZCUXpGRkxFOUJRWEJDTEVWQlFUWkNNRVVzUzBGQk4wSTdPMFZCUTBFc1VVRkJRU3hMUVVGSkxFTkJRVU5ETEdsQ1FVRk1MRU5CUVhWQ1JDeExRVUYyUWl4RlFVRTRRa1lzVVVGQk9VSTdSVUZEUkN4UFFVaEVPenRGUVVsQkxGZEJRVXQ0UXl4dFFrRkJUQ3hIUVVFeVFpeFZRVUZETUVNc1MwRkJSQ3hGUVVGWE8wVkJRM0JETEZGQlFVRXNTMEZCU1N4RFFVRkRhRVVzVlVGQlRDeERRVUZuUW1kRkxFdEJRVXNzUTBGQlF6RkZMRTlCUVhSQ0xFVkJRU3RDTUVVc1MwRkJMMEk3UlVGRFJDeFBRVVpFT3p0RlFVZEJMRmRCUVV0NlF5eHRRa0ZCVEN4SFFVRXlRaXhWUVVGRGVVTXNTMEZCUkN4RlFVRlhPMFZCUTNCRExGRkJRVUVzUzBGQlNTeERRVUZEYmtJc1kwRkJUQ3hEUVVGdlFtMUNMRXRCUVhCQ08wVkJRMFFzVDBGR1JEczdSVUZKUVN4WFFVRkxSU3hWUVVGTUxFTkJRV2RDTTBRc1lVRkJhRUlzUlVGQkswSXNVMEZCTDBJc1JVRkJNRU1zUzBGQlMyTXNjVUpCUVM5RE96dEZRVU5CTEZkQlFVczJReXhWUVVGTUxFTkJRV2RDTTBRc1lVRkJhRUlzUlVGQkswSXNUMEZCTDBJc1JVRkJNRU1zUzBGQlMyVXNiVUpCUVM5RE96dEZRVU5CTEZkQlFVczBReXhWUVVGTUxFTkJRV2RDTlVRc1dVRkJhRUlzUlVGQkswSXNUMEZCTDBJc1JVRkJNRU1zUzBGQlMybENMRzFDUVVFdlF6czdSVUZEUVN4WFFVRkxNa01zVlVGQlRDeERRVUZuUWpWRUxGbEJRV2hDTEVWQlFTdENMRTFCUVM5Q0xFVkJRVEJETEV0QlFVdHBRaXh0UWtGQkwwTTdPMFZCUlVFc1YwRkJTMUFzWTBGQlRDeEhRVUYzUWxRc1lVRkJlRUk3UlVGRFFTeFhRVUZMVlN4aFFVRk1MRWRCUVhkQ1dDeFpRVUY0UWp0RlFVTkJMRmRCUVV0WkxHVkJRVXdzUjBGQmQwSldMR05CUVhoQ08wVkJRMEVzVjBGQlMxY3NaMEpCUVV3c1IwRkJkMEpXTEdWQlFYaENPMFZCUlVFc1ZVRkJUVEJFTEdOQlFXTXNSMEZCWVN4TFFVRkxka1FzVTBGQlRDeERRVUZsTEV0QlFVdEVMR1ZCUVhCQ0xFTkJRV3BETzBWQlEwRjNSQ3hOUVVGQlFTeGpRVUZqTEVOQlFVTTNSQ3haUVVGbUxFZEJRV2xETEV0QlFVdFhMR0ZCUVhSRE8wVkJRMEZyUkN4TlFVRkJRU3hqUVVGakxFTkJRVU0xUkN4aFFVRm1MRWRCUVdsRExFdEJRVXRUTEdOQlFYUkRPMFZCUTBGdFJDeE5RVUZCUVN4alFVRmpMRU5CUVVNelJDeGpRVUZtTEVkQlFXbERMRXRCUVV0VkxHVkJRWFJETzBWQlEwRnBSQ3hOUVVGQlFTeGpRVUZqTEVOQlFVTXhSQ3hsUVVGbUxFZEJRV2xETEV0QlFVdFZMR2RDUVVGMFF6dEZRVVZCTEdGQlFVOHNTVUZCVUR0RlFVTkVPMFZCZWxGSU8wVkJRVUU3UlVGQlFTd3lRa0V5VVZNN1JVRkRUQ3hWUVVGSkxFTkJRVU1zUzBGQlMwZ3NZMEZCVGl4SlFVRjNRaXhEUVVGRExFdEJRVXRETEdGQlFXeERMRVZCUVdsRU8wVkJRVVU3UlVGQlV6czdSVUZGTlVRc1YwRkJTMjFFTEZsQlFVd3NRMEZCYTBJc1MwRkJTM0JFTEdOQlFYWkNMRVZCUVhWRExGTkJRWFpETEVWQlFXdEVMRXRCUVV0TExIRkNRVUYyUkRzN1JVRkRRU3hYUVVGTEswTXNXVUZCVEN4RFFVRnJRaXhMUVVGTGNFUXNZMEZCZGtJc1JVRkJkVU1zVDBGQmRrTXNSVUZCYTBRc1MwRkJTMDBzYlVKQlFYWkVPenRGUVVOQkxGZEJRVXM0UXl4WlFVRk1MRU5CUVd0Q0xFdEJRVXR1UkN4aFFVRjJRaXhGUVVGMVF5eFBRVUYyUXl4RlFVRnJSQ3hMUVVGTFRTeHRRa0ZCZGtRN08wVkJRMEVzVjBGQlN6WkRMRmxCUVV3c1EwRkJhMElzUzBGQlMyNUVMR0ZCUVhaQ0xFVkJRWFZETEUxQlFYWkRMRVZCUVd0RUxFdEJRVXROTEcxQ1FVRjJSRHM3UlVGRlFTeFhRVUZMVGl4aFFVRk1MRWRCUVhOQ0xFbEJRWFJDTzBWQlEwRXNWMEZCUzBRc1kwRkJUQ3hIUVVGelFpeEpRVUYwUWp0RlFVVkJMR0ZCUVU4c1NVRkJVRHRGUVVORU8wVkJkbEpJTzBWQlFVRTdSVUZCUVN3MlFrRjVVbGN4UWl4UFFYcFNXQ3hGUVhsU2IwSXdSU3hMUVhwU2NFSXNSVUY1VWpKQ08wVkJRM1pDTEZWQlFVa3NTMEZCUzNoRExFOUJRVlFzUlVGQmEwSTdSVUZCUlN4bFFVRlBMRWxCUVZBN1JVRkJZenM3UlVGRGJFTXNWVUZCU1N4RFFVRkRMRXRCUVV0a0xFOUJRVllzUlVGQmJVSTdSVUZCUlN4alFVRk5MRWxCUVVsblJDeExRVUZLTEVOQlFWVXNaMEpCUVZZc1EwRkJUanRGUVVGdlF6czdSVUZGZWtRc1YwRkJTMmhFTEU5QlFVd3NRMEZCWVdJc1VVRkJZaXhEUVVGelFsQXNUMEZCZEVJN08wVkJRMEVzVjBGQlN5dEZMR05CUVV3c1EwRkJiMEpNTEV0QlFYQkNPenRGUVVWQkxHRkJRVThzU1VGQlVEdEZRVU5FTzBWQmFsTklPMFZCUVVFN1JVRkJRU3dyUWtGdFUyRXhSU3hQUVc1VFlpeEZRVzFUYzBJd1JTeExRVzVUZEVJc1JVRnRVelpDTzBWQlEzcENMRlZCUVVrc1MwRkJTM2hETEU5QlFWUXNSVUZCYTBJN1JVRkJSU3hsUVVGUExFbEJRVkE3UlVGQll6czdSVUZEYkVNc1ZVRkJTU3hEUVVGRExFdEJRVXRrTEU5QlFWWXNSVUZCYlVJN1JVRkJSU3hqUVVGTkxFbEJRVWxuUkN4TFFVRktMRU5CUVZVc1owSkJRVllzUTBGQlRqdEZRVUZ2UXpzN1JVRkZla1FzVjBGQlMyaEVMRTlCUVV3c1EwRkJZVllzVlVGQllpeERRVUYzUWxZc1QwRkJlRUk3TzBWQlEwRXNWMEZCUzJkR0xHTkJRVXdzUTBGQmIwSk9MRXRCUVhCQ096dEZRVVZCTEdGQlFVOHNTVUZCVUR0RlFVTkVPMFZCTTFOSU8wVkJRVUU3UlVGQlFTeHRRMEUyVTJsQ1FTeExRVGRUYWtJc1JVRTJVM2RDTzBWQlEzQkNMRlZCUVVrc1MwRkJTM2hETEU5QlFWUXNSVUZCYTBJN1JVRkJSU3hsUVVGUExFbEJRVkE3UlVGQll6czdSVUZEYkVNc1ZVRkJTU3hEUVVGRExFdEJRVXRrTEU5QlFWWXNSVUZCYlVJN1JVRkJSU3hqUVVGTkxFbEJRVWxuUkN4TFFVRktMRU5CUVZVc1owSkJRVllzUTBGQlRqdEZRVUZ2UXpzN1JVRkZla1FzVjBGQlMyaEVMRTlCUVV3c1EwRkJZWHBDTEZkQlFXSXNRMEZCZVVJdlFpeE5RVUY2UWl4SFFVRnJReXhEUVVGc1F6czdSVUZEUVN4WFFVRkxiMGdzWTBGQlRDeERRVUZ2UWs0c1MwRkJjRUk3TzBWQlJVRXNZVUZCVHl4SlFVRlFPMFZCUTBRN1JVRnlWRWc3UlVGQlFUdEZRVUZCTERSQ1FYVlVWVHRGUVVOT0xGVkJRVWtzUzBGQlMzaERMRTlCUVZRc1JVRkJhMEk3UlVGQlJTeGxRVUZQTEVsQlFWQTdSVUZCWXpzN1JVRkRiRU1zVlVGQlNTeExRVUZMWkN4UFFVRlVMRVZCUVd0Q08wVkJRVVVzWVVGQlMyMURMR05CUVV3N1JVRkJkMEk3TzBWQlF6VkRMRmRCUVV0eVFpeFBRVUZNTEVkQlFXVXNTVUZCWmp0RlFVVkJMR0ZCUVU4c1NVRkJVRHRGUVVORU8wVkJOMVJJTzBWQlFVRTdSVUZCUVN3MlFrRXJWRmM3UlVGRFVDeFhRVUZMUVN4UFFVRk1MRWRCUVdVc1MwRkJaanRGUVVWQkxHRkJRVThzU1VGQlVEdEZRVU5FTzBWQmJsVklPMFZCUVVFN1JVRkJRU3cwUWtGeFZWVTdSVUZEVGl4WFFVRkxjVUlzWTBGQlREdEZRVU5CTEZkQlFVdG9ReXhWUVVGTUxFTkJRV2RDTTBRc1RVRkJhRUlzUjBGQmVVSXNRMEZCZWtJN1JVRkZRU3hoUVVGUExFbEJRVkE3UlVGRFJEdEZRVEZWU0R0RlFVRkJPMFZCUVVFc0swSkJORlZoY1VRc1lVRTFWV0lzUlVFMFZUUkNaMFVzVTBFMVZUVkNMRVZCTkZWMVEyaEdMRTlCTlZWMlF5eEZRVFJWWjBRN1JVRkROVU1zWVVGQlR5eExRVUZMTmtJc1owSkJRVXdzUjBGRFRHSXNZVUZCWVN4RFFVRkRhVVFzWjBKQlFXUXNRMEZCSzBKbExGTkJRUzlDTEVWQlFUQkRhRVlzVDBGQk1VTXNSVUZCYlVRc1MwRkJia1FzUTBGRVN5eEhRVVZNWjBJc1lVRkJZU3hEUVVGRGEwUXNWMEZCWkN4RFFVRXdRaXhQUVVGUFl5eFRRVUZxUXl4RlFVRTBRMmhHTEU5QlFUVkRMRU5CUmtZN1JVRkhSRHRGUVdoV1NEdEZRVUZCTzBWQlFVRXNhVU5CYTFabFowSXNZVUZzVm1Zc1JVRnJWamhDWjBVc1UwRnNWamxDTEVWQmExWjVRMmhHTEU5QmJGWjZReXhGUVd0V2EwUTdSVUZET1VNc1lVRkJUeXhMUVVGTE5rSXNaMEpCUVV3c1IwRkRUR0lzWVVGQllTeERRVUZEYVVVc2JVSkJRV1FzUTBGQmEwTkVMRk5CUVd4RExFVkJRVFpEYUVZc1QwRkJOME1zUlVGQmMwUXNTMEZCZEVRc1EwRkVTeXhIUVVWTVowSXNZVUZCWVN4RFFVRkRhMFVzVjBGQlpDeERRVUV3UWl4UFFVRlBSaXhUUVVGcVF5eEZRVUUwUTJoR0xFOUJRVFZETEVOQlJrWTdSVUZIUkR0RlFYUldTRHRGUVVGQk8wVkJRVUVzTWtOQmQxWjVRanRGUVVOeVFpeFZRVUZOYlVZc1kwRkJZeXhIUVVGTExFVkJRWHBDTzBWQlEwRXNWVUZCVFVNc1owSkJRV2RDTEVkQlFVY3NSVUZCZWtJN1JVRkZRU3hWUVVGSmFrUXNVMEZCVXl4SFFVRkhMRXRCUVV0aUxGVkJRWEpDT3p0RlFVTkJMRlZCUVVrc1MwRkJTMFlzWlVGQlRDeExRVUY1UWl4UlFVRTNRaXhGUVVGMVF6dEZRVU55UTJVc1VVRkJRVUVzVTBGQlV5eG5RMEZCVDBFc1UwRkJVQ3h6UWtGQmNVSXNTMEZCUzJRc1UwRkJUQ3hEUVVGbFlTeE5RVUZtTEVOQlFYTkNReXhUUVVFelF5eEZRVUZVTzBWQlEwUTdPMFZCUlVSQkxFMUJRVUZCTEZOQlFWTXNRMEZCUTJ0RUxFbEJRVllzUTBGRFJTeFZRVUZEUXl4RFFVRkVMRVZCUVVsRExFTkJRVW83UlVGQlFTeGxRVU5GTEVOQlFVTkJMRU5CUVVNc1EwRkJRM0pHTEZGQlFVWXNSMEZCWVhGR0xFTkJRVU1zUTBGQlEzSkdMRkZCUVVZc1EwRkJWeTlETEZGQlFWZ3NRMEZCYjBKUkxFMUJRV3BETEVkQlFUQkRMRU5CUVRORExFdEJRME15U0N4RFFVRkRMRU5CUVVOd1JpeFJRVUZHTEVkQlFXRnZSaXhEUVVGRExFTkJRVU53Uml4UlFVRkdMRU5CUVZjdlF5eFJRVUZZTEVOQlFXOUNVU3hOUVVGcVF5eEhRVUV3UXl4RFFVUXpReXhEUVVSR08wVkJRVUVzVDBGRVJpeEZRVWxGTmtnc1QwRktSaXhEUVVsVkxGVkJRVU5ETEVOQlFVUXNSVUZCVHp0RlFVTm1MRmxCUVVsRExGRkJRVkVzUjBGQlJ5eERRVUZETEVOQlFXaENPenRGUVVOQkxHRkJRVXNzU1VGQlNXaEpMRU5CUVVNc1IwRkJSeXhEUVVGaUxFVkJRV2RDUVN4RFFVRkRMRWRCUVVjd1NDeG5Ra0ZCWjBJc1EwRkJRM3BJTEUxQlFYSkRMRVZCUVRaRFJDeERRVUZETEVsQlFVa3NRMEZCYkVRc1JVRkJjVVE3UlVGRGJrUXNZMEZCU1RCSUxHZENRVUZuUWl4RFFVRkRNVWdzUTBGQlJDeERRVUZvUWl4TFFVRjNRaXhKUVVGNFFpeEpRVUZuUXl0SUxFTkJRVU1zUTBGQlEzWkdMRkZCUVVZc1MwRkJaU3hKUVVFdlF5eEpRVU5CYTBZc1owSkJRV2RDTEVOQlFVTXhTQ3hEUVVGRUxFTkJRV2hDTEV0QlFYZENMRWxCUVhoQ0xFbEJRV2RETUVnc1owSkJRV2RDTEVOQlFVTXhTQ3hEUVVGRUxFTkJRV2hDTEVOQlFXOUNkMFlzVDBGQmNFSXNRMEZCTkVKMVF5eERRVUZETEVOQlFVTjJSaXhSUVVFNVFpeERRVVJ3UXl4RlFVTTJSVHRGUVVNelJYZEdMRmxCUVVGQkxGRkJRVkVzUjBGQlIyaEpMRU5CUVZnN1JVRkRSRHRGUVVOR096dEZRVU5FTEZsQlFVbG5TU3hSUVVGUkxFdEJRVXNzUTBGQlF5eERRVUZzUWl4RlFVRnhRanRGUVVOdVFrRXNWVUZCUVVFc1VVRkJVU3hIUVVGSFRpeG5Ra0ZCWjBJc1EwRkJRM3BJTEUxQlFUVkNPMFZCUTBGNVNDeFZRVUZCUVN4blFrRkJaMElzUTBGQlEzWkhMRWxCUVdwQ0xFTkJRWE5DTkVjc1EwRkJReXhEUVVGRGRrWXNVVUZCZUVJN1JVRkRSRHM3UlVGRFJDeFpRVUZKTEVOQlFVTnBSaXhqUVVGakxFTkJRVU5QTEZGQlFVUXNRMEZCYmtJc1JVRkJLMEk3UlVGRE4wSlFMRlZCUVVGQkxHTkJRV01zUTBGQlEwOHNVVUZCUkN4RFFVRmtMRWRCUVRKQ0xFVkJRVE5DTzBWQlEwUTdPMFZCUTBSUUxGRkJRVUZCTEdOQlFXTXNRMEZCUTA4c1VVRkJSQ3hEUVVGa0xFTkJRWGxDTjBjc1NVRkJla0lzUTBGQk9FSTBSeXhEUVVFNVFqdEZRVU5FTEU5QmNFSkVPMFZCYzBKQkxHRkJRVTlPTEdOQlFWQTdSVUZEUkR0RlFYaFlTRHRGUVVGQk8wVkJRVUVzYlVOQk1GaHBRbFlzUzBFeFdHcENMRVZCTUZoM1FqdEZRVUZCT3p0RlFVTndRaXhWUVVGSk5VSXNZVUZCWVN4SFFVRkhMRXRCUVhCQ08wVkJSVUUwUWl4TlFVRkJRU3hMUVVGTExFdEJRVXRCTEV0QlFVc3NSMEZCUnl4RlFVRmlMRU5CUVV3N08wVkJRMEZCTEUxQlFVRkJMRXRCUVVzc1EwRkJRelZDTEdGQlFVNHNSMEZCYzBJc1dVRkJUVHRGUVVGRlFTeFJRVUZCUVN4aFFVRmhMRWRCUVVjc1NVRkJhRUk3UlVGQmRVSXNUMEZCY2tRN08wVkJRMEUwUWl4TlFVRkJRU3hMUVVGTExFTkJRVU12UlN4WFFVRk9MRWRCUVhOQ0xFdEJRVXQ1UWl4UFFVRk1MRU5CUVdGNlFpeFhRVUZpTEVOQlFYbENNVUlzUzBGQmVrSXNRMEZCSzBJc1EwRkJMMElzUTBGQmRFSTdSVUZGUVN4VlFVRk5lVUlzWjBKQlFXZENMRWRCUVVjc1MwRkJTekJDTEU5QlFVd3NRMEZCWVRGQ0xHZENRVUYwUXpzN1JVRkRRU3hWUVVGTlF5eFhRVUZYTEVkQlFWRXNTMEZCUzNsQ0xFOUJRVXdzUTBGQllYcENMRmRCUVdJc1EwRkJlVUl4UWl4TFFVRjZRaXhEUVVFclFpeERRVUV2UWl4RFFVRjZRanM3UlVGRFFTeFZRVUZOYlVnc1kwRkJZeXhIUVVGTExFdEJRVXRSTEc5Q1FVRk1MRVZCUVhwQ096dEZRVlJ2UWl4cFEwRlhXR3BKTEVOQldGYzdSVUZaYkVJc1dVRkJUWGxGTEZOQlFWTXNSMEZCUjJkRUxHTkJRV01zUTBGQlEzcElMRU5CUVVRc1EwRkJhRU03UlVGRFFTeFpRVUZOZDBNc1VVRkJVU3hIUVVGSmFVTXNVMEZCVXl4RFFVRkRMRU5CUVVRc1EwRkJWQ3hEUVVGaGFrTXNVVUZCTDBJN08wVkJSVUVzV1VGRFJVRXNVVUZCVVN4TFFVRkxMRWxCUVdJc1NVRkRRVUVzVVVGQlVTeERRVUZEVnl4TFFVRlVMRU5CUVdWdVFpeFhRVUZtTEV0QlEwRkVMR2RDUVVGblFpeERRVUZEYlVjc1NVRkJha0lzUTBGQmMwSXNWVUZCUVVNc1EwRkJRenRGUVVGQkxHbENRVUZKTTBZc1VVRkJVU3hEUVVGREwwTXNVVUZCVkN4RFFVRnJRakpKTEZGQlFXeENMRU5CUVRKQ1JDeERRVUV6UWl4RFFVRktPMFZCUVVFc1UwRkJka0lzUTBGSVJpeEZRVWxGTzBWQlEwRXNaVUZCU3l4SlFVRkpOVWdzUTBGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFTkJRVU1zUjBGQlIydEZMRk5CUVZNc1EwRkJRM2hGTEUxQlFUbENMRVZCUVhORFRTeERRVUZETEVsQlFVa3NRMEZCTTBNc1JVRkJPRU03UlVGRE5VTXNaMEpCUVVrclJTeFJRVUZSTEVkQlFVZGlMRk5CUVZNc1EwRkJRMnhGTEVOQlFVUXNRMEZCZUVJN08wVkJSVUVzWjBKQlFVa3NRMEZCUXl0RkxGRkJRVkVzUTBGQlEwWXNaMEpCUVZZc1NVRkJPRUpGTEZGQlFWRXNRMEZCUTFBc1dVRkJka01zU1VGQmRVUXNRMEZCUTA4c1VVRkJVU3hEUVVGRFNDeGhRVUZ5UlN4RlFVRnZSanRGUVVOc1JrY3NZMEZCUVVFc1VVRkJVU3hEUVVGRFJpeG5Ra0ZCVkN4SFFVRTBRaXhKUVVFMVFqdEZRVU5CUlN4alFVRkJRU3hSUVVGUkxFTkJRVU5RTEZsQlFWUXNRMEZCYzBKelJDeEpRVUYwUWl4RFFVRXlRaXhOUVVFelFpeEZRVUZwUTNSQ0xFdEJRV3BETzBWQlEwRjZRaXhqUVVGQlFTeFJRVUZSTEVOQlFVTkdMR2RDUVVGVUxFZEJRVFJDTEV0QlFUVkNPenRGUVVWQkxHdENRVUZKUkN4aFFVRmhMRWxCUVVsSExGRkJRVkVzUTBGQlEwd3NjMEpCUVRsQ0xFVkJRWE5FTzBWQlEzQkVTeXhuUWtGQlFVRXNVVUZCVVN4RFFVRkRTQ3hoUVVGVUxFZEJRWGxDTEVsQlFYcENPMFZCUTBGQkxHZENRVUZCUVN4aFFVRmhMRWRCUVZrc1MwRkJla0k3UlVGRFJEdEZRVU5HT3p0RlFVVkVMR2RDUVVGSkxFMUJRVWtzUTBGQlEzUkNMR2xDUVVGTUxFTkJRWFZDYmtRc1QwRkJka0lzUTBGQkswSTBSU3hSUVVFdlFpeE5RVUUyUXl4RFFVRkRMRU5CUVd4RUxFVkJRWEZFTzBWQlEyNUVMR05CUVVFc1RVRkJTU3hEUVVGRGVrSXNhVUpCUVV3c1EwRkJkVUl4UXl4SlFVRjJRaXhEUVVFMFFtMUZMRkZCUVRWQ08wVkJRMFE3UlVGRFJqczdSVUZGUkN4alFVRkpPVU1zVVVGQlNpeEZRVUZqTzBWQlExb3NhVUpCUVVzc1NVRkJTV3BETEVWQlFVTXNSMEZCUnl4RFFVRmlMRVZCUVdkQ1FTeEZRVUZETEVkQlFVZHBReXhSUVVGUkxFTkJRVU12UXl4UlFVRlVMRU5CUVd0Q1VTeE5RVUYwUXl4RlFVRTRRMDBzUlVGQlF5eEpRVUZKTEVOQlFXNUVMRVZCUVhORU8wVkJRM0JFTEd0Q1FVRk5SU3hMUVVGTExFZEJRVWQxUWl4WFFVRlhMRU5CUVVOMFFpeFBRVUZhTEVOQlFXOUNPRUlzVVVGQlVTeERRVUZETDBNc1VVRkJWQ3hEUVVGclFtTXNSVUZCYkVJc1EwRkJjRUlzUTBGQlpEczdSVUZEUVN4clFrRkJTVVVzUzBGQlN5eExRVUZMTEVOQlFVTXNRMEZCWml4RlFVRnJRanRGUVVOb1FuVkNMR2RDUVVGQlFTeFhRVUZYTEVOQlFVTnlRaXhOUVVGYUxFTkJRVzFDUml4TFFVRnVRaXhGUVVFd1FpeERRVUV4UWp0RlFVTkJSaXhuUWtGQlFVRXNSVUZCUXl4SlFVRkpMRU5CUVV3N1JVRkRSRHRGUVVOR08wVkJRMFk3UlVGRFJqdEZRV2hFYVVJN08wVkJWM0JDTEZkQlFVc3NTVUZCU1ZBc1EwRkJReXhIUVVGSExFTkJRV0lzUlVGQlowSkJMRU5CUVVNc1IwRkJSM2xJTEdOQlFXTXNRMEZCUTNoSUxFMUJRVzVETEVWQlFUSkRSQ3hEUVVGRExFbEJRVWtzUTBGQmFFUXNSVUZCYlVRN1JVRkJRU3hqUVVFeFEwRXNRMEZCTUVNN1JVRnpRMnhFTzBWQlEwWTdSVUUxWVVnN1JVRkJRVHRGUVVGQkxHMURRVGhoYVVJclJ5eExRVGxoYWtJc1JVRTRZWGRDTzBWQlEzQkNRU3hOUVVGQlFTeExRVUZMTEV0QlFVdEJMRXRCUVVzc1IwRkJSeXhGUVVGaUxFTkJRVXc3UlVGRFFVRXNUVUZCUVVFc1MwRkJTeXhEUVVGREwwVXNWMEZCVGl4SFFVRnZRaXhMUVVGTGVVSXNUMEZCVEN4RFFVRmhla0lzVjBGQllpeERRVUY1UWpGQ0xFdEJRWHBDTEVOQlFTdENMRU5CUVM5Q0xFTkJRWEJDT3p0RlFVVkJMRmRCUVVzc1NVRkJTVTRzUTBGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFTkJRVU1zUjBGQlJ5eExRVUZMTmtRc2FVSkJRVXdzUTBGQmRVSTFSQ3hOUVVFelF5eEZRVUZ0UkVRc1EwRkJReXhKUVVGSkxFTkJRWGhFTEVWQlFUSkVPMFZCUTNwRUxGbEJRVTF6Uml4UlFVRlJMRWRCUVVjc1MwRkJTM3BDTEdsQ1FVRk1MRU5CUVhWQ04wUXNRMEZCZGtJc1EwRkJha0k3UlVGRFFTeFpRVUZOZDBNc1VVRkJVU3hIUVVGSE9FTXNVVUZCVVN4RFFVRkRPVU1zVVVGQk1VSTdPMFZCUTBFc1dVRkJTVUVzVVVGQlVTeExRVUZMTEVsQlFXSXNTVUZCY1VJc1EwRkJRMEVzVVVGQlVTeERRVUZEVnl4TFFVRlVMRU5CUVdVc1MwRkJTMDBzVDBGQlRDeERRVUZoZWtJc1YwRkJOVUlzUTBGQk1VSXNSVUZCYjBVN1JVRkRiRVZ6UkN4VlFVRkJRU3hSUVVGUkxFTkJRVU5JTEdGQlFWUXNSMEZCZVVJc1MwRkJla0k3TzBWQlEwRXNZMEZCU1RORExGRkJRVkVzUzBGQlN5eEpRVUZpTEVsQlFYRkNkVVVzUzBGQlN5eERRVUZETDBVc1YwRkJUaXhEUVVGclFpOUNMRTFCUVd4Q0xFdEJRVFpDTEVOQlFYUkVMRVZCUVhsRU8wVkJRM1pFTEdsQ1FVRkxORVFzYVVKQlFVd3NRMEZCZFVKc1JDeE5RVUYyUWl4RFFVRTRRbGdzUTBGQk9VSXNSVUZCYVVNc1EwRkJha003TzBWQlEwRkJMRmxCUVVGQkxFTkJRVU1zU1VGQlNTeERRVUZNTzBWQlEwUTdPMFZCUTBRc1kwRkJTU3hEUVVGRGMwWXNVVUZCVVN4RFFVRkRSaXhuUWtGQlZpeEpRVUU0UWtVc1VVRkJVU3hEUVVGRFRpeGpRVUV6UXl4RlFVRXlSRHRGUVVONlJFMHNXVUZCUVVFc1VVRkJVU3hEUVVGRFJpeG5Ra0ZCVkN4SFFVRTBRaXhKUVVFMVFqdEZRVU5CUlN4WlFVRkJRU3hSUVVGUkxFTkJRVU5PTEdOQlFWUXNRMEZCZDBKeFJDeEpRVUY0UWl4RFFVRTJRaXhKUVVFM1FpeEZRVUZ0UTNSQ0xFdEJRVzVETzBWQlEwRjZRaXhaUVVGQlFTeFJRVUZSTEVOQlFVTkdMR2RDUVVGVUxFZEJRVFJDTEV0QlFUVkNPMFZCUTBRN1JVRkRSanRGUVVOR08wVkJRMFk3UlVGc1kwZzdSVUZCUVR0RlFVRkJMSE5EUVc5amIwSXlRaXhMUVhCamNFSXNSVUZ2WXpKQ1JpeFJRWEJqTTBJc1JVRnZZM0ZETzBWQlEycERPMFZCUTBFN1JVRkRRU3hWUVVGTmVVSXNXVUZCV1N4SFFVRkhMRU5CUVVNc1QwRkJSQ3hGUVVGVkxFMUJRVllzUlVGQmEwSXNTMEZCYkVJc1JVRkJlVUlzVlVGQmVrSXNSVUZCY1VNc1MwRkJja01zUlVGQk5FTXNVMEZCTlVNc1EwRkJja0k3TzBWQlEwRXNWVUZCU1hwQ0xGRkJRVkVzUTBGQlF6QkNMRXRCUVZRc1EwRkJaU3hMUVVGbUxFdEJRWGxDTEV0QlFVczVSU3hQUVVGTUxFTkJRV0Y2UWl4WFFVRmlMRU5CUVhsQ2IwY3NVVUZCZWtJc1EwRkJhME1zVTBGQmJFTXNRMEZCZWtJc1NVRkRRU3hEUVVGRFJTeFpRVUZaTEVOQlFVTkdMRkZCUVdJc1EwRkJjMElzUzBGQlN6TkZMRTlCUVV3c1EwRkJZVm9zVjBGQllpeERRVUY1UW10RkxFdEJRVXNzUTBGQlF6RkZMRTlCUVM5Q0xFVkJRWGRETEVOQlFYaERMRU5CUVhSQ0xFTkJSRXdzUlVGRGQwVTdSVUZEZEVVc1lVRkJTMmRETEcxQ1FVRk1MRU5CUVhsQ01FTXNTMEZCZWtJN1JVRkRSRHRGUVVOR08wVkJOV05JT3p0RlFVRkJPMFZCUVVFN08wVkRTRThzVTBGQlUzbENMRVZCUVZRc1EwRkJXVFZFTEUxQlFWb3NSVUZCYjBKcFF5eFJRVUZ3UWl4RlFVRTRRa1lzVTBGQk9VSXNSVUZCZVVNN1JVRkZPVU03UlVGRFFTOUNMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUTBGQmJrSXNSVUZCZDBJc1EwRkJReXhSUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVOQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVjBGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RFFVRnVRaXhGUVVGM1FpeERRVUZETEV0QlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4UFFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYZENMRU5CUVVNc1QwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExFOUJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkMElzUTBGQlF5eE5RVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTMEZCUkN4RlFVRlJMRTFCUVZJc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhQUVVGRUxFVkJRVlVzVDBGQlZpeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGM1FpeERRVUZETEZWQlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4UlFVRkVMRVZCUVZjc1MwRkJXQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExFOUJRVVFzUlVGQlZTeFZRVUZXTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWGRDTEVOQlFVTXNVVUZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhGUVVGdVFpeEZRVUYzUWl4RFFVRkRMRlZCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhMUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVFVGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGM1FpeERRVUZETEUxQlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4SlFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYZENMRU5CUVVNc1QwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExFMUJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkMElzUTBGQlF5eFJRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWGRDTEVOQlFVTXNZVUZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhGUVVGdVFpeEZRVUYzUWl4RFFVRkRMRk5CUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhWUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVVVGQlJDeEZRVUZYTEV0QlFWZ3NRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4UlFVRkVMRVZCUVZjc1MwRkJXQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExFMUJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eFpRVUZFTEVWQlFXVXNVVUZCWml4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRTlCUVVRc1JVRkJWU3hIUVVGV0xFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVVVGQlJDeEZRVUZYTEVkQlFWZ3NRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4UFFVRkVMRVZCUVZVc1kwRkJWaXhGUVVFd1FpeEhRVUV4UWl4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMR0ZCUVVRc1JVRkJaMElzUjBGQmFFSXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4aFFVRkVMRVZCUVdkQ0xFZEJRV2hDTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNWMEZCUkN4RlFVRmpMRWxCUVdRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhqUVVGRUxFVkJRV2xDTEVkQlFXcENMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1dVRkJSQ3hGUVVGbExFbEJRV1lzUTBGQmVFSXNSVUYwUXpoRE96dEZRWGxET1VNM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWFZDTEVOQlFVTXNUVUZCUkN4RlFVRlRMRWRCUVZRc1EwRkJka0k3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZFVJc1EwRkJReXhMUVVGRUxFVkJRVkVzUjBGQlVpeERRVUYyUWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGMVFpeERRVUZETEV0QlFVUXNSVUZCVVN4SFFVRlNMRU5CUVhaQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYVkNMRU5CUVVNc1QwRkJSQ3hGUVVGVkxFZEJRVllzUTBGQmRrSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkVUlzUTBGQlF5eE5RVUZFTEVWQlFWTXNSMEZCVkN4RFFVRjJRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhGUVVGdVFpeEZRVUYxUWl4RFFVRkRMRTFCUVVRc1JVRkJVeXhIUVVGVUxFTkJRWFpDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhWQ0xFTkJRVU1zUzBGQlJDeEZRVUZSTEVkQlFWSXNRMEZCZGtJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmRVSXNRMEZCUXl4UFFVRkVMRVZCUVZVc1IwRkJWaXhEUVVGMlFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjFRaXhEUVVGRExFOUJRVVFzUlVGQlZTeEhRVUZXTEVOQlFYWkNPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWFZDTEVOQlFVTXNUVUZCUkN4RlFVRlRMRWRCUVZRc1EwRkJka0lzUlVGc1JEaERPenRGUVhGRU9VTTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhWQ0xFTkJRVU1zVTBGQlJDeEZRVUZaTEUxQlFWb3NRMEZCZGtJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmRVSXNRMEZCUXl4UlFVRkVMRVZCUVZjc1RVRkJXQ3hEUVVGMlFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjFRaXhEUVVGRExGRkJRVVFzUlVGQlZ5eE5RVUZZTEVOQlFYWkNPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWFZDTEVOQlFVTXNWVUZCUkN4RlFVRmhMRTFCUVdJc1EwRkJka0k3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhUUVVGRUxFVkJRVmtzVFVGQldpeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEZOQlFVUXNSVUZCV1N4TlFVRmFMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1VVRkJSQ3hGUVVGWExFMUJRVmdzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eFZRVUZFTEVWQlFXRXNUVUZCWWl4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRlZCUVVRc1JVRkJZU3hOUVVGaUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVTBGQlJDeEZRVUZaTEUxQlFWb3NRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4aFFVRkVMRVZCUVdkQ0xFMUJRV2hDTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNVVUZCUkN4RlFVRlhMRTFCUVZnc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhWUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zWVVGQlJDeEZRVUZuUWl4TlFVRm9RaXhEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExGbEJRVVFzUlVGQlpTeE5RVUZtTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNWMEZCUkN4RlFVRmpMRTFCUVdRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhUUVVGRUxFVkJRVmtzUzBGQldpeERRVUY0UWl4RlFYSkZPRU03TzBWQmQwVTVRemRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4SlFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1NVRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFbEJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eEpRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTVUZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRWxCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhKUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zU1VGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEVsQlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4TFFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1MwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFdEJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eExRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTMEZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRXRCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhMUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zUzBGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEV0QlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4TFFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1MwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFdEJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eExRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTMEZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRXRCUVVRc1EwRkJlRUlzUlVFdlJqaERPenRGUVd0SE9VTTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTRSQ3hUUVVGUUxFTkJRV2xDTEZkQlFXcENMRVZCUVRoQ0xFTkJRVU1zVDBGQlJDeEZRVUZWTEVkQlFWWXNRMEZCT1VJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1YwRkJha0lzUlVGQk9FSXNRMEZCUXl4aFFVRkVMRVZCUVdkQ0xHdENRVUZvUWl4RlFVRnZReXhIUVVGd1F5eERRVUU1UWp0RlFVTkJPVVFzUlVGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4WFFVRnFRaXhGUVVFNFFpeERRVUZETEVsQlFVUXNSVUZCVHl4SFFVRlFMRU5CUVRsQ08wVkJRMEU1UkN4RlFVRkJRU3hOUVVGTkxFTkJRVU00UkN4VFFVRlFMRU5CUVdsQ0xGZEJRV3BDTEVWQlFUaENMRU5CUVVNc1VVRkJSQ3hGUVVGWExFZEJRVmdzUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNWMEZCYWtJc1JVRkJPRUlzUTBGQlF5eFJRVUZFTEVWQlFWY3NVMEZCV0N4RlFVRnpRaXhaUVVGMFFpeEZRVUZ2UXl4SFFVRndReXhEUVVFNVFqdEZRVU5CT1VRc1JVRkJRVUVzVFVGQlRTeERRVUZET0VRc1UwRkJVQ3hEUVVGcFFpeFhRVUZxUWl4RlFVRTRRaXhEUVVGRExGTkJRVVFzUlVGQldTeEhRVUZhTEVOQlFUbENPMFZCUTBFNVJDeEZRVUZCUVN4TlFVRk5MRU5CUVVNNFJDeFRRVUZRTEVOQlFXbENMRmRCUVdwQ0xFVkJRVGhDTEVOQlFVTXNUMEZCUkN4RlFVRlZMRWRCUVZZc1EwRkJPVUk3UlVGRFFUbEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6aEVMRk5CUVZBc1EwRkJhVUlzVjBGQmFrSXNSVUZCT0VJc1EwRkJReXhYUVVGRUxFVkJRV01zUzBGQlpDeEZRVUZ4UWl4SFFVRnlRaXhEUVVFNVFqdEZRVU5CT1VRc1JVRkJRVUVzVFVGQlRTeERRVUZET0VRc1UwRkJVQ3hEUVVGcFFpeFhRVUZxUWl4RlFVRTRRaXhEUVVGRExGVkJRVVFzUlVGQllTeEhRVUZpTEVOQlFUbENPMFZCUTBFNVJDeEZRVUZCUVN4TlFVRk5MRU5CUVVNNFJDeFRRVUZRTEVOQlFXbENMRmRCUVdwQ0xFVkJRVGhDTEVOQlFVTXNWMEZCUkN4RlFVRmpMRWRCUVdRc1EwRkJPVUk3UlVGRFFUbEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6aEVMRk5CUVZBc1EwRkJhVUlzVjBGQmFrSXNSVUZCT0VJc1EwRkJReXhaUVVGRUxFVkJRV1VzUjBGQlppeERRVUU1UWp0RlFVTkJPVVFzUlVGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4WFFVRnFRaXhGUVVFNFFpeERRVUZETEZsQlFVUXNSVUZCWlN4SFFVRm1MRU5CUVRsQ08wVkJRMEU1UkN4RlFVRkJRU3hOUVVGTkxFTkJRVU00UkN4VFFVRlFMRU5CUVdsQ0xGZEJRV3BDTEVWQlFUaENMRU5CUVVNc1RVRkJSQ3hGUVVGVExFZEJRVlFzUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNWMEZCYWtJc1JVRkJPRUlzUTBGQlF5eG5Ra0ZCUkN4RlFVRnRRaXhyUWtGQmJrSXNSVUZCZFVNc1IwRkJka01zUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNWMEZCYWtJc1JVRkJPRUlzUTBGQlF5eHBRa0ZCUkN4RlFVRnZRaXh0UWtGQmNFSXNSVUZCZVVNc1IwRkJla01zUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNXVUZCYWtJc1JVRkJLMElzUTBGQlF5eGhRVUZFTEVWQlFXZENMRWRCUVdoQ0xFTkJRUzlDTzBWQlEwRTVSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTRSQ3hUUVVGUUxFTkJRV2xDTEZkQlFXcENMRVZCUVRoQ0xFTkJRVU1zVDBGQlJDeEZRVUZWTEVkQlFWWXNRMEZCT1VJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1dVRkJha0lzUlVGQkswSXNRMEZCUXl4bFFVRkVMRVZCUVd0Q0xFbEJRV3hDTEVOQlFTOUNPMFZCUTBFNVJDeEZRVUZCUVN4TlFVRk5MRU5CUVVNNFJDeFRRVUZRTEVOQlFXbENMRmxCUVdwQ0xFVkJRU3RDTEVOQlFVTXNhMEpCUVVRc1JVRkJjVUlzUjBGQmNrSXNRMEZCTDBJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1YwRkJha0lzUlVGQk9FSXNRMEZCUXl4dFFrRkJSQ3hGUVVGelFpeEhRVUYwUWl4RFFVRTVRanRGUVVOQk9VUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE9FUXNVMEZCVUN4RFFVRnBRaXhYUVVGcVFpeEZRVUU0UWl4RFFVRkRMR05CUVVRc1JVRkJhVUlzUjBGQmFrSXNRMEZCT1VJN08wVkJSVUVzVFVGQlNUZENMRkZCUVZFc1EwRkJRekJDTEV0QlFWUXNRMEZCWlN4TFFVRm1MRU5CUVVvc1JVRkJNa0k3UlVGRGVrSXpSQ3hKUVVGQlFTeE5RVUZOTEVOQlFVTTRSQ3hUUVVGUUxFTkJRV2xDTEZOQlFXcENMRVZCUVRSQ0xFTkJRVU1zUzBGQlJDeEZRVUZSTEZWQlFWSXNRMEZCTlVJN1JVRkRSQ3hIUVVaRUxFMUJSVTg3UlVGRFREbEVMRWxCUVVGQkxFMUJRVTBzUTBGQlF6aEVMRk5CUVZBc1EwRkJhVUlzVFVGQmFrSXNSVUZCZVVJc1EwRkJReXhMUVVGRUxFVkJRVkVzVlVGQlVpeERRVUY2UWp0RlFVTkVMRWRCTlVnMlF6czdPMFZCSzBnNVF5eFBRVUZMTEVsQlFVbHlSeXhQUVVGUExFZEJRVWNzUlVGQmJrSXNSVUZCZFVKQkxFOUJRVThzU1VGQlNTeEZRVUZzUXl4RlFVRnpRMEVzVDBGQlR5eEpRVUZKTEVOQlFXcEVMRVZCUVc5RU8wVkJRMnhFTEZGQlFVazNRaXhQUVVGUExFZEJRVWR0U1N4TlFVRk5MRU5CUVVORExGbEJRVkFzUTBGQmIwSjJSeXhQUVVGUExFZEJRVWNzUlVGQk9VSXNRMEZCWkR0RlFVTkJMRkZCUVVsM1J5eGpRVUZqTEVkQlFVZEdMRTFCUVUwc1EwRkJRME1zV1VGQlVDeERRVUZ2UW5aSExFOUJRWEJDTEVOQlFYSkNPMFZCUTBSMVF5eEpRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNjRWNzVDBGQmJrSXNSVUZCTkVJM1FpeFBRVUUxUWp0RlFVTkJiMFVzU1VGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4aFFVRmhiRWtzVDBGQk9VSXNSVUZCZFVOeFNTeGpRVUYyUXp0RlFVTkJha1VzU1VGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4blFrRkJaMEpzU1N4UFFVRnFReXhGUVVFd1EzRkpMR05CUVRGRE8wVkJRMEVzUjBGeVNUWkRPenM3UlVGM1NUbERMRTFCUVUxRExHZENRVUZuUWl4SFFVRkhia01zVTBGQlV5eERRVUZETkVJc1MwRkJWaXhEUVVGblFpeFRRVUZvUWl4SlFVRTJRaXhGUVVFM1FpeEhRVUZ0UXl4SFFVRTFSRHRGUVVOQkxFMUJRVTFSTEZkQlFWY3NSMEZCVVhCRExGTkJRVk1zUTBGQlF6UkNMRXRCUVZZc1EwRkJaMElzVTBGQmFFSXNTVUZCTmtJc1IwRkJOMElzUjBGQmJVTXNSMEZCTlVRN1JVRkRRU3hOUVVGTlV5eFpRVUZaTEVkQlFVOXlReXhUUVVGVExFTkJRVU0wUWl4TFFVRldMRU5CUVdkQ0xGTkJRV2hDTEVsQlFUWkNMRVZCUVRkQ0xFZEJRVzFETEVkQlFUVkVPMFZCUTBFc1RVRkJTVlVzYTBKQlFVbzdSVUZEUVN4TlFVRkpReXh0UWtGQlNqczdSVUZEUVN4TlFVRkpja01zVVVGQlVTeERRVUZETUVJc1MwRkJWQ3hEUVVGbExFdEJRV1lzVFVGQk1FSTFRaXhUUVVGVExFTkJRVU0wUWl4TFFVRldMRU5CUVdkQ0xGRkJRV2hDTEV0QlFUWkNOVUlzVTBGQlV5eERRVUZETkVJc1MwRkJWaXhEUVVGblFpeFJRVUZvUWl4RFFVRjJSQ3hEUVVGS0xFVkJRWFZHTzBWQlEzSkdWU3hKUVVGQlFTeHJRa0ZCYTBJc1IwRkJTU3hGUVVGMFFqdEZRVU5CUXl4SlFVRkJRU3h0UWtGQmJVSXNSMEZCUnl4RlFVRjBRanRGUVVORUxFZEJTRVFzVFVGSFR5eEpRVUZIY2tNc1VVRkJVU3hEUVVGRE1FSXNTMEZCVkN4RFFVRmxMRXRCUVdZc1MwRkJlVUkxUWl4VFFVRlRMRU5CUVVNMFFpeExRVUZXTEVOQlFXZENMRTlCUVdoQ0xFTkJRVFZDTEVWQlFYTkVPMFZCUXpORVZTeEpRVUZCUVN4clFrRkJhMElzUjBGQlNTeEZRVUYwUWp0RlFVTkJReXhKUVVGQlFTeHRRa0ZCYlVJc1IwRkJSeXhGUVVGMFFqdEZRVU5FTEVkQlNFMHNUVUZIUVN4SlFVRkhja01zVVVGQlVTeERRVUZETUVJc1MwRkJWQ3hEUVVGbExFdEJRV1lzUzBGQmVVSTFRaXhUUVVGVExFTkJRVU0wUWl4TFFVRldMRU5CUVdkQ0xGTkJRV2hDTEVOQlFUVkNMRVZCUVhkRU8wVkJRemRFVlN4SlFVRkJRU3hyUWtGQmEwSXNSMEZCU1N4SFFVRjBRanRGUVVOQlF5eEpRVUZCUVN4dFFrRkJiVUlzUjBGQlJ5eEhRVUYwUWp0RlFVTkVPenRGUVVORWRFVXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRa3NzWjBKQlFXNUNMRVZCUVhkRExFTkJRVU1zVjBGQlJDeEZRVUZqTEVkQlFXUXNRMEZCZUVNN1JVRkRRV3hGTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVKTkxGZEJRVzVDTEVWQlFYZERMRU5CUVVNc1RVRkJSQ3hGUVVGVExFZEJRVlFzUTBGQmVFTTdSVUZEUVc1RkxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSlBMRmxCUVc1Q0xFVkJRWGRETEVOQlFVTXNUMEZCUkN4RlFVRlZMRmRCUVZZc1JVRkJkVUlzUjBGQmRrSXNRMEZCZUVNN1JVRkRRWEJGTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVKUkxHdENRVUZ1UWl4RlFVRjNReXhEUVVGRExGTkJRVVFzUlVGQldTeFRRVUZhTEVWQlFYVkNMRXRCUVhaQ0xFVkJRVGhDTEU5QlFUbENMRVZCUVhWRExHRkJRWFpETEVWQlFYTkVMR0ZCUVhSRUxFVkJRWEZGTEZOQlFYSkZMRVZCUVdkR0xGZEJRV2hHTEVOQlFYaERPMFZCUTBGeVJTeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNVeXh0UWtGQmJrSXNSVUZCZDBNc1EwRkJReXhUUVVGRUxFVkJRVmtzVTBGQldpeEZRVUYxUWl4TFFVRjJRaXhGUVVFNFFpeFBRVUU1UWl4RlFVRjFReXhqUVVGMlF5eEZRVUYxUkN4alFVRjJSQ3hGUVVGMVJTeFZRVUYyUlN4RlFVRnRSaXhaUVVGdVJpeERRVUY0UXl4RlFUTktPRU03TzBWQk9FbzVRM1JGTEVWQlFVRkJMRTFCUVUwc1EwRkJRMnBETEZWQlFWQXNRMEZCYTBJc1UwRkJiRUk3UlVGRFJEczdUVU16U2t0M1J5eFJRVUZSTEVkQlFVY3NTVUZCU1M5R0xGRkJRVW83UlVGRmFrSXJSaXhSUVVGUkxFTkJRVU5ETEZOQlFWUXNRMEZCYlVJc1NVRkJia0lzUlVGQmVVSmFMRVZCUVhwQ08wVkJSVUZYTEZGQlFWRXNRMEZCUXk5R0xGRkJRVlFzUjBGQmIwSkJMRkZCUVhCQ08wVkJRMEVyUml4UlFVRlJMRU5CUVVOMlNDeE5RVUZVTEVkQlFXdENRU3hOUVVGc1FqdEZRVU5CZFVnc1VVRkJVU3hEUVVGREwwb3NVVUZCVkN4SFFVRnZRa0VzVVVGQmNFSTdPenM3T3pzN095SjlcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIExvZGFzaCA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIENvcHlyaWdodCBPcGVuSlMgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzIDxodHRwczovL29wZW5qc2Yub3JnLz5cbiAqIFJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlIDxodHRwczovL2xvZGFzaC5jb20vbGljZW5zZT5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqL1xuOyhmdW5jdGlvbigpIHtcblxuICAvKiogVXNlZCBhcyBhIHNhZmUgcmVmZXJlbmNlIGZvciBgdW5kZWZpbmVkYCBpbiBwcmUtRVM1IGVudmlyb25tZW50cy4gKi9cbiAgdmFyIHVuZGVmaW5lZDtcblxuICAvKiogVXNlZCBhcyB0aGUgc2VtYW50aWMgdmVyc2lvbiBudW1iZXIuICovXG4gIHZhciBWRVJTSU9OID0gJzQuMTcuMjEnO1xuXG4gIC8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqL1xuICB2YXIgTEFSR0VfQVJSQVlfU0laRSA9IDIwMDtcblxuICAvKiogRXJyb3IgbWVzc2FnZSBjb25zdGFudHMuICovXG4gIHZhciBDT1JFX0VSUk9SX1RFWFQgPSAnVW5zdXBwb3J0ZWQgY29yZS1qcyB1c2UuIFRyeSBodHRwczovL25wbXMuaW8vc2VhcmNoP3E9cG9ueWZpbGwuJyxcbiAgICAgIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJyxcbiAgICAgIElOVkFMSURfVEVNUExfVkFSX0VSUk9SX1RFWFQgPSAnSW52YWxpZCBgdmFyaWFibGVgIG9wdGlvbiBwYXNzZWQgaW50byBgXy50ZW1wbGF0ZWAnO1xuXG4gIC8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi9cbiAgdmFyIEhBU0hfVU5ERUZJTkVEID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nO1xuXG4gIC8qKiBVc2VkIGFzIHRoZSBtYXhpbXVtIG1lbW9pemUgY2FjaGUgc2l6ZS4gKi9cbiAgdmFyIE1BWF9NRU1PSVpFX1NJWkUgPSA1MDA7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xuICB2YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgY2xvbmluZy4gKi9cbiAgdmFyIENMT05FX0RFRVBfRkxBRyA9IDEsXG4gICAgICBDTE9ORV9GTEFUX0ZMQUcgPSAyLFxuICAgICAgQ0xPTkVfU1lNQk9MU19GTEFHID0gNDtcblxuICAvKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi9cbiAgdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMSxcbiAgICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xuICB2YXIgV1JBUF9CSU5EX0ZMQUcgPSAxLFxuICAgICAgV1JBUF9CSU5EX0tFWV9GTEFHID0gMixcbiAgICAgIFdSQVBfQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgICBXUkFQX0NVUlJZX0ZMQUcgPSA4LFxuICAgICAgV1JBUF9DVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgICBXUkFQX1BBUlRJQUxfRkxBRyA9IDMyLFxuICAgICAgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcgPSA2NCxcbiAgICAgIFdSQVBfQVJZX0ZMQUcgPSAxMjgsXG4gICAgICBXUkFQX1JFQVJHX0ZMQUcgPSAyNTYsXG4gICAgICBXUkFQX0ZMSVBfRkxBRyA9IDUxMjtcblxuICAvKiogVXNlZCBhcyBkZWZhdWx0IG9wdGlvbnMgZm9yIGBfLnRydW5jYXRlYC4gKi9cbiAgdmFyIERFRkFVTFRfVFJVTkNfTEVOR1RIID0gMzAsXG4gICAgICBERUZBVUxUX1RSVU5DX09NSVNTSU9OID0gJy4uLic7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGhvdCBmdW5jdGlvbnMgYnkgbnVtYmVyIG9mIGNhbGxzIHdpdGhpbiBhIHNwYW4gb2YgbWlsbGlzZWNvbmRzLiAqL1xuICB2YXIgSE9UX0NPVU5UID0gODAwLFxuICAgICAgSE9UX1NQQU4gPSAxNjtcblxuICAvKiogVXNlZCB0byBpbmRpY2F0ZSB0aGUgdHlwZSBvZiBsYXp5IGl0ZXJhdGVlcy4gKi9cbiAgdmFyIExBWllfRklMVEVSX0ZMQUcgPSAxLFxuICAgICAgTEFaWV9NQVBfRkxBRyA9IDIsXG4gICAgICBMQVpZX1dISUxFX0ZMQUcgPSAzO1xuXG4gIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xuICB2YXIgSU5GSU5JVFkgPSAxIC8gMCxcbiAgICAgIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxLFxuICAgICAgTUFYX0lOVEVHRVIgPSAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOCxcbiAgICAgIE5BTiA9IDAgLyAwO1xuXG4gIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG4gIHZhciBNQVhfQVJSQVlfTEVOR1RIID0gNDI5NDk2NzI5NSxcbiAgICAgIE1BWF9BUlJBWV9JTkRFWCA9IE1BWF9BUlJBWV9MRU5HVEggLSAxLFxuICAgICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuICAvKiogVXNlZCB0byBhc3NvY2lhdGUgd3JhcCBtZXRob2RzIHdpdGggdGhlaXIgYml0IGZsYWdzLiAqL1xuICB2YXIgd3JhcEZsYWdzID0gW1xuICAgIFsnYXJ5JywgV1JBUF9BUllfRkxBR10sXG4gICAgWydiaW5kJywgV1JBUF9CSU5EX0ZMQUddLFxuICAgIFsnYmluZEtleScsIFdSQVBfQklORF9LRVlfRkxBR10sXG4gICAgWydjdXJyeScsIFdSQVBfQ1VSUllfRkxBR10sXG4gICAgWydjdXJyeVJpZ2h0JywgV1JBUF9DVVJSWV9SSUdIVF9GTEFHXSxcbiAgICBbJ2ZsaXAnLCBXUkFQX0ZMSVBfRkxBR10sXG4gICAgWydwYXJ0aWFsJywgV1JBUF9QQVJUSUFMX0ZMQUddLFxuICAgIFsncGFydGlhbFJpZ2h0JywgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUddLFxuICAgIFsncmVhcmcnLCBXUkFQX1JFQVJHX0ZMQUddXG4gIF07XG5cbiAgLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xuICB2YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgICAgYXN5bmNUYWcgPSAnW29iamVjdCBBc3luY0Z1bmN0aW9uXScsXG4gICAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICAgIGRvbUV4Y1RhZyA9ICdbb2JqZWN0IERPTUV4Y2VwdGlvbl0nLFxuICAgICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICAgIG51bGxUYWcgPSAnW29iamVjdCBOdWxsXScsXG4gICAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICAgIHByb21pc2VUYWcgPSAnW29iamVjdCBQcm9taXNlXScsXG4gICAgICBwcm94eVRhZyA9ICdbb2JqZWN0IFByb3h5XScsXG4gICAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJyxcbiAgICAgIHVuZGVmaW5lZFRhZyA9ICdbb2JqZWN0IFVuZGVmaW5lZF0nLFxuICAgICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJyxcbiAgICAgIHdlYWtTZXRUYWcgPSAnW29iamVjdCBXZWFrU2V0XSc7XG5cbiAgdmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICAgIGRhdGFWaWV3VGFnID0gJ1tvYmplY3QgRGF0YVZpZXddJyxcbiAgICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuICAvKiogVXNlZCB0byBtYXRjaCBlbXB0eSBzdHJpbmcgbGl0ZXJhbHMgaW4gY29tcGlsZWQgdGVtcGxhdGUgc291cmNlLiAqL1xuICB2YXIgcmVFbXB0eVN0cmluZ0xlYWRpbmcgPSAvXFxiX19wIFxcKz0gJyc7L2csXG4gICAgICByZUVtcHR5U3RyaW5nTWlkZGxlID0gL1xcYihfX3AgXFwrPSkgJycgXFwrL2csXG4gICAgICByZUVtcHR5U3RyaW5nVHJhaWxpbmcgPSAvKF9fZVxcKC4qP1xcKXxcXGJfX3RcXCkpIFxcK1xcbicnOy9nO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIEhUTUwgZW50aXRpZXMgYW5kIEhUTUwgY2hhcmFjdGVycy4gKi9cbiAgdmFyIHJlRXNjYXBlZEh0bWwgPSAvJig/OmFtcHxsdHxndHxxdW90fCMzOSk7L2csXG4gICAgICByZVVuZXNjYXBlZEh0bWwgPSAvWyY8PlwiJ10vZyxcbiAgICAgIHJlSGFzRXNjYXBlZEh0bWwgPSBSZWdFeHAocmVFc2NhcGVkSHRtbC5zb3VyY2UpLFxuICAgICAgcmVIYXNVbmVzY2FwZWRIdG1sID0gUmVnRXhwKHJlVW5lc2NhcGVkSHRtbC5zb3VyY2UpO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHRlbXBsYXRlIGRlbGltaXRlcnMuICovXG4gIHZhciByZUVzY2FwZSA9IC88JS0oW1xcc1xcU10rPyklPi9nLFxuICAgICAgcmVFdmFsdWF0ZSA9IC88JShbXFxzXFxTXSs/KSU+L2csXG4gICAgICByZUludGVycG9sYXRlID0gLzwlPShbXFxzXFxTXSs/KSU+L2c7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xuICB2YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICAgIHJlSXNQbGFpblByb3AgPSAvXlxcdyokLyxcbiAgICAgIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxcXF18XFxcXC4pKj8pXFwyKVxcXXwoPz0oPzpcXC58XFxbXFxdKSg/OlxcLnxcXFtcXF18JCkpL2c7XG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGBcbiAgICogW3N5bnRheCBjaGFyYWN0ZXJzXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1wYXR0ZXJucykuXG4gICAqL1xuICB2YXIgcmVSZWdFeHBDaGFyID0gL1tcXFxcXiQuKis/KClbXFxde318XS9nLFxuICAgICAgcmVIYXNSZWdFeHBDaGFyID0gUmVnRXhwKHJlUmVnRXhwQ2hhci5zb3VyY2UpO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGxlYWRpbmcgd2hpdGVzcGFjZS4gKi9cbiAgdmFyIHJlVHJpbVN0YXJ0ID0gL15cXHMrLztcblxuICAvKiogVXNlZCB0byBtYXRjaCBhIHNpbmdsZSB3aGl0ZXNwYWNlIGNoYXJhY3Rlci4gKi9cbiAgdmFyIHJlV2hpdGVzcGFjZSA9IC9cXHMvO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHdyYXAgZGV0YWlsIGNvbW1lbnRzLiAqL1xuICB2YXIgcmVXcmFwQ29tbWVudCA9IC9cXHsoPzpcXG5cXC9cXCogXFxbd3JhcHBlZCB3aXRoIC4rXFxdIFxcKlxcLyk/XFxuPy8sXG4gICAgICByZVdyYXBEZXRhaWxzID0gL1xce1xcblxcL1xcKiBcXFt3cmFwcGVkIHdpdGggKC4rKVxcXSBcXCovLFxuICAgICAgcmVTcGxpdERldGFpbHMgPSAvLD8gJiAvO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHdvcmRzIGNvbXBvc2VkIG9mIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzLiAqL1xuICB2YXIgcmVBc2NpaVdvcmQgPSAvW15cXHgwMC1cXHgyZlxceDNhLVxceDQwXFx4NWItXFx4NjBcXHg3Yi1cXHg3Zl0rL2c7XG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gdmFsaWRhdGUgdGhlIGB2YWxpZGF0ZWAgb3B0aW9uIGluIGBfLnRlbXBsYXRlYCB2YXJpYWJsZS5cbiAgICpcbiAgICogRm9yYmlkcyBjaGFyYWN0ZXJzIHdoaWNoIGNvdWxkIHBvdGVudGlhbGx5IGNoYW5nZSB0aGUgbWVhbmluZyBvZiB0aGUgZnVuY3Rpb24gYXJndW1lbnQgZGVmaW5pdGlvbjpcbiAgICogLSBcIigpLFwiIChtb2RpZmljYXRpb24gb2YgZnVuY3Rpb24gcGFyYW1ldGVycylcbiAgICogLSBcIj1cIiAoZGVmYXVsdCB2YWx1ZSlcbiAgICogLSBcIltde31cIiAoZGVzdHJ1Y3R1cmluZyBvZiBmdW5jdGlvbiBwYXJhbWV0ZXJzKVxuICAgKiAtIFwiL1wiIChiZWdpbm5pbmcgb2YgYSBjb21tZW50KVxuICAgKiAtIHdoaXRlc3BhY2VcbiAgICovXG4gIHZhciByZUZvcmJpZGRlbklkZW50aWZpZXJDaGFycyA9IC9bKCk9LHt9XFxbXFxdXFwvXFxzXS87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggYmFja3NsYXNoZXMgaW4gcHJvcGVydHkgcGF0aHMuICovXG4gIHZhciByZUVzY2FwZUNoYXIgPSAvXFxcXChcXFxcKT8vZztcblxuICAvKipcbiAgICogVXNlZCB0byBtYXRjaFxuICAgKiBbRVMgdGVtcGxhdGUgZGVsaW1pdGVyc10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtdGVtcGxhdGUtbGl0ZXJhbC1sZXhpY2FsLWNvbXBvbmVudHMpLlxuICAgKi9cbiAgdmFyIHJlRXNUZW1wbGF0ZSA9IC9cXCRcXHsoW15cXFxcfV0qKD86XFxcXC5bXlxcXFx9XSopKilcXH0vZztcblxuICAvKiogVXNlZCB0byBtYXRjaCBgUmVnRXhwYCBmbGFncyBmcm9tIHRoZWlyIGNvZXJjZWQgc3RyaW5nIHZhbHVlcy4gKi9cbiAgdmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBiYWQgc2lnbmVkIGhleGFkZWNpbWFsIHN0cmluZyB2YWx1ZXMuICovXG4gIHZhciByZUlzQmFkSGV4ID0gL15bLStdMHhbMC05YS1mXSskL2k7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xuICB2YXIgcmVJc0JpbmFyeSA9IC9eMGJbMDFdKyQvaTtcblxuICAvKiogVXNlZCB0byBkZXRlY3QgaG9zdCBjb25zdHJ1Y3RvcnMgKFNhZmFyaSkuICovXG4gIHZhciByZUlzSG9zdEN0b3IgPSAvXlxcW29iamVjdCAuKz9Db25zdHJ1Y3RvclxcXSQvO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xuICB2YXIgcmVJc09jdGFsID0gL14wb1swLTddKyQvaTtcblxuICAvKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovXG4gIHZhciByZUlzVWludCA9IC9eKD86MHxbMS05XVxcZCopJC87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggTGF0aW4gVW5pY29kZSBsZXR0ZXJzIChleGNsdWRpbmcgbWF0aGVtYXRpY2FsIG9wZXJhdG9ycykuICovXG4gIHZhciByZUxhdGluID0gL1tcXHhjMC1cXHhkNlxceGQ4LVxceGY2XFx4ZjgtXFx4ZmZcXHUwMTAwLVxcdTAxN2ZdL2c7XG5cbiAgLyoqIFVzZWQgdG8gZW5zdXJlIGNhcHR1cmluZyBvcmRlciBvZiB0ZW1wbGF0ZSBkZWxpbWl0ZXJzLiAqL1xuICB2YXIgcmVOb01hdGNoID0gLygkXikvO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHVuZXNjYXBlZCBjaGFyYWN0ZXJzIGluIGNvbXBpbGVkIHN0cmluZyBsaXRlcmFscy4gKi9cbiAgdmFyIHJlVW5lc2NhcGVkU3RyaW5nID0gL1snXFxuXFxyXFx1MjAyOFxcdTIwMjlcXFxcXS9nO1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjaGFyYWN0ZXIgY2xhc3Nlcy4gKi9cbiAgdmFyIHJzQXN0cmFsUmFuZ2UgPSAnXFxcXHVkODAwLVxcXFx1ZGZmZicsXG4gICAgICByc0NvbWJvTWFya3NSYW5nZSA9ICdcXFxcdTAzMDAtXFxcXHUwMzZmJyxcbiAgICAgIHJlQ29tYm9IYWxmTWFya3NSYW5nZSA9ICdcXFxcdWZlMjAtXFxcXHVmZTJmJyxcbiAgICAgIHJzQ29tYm9TeW1ib2xzUmFuZ2UgPSAnXFxcXHUyMGQwLVxcXFx1MjBmZicsXG4gICAgICByc0NvbWJvUmFuZ2UgPSByc0NvbWJvTWFya3NSYW5nZSArIHJlQ29tYm9IYWxmTWFya3NSYW5nZSArIHJzQ29tYm9TeW1ib2xzUmFuZ2UsXG4gICAgICByc0RpbmdiYXRSYW5nZSA9ICdcXFxcdTI3MDAtXFxcXHUyN2JmJyxcbiAgICAgIHJzTG93ZXJSYW5nZSA9ICdhLXpcXFxceGRmLVxcXFx4ZjZcXFxceGY4LVxcXFx4ZmYnLFxuICAgICAgcnNNYXRoT3BSYW5nZSA9ICdcXFxceGFjXFxcXHhiMVxcXFx4ZDdcXFxceGY3JyxcbiAgICAgIHJzTm9uQ2hhclJhbmdlID0gJ1xcXFx4MDAtXFxcXHgyZlxcXFx4M2EtXFxcXHg0MFxcXFx4NWItXFxcXHg2MFxcXFx4N2ItXFxcXHhiZicsXG4gICAgICByc1B1bmN0dWF0aW9uUmFuZ2UgPSAnXFxcXHUyMDAwLVxcXFx1MjA2ZicsXG4gICAgICByc1NwYWNlUmFuZ2UgPSAnIFxcXFx0XFxcXHgwYlxcXFxmXFxcXHhhMFxcXFx1ZmVmZlxcXFxuXFxcXHJcXFxcdTIwMjhcXFxcdTIwMjlcXFxcdTE2ODBcXFxcdTE4MGVcXFxcdTIwMDBcXFxcdTIwMDFcXFxcdTIwMDJcXFxcdTIwMDNcXFxcdTIwMDRcXFxcdTIwMDVcXFxcdTIwMDZcXFxcdTIwMDdcXFxcdTIwMDhcXFxcdTIwMDlcXFxcdTIwMGFcXFxcdTIwMmZcXFxcdTIwNWZcXFxcdTMwMDAnLFxuICAgICAgcnNVcHBlclJhbmdlID0gJ0EtWlxcXFx4YzAtXFxcXHhkNlxcXFx4ZDgtXFxcXHhkZScsXG4gICAgICByc1ZhclJhbmdlID0gJ1xcXFx1ZmUwZVxcXFx1ZmUwZicsXG4gICAgICByc0JyZWFrUmFuZ2UgPSByc01hdGhPcFJhbmdlICsgcnNOb25DaGFyUmFuZ2UgKyByc1B1bmN0dWF0aW9uUmFuZ2UgKyByc1NwYWNlUmFuZ2U7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNhcHR1cmUgZ3JvdXBzLiAqL1xuICB2YXIgcnNBcG9zID0gXCJbJ1xcdTIwMTldXCIsXG4gICAgICByc0FzdHJhbCA9ICdbJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsXG4gICAgICByc0JyZWFrID0gJ1snICsgcnNCcmVha1JhbmdlICsgJ10nLFxuICAgICAgcnNDb21ibyA9ICdbJyArIHJzQ29tYm9SYW5nZSArICddJyxcbiAgICAgIHJzRGlnaXRzID0gJ1xcXFxkKycsXG4gICAgICByc0RpbmdiYXQgPSAnWycgKyByc0RpbmdiYXRSYW5nZSArICddJyxcbiAgICAgIHJzTG93ZXIgPSAnWycgKyByc0xvd2VyUmFuZ2UgKyAnXScsXG4gICAgICByc01pc2MgPSAnW14nICsgcnNBc3RyYWxSYW5nZSArIHJzQnJlYWtSYW5nZSArIHJzRGlnaXRzICsgcnNEaW5nYmF0UmFuZ2UgKyByc0xvd2VyUmFuZ2UgKyByc1VwcGVyUmFuZ2UgKyAnXScsXG4gICAgICByc0ZpdHogPSAnXFxcXHVkODNjW1xcXFx1ZGZmYi1cXFxcdWRmZmZdJyxcbiAgICAgIHJzTW9kaWZpZXIgPSAnKD86JyArIHJzQ29tYm8gKyAnfCcgKyByc0ZpdHogKyAnKScsXG4gICAgICByc05vbkFzdHJhbCA9ICdbXicgKyByc0FzdHJhbFJhbmdlICsgJ10nLFxuICAgICAgcnNSZWdpb25hbCA9ICcoPzpcXFxcdWQ4M2NbXFxcXHVkZGU2LVxcXFx1ZGRmZl0pezJ9JyxcbiAgICAgIHJzU3VyclBhaXIgPSAnW1xcXFx1ZDgwMC1cXFxcdWRiZmZdW1xcXFx1ZGMwMC1cXFxcdWRmZmZdJyxcbiAgICAgIHJzVXBwZXIgPSAnWycgKyByc1VwcGVyUmFuZ2UgKyAnXScsXG4gICAgICByc1pXSiA9ICdcXFxcdTIwMGQnO1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSByZWdleGVzLiAqL1xuICB2YXIgcnNNaXNjTG93ZXIgPSAnKD86JyArIHJzTG93ZXIgKyAnfCcgKyByc01pc2MgKyAnKScsXG4gICAgICByc01pc2NVcHBlciA9ICcoPzonICsgcnNVcHBlciArICd8JyArIHJzTWlzYyArICcpJyxcbiAgICAgIHJzT3B0Q29udHJMb3dlciA9ICcoPzonICsgcnNBcG9zICsgJyg/OmR8bGx8bXxyZXxzfHR8dmUpKT8nLFxuICAgICAgcnNPcHRDb250clVwcGVyID0gJyg/OicgKyByc0Fwb3MgKyAnKD86RHxMTHxNfFJFfFN8VHxWRSkpPycsXG4gICAgICByZU9wdE1vZCA9IHJzTW9kaWZpZXIgKyAnPycsXG4gICAgICByc09wdFZhciA9ICdbJyArIHJzVmFyUmFuZ2UgKyAnXT8nLFxuICAgICAgcnNPcHRKb2luID0gJyg/OicgKyByc1pXSiArICcoPzonICsgW3JzTm9uQXN0cmFsLCByc1JlZ2lvbmFsLCByc1N1cnJQYWlyXS5qb2luKCd8JykgKyAnKScgKyByc09wdFZhciArIHJlT3B0TW9kICsgJykqJyxcbiAgICAgIHJzT3JkTG93ZXIgPSAnXFxcXGQqKD86MXN0fDJuZHwzcmR8KD8hWzEyM10pXFxcXGR0aCkoPz1cXFxcYnxbQS1aX10pJyxcbiAgICAgIHJzT3JkVXBwZXIgPSAnXFxcXGQqKD86MVNUfDJORHwzUkR8KD8hWzEyM10pXFxcXGRUSCkoPz1cXFxcYnxbYS16X10pJyxcbiAgICAgIHJzU2VxID0gcnNPcHRWYXIgKyByZU9wdE1vZCArIHJzT3B0Sm9pbixcbiAgICAgIHJzRW1vamkgPSAnKD86JyArIFtyc0RpbmdiYXQsIHJzUmVnaW9uYWwsIHJzU3VyclBhaXJdLmpvaW4oJ3wnKSArICcpJyArIHJzU2VxLFxuICAgICAgcnNTeW1ib2wgPSAnKD86JyArIFtyc05vbkFzdHJhbCArIHJzQ29tYm8gKyAnPycsIHJzQ29tYm8sIHJzUmVnaW9uYWwsIHJzU3VyclBhaXIsIHJzQXN0cmFsXS5qb2luKCd8JykgKyAnKSc7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggYXBvc3Ryb3BoZXMuICovXG4gIHZhciByZUFwb3MgPSBSZWdFeHAocnNBcG9zLCAnZycpO1xuXG4gIC8qKlxuICAgKiBVc2VkIHRvIG1hdGNoIFtjb21iaW5pbmcgZGlhY3JpdGljYWwgbWFya3NdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrcykgYW5kXG4gICAqIFtjb21iaW5pbmcgZGlhY3JpdGljYWwgbWFya3MgZm9yIHN5bWJvbHNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrc19mb3JfU3ltYm9scykuXG4gICAqL1xuICB2YXIgcmVDb21ib01hcmsgPSBSZWdFeHAocnNDb21ibywgJ2cnKTtcblxuICAvKiogVXNlZCB0byBtYXRjaCBbc3RyaW5nIHN5bWJvbHNdKGh0dHBzOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LXVuaWNvZGUpLiAqL1xuICB2YXIgcmVVbmljb2RlID0gUmVnRXhwKHJzRml0eiArICcoPz0nICsgcnNGaXR6ICsgJyl8JyArIHJzU3ltYm9sICsgcnNTZXEsICdnJyk7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggY29tcGxleCBvciBjb21wb3VuZCB3b3Jkcy4gKi9cbiAgdmFyIHJlVW5pY29kZVdvcmQgPSBSZWdFeHAoW1xuICAgIHJzVXBwZXIgKyAnPycgKyByc0xvd2VyICsgJysnICsgcnNPcHRDb250ckxvd2VyICsgJyg/PScgKyBbcnNCcmVhaywgcnNVcHBlciwgJyQnXS5qb2luKCd8JykgKyAnKScsXG4gICAgcnNNaXNjVXBwZXIgKyAnKycgKyByc09wdENvbnRyVXBwZXIgKyAnKD89JyArIFtyc0JyZWFrLCByc1VwcGVyICsgcnNNaXNjTG93ZXIsICckJ10uam9pbignfCcpICsgJyknLFxuICAgIHJzVXBwZXIgKyAnPycgKyByc01pc2NMb3dlciArICcrJyArIHJzT3B0Q29udHJMb3dlcixcbiAgICByc1VwcGVyICsgJysnICsgcnNPcHRDb250clVwcGVyLFxuICAgIHJzT3JkVXBwZXIsXG4gICAgcnNPcmRMb3dlcixcbiAgICByc0RpZ2l0cyxcbiAgICByc0Vtb2ppXG4gIF0uam9pbignfCcpLCAnZycpO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBzdHJpbmdzIHdpdGggW3plcm8td2lkdGggam9pbmVycyBvciBjb2RlIHBvaW50cyBmcm9tIHRoZSBhc3RyYWwgcGxhbmVzXShodHRwOi8vZWV2LmVlL2Jsb2cvMjAxNS8wOS8xMi9kYXJrLWNvcm5lcnMtb2YtdW5pY29kZS8pLiAqL1xuICB2YXIgcmVIYXNVbmljb2RlID0gUmVnRXhwKCdbJyArIHJzWldKICsgcnNBc3RyYWxSYW5nZSAgKyByc0NvbWJvUmFuZ2UgKyByc1ZhclJhbmdlICsgJ10nKTtcblxuICAvKiogVXNlZCB0byBkZXRlY3Qgc3RyaW5ncyB0aGF0IG5lZWQgYSBtb3JlIHJvYnVzdCByZWdleHAgdG8gbWF0Y2ggd29yZHMuICovXG4gIHZhciByZUhhc1VuaWNvZGVXb3JkID0gL1thLXpdW0EtWl18W0EtWl17Mn1bYS16XXxbMC05XVthLXpBLVpdfFthLXpBLVpdWzAtOV18W15hLXpBLVowLTkgXS87XG5cbiAgLyoqIFVzZWQgdG8gYXNzaWduIGRlZmF1bHQgYGNvbnRleHRgIG9iamVjdCBwcm9wZXJ0aWVzLiAqL1xuICB2YXIgY29udGV4dFByb3BzID0gW1xuICAgICdBcnJheScsICdCdWZmZXInLCAnRGF0YVZpZXcnLCAnRGF0ZScsICdFcnJvcicsICdGbG9hdDMyQXJyYXknLCAnRmxvYXQ2NEFycmF5JyxcbiAgICAnRnVuY3Rpb24nLCAnSW50OEFycmF5JywgJ0ludDE2QXJyYXknLCAnSW50MzJBcnJheScsICdNYXAnLCAnTWF0aCcsICdPYmplY3QnLFxuICAgICdQcm9taXNlJywgJ1JlZ0V4cCcsICdTZXQnLCAnU3RyaW5nJywgJ1N5bWJvbCcsICdUeXBlRXJyb3InLCAnVWludDhBcnJheScsXG4gICAgJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ1VpbnQxNkFycmF5JywgJ1VpbnQzMkFycmF5JywgJ1dlYWtNYXAnLFxuICAgICdfJywgJ2NsZWFyVGltZW91dCcsICdpc0Zpbml0ZScsICdwYXJzZUludCcsICdzZXRUaW1lb3V0J1xuICBdO1xuXG4gIC8qKiBVc2VkIHRvIG1ha2UgdGVtcGxhdGUgc291cmNlVVJMcyBlYXNpZXIgdG8gaWRlbnRpZnkuICovXG4gIHZhciB0ZW1wbGF0ZUNvdW50ZXIgPSAtMTtcblxuICAvKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG4gIHZhciB0eXBlZEFycmF5VGFncyA9IHt9O1xuICB0eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tpbnQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50OFRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuICB0eXBlZEFycmF5VGFnc1thcmdzVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2FycmF5VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2FycmF5QnVmZmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbZGF0YVZpZXdUYWddID0gdHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tlcnJvclRhZ10gPSB0eXBlZEFycmF5VGFnc1tmdW5jVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW21hcFRhZ10gPSB0eXBlZEFycmF5VGFnc1tudW1iZXJUYWddID1cbiAgdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tzZXRUYWddID0gdHlwZWRBcnJheVRhZ3Nbc3RyaW5nVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW3dlYWtNYXBUYWddID0gZmFsc2U7XG5cbiAgLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgc3VwcG9ydGVkIGJ5IGBfLmNsb25lYC4gKi9cbiAgdmFyIGNsb25lYWJsZVRhZ3MgPSB7fTtcbiAgY2xvbmVhYmxlVGFnc1thcmdzVGFnXSA9IGNsb25lYWJsZVRhZ3NbYXJyYXlUYWddID1cbiAgY2xvbmVhYmxlVGFnc1thcnJheUJ1ZmZlclRhZ10gPSBjbG9uZWFibGVUYWdzW2RhdGFWaWV3VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbYm9vbFRhZ10gPSBjbG9uZWFibGVUYWdzW2RhdGVUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tmbG9hdDMyVGFnXSA9IGNsb25lYWJsZVRhZ3NbZmxvYXQ2NFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW2ludDhUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQxNlRhZ10gPVxuICBjbG9uZWFibGVUYWdzW2ludDMyVGFnXSA9IGNsb25lYWJsZVRhZ3NbbWFwVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbbnVtYmVyVGFnXSA9IGNsb25lYWJsZVRhZ3Nbb2JqZWN0VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbcmVnZXhwVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc2V0VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3Nbc3RyaW5nVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc3ltYm9sVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbdWludDhUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50OENsYW1wZWRUYWddID1cbiAgY2xvbmVhYmxlVGFnc1t1aW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbiAgY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbiAgY2xvbmVhYmxlVGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4gIC8qKiBVc2VkIHRvIG1hcCBMYXRpbiBVbmljb2RlIGxldHRlcnMgdG8gYmFzaWMgTGF0aW4gbGV0dGVycy4gKi9cbiAgdmFyIGRlYnVycmVkTGV0dGVycyA9IHtcbiAgICAvLyBMYXRpbi0xIFN1cHBsZW1lbnQgYmxvY2suXG4gICAgJ1xceGMwJzogJ0EnLCAgJ1xceGMxJzogJ0EnLCAnXFx4YzInOiAnQScsICdcXHhjMyc6ICdBJywgJ1xceGM0JzogJ0EnLCAnXFx4YzUnOiAnQScsXG4gICAgJ1xceGUwJzogJ2EnLCAgJ1xceGUxJzogJ2EnLCAnXFx4ZTInOiAnYScsICdcXHhlMyc6ICdhJywgJ1xceGU0JzogJ2EnLCAnXFx4ZTUnOiAnYScsXG4gICAgJ1xceGM3JzogJ0MnLCAgJ1xceGU3JzogJ2MnLFxuICAgICdcXHhkMCc6ICdEJywgICdcXHhmMCc6ICdkJyxcbiAgICAnXFx4YzgnOiAnRScsICAnXFx4YzknOiAnRScsICdcXHhjYSc6ICdFJywgJ1xceGNiJzogJ0UnLFxuICAgICdcXHhlOCc6ICdlJywgICdcXHhlOSc6ICdlJywgJ1xceGVhJzogJ2UnLCAnXFx4ZWInOiAnZScsXG4gICAgJ1xceGNjJzogJ0knLCAgJ1xceGNkJzogJ0knLCAnXFx4Y2UnOiAnSScsICdcXHhjZic6ICdJJyxcbiAgICAnXFx4ZWMnOiAnaScsICAnXFx4ZWQnOiAnaScsICdcXHhlZSc6ICdpJywgJ1xceGVmJzogJ2knLFxuICAgICdcXHhkMSc6ICdOJywgICdcXHhmMSc6ICduJyxcbiAgICAnXFx4ZDInOiAnTycsICAnXFx4ZDMnOiAnTycsICdcXHhkNCc6ICdPJywgJ1xceGQ1JzogJ08nLCAnXFx4ZDYnOiAnTycsICdcXHhkOCc6ICdPJyxcbiAgICAnXFx4ZjInOiAnbycsICAnXFx4ZjMnOiAnbycsICdcXHhmNCc6ICdvJywgJ1xceGY1JzogJ28nLCAnXFx4ZjYnOiAnbycsICdcXHhmOCc6ICdvJyxcbiAgICAnXFx4ZDknOiAnVScsICAnXFx4ZGEnOiAnVScsICdcXHhkYic6ICdVJywgJ1xceGRjJzogJ1UnLFxuICAgICdcXHhmOSc6ICd1JywgICdcXHhmYSc6ICd1JywgJ1xceGZiJzogJ3UnLCAnXFx4ZmMnOiAndScsXG4gICAgJ1xceGRkJzogJ1knLCAgJ1xceGZkJzogJ3knLCAnXFx4ZmYnOiAneScsXG4gICAgJ1xceGM2JzogJ0FlJywgJ1xceGU2JzogJ2FlJyxcbiAgICAnXFx4ZGUnOiAnVGgnLCAnXFx4ZmUnOiAndGgnLFxuICAgICdcXHhkZic6ICdzcycsXG4gICAgLy8gTGF0aW4gRXh0ZW5kZWQtQSBibG9jay5cbiAgICAnXFx1MDEwMCc6ICdBJywgICdcXHUwMTAyJzogJ0EnLCAnXFx1MDEwNCc6ICdBJyxcbiAgICAnXFx1MDEwMSc6ICdhJywgICdcXHUwMTAzJzogJ2EnLCAnXFx1MDEwNSc6ICdhJyxcbiAgICAnXFx1MDEwNic6ICdDJywgICdcXHUwMTA4JzogJ0MnLCAnXFx1MDEwYSc6ICdDJywgJ1xcdTAxMGMnOiAnQycsXG4gICAgJ1xcdTAxMDcnOiAnYycsICAnXFx1MDEwOSc6ICdjJywgJ1xcdTAxMGInOiAnYycsICdcXHUwMTBkJzogJ2MnLFxuICAgICdcXHUwMTBlJzogJ0QnLCAgJ1xcdTAxMTAnOiAnRCcsICdcXHUwMTBmJzogJ2QnLCAnXFx1MDExMSc6ICdkJyxcbiAgICAnXFx1MDExMic6ICdFJywgICdcXHUwMTE0JzogJ0UnLCAnXFx1MDExNic6ICdFJywgJ1xcdTAxMTgnOiAnRScsICdcXHUwMTFhJzogJ0UnLFxuICAgICdcXHUwMTEzJzogJ2UnLCAgJ1xcdTAxMTUnOiAnZScsICdcXHUwMTE3JzogJ2UnLCAnXFx1MDExOSc6ICdlJywgJ1xcdTAxMWInOiAnZScsXG4gICAgJ1xcdTAxMWMnOiAnRycsICAnXFx1MDExZSc6ICdHJywgJ1xcdTAxMjAnOiAnRycsICdcXHUwMTIyJzogJ0cnLFxuICAgICdcXHUwMTFkJzogJ2cnLCAgJ1xcdTAxMWYnOiAnZycsICdcXHUwMTIxJzogJ2cnLCAnXFx1MDEyMyc6ICdnJyxcbiAgICAnXFx1MDEyNCc6ICdIJywgICdcXHUwMTI2JzogJ0gnLCAnXFx1MDEyNSc6ICdoJywgJ1xcdTAxMjcnOiAnaCcsXG4gICAgJ1xcdTAxMjgnOiAnSScsICAnXFx1MDEyYSc6ICdJJywgJ1xcdTAxMmMnOiAnSScsICdcXHUwMTJlJzogJ0knLCAnXFx1MDEzMCc6ICdJJyxcbiAgICAnXFx1MDEyOSc6ICdpJywgICdcXHUwMTJiJzogJ2knLCAnXFx1MDEyZCc6ICdpJywgJ1xcdTAxMmYnOiAnaScsICdcXHUwMTMxJzogJ2knLFxuICAgICdcXHUwMTM0JzogJ0onLCAgJ1xcdTAxMzUnOiAnaicsXG4gICAgJ1xcdTAxMzYnOiAnSycsICAnXFx1MDEzNyc6ICdrJywgJ1xcdTAxMzgnOiAnaycsXG4gICAgJ1xcdTAxMzknOiAnTCcsICAnXFx1MDEzYic6ICdMJywgJ1xcdTAxM2QnOiAnTCcsICdcXHUwMTNmJzogJ0wnLCAnXFx1MDE0MSc6ICdMJyxcbiAgICAnXFx1MDEzYSc6ICdsJywgICdcXHUwMTNjJzogJ2wnLCAnXFx1MDEzZSc6ICdsJywgJ1xcdTAxNDAnOiAnbCcsICdcXHUwMTQyJzogJ2wnLFxuICAgICdcXHUwMTQzJzogJ04nLCAgJ1xcdTAxNDUnOiAnTicsICdcXHUwMTQ3JzogJ04nLCAnXFx1MDE0YSc6ICdOJyxcbiAgICAnXFx1MDE0NCc6ICduJywgICdcXHUwMTQ2JzogJ24nLCAnXFx1MDE0OCc6ICduJywgJ1xcdTAxNGInOiAnbicsXG4gICAgJ1xcdTAxNGMnOiAnTycsICAnXFx1MDE0ZSc6ICdPJywgJ1xcdTAxNTAnOiAnTycsXG4gICAgJ1xcdTAxNGQnOiAnbycsICAnXFx1MDE0Zic6ICdvJywgJ1xcdTAxNTEnOiAnbycsXG4gICAgJ1xcdTAxNTQnOiAnUicsICAnXFx1MDE1Nic6ICdSJywgJ1xcdTAxNTgnOiAnUicsXG4gICAgJ1xcdTAxNTUnOiAncicsICAnXFx1MDE1Nyc6ICdyJywgJ1xcdTAxNTknOiAncicsXG4gICAgJ1xcdTAxNWEnOiAnUycsICAnXFx1MDE1Yyc6ICdTJywgJ1xcdTAxNWUnOiAnUycsICdcXHUwMTYwJzogJ1MnLFxuICAgICdcXHUwMTViJzogJ3MnLCAgJ1xcdTAxNWQnOiAncycsICdcXHUwMTVmJzogJ3MnLCAnXFx1MDE2MSc6ICdzJyxcbiAgICAnXFx1MDE2Mic6ICdUJywgICdcXHUwMTY0JzogJ1QnLCAnXFx1MDE2Nic6ICdUJyxcbiAgICAnXFx1MDE2Myc6ICd0JywgICdcXHUwMTY1JzogJ3QnLCAnXFx1MDE2Nyc6ICd0JyxcbiAgICAnXFx1MDE2OCc6ICdVJywgICdcXHUwMTZhJzogJ1UnLCAnXFx1MDE2Yyc6ICdVJywgJ1xcdTAxNmUnOiAnVScsICdcXHUwMTcwJzogJ1UnLCAnXFx1MDE3Mic6ICdVJyxcbiAgICAnXFx1MDE2OSc6ICd1JywgICdcXHUwMTZiJzogJ3UnLCAnXFx1MDE2ZCc6ICd1JywgJ1xcdTAxNmYnOiAndScsICdcXHUwMTcxJzogJ3UnLCAnXFx1MDE3Myc6ICd1JyxcbiAgICAnXFx1MDE3NCc6ICdXJywgICdcXHUwMTc1JzogJ3cnLFxuICAgICdcXHUwMTc2JzogJ1knLCAgJ1xcdTAxNzcnOiAneScsICdcXHUwMTc4JzogJ1knLFxuICAgICdcXHUwMTc5JzogJ1onLCAgJ1xcdTAxN2InOiAnWicsICdcXHUwMTdkJzogJ1onLFxuICAgICdcXHUwMTdhJzogJ3onLCAgJ1xcdTAxN2MnOiAneicsICdcXHUwMTdlJzogJ3onLFxuICAgICdcXHUwMTMyJzogJ0lKJywgJ1xcdTAxMzMnOiAnaWonLFxuICAgICdcXHUwMTUyJzogJ09lJywgJ1xcdTAxNTMnOiAnb2UnLFxuICAgICdcXHUwMTQ5JzogXCInblwiLCAnXFx1MDE3Zic6ICdzJ1xuICB9O1xuXG4gIC8qKiBVc2VkIHRvIG1hcCBjaGFyYWN0ZXJzIHRvIEhUTUwgZW50aXRpZXMuICovXG4gIHZhciBodG1sRXNjYXBlcyA9IHtcbiAgICAnJic6ICcmYW1wOycsXG4gICAgJzwnOiAnJmx0OycsXG4gICAgJz4nOiAnJmd0OycsXG4gICAgJ1wiJzogJyZxdW90OycsXG4gICAgXCInXCI6ICcmIzM5OydcbiAgfTtcblxuICAvKiogVXNlZCB0byBtYXAgSFRNTCBlbnRpdGllcyB0byBjaGFyYWN0ZXJzLiAqL1xuICB2YXIgaHRtbFVuZXNjYXBlcyA9IHtcbiAgICAnJmFtcDsnOiAnJicsXG4gICAgJyZsdDsnOiAnPCcsXG4gICAgJyZndDsnOiAnPicsXG4gICAgJyZxdW90Oyc6ICdcIicsXG4gICAgJyYjMzk7JzogXCInXCJcbiAgfTtcblxuICAvKiogVXNlZCB0byBlc2NhcGUgY2hhcmFjdGVycyBmb3IgaW5jbHVzaW9uIGluIGNvbXBpbGVkIHN0cmluZyBsaXRlcmFscy4gKi9cbiAgdmFyIHN0cmluZ0VzY2FwZXMgPSB7XG4gICAgJ1xcXFwnOiAnXFxcXCcsXG4gICAgXCInXCI6IFwiJ1wiLFxuICAgICdcXG4nOiAnbicsXG4gICAgJ1xccic6ICdyJyxcbiAgICAnXFx1MjAyOCc6ICd1MjAyOCcsXG4gICAgJ1xcdTIwMjknOiAndTIwMjknXG4gIH07XG5cbiAgLyoqIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHdpdGhvdXQgYSBkZXBlbmRlbmN5IG9uIGByb290YC4gKi9cbiAgdmFyIGZyZWVQYXJzZUZsb2F0ID0gcGFyc2VGbG9hdCxcbiAgICAgIGZyZWVQYXJzZUludCA9IHBhcnNlSW50O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG4gIHZhciBmcmVlR2xvYmFsID0gdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWwgJiYgZ2xvYmFsLk9iamVjdCA9PT0gT2JqZWN0ICYmIGdsb2JhbDtcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqL1xuICB2YXIgZnJlZVNlbGYgPSB0eXBlb2Ygc2VsZiA9PSAnb2JqZWN0JyAmJiBzZWxmICYmIHNlbGYuT2JqZWN0ID09PSBPYmplY3QgJiYgc2VsZjtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8IGZyZWVTZWxmIHx8IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi9cbiAgdmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBmcmVlRXhwb3J0cyAmJiB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZTtcblxuICAvKiogRGV0ZWN0IHRoZSBwb3B1bGFyIENvbW1vbkpTIGV4dGVuc2lvbiBgbW9kdWxlLmV4cG9ydHNgLiAqL1xuICB2YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0cztcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHByb2Nlc3NgIGZyb20gTm9kZS5qcy4gKi9cbiAgdmFyIGZyZWVQcm9jZXNzID0gbW9kdWxlRXhwb3J0cyAmJiBmcmVlR2xvYmFsLnByb2Nlc3M7XG5cbiAgLyoqIFVzZWQgdG8gYWNjZXNzIGZhc3RlciBOb2RlLmpzIGhlbHBlcnMuICovXG4gIHZhciBub2RlVXRpbCA9IChmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgLy8gVXNlIGB1dGlsLnR5cGVzYCBmb3IgTm9kZS5qcyAxMCsuXG4gICAgICB2YXIgdHlwZXMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUucmVxdWlyZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUoJ3V0aWwnKS50eXBlcztcblxuICAgICAgaWYgKHR5cGVzKSB7XG4gICAgICAgIHJldHVybiB0eXBlcztcbiAgICAgIH1cblxuICAgICAgLy8gTGVnYWN5IGBwcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKWAgZm9yIE5vZGUuanMgPCAxMC5cbiAgICAgIHJldHVybiBmcmVlUHJvY2VzcyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICB9KCkpO1xuXG4gIC8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG4gIHZhciBub2RlSXNBcnJheUJ1ZmZlciA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzQXJyYXlCdWZmZXIsXG4gICAgICBub2RlSXNEYXRlID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNEYXRlLFxuICAgICAgbm9kZUlzTWFwID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNNYXAsXG4gICAgICBub2RlSXNSZWdFeHAgPSBub2RlVXRpbCAmJiBub2RlVXRpbC5pc1JlZ0V4cCxcbiAgICAgIG5vZGVJc1NldCA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzU2V0LFxuICAgICAgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzVHlwZWRBcnJheTtcblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQSBmYXN0ZXIgYWx0ZXJuYXRpdmUgdG8gYEZ1bmN0aW9uI2FwcGx5YCwgdGhpcyBmdW5jdGlvbiBpbnZva2VzIGBmdW5jYFxuICAgKiB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiBgdGhpc0FyZ2AgYW5kIHRoZSBhcmd1bWVudHMgb2YgYGFyZ3NgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBpbnZva2UuXG4gICAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIGBmdW5jYCB3aXRoLlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzdWx0IG9mIGBmdW5jYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFwcGx5KGZ1bmMsIHRoaXNBcmcsIGFyZ3MpIHtcbiAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZyk7XG4gICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYXJnc1swXSk7XG4gICAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICBjYXNlIDM6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgfVxuICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUFnZ3JlZ2F0b3JgIGZvciBhcnJheXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAgICogQHBhcmFtIHtPYmplY3R9IGFjY3VtdWxhdG9yIFRoZSBpbml0aWFsIGFnZ3JlZ2F0ZWQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5QWdncmVnYXRvcihhcnJheSwgc2V0dGVyLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgICAgc2V0dGVyKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaXRlcmF0ZWUodmFsdWUpLCBhcnJheSk7XG4gICAgfVxuICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUVhY2goYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hSaWdodGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUVhY2hSaWdodChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGlmIChpdGVyYXRlZShhcnJheVtsZW5ndGhdLCBsZW5ndGgsIGFycmF5KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZXZlcnlgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYWxsIGVsZW1lbnRzIHBhc3MgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAgICogIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5RXZlcnkoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIXByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZmlsdGVyYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUZpbHRlcihhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmluY2x1ZGVzYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogc3BlY2lmeWluZyBhbiBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdGFyZ2V0YCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlJbmNsdWRlcyhhcnJheSwgdmFsdWUpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgcmV0dXJuICEhbGVuZ3RoICYmIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgMCkgPiAtMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGFycmF5SW5jbHVkZXNgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYSBjb21wYXJhdG9yLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHRhcmdldCBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyYXRvciBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHRhcmdldGAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5SW5jbHVkZXNXaXRoKGFycmF5LCB2YWx1ZSwgY29tcGFyYXRvcikge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAoY29tcGFyYXRvcih2YWx1ZSwgYXJyYXlbaW5kZXhdKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tYXBgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZVxuICAgKiBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5TWFwKGFycmF5LCBpdGVyYXRlZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZHMgdGhlIGVsZW1lbnRzIG9mIGB2YWx1ZXNgIHRvIGBhcnJheWAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFwcGVuZC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheVB1c2goYXJyYXksIHZhbHVlcykge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgICBvZmZzZXQgPSBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgYXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gdmFsdWVzW2luZGV4XTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5yZWR1Y2VgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBbaW5pdEFjY3VtXSBTcGVjaWZ5IHVzaW5nIHRoZSBmaXJzdCBlbGVtZW50IG9mIGBhcnJheWAgYXNcbiAgICogIHRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheVJlZHVjZShhcnJheSwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yLCBpbml0QWNjdW0pIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICBpZiAoaW5pdEFjY3VtICYmIGxlbmd0aCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBhcnJheVsrK2luZGV4XTtcbiAgICB9XG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gaXRlcmF0ZWUoYWNjdW11bGF0b3IsIGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5yZWR1Y2VSaWdodGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIFRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpbml0QWNjdW1dIFNwZWNpZnkgdXNpbmcgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgIGFzXG4gICAqICB0aGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlSZWR1Y2VSaWdodChhcnJheSwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yLCBpbml0QWNjdW0pIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgaWYgKGluaXRBY2N1bSAmJiBsZW5ndGgpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gYXJyYXlbLS1sZW5ndGhdO1xuICAgIH1cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gaXRlcmF0ZWUoYWNjdW11bGF0b3IsIGFycmF5W2xlbmd0aF0sIGxlbmd0aCwgYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNvbWVgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZVxuICAgKiBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAqICBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheVNvbWUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHNpemUgb2YgYW4gQVNDSUkgYHN0cmluZ2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS5cbiAgICovXG4gIHZhciBhc2NpaVNpemUgPSBiYXNlUHJvcGVydHkoJ2xlbmd0aCcpO1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbiBBU0NJSSBgc3RyaW5nYCB0byBhbiBhcnJheS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gYXNjaWlUb0FycmF5KHN0cmluZykge1xuICAgIHJldHVybiBzdHJpbmcuc3BsaXQoJycpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwbGl0cyBhbiBBU0NJSSBgc3RyaW5nYCBpbnRvIGFuIGFycmF5IG9mIGl0cyB3b3Jkcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3b3JkcyBvZiBgc3RyaW5nYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFzY2lpV29yZHMoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5tYXRjaChyZUFzY2lpV29yZCkgfHwgW107XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLmZpbmRLZXlgIGFuZCBgXy5maW5kTGFzdEtleWAsXG4gICAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcywgd2hpY2ggaXRlcmF0ZXMgb3ZlciBgY29sbGVjdGlvbmBcbiAgICogdXNpbmcgYGVhY2hGdW5jYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYGNvbGxlY3Rpb25gLlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZm91bmQgZWxlbWVudCBvciBpdHMga2V5LCBlbHNlIGB1bmRlZmluZWRgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUZpbmRLZXkoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYykge1xuICAgIHZhciByZXN1bHQ7XG4gICAgZWFjaEZ1bmMoY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSkge1xuICAgICAgICByZXN1bHQgPSBrZXk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbmRJbmRleGAgYW5kIGBfLmZpbmRMYXN0SW5kZXhgIHdpdGhvdXRcbiAgICogc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlRmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCwgZnJvbVJpZ2h0KSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgaW5kZXggPSBmcm9tSW5kZXggKyAoZnJvbVJpZ2h0ID8gMSA6IC0xKTtcblxuICAgIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpKSB7XG4gICAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pbmRleE9mYCB3aXRob3V0IGBmcm9tSW5kZXhgIGJvdW5kcyBjaGVja3MuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZVxuICAgICAgPyBzdHJpY3RJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KVxuICAgICAgOiBiYXNlRmluZEluZGV4KGFycmF5LCBiYXNlSXNOYU4sIGZyb21JbmRleCk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBiYXNlSW5kZXhPZmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBhIGNvbXBhcmF0b3IuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyYXRvciBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUluZGV4T2ZXaXRoKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4LCBjb21wYXJhdG9yKSB7XG4gICAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChjb21wYXJhdG9yKGFycmF5W2luZGV4XSwgdmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmFOYCB3aXRob3V0IHN1cHBvcnQgZm9yIG51bWJlciBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYE5hTmAsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VJc05hTih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWVhbmAgYW5kIGBfLm1lYW5CeWAgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZU1lYW4oYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgIHJldHVybiBsZW5ndGggPyAoYmFzZVN1bShhcnJheSwgaXRlcmF0ZWUpIC8gbGVuZ3RoKSA6IE5BTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wcm9wZXJ0eWAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlUHJvcGVydHkoa2V5KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wcm9wZXJ0eU9mYCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlUHJvcGVydHlPZihvYmplY3QpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJlZHVjZWAgYW5kIGBfLnJlZHVjZVJpZ2h0YCwgd2l0aG91dCBzdXBwb3J0XG4gICAqIGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLCB3aGljaCBpdGVyYXRlcyBvdmVyIGBjb2xsZWN0aW9uYCB1c2luZyBgZWFjaEZ1bmNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEBwYXJhbSB7Kn0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaW5pdEFjY3VtIFNwZWNpZnkgdXNpbmcgdGhlIGZpcnN0IG9yIGxhc3QgZWxlbWVudCBvZlxuICAgKiAgYGNvbGxlY3Rpb25gIGFzIHRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGBjb2xsZWN0aW9uYC5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVJlZHVjZShjb2xsZWN0aW9uLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSwgZWFjaEZ1bmMpIHtcbiAgICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gaW5pdEFjY3VtXG4gICAgICAgID8gKGluaXRBY2N1bSA9IGZhbHNlLCB2YWx1ZSlcbiAgICAgICAgOiBpdGVyYXRlZShhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9KTtcbiAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc29ydEJ5YCB3aGljaCB1c2VzIGBjb21wYXJlcmAgdG8gZGVmaW5lIHRoZVxuICAgKiBzb3J0IG9yZGVyIG9mIGBhcnJheWAgYW5kIHJlcGxhY2VzIGNyaXRlcmlhIG9iamVjdHMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nXG4gICAqIHZhbHVlcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNvcnQuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmVyIFRoZSBmdW5jdGlvbiB0byBkZWZpbmUgc29ydCBvcmRlci5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlU29ydEJ5KGFycmF5LCBjb21wYXJlcikge1xuICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICBhcnJheS5zb3J0KGNvbXBhcmVyKTtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGFycmF5W2xlbmd0aF0gPSBhcnJheVtsZW5ndGhdLnZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc3VtYCBhbmQgYF8uc3VtQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3VtLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVN1bShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgcmVzdWx0LFxuICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgdmFyIGN1cnJlbnQgPSBpdGVyYXRlZShhcnJheVtpbmRleF0pO1xuICAgICAgaWYgKGN1cnJlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQgPT09IHVuZGVmaW5lZCA/IGN1cnJlbnQgOiAocmVzdWx0ICsgY3VycmVudCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udGltZXNgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kc1xuICAgKiBvciBtYXggYXJyYXkgbGVuZ3RoIGNoZWNrcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiB0aW1lcyB0byBpbnZva2UgYGl0ZXJhdGVlYC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVRpbWVzKG4sIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIHJlc3VsdCA9IEFycmF5KG4pO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBuKSB7XG4gICAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoaW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRvUGFpcnNgIGFuZCBgXy50b1BhaXJzSW5gIHdoaWNoIGNyZWF0ZXMgYW4gYXJyYXlcbiAgICogb2Yga2V5LXZhbHVlIHBhaXJzIGZvciBgb2JqZWN0YCBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lcyBvZiBgcHJvcHNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBnZXQgdmFsdWVzIGZvci5cbiAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUga2V5LXZhbHVlIHBhaXJzLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVRvUGFpcnMob2JqZWN0LCBwcm9wcykge1xuICAgIHJldHVybiBhcnJheU1hcChwcm9wcywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gW2tleSwgb2JqZWN0W2tleV1dO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRyaW1gLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlVHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nXG4gICAgICA/IHN0cmluZy5zbGljZSgwLCB0cmltbWVkRW5kSW5kZXgoc3RyaW5nKSArIDEpLnJlcGxhY2UocmVUcmltU3RhcnQsICcnKVxuICAgICAgOiBzdHJpbmc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udW5hcnlgIHdpdGhvdXQgc3VwcG9ydCBmb3Igc3RvcmluZyBtZXRhZGF0YS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2FwIGFyZ3VtZW50cyBmb3IuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNhcHBlZCBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VVbmFyeShmdW5jKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuYyh2YWx1ZSk7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy52YWx1ZXNgIGFuZCBgXy52YWx1ZXNJbmAgd2hpY2ggY3JlYXRlcyBhblxuICAgKiBhcnJheSBvZiBgb2JqZWN0YCBwcm9wZXJ0eSB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byB0aGUgcHJvcGVydHkgbmFtZXNcbiAgICogb2YgYHByb3BzYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZ2V0IHZhbHVlcyBmb3IuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IHZhbHVlcy5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VWYWx1ZXMob2JqZWN0LCBwcm9wcykge1xuICAgIHJldHVybiBhcnJheU1hcChwcm9wcywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gb2JqZWN0W2tleV07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGEgYGNhY2hlYCB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gY2FjaGUgVGhlIGNhY2hlIHRvIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gY2FjaGVIYXMoY2FjaGUsIGtleSkge1xuICAgIHJldHVybiBjYWNoZS5oYXMoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLnRyaW1gIGFuZCBgXy50cmltU3RhcnRgIHRvIGdldCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IHN0cmluZyBzeW1ib2xcbiAgICogdGhhdCBpcyBub3QgZm91bmQgaW4gdGhlIGNoYXJhY3RlciBzeW1ib2xzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBzdHJTeW1ib2xzIFRoZSBzdHJpbmcgc3ltYm9scyB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0ge0FycmF5fSBjaHJTeW1ib2xzIFRoZSBjaGFyYWN0ZXIgc3ltYm9scyB0byBmaW5kLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgdW5tYXRjaGVkIHN0cmluZyBzeW1ib2wuXG4gICAqL1xuICBmdW5jdGlvbiBjaGFyc1N0YXJ0SW5kZXgoc3RyU3ltYm9scywgY2hyU3ltYm9scykge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBzdHJTeW1ib2xzLmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoICYmIGJhc2VJbmRleE9mKGNoclN5bWJvbHMsIHN0clN5bWJvbHNbaW5kZXhdLCAwKSA+IC0xKSB7fVxuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLnRyaW1gIGFuZCBgXy50cmltRW5kYCB0byBnZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IHN0cmluZyBzeW1ib2xcbiAgICogdGhhdCBpcyBub3QgZm91bmQgaW4gdGhlIGNoYXJhY3RlciBzeW1ib2xzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBzdHJTeW1ib2xzIFRoZSBzdHJpbmcgc3ltYm9scyB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0ge0FycmF5fSBjaHJTeW1ib2xzIFRoZSBjaGFyYWN0ZXIgc3ltYm9scyB0byBmaW5kLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGFzdCB1bm1hdGNoZWQgc3RyaW5nIHN5bWJvbC5cbiAgICovXG4gIGZ1bmN0aW9uIGNoYXJzRW5kSW5kZXgoc3RyU3ltYm9scywgY2hyU3ltYm9scykge1xuICAgIHZhciBpbmRleCA9IHN0clN5bWJvbHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGluZGV4LS0gJiYgYmFzZUluZGV4T2YoY2hyU3ltYm9scywgc3RyU3ltYm9sc1tpbmRleF0sIDApID4gLTEpIHt9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIG51bWJlciBvZiBgcGxhY2Vob2xkZXJgIG9jY3VycmVuY2VzIGluIGBhcnJheWAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB0byBzZWFyY2ggZm9yLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBwbGFjZWhvbGRlciBjb3VudC5cbiAgICovXG4gIGZ1bmN0aW9uIGNvdW50SG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXN1bHQgPSAwO1xuXG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICBpZiAoYXJyYXlbbGVuZ3RoXSA9PT0gcGxhY2Vob2xkZXIpIHtcbiAgICAgICAgKytyZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCBieSBgXy5kZWJ1cnJgIHRvIGNvbnZlcnQgTGF0aW4tMSBTdXBwbGVtZW50IGFuZCBMYXRpbiBFeHRlbmRlZC1BXG4gICAqIGxldHRlcnMgdG8gYmFzaWMgTGF0aW4gbGV0dGVycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGxldHRlciBUaGUgbWF0Y2hlZCBsZXR0ZXIgdG8gZGVidXJyLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBkZWJ1cnJlZCBsZXR0ZXIuXG4gICAqL1xuICB2YXIgZGVidXJyTGV0dGVyID0gYmFzZVByb3BlcnR5T2YoZGVidXJyZWRMZXR0ZXJzKTtcblxuICAvKipcbiAgICogVXNlZCBieSBgXy5lc2NhcGVgIHRvIGNvbnZlcnQgY2hhcmFjdGVycyB0byBIVE1MIGVudGl0aWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2hyIFRoZSBtYXRjaGVkIGNoYXJhY3RlciB0byBlc2NhcGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGVzY2FwZWQgY2hhcmFjdGVyLlxuICAgKi9cbiAgdmFyIGVzY2FwZUh0bWxDaGFyID0gYmFzZVByb3BlcnR5T2YoaHRtbEVzY2FwZXMpO1xuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLnRlbXBsYXRlYCB0byBlc2NhcGUgY2hhcmFjdGVycyBmb3IgaW5jbHVzaW9uIGluIGNvbXBpbGVkIHN0cmluZyBsaXRlcmFscy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNociBUaGUgbWF0Y2hlZCBjaGFyYWN0ZXIgdG8gZXNjYXBlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIGNoYXJhY3Rlci5cbiAgICovXG4gIGZ1bmN0aW9uIGVzY2FwZVN0cmluZ0NoYXIoY2hyKSB7XG4gICAgcmV0dXJuICdcXFxcJyArIHN0cmluZ0VzY2FwZXNbY2hyXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSB2YWx1ZSBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRWYWx1ZShvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBgc3RyaW5nYCBjb250YWlucyBVbmljb2RlIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYSBzeW1ib2wgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGhhc1VuaWNvZGUoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHJlSGFzVW5pY29kZS50ZXN0KHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGBzdHJpbmdgIGNvbnRhaW5zIGEgd29yZCBjb21wb3NlZCBvZiBVbmljb2RlIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYSB3b3JkIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBoYXNVbmljb2RlV29yZChzdHJpbmcpIHtcbiAgICByZXR1cm4gcmVIYXNVbmljb2RlV29yZC50ZXN0KHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYGl0ZXJhdG9yYCB0byBhbiBhcnJheS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGl0ZXJhdG9yIFRoZSBpdGVyYXRvciB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIGl0ZXJhdG9yVG9BcnJheShpdGVyYXRvcikge1xuICAgIHZhciBkYXRhLFxuICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgIHdoaWxlICghKGRhdGEgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGRhdGEudmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGBtYXBgIHRvIGl0cyBrZXktdmFsdWUgcGFpcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICovXG4gIGZ1bmN0aW9uIG1hcFRvQXJyYXkobWFwKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIHJlc3VsdCA9IEFycmF5KG1hcC5zaXplKTtcblxuICAgIG1hcC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgIHJlc3VsdFsrK2luZGV4XSA9IFtrZXksIHZhbHVlXTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSB1bmFyeSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50IHRyYW5zZm9ybWVkLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIGFyZ3VtZW50IHRyYW5zZm9ybS5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAqL1xuICBmdW5jdGlvbiBvdmVyQXJnKGZ1bmMsIHRyYW5zZm9ybSkge1xuICAgIHJldHVybiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIHJldHVybiBmdW5jKHRyYW5zZm9ybShhcmcpKTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGFsbCBgcGxhY2Vob2xkZXJgIGVsZW1lbnRzIGluIGBhcnJheWAgd2l0aCBhbiBpbnRlcm5hbCBwbGFjZWhvbGRlclxuICAgKiBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiB0aGVpciBpbmRleGVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB0byByZXBsYWNlLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVwbGFjZUhvbGRlcnMoYXJyYXksIHBsYWNlaG9sZGVyKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICBpZiAodmFsdWUgPT09IHBsYWNlaG9sZGVyIHx8IHZhbHVlID09PSBQTEFDRUhPTERFUikge1xuICAgICAgICBhcnJheVtpbmRleF0gPSBQTEFDRUhPTERFUjtcbiAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYHNldGAgdG8gYW4gYXJyYXkgb2YgaXRzIHZhbHVlcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IHNldCBUaGUgc2V0IHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgdmFsdWVzLlxuICAgKi9cbiAgZnVuY3Rpb24gc2V0VG9BcnJheShzZXQpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkoc2V0LnNpemUpO1xuXG4gICAgc2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJlc3VsdFsrK2luZGV4XSA9IHZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYHNldGAgdG8gaXRzIHZhbHVlLXZhbHVlIHBhaXJzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gc2V0IFRoZSBzZXQgdG8gY29udmVydC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB2YWx1ZS12YWx1ZSBwYWlycy5cbiAgICovXG4gIGZ1bmN0aW9uIHNldFRvUGFpcnMoc2V0KSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIHJlc3VsdCA9IEFycmF5KHNldC5zaXplKTtcblxuICAgIHNldC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXN1bHRbKytpbmRleF0gPSBbdmFsdWUsIHZhbHVlXTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5pbmRleE9mYCB3aGljaCBwZXJmb3JtcyBzdHJpY3QgZXF1YWxpdHlcbiAgICogY29tcGFyaXNvbnMgb2YgdmFsdWVzLCBpLmUuIGA9PT1gLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBzdHJpY3RJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gICAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5sYXN0SW5kZXhPZmAgd2hpY2ggcGVyZm9ybXMgc3RyaWN0IGVxdWFsaXR5XG4gICAqIGNvbXBhcmlzb25zIG9mIHZhbHVlcywgaS5lLiBgPT09YC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgKi9cbiAgZnVuY3Rpb24gc3RyaWN0TGFzdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICB2YXIgaW5kZXggPSBmcm9tSW5kZXggKyAxO1xuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBpZiAoYXJyYXlbaW5kZXhdID09PSB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBudW1iZXIgb2Ygc3ltYm9scyBpbiBgc3RyaW5nYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN0cmluZyBzaXplLlxuICAgKi9cbiAgZnVuY3Rpb24gc3RyaW5nU2l6ZShzdHJpbmcpIHtcbiAgICByZXR1cm4gaGFzVW5pY29kZShzdHJpbmcpXG4gICAgICA/IHVuaWNvZGVTaXplKHN0cmluZylcbiAgICAgIDogYXNjaWlTaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYHN0cmluZ2AgdG8gYW4gYXJyYXkuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIHN0cmluZ1RvQXJyYXkoc3RyaW5nKSB7XG4gICAgcmV0dXJuIGhhc1VuaWNvZGUoc3RyaW5nKVxuICAgICAgPyB1bmljb2RlVG9BcnJheShzdHJpbmcpXG4gICAgICA6IGFzY2lpVG9BcnJheShzdHJpbmcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1FbmRgIHRvIGdldCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9uLXdoaXRlc3BhY2VcbiAgICogY2hhcmFjdGVyIG9mIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbW1lZEVuZEluZGV4KHN0cmluZykge1xuICAgIHZhciBpbmRleCA9IHN0cmluZy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSAmJiByZVdoaXRlc3BhY2UudGVzdChzdHJpbmcuY2hhckF0KGluZGV4KSkpIHt9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udW5lc2NhcGVgIHRvIGNvbnZlcnQgSFRNTCBlbnRpdGllcyB0byBjaGFyYWN0ZXJzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2hyIFRoZSBtYXRjaGVkIGNoYXJhY3RlciB0byB1bmVzY2FwZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdW5lc2NhcGVkIGNoYXJhY3Rlci5cbiAgICovXG4gIHZhciB1bmVzY2FwZUh0bWxDaGFyID0gYmFzZVByb3BlcnR5T2YoaHRtbFVuZXNjYXBlcyk7XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHNpemUgb2YgYSBVbmljb2RlIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuXG4gICAqL1xuICBmdW5jdGlvbiB1bmljb2RlU2l6ZShzdHJpbmcpIHtcbiAgICB2YXIgcmVzdWx0ID0gcmVVbmljb2RlLmxhc3RJbmRleCA9IDA7XG4gICAgd2hpbGUgKHJlVW5pY29kZS50ZXN0KHN0cmluZykpIHtcbiAgICAgICsrcmVzdWx0O1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgVW5pY29kZSBgc3RyaW5nYCB0byBhbiBhcnJheS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gdW5pY29kZVRvQXJyYXkoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5tYXRjaChyZVVuaWNvZGUpIHx8IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwbGl0cyBhIFVuaWNvZGUgYHN0cmluZ2AgaW50byBhbiBhcnJheSBvZiBpdHMgd29yZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgd29yZHMgb2YgYHN0cmluZ2AuXG4gICAqL1xuICBmdW5jdGlvbiB1bmljb2RlV29yZHMoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5tYXRjaChyZVVuaWNvZGVXb3JkKSB8fCBbXTtcbiAgfVxuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgcHJpc3RpbmUgYGxvZGFzaGAgZnVuY3Rpb24gdXNpbmcgdGhlIGBjb250ZXh0YCBvYmplY3QuXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIF9cbiAgICogQHNpbmNlIDEuMS4wXG4gICAqIEBjYXRlZ29yeSBVdGlsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dD1yb290XSBUaGUgY29udGV4dCBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBhIG5ldyBgbG9kYXNoYCBmdW5jdGlvbi5cbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogXy5taXhpbih7ICdmb28nOiBfLmNvbnN0YW50KCdmb28nKSB9KTtcbiAgICpcbiAgICogdmFyIGxvZGFzaCA9IF8ucnVuSW5Db250ZXh0KCk7XG4gICAqIGxvZGFzaC5taXhpbih7ICdiYXInOiBsb2Rhc2guY29uc3RhbnQoJ2JhcicpIH0pO1xuICAgKlxuICAgKiBfLmlzRnVuY3Rpb24oXy5mb28pO1xuICAgKiAvLyA9PiB0cnVlXG4gICAqIF8uaXNGdW5jdGlvbihfLmJhcik7XG4gICAqIC8vID0+IGZhbHNlXG4gICAqXG4gICAqIGxvZGFzaC5pc0Z1bmN0aW9uKGxvZGFzaC5mb28pO1xuICAgKiAvLyA9PiBmYWxzZVxuICAgKiBsb2Rhc2guaXNGdW5jdGlvbihsb2Rhc2guYmFyKTtcbiAgICogLy8gPT4gdHJ1ZVxuICAgKlxuICAgKiAvLyBDcmVhdGUgYSBzdXBlZC11cCBgZGVmZXJgIGluIE5vZGUuanMuXG4gICAqIHZhciBkZWZlciA9IF8ucnVuSW5Db250ZXh0KHsgJ3NldFRpbWVvdXQnOiBzZXRJbW1lZGlhdGUgfSkuZGVmZXI7XG4gICAqL1xuICB2YXIgcnVuSW5Db250ZXh0ID0gKGZ1bmN0aW9uIHJ1bkluQ29udGV4dChjb250ZXh0KSB7XG4gICAgY29udGV4dCA9IGNvbnRleHQgPT0gbnVsbCA/IHJvb3QgOiBfLmRlZmF1bHRzKHJvb3QuT2JqZWN0KCksIGNvbnRleHQsIF8ucGljayhyb290LCBjb250ZXh0UHJvcHMpKTtcblxuICAgIC8qKiBCdWlsdC1pbiBjb25zdHJ1Y3RvciByZWZlcmVuY2VzLiAqL1xuICAgIHZhciBBcnJheSA9IGNvbnRleHQuQXJyYXksXG4gICAgICAgIERhdGUgPSBjb250ZXh0LkRhdGUsXG4gICAgICAgIEVycm9yID0gY29udGV4dC5FcnJvcixcbiAgICAgICAgRnVuY3Rpb24gPSBjb250ZXh0LkZ1bmN0aW9uLFxuICAgICAgICBNYXRoID0gY29udGV4dC5NYXRoLFxuICAgICAgICBPYmplY3QgPSBjb250ZXh0Lk9iamVjdCxcbiAgICAgICAgUmVnRXhwID0gY29udGV4dC5SZWdFeHAsXG4gICAgICAgIFN0cmluZyA9IGNvbnRleHQuU3RyaW5nLFxuICAgICAgICBUeXBlRXJyb3IgPSBjb250ZXh0LlR5cGVFcnJvcjtcblxuICAgIC8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgICB2YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSxcbiAgICAgICAgZnVuY1Byb3RvID0gRnVuY3Rpb24ucHJvdG90eXBlLFxuICAgICAgICBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3Qgb3ZlcnJlYWNoaW5nIGNvcmUtanMgc2hpbXMuICovXG4gICAgdmFyIGNvcmVKc0RhdGEgPSBjb250ZXh0WydfX2NvcmUtanNfc2hhcmVkX18nXTtcblxuICAgIC8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbiAgICB2YXIgZnVuY1RvU3RyaW5nID0gZnVuY1Byb3RvLnRvU3RyaW5nO1xuXG4gICAgLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG4gICAgdmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbiAgICAvKiogVXNlZCB0byBnZW5lcmF0ZSB1bmlxdWUgSURzLiAqL1xuICAgIHZhciBpZENvdW50ZXIgPSAwO1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IG1ldGhvZHMgbWFzcXVlcmFkaW5nIGFzIG5hdGl2ZS4gKi9cbiAgICB2YXIgbWFza1NyY0tleSA9IChmdW5jdGlvbigpIHtcbiAgICAgIHZhciB1aWQgPSAvW14uXSskLy5leGVjKGNvcmVKc0RhdGEgJiYgY29yZUpzRGF0YS5rZXlzICYmIGNvcmVKc0RhdGEua2V5cy5JRV9QUk9UTyB8fCAnJyk7XG4gICAgICByZXR1cm4gdWlkID8gKCdTeW1ib2woc3JjKV8xLicgKyB1aWQpIDogJyc7XG4gICAgfSgpKTtcblxuICAgIC8qKlxuICAgICAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAgICAgKiBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAgICAgKiBvZiB2YWx1ZXMuXG4gICAgICovXG4gICAgdmFyIG5hdGl2ZU9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbiAgICAvKiogVXNlZCB0byBpbmZlciB0aGUgYE9iamVjdGAgY29uc3RydWN0b3IuICovXG4gICAgdmFyIG9iamVjdEN0b3JTdHJpbmcgPSBmdW5jVG9TdHJpbmcuY2FsbChPYmplY3QpO1xuXG4gICAgLyoqIFVzZWQgdG8gcmVzdG9yZSB0aGUgb3JpZ2luYWwgYF9gIHJlZmVyZW5jZSBpbiBgXy5ub0NvbmZsaWN0YC4gKi9cbiAgICB2YXIgb2xkRGFzaCA9IHJvb3QuXztcblxuICAgIC8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG4gICAgdmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICtcbiAgICAgIGZ1bmNUb1N0cmluZy5jYWxsKGhhc093blByb3BlcnR5KS5yZXBsYWNlKHJlUmVnRXhwQ2hhciwgJ1xcXFwkJicpXG4gICAgICAucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXFxcXCgpfCBmb3IgLis/KD89XFxcXFxcXSkvZywgJyQxLio/JykgKyAnJCdcbiAgICApO1xuXG4gICAgLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG4gICAgdmFyIEJ1ZmZlciA9IG1vZHVsZUV4cG9ydHMgPyBjb250ZXh0LkJ1ZmZlciA6IHVuZGVmaW5lZCxcbiAgICAgICAgU3ltYm9sID0gY29udGV4dC5TeW1ib2wsXG4gICAgICAgIFVpbnQ4QXJyYXkgPSBjb250ZXh0LlVpbnQ4QXJyYXksXG4gICAgICAgIGFsbG9jVW5zYWZlID0gQnVmZmVyID8gQnVmZmVyLmFsbG9jVW5zYWZlIDogdW5kZWZpbmVkLFxuICAgICAgICBnZXRQcm90b3R5cGUgPSBvdmVyQXJnKE9iamVjdC5nZXRQcm90b3R5cGVPZiwgT2JqZWN0KSxcbiAgICAgICAgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSxcbiAgICAgICAgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZSxcbiAgICAgICAgc3BsaWNlID0gYXJyYXlQcm90by5zcGxpY2UsXG4gICAgICAgIHNwcmVhZGFibGVTeW1ib2wgPSBTeW1ib2wgPyBTeW1ib2wuaXNDb25jYXRTcHJlYWRhYmxlIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1JdGVyYXRvciA9IFN5bWJvbCA/IFN5bWJvbC5pdGVyYXRvciA6IHVuZGVmaW5lZCxcbiAgICAgICAgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgZGVmaW5lUHJvcGVydHkgPSAoZnVuY3Rpb24oKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgZnVuYyA9IGdldE5hdGl2ZShPYmplY3QsICdkZWZpbmVQcm9wZXJ0eScpO1xuICAgICAgICBmdW5jKHt9LCAnJywge30pO1xuICAgICAgICByZXR1cm4gZnVuYztcbiAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgfSgpKTtcblxuICAgIC8qKiBNb2NrZWQgYnVpbHQtaW5zLiAqL1xuICAgIHZhciBjdHhDbGVhclRpbWVvdXQgPSBjb250ZXh0LmNsZWFyVGltZW91dCAhPT0gcm9vdC5jbGVhclRpbWVvdXQgJiYgY29udGV4dC5jbGVhclRpbWVvdXQsXG4gICAgICAgIGN0eE5vdyA9IERhdGUgJiYgRGF0ZS5ub3cgIT09IHJvb3QuRGF0ZS5ub3cgJiYgRGF0ZS5ub3csXG4gICAgICAgIGN0eFNldFRpbWVvdXQgPSBjb250ZXh0LnNldFRpbWVvdXQgIT09IHJvb3Quc2V0VGltZW91dCAmJiBjb250ZXh0LnNldFRpbWVvdXQ7XG5cbiAgICAvKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG4gICAgdmFyIG5hdGl2ZUNlaWwgPSBNYXRoLmNlaWwsXG4gICAgICAgIG5hdGl2ZUZsb29yID0gTWF0aC5mbG9vcixcbiAgICAgICAgbmF0aXZlR2V0U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMsXG4gICAgICAgIG5hdGl2ZUlzQnVmZmVyID0gQnVmZmVyID8gQnVmZmVyLmlzQnVmZmVyIDogdW5kZWZpbmVkLFxuICAgICAgICBuYXRpdmVJc0Zpbml0ZSA9IGNvbnRleHQuaXNGaW5pdGUsXG4gICAgICAgIG5hdGl2ZUpvaW4gPSBhcnJheVByb3RvLmpvaW4sXG4gICAgICAgIG5hdGl2ZUtleXMgPSBvdmVyQXJnKE9iamVjdC5rZXlzLCBPYmplY3QpLFxuICAgICAgICBuYXRpdmVNYXggPSBNYXRoLm1heCxcbiAgICAgICAgbmF0aXZlTWluID0gTWF0aC5taW4sXG4gICAgICAgIG5hdGl2ZU5vdyA9IERhdGUubm93LFxuICAgICAgICBuYXRpdmVQYXJzZUludCA9IGNvbnRleHQucGFyc2VJbnQsXG4gICAgICAgIG5hdGl2ZVJhbmRvbSA9IE1hdGgucmFuZG9tLFxuICAgICAgICBuYXRpdmVSZXZlcnNlID0gYXJyYXlQcm90by5yZXZlcnNlO1xuXG4gICAgLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xuICAgIHZhciBEYXRhVmlldyA9IGdldE5hdGl2ZShjb250ZXh0LCAnRGF0YVZpZXcnKSxcbiAgICAgICAgTWFwID0gZ2V0TmF0aXZlKGNvbnRleHQsICdNYXAnKSxcbiAgICAgICAgUHJvbWlzZSA9IGdldE5hdGl2ZShjb250ZXh0LCAnUHJvbWlzZScpLFxuICAgICAgICBTZXQgPSBnZXROYXRpdmUoY29udGV4dCwgJ1NldCcpLFxuICAgICAgICBXZWFrTWFwID0gZ2V0TmF0aXZlKGNvbnRleHQsICdXZWFrTWFwJyksXG4gICAgICAgIG5hdGl2ZUNyZWF0ZSA9IGdldE5hdGl2ZShPYmplY3QsICdjcmVhdGUnKTtcblxuICAgIC8qKiBVc2VkIHRvIHN0b3JlIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xuICAgIHZhciBtZXRhTWFwID0gV2Vha01hcCAmJiBuZXcgV2Vha01hcDtcblxuICAgIC8qKiBVc2VkIHRvIGxvb2t1cCB1bm1pbmlmaWVkIGZ1bmN0aW9uIG5hbWVzLiAqL1xuICAgIHZhciByZWFsTmFtZXMgPSB7fTtcblxuICAgIC8qKiBVc2VkIHRvIGRldGVjdCBtYXBzLCBzZXRzLCBhbmQgd2Vha21hcHMuICovXG4gICAgdmFyIGRhdGFWaWV3Q3RvclN0cmluZyA9IHRvU291cmNlKERhdGFWaWV3KSxcbiAgICAgICAgbWFwQ3RvclN0cmluZyA9IHRvU291cmNlKE1hcCksXG4gICAgICAgIHByb21pc2VDdG9yU3RyaW5nID0gdG9Tb3VyY2UoUHJvbWlzZSksXG4gICAgICAgIHNldEN0b3JTdHJpbmcgPSB0b1NvdXJjZShTZXQpLFxuICAgICAgICB3ZWFrTWFwQ3RvclN0cmluZyA9IHRvU291cmNlKFdlYWtNYXApO1xuXG4gICAgLyoqIFVzZWQgdG8gY29udmVydCBzeW1ib2xzIHRvIHByaW1pdGl2ZXMgYW5kIHN0cmluZ3MuICovXG4gICAgdmFyIHN5bWJvbFByb3RvID0gU3ltYm9sID8gU3ltYm9sLnByb3RvdHlwZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgc3ltYm9sVmFsdWVPZiA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udmFsdWVPZiA6IHVuZGVmaW5lZCxcbiAgICAgICAgc3ltYm9sVG9TdHJpbmcgPSBzeW1ib2xQcm90byA/IHN5bWJvbFByb3RvLnRvU3RyaW5nIDogdW5kZWZpbmVkO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBsb2Rhc2hgIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBpbXBsaWNpdCBtZXRob2RcbiAgICAgKiBjaGFpbiBzZXF1ZW5jZXMuIE1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIGFuZCByZXR1cm4gYXJyYXlzLCBjb2xsZWN0aW9ucyxcbiAgICAgKiBhbmQgZnVuY3Rpb25zIGNhbiBiZSBjaGFpbmVkIHRvZ2V0aGVyLiBNZXRob2RzIHRoYXQgcmV0cmlldmUgYSBzaW5nbGUgdmFsdWVcbiAgICAgKiBvciBtYXkgcmV0dXJuIGEgcHJpbWl0aXZlIHZhbHVlIHdpbGwgYXV0b21hdGljYWxseSBlbmQgdGhlIGNoYWluIHNlcXVlbmNlXG4gICAgICogYW5kIHJldHVybiB0aGUgdW53cmFwcGVkIHZhbHVlLiBPdGhlcndpc2UsIHRoZSB2YWx1ZSBtdXN0IGJlIHVud3JhcHBlZFxuICAgICAqIHdpdGggYF8jdmFsdWVgLlxuICAgICAqXG4gICAgICogRXhwbGljaXQgY2hhaW4gc2VxdWVuY2VzLCB3aGljaCBtdXN0IGJlIHVud3JhcHBlZCB3aXRoIGBfI3ZhbHVlYCwgbWF5IGJlXG4gICAgICogZW5hYmxlZCB1c2luZyBgXy5jaGFpbmAuXG4gICAgICpcbiAgICAgKiBUaGUgZXhlY3V0aW9uIG9mIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBpdCdzIGRlZmVycmVkIHVudGlsXG4gICAgICogYF8jdmFsdWVgIGlzIGltcGxpY2l0bHkgb3IgZXhwbGljaXRseSBjYWxsZWQuXG4gICAgICpcbiAgICAgKiBMYXp5IGV2YWx1YXRpb24gYWxsb3dzIHNldmVyYWwgbWV0aG9kcyB0byBzdXBwb3J0IHNob3J0Y3V0IGZ1c2lvbi5cbiAgICAgKiBTaG9ydGN1dCBmdXNpb24gaXMgYW4gb3B0aW1pemF0aW9uIHRvIG1lcmdlIGl0ZXJhdGVlIGNhbGxzOyB0aGlzIGF2b2lkc1xuICAgICAqIHRoZSBjcmVhdGlvbiBvZiBpbnRlcm1lZGlhdGUgYXJyYXlzIGFuZCBjYW4gZ3JlYXRseSByZWR1Y2UgdGhlIG51bWJlciBvZlxuICAgICAqIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuIFNlY3Rpb25zIG9mIGEgY2hhaW4gc2VxdWVuY2UgcXVhbGlmeSBmb3Igc2hvcnRjdXRcbiAgICAgKiBmdXNpb24gaWYgdGhlIHNlY3Rpb24gaXMgYXBwbGllZCB0byBhbiBhcnJheSBhbmQgaXRlcmF0ZWVzIGFjY2VwdCBvbmx5XG4gICAgICogb25lIGFyZ3VtZW50LiBUaGUgaGV1cmlzdGljIGZvciB3aGV0aGVyIGEgc2VjdGlvbiBxdWFsaWZpZXMgZm9yIHNob3J0Y3V0XG4gICAgICogZnVzaW9uIGlzIHN1YmplY3QgdG8gY2hhbmdlLlxuICAgICAqXG4gICAgICogQ2hhaW5pbmcgaXMgc3VwcG9ydGVkIGluIGN1c3RvbSBidWlsZHMgYXMgbG9uZyBhcyB0aGUgYF8jdmFsdWVgIG1ldGhvZCBpc1xuICAgICAqIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgaW5jbHVkZWQgaW4gdGhlIGJ1aWxkLlxuICAgICAqXG4gICAgICogSW4gYWRkaXRpb24gdG8gbG9kYXNoIG1ldGhvZHMsIHdyYXBwZXJzIGhhdmUgYEFycmF5YCBhbmQgYFN0cmluZ2AgbWV0aG9kcy5cbiAgICAgKlxuICAgICAqIFRoZSB3cmFwcGVyIGBBcnJheWAgbWV0aG9kcyBhcmU6XG4gICAgICogYGNvbmNhdGAsIGBqb2luYCwgYHBvcGAsIGBwdXNoYCwgYHNoaWZ0YCwgYHNvcnRgLCBgc3BsaWNlYCwgYW5kIGB1bnNoaWZ0YFxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgYFN0cmluZ2AgbWV0aG9kcyBhcmU6XG4gICAgICogYHJlcGxhY2VgIGFuZCBgc3BsaXRgXG4gICAgICpcbiAgICAgKiBUaGUgd3JhcHBlciBtZXRob2RzIHRoYXQgc3VwcG9ydCBzaG9ydGN1dCBmdXNpb24gYXJlOlxuICAgICAqIGBhdGAsIGBjb21wYWN0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BXaGlsZWAsIGBmaWx0ZXJgLCBgZmluZGAsXG4gICAgICogYGZpbmRMYXN0YCwgYGhlYWRgLCBgaW5pdGlhbGAsIGBsYXN0YCwgYG1hcGAsIGByZWplY3RgLCBgcmV2ZXJzZWAsIGBzbGljZWAsXG4gICAgICogYHRhaWxgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYW5kIGB0b0FycmF5YFxuICAgICAqXG4gICAgICogVGhlIGNoYWluYWJsZSB3cmFwcGVyIG1ldGhvZHMgYXJlOlxuICAgICAqIGBhZnRlcmAsIGBhcnlgLCBgYXNzaWduYCwgYGFzc2lnbkluYCwgYGFzc2lnbkluV2l0aGAsIGBhc3NpZ25XaXRoYCwgYGF0YCxcbiAgICAgKiBgYmVmb3JlYCwgYGJpbmRgLCBgYmluZEFsbGAsIGBiaW5kS2V5YCwgYGNhc3RBcnJheWAsIGBjaGFpbmAsIGBjaHVua2AsXG4gICAgICogYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25mb3Jtc2AsIGBjb25zdGFudGAsIGBjb3VudEJ5YCwgYGNyZWF0ZWAsXG4gICAgICogYGN1cnJ5YCwgYGRlYm91bmNlYCwgYGRlZmF1bHRzYCwgYGRlZmF1bHRzRGVlcGAsIGBkZWZlcmAsIGBkZWxheWAsXG4gICAgICogYGRpZmZlcmVuY2VgLCBgZGlmZmVyZW5jZUJ5YCwgYGRpZmZlcmVuY2VXaXRoYCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCxcbiAgICAgKiBgZHJvcFJpZ2h0V2hpbGVgLCBgZHJvcFdoaWxlYCwgYGV4dGVuZGAsIGBleHRlbmRXaXRoYCwgYGZpbGxgLCBgZmlsdGVyYCxcbiAgICAgKiBgZmxhdE1hcGAsIGBmbGF0TWFwRGVlcGAsIGBmbGF0TWFwRGVwdGhgLCBgZmxhdHRlbmAsIGBmbGF0dGVuRGVlcGAsXG4gICAgICogYGZsYXR0ZW5EZXB0aGAsIGBmbGlwYCwgYGZsb3dgLCBgZmxvd1JpZ2h0YCwgYGZyb21QYWlyc2AsIGBmdW5jdGlvbnNgLFxuICAgICAqIGBmdW5jdGlvbnNJbmAsIGBncm91cEJ5YCwgYGluaXRpYWxgLCBgaW50ZXJzZWN0aW9uYCwgYGludGVyc2VjdGlvbkJ5YCxcbiAgICAgKiBgaW50ZXJzZWN0aW9uV2l0aGAsIGBpbnZlcnRgLCBgaW52ZXJ0QnlgLCBgaW52b2tlTWFwYCwgYGl0ZXJhdGVlYCwgYGtleUJ5YCxcbiAgICAgKiBga2V5c2AsIGBrZXlzSW5gLCBgbWFwYCwgYG1hcEtleXNgLCBgbWFwVmFsdWVzYCwgYG1hdGNoZXNgLCBgbWF0Y2hlc1Byb3BlcnR5YCxcbiAgICAgKiBgbWVtb2l6ZWAsIGBtZXJnZWAsIGBtZXJnZVdpdGhgLCBgbWV0aG9kYCwgYG1ldGhvZE9mYCwgYG1peGluYCwgYG5lZ2F0ZWAsXG4gICAgICogYG50aEFyZ2AsIGBvbWl0YCwgYG9taXRCeWAsIGBvbmNlYCwgYG9yZGVyQnlgLCBgb3ZlcmAsIGBvdmVyQXJnc2AsXG4gICAgICogYG92ZXJFdmVyeWAsIGBvdmVyU29tZWAsIGBwYXJ0aWFsYCwgYHBhcnRpYWxSaWdodGAsIGBwYXJ0aXRpb25gLCBgcGlja2AsXG4gICAgICogYHBpY2tCeWAsIGBwbGFudGAsIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLCBgcHVsbEFsbGAsIGBwdWxsQWxsQnlgLFxuICAgICAqIGBwdWxsQWxsV2l0aGAsIGBwdWxsQXRgLCBgcHVzaGAsIGByYW5nZWAsIGByYW5nZVJpZ2h0YCwgYHJlYXJnYCwgYHJlamVjdGAsXG4gICAgICogYHJlbW92ZWAsIGByZXN0YCwgYHJldmVyc2VgLCBgc2FtcGxlU2l6ZWAsIGBzZXRgLCBgc2V0V2l0aGAsIGBzaHVmZmxlYCxcbiAgICAgKiBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc3BsaWNlYCwgYHNwcmVhZGAsIGB0YWlsYCwgYHRha2VgLCBgdGFrZVJpZ2h0YCxcbiAgICAgKiBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYHRhcGAsIGB0aHJvdHRsZWAsIGB0aHJ1YCwgYHRvQXJyYXlgLFxuICAgICAqIGB0b1BhaXJzYCwgYHRvUGFpcnNJbmAsIGB0b1BhdGhgLCBgdG9QbGFpbk9iamVjdGAsIGB0cmFuc2Zvcm1gLCBgdW5hcnlgLFxuICAgICAqIGB1bmlvbmAsIGB1bmlvbkJ5YCwgYHVuaW9uV2l0aGAsIGB1bmlxYCwgYHVuaXFCeWAsIGB1bmlxV2l0aGAsIGB1bnNldGAsXG4gICAgICogYHVuc2hpZnRgLCBgdW56aXBgLCBgdW56aXBXaXRoYCwgYHVwZGF0ZWAsIGB1cGRhdGVXaXRoYCwgYHZhbHVlc2AsXG4gICAgICogYHZhbHVlc0luYCwgYHdpdGhvdXRgLCBgd3JhcGAsIGB4b3JgLCBgeG9yQnlgLCBgeG9yV2l0aGAsIGB6aXBgLFxuICAgICAqIGB6aXBPYmplY3RgLCBgemlwT2JqZWN0RGVlcGAsIGFuZCBgemlwV2l0aGBcbiAgICAgKlxuICAgICAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBhcmUgKipub3QqKiBjaGFpbmFibGUgYnkgZGVmYXVsdCBhcmU6XG4gICAgICogYGFkZGAsIGBhdHRlbXB0YCwgYGNhbWVsQ2FzZWAsIGBjYXBpdGFsaXplYCwgYGNlaWxgLCBgY2xhbXBgLCBgY2xvbmVgLFxuICAgICAqIGBjbG9uZURlZXBgLCBgY2xvbmVEZWVwV2l0aGAsIGBjbG9uZVdpdGhgLCBgY29uZm9ybXNUb2AsIGBkZWJ1cnJgLFxuICAgICAqIGBkZWZhdWx0VG9gLCBgZGl2aWRlYCwgYGVhY2hgLCBgZWFjaFJpZ2h0YCwgYGVuZHNXaXRoYCwgYGVxYCwgYGVzY2FwZWAsXG4gICAgICogYGVzY2FwZVJlZ0V4cGAsIGBldmVyeWAsIGBmaW5kYCwgYGZpbmRJbmRleGAsIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCxcbiAgICAgKiBgZmluZExhc3RJbmRleGAsIGBmaW5kTGFzdEtleWAsIGBmaXJzdGAsIGBmbG9vcmAsIGBmb3JFYWNoYCwgYGZvckVhY2hSaWdodGAsXG4gICAgICogYGZvckluYCwgYGZvckluUmlnaHRgLCBgZm9yT3duYCwgYGZvck93blJpZ2h0YCwgYGdldGAsIGBndGAsIGBndGVgLCBgaGFzYCxcbiAgICAgKiBgaGFzSW5gLCBgaGVhZGAsIGBpZGVudGl0eWAsIGBpbmNsdWRlc2AsIGBpbmRleE9mYCwgYGluUmFuZ2VgLCBgaW52b2tlYCxcbiAgICAgKiBgaXNBcmd1bWVudHNgLCBgaXNBcnJheWAsIGBpc0FycmF5QnVmZmVyYCwgYGlzQXJyYXlMaWtlYCwgYGlzQXJyYXlMaWtlT2JqZWN0YCxcbiAgICAgKiBgaXNCb29sZWFuYCwgYGlzQnVmZmVyYCwgYGlzRGF0ZWAsIGBpc0VsZW1lbnRgLCBgaXNFbXB0eWAsIGBpc0VxdWFsYCxcbiAgICAgKiBgaXNFcXVhbFdpdGhgLCBgaXNFcnJvcmAsIGBpc0Zpbml0ZWAsIGBpc0Z1bmN0aW9uYCwgYGlzSW50ZWdlcmAsIGBpc0xlbmd0aGAsXG4gICAgICogYGlzTWFwYCwgYGlzTWF0Y2hgLCBgaXNNYXRjaFdpdGhgLCBgaXNOYU5gLCBgaXNOYXRpdmVgLCBgaXNOaWxgLCBgaXNOdWxsYCxcbiAgICAgKiBgaXNOdW1iZXJgLCBgaXNPYmplY3RgLCBgaXNPYmplY3RMaWtlYCwgYGlzUGxhaW5PYmplY3RgLCBgaXNSZWdFeHBgLFxuICAgICAqIGBpc1NhZmVJbnRlZ2VyYCwgYGlzU2V0YCwgYGlzU3RyaW5nYCwgYGlzVW5kZWZpbmVkYCwgYGlzVHlwZWRBcnJheWAsXG4gICAgICogYGlzV2Vha01hcGAsIGBpc1dlYWtTZXRgLCBgam9pbmAsIGBrZWJhYkNhc2VgLCBgbGFzdGAsIGBsYXN0SW5kZXhPZmAsXG4gICAgICogYGxvd2VyQ2FzZWAsIGBsb3dlckZpcnN0YCwgYGx0YCwgYGx0ZWAsIGBtYXhgLCBgbWF4QnlgLCBgbWVhbmAsIGBtZWFuQnlgLFxuICAgICAqIGBtaW5gLCBgbWluQnlgLCBgbXVsdGlwbHlgLCBgbm9Db25mbGljdGAsIGBub29wYCwgYG5vd2AsIGBudGhgLCBgcGFkYCxcbiAgICAgKiBgcGFkRW5kYCwgYHBhZFN0YXJ0YCwgYHBhcnNlSW50YCwgYHBvcGAsIGByYW5kb21gLCBgcmVkdWNlYCwgYHJlZHVjZVJpZ2h0YCxcbiAgICAgKiBgcmVwZWF0YCwgYHJlc3VsdGAsIGByb3VuZGAsIGBydW5JbkNvbnRleHRgLCBgc2FtcGxlYCwgYHNoaWZ0YCwgYHNpemVgLFxuICAgICAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRJbmRleEJ5YCwgYHNvcnRlZExhc3RJbmRleGAsXG4gICAgICogYHNvcnRlZExhc3RJbmRleEJ5YCwgYHN0YXJ0Q2FzZWAsIGBzdGFydHNXaXRoYCwgYHN0dWJBcnJheWAsIGBzdHViRmFsc2VgLFxuICAgICAqIGBzdHViT2JqZWN0YCwgYHN0dWJTdHJpbmdgLCBgc3R1YlRydWVgLCBgc3VidHJhY3RgLCBgc3VtYCwgYHN1bUJ5YCxcbiAgICAgKiBgdGVtcGxhdGVgLCBgdGltZXNgLCBgdG9GaW5pdGVgLCBgdG9JbnRlZ2VyYCwgYHRvSlNPTmAsIGB0b0xlbmd0aGAsXG4gICAgICogYHRvTG93ZXJgLCBgdG9OdW1iZXJgLCBgdG9TYWZlSW50ZWdlcmAsIGB0b1N0cmluZ2AsIGB0b1VwcGVyYCwgYHRyaW1gLFxuICAgICAqIGB0cmltRW5kYCwgYHRyaW1TdGFydGAsIGB0cnVuY2F0ZWAsIGB1bmVzY2FwZWAsIGB1bmlxdWVJZGAsIGB1cHBlckNhc2VgLFxuICAgICAqIGB1cHBlckZpcnN0YCwgYHZhbHVlYCwgYW5kIGB3b3Jkc2BcbiAgICAgKlxuICAgICAqIEBuYW1lIF9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcCBpbiBhIGBsb2Rhc2hgIGluc3RhbmNlLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICAgICAqICAgcmV0dXJuIG4gKiBuO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciB3cmFwcGVkID0gXyhbMSwgMiwgM10pO1xuICAgICAqXG4gICAgICogLy8gUmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWUuXG4gICAgICogd3JhcHBlZC5yZWR1Y2UoXy5hZGQpO1xuICAgICAqIC8vID0+IDZcbiAgICAgKlxuICAgICAqIC8vIFJldHVybnMgYSB3cmFwcGVkIHZhbHVlLlxuICAgICAqIHZhciBzcXVhcmVzID0gd3JhcHBlZC5tYXAoc3F1YXJlKTtcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShzcXVhcmVzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KHNxdWFyZXMudmFsdWUoKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxvZGFzaCh2YWx1ZSkge1xuICAgICAgaWYgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzQXJyYXkodmFsdWUpICYmICEodmFsdWUgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikpIHtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTG9kYXNoV3JhcHBlcikge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ19fd3JhcHBlZF9fJykpIHtcbiAgICAgICAgICByZXR1cm4gd3JhcHBlckNsb25lKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jcmVhdGVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXNzaWduaW5nXG4gICAgICogcHJvcGVydGllcyB0byB0aGUgY3JlYXRlZCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwcm90byBUaGUgb2JqZWN0IHRvIGluaGVyaXQgZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqL1xuICAgIHZhciBiYXNlQ3JlYXRlID0gKGZ1bmN0aW9uKCkge1xuICAgICAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgICAgIHJldHVybiBmdW5jdGlvbihwcm90bykge1xuICAgICAgICBpZiAoIWlzT2JqZWN0KHByb3RvKSkge1xuICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob2JqZWN0Q3JlYXRlKSB7XG4gICAgICAgICAgcmV0dXJuIG9iamVjdENyZWF0ZShwcm90byk7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0LnByb3RvdHlwZSA9IHByb3RvO1xuICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IG9iamVjdDtcbiAgICAgICAgb2JqZWN0LnByb3RvdHlwZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfSgpKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBmdW5jdGlvbiB3aG9zZSBwcm90b3R5cGUgY2hhaW4gc2VxdWVuY2Ugd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTG9kYXNoKCkge1xuICAgICAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBjb25zdHJ1Y3RvciBmb3IgY3JlYXRpbmcgYGxvZGFzaGAgd3JhcHBlciBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NoYWluQWxsXSBFbmFibGUgZXhwbGljaXQgbWV0aG9kIGNoYWluIHNlcXVlbmNlcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBMb2Rhc2hXcmFwcGVyKHZhbHVlLCBjaGFpbkFsbCkge1xuICAgICAgdGhpcy5fX3dyYXBwZWRfXyA9IHZhbHVlO1xuICAgICAgdGhpcy5fX2FjdGlvbnNfXyA9IFtdO1xuICAgICAgdGhpcy5fX2NoYWluX18gPSAhIWNoYWluQWxsO1xuICAgICAgdGhpcy5fX2luZGV4X18gPSAwO1xuICAgICAgdGhpcy5fX3ZhbHVlc19fID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJ5IGRlZmF1bHQsIHRoZSB0ZW1wbGF0ZSBkZWxpbWl0ZXJzIHVzZWQgYnkgbG9kYXNoIGFyZSBsaWtlIHRob3NlIGluXG4gICAgICogZW1iZWRkZWQgUnVieSAoRVJCKSBhcyB3ZWxsIGFzIEVTMjAxNSB0ZW1wbGF0ZSBzdHJpbmdzLiBDaGFuZ2UgdGhlXG4gICAgICogZm9sbG93aW5nIHRlbXBsYXRlIHNldHRpbmdzIHRvIHVzZSBhbHRlcm5hdGl2ZSBkZWxpbWl0ZXJzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICBsb2Rhc2gudGVtcGxhdGVTZXR0aW5ncyA9IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGRldGVjdCBgZGF0YWAgcHJvcGVydHkgdmFsdWVzIHRvIGJlIEhUTUwtZXNjYXBlZC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7UmVnRXhwfVxuICAgICAgICovXG4gICAgICAnZXNjYXBlJzogcmVFc2NhcGUsXG5cbiAgICAgIC8qKlxuICAgICAgICogVXNlZCB0byBkZXRlY3QgY29kZSB0byBiZSBldmFsdWF0ZWQuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIF8udGVtcGxhdGVTZXR0aW5nc1xuICAgICAgICogQHR5cGUge1JlZ0V4cH1cbiAgICAgICAqL1xuICAgICAgJ2V2YWx1YXRlJzogcmVFdmFsdWF0ZSxcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGRldGVjdCBgZGF0YWAgcHJvcGVydHkgdmFsdWVzIHRvIGluamVjdC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7UmVnRXhwfVxuICAgICAgICovXG4gICAgICAnaW50ZXJwb2xhdGUnOiByZUludGVycG9sYXRlLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gcmVmZXJlbmNlIHRoZSBkYXRhIG9iamVjdCBpbiB0aGUgdGVtcGxhdGUgdGV4dC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAgICovXG4gICAgICAndmFyaWFibGUnOiAnJyxcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGltcG9ydCB2YXJpYWJsZXMgaW50byB0aGUgY29tcGlsZWQgdGVtcGxhdGUuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIF8udGVtcGxhdGVTZXR0aW5nc1xuICAgICAgICogQHR5cGUge09iamVjdH1cbiAgICAgICAqL1xuICAgICAgJ2ltcG9ydHMnOiB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBgbG9kYXNoYCBmdW5jdGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogQG1lbWJlck9mIF8udGVtcGxhdGVTZXR0aW5ncy5pbXBvcnRzXG4gICAgICAgICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICAgICAgICovXG4gICAgICAgICdfJzogbG9kYXNoXG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIEVuc3VyZSB3cmFwcGVycyBhcmUgaW5zdGFuY2VzIG9mIGBiYXNlTG9kYXNoYC5cbiAgICBsb2Rhc2gucHJvdG90eXBlID0gYmFzZUxvZGFzaC5wcm90b3R5cGU7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGxvZGFzaDtcblxuICAgIExvZGFzaFdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG4gICAgTG9kYXNoV3JhcHBlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBMb2Rhc2hXcmFwcGVyO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGxhenkgd3JhcHBlciBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgbGF6eSBldmFsdWF0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIExhenlXcmFwcGVyKHZhbHVlKSB7XG4gICAgICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gICAgICB0aGlzLl9fYWN0aW9uc19fID0gW107XG4gICAgICB0aGlzLl9fZGlyX18gPSAxO1xuICAgICAgdGhpcy5fX2ZpbHRlcmVkX18gPSBmYWxzZTtcbiAgICAgIHRoaXMuX19pdGVyYXRlZXNfXyA9IFtdO1xuICAgICAgdGhpcy5fX3Rha2VDb3VudF9fID0gTUFYX0FSUkFZX0xFTkdUSDtcbiAgICAgIHRoaXMuX192aWV3c19fID0gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBsYXp5IHdyYXBwZXIgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBjbG9uZVxuICAgICAqIEBtZW1iZXJPZiBMYXp5V3JhcHBlclxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCBgTGF6eVdyYXBwZXJgIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXp5Q2xvbmUoKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IExhenlXcmFwcGVyKHRoaXMuX193cmFwcGVkX18pO1xuICAgICAgcmVzdWx0Ll9fYWN0aW9uc19fID0gY29weUFycmF5KHRoaXMuX19hY3Rpb25zX18pO1xuICAgICAgcmVzdWx0Ll9fZGlyX18gPSB0aGlzLl9fZGlyX187XG4gICAgICByZXN1bHQuX19maWx0ZXJlZF9fID0gdGhpcy5fX2ZpbHRlcmVkX187XG4gICAgICByZXN1bHQuX19pdGVyYXRlZXNfXyA9IGNvcHlBcnJheSh0aGlzLl9faXRlcmF0ZWVzX18pO1xuICAgICAgcmVzdWx0Ll9fdGFrZUNvdW50X18gPSB0aGlzLl9fdGFrZUNvdW50X187XG4gICAgICByZXN1bHQuX192aWV3c19fID0gY29weUFycmF5KHRoaXMuX192aWV3c19fKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV2ZXJzZXMgdGhlIGRpcmVjdGlvbiBvZiBsYXp5IGl0ZXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgcmV2ZXJzZVxuICAgICAqIEBtZW1iZXJPZiBMYXp5V3JhcHBlclxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyByZXZlcnNlZCBgTGF6eVdyYXBwZXJgIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXp5UmV2ZXJzZSgpIHtcbiAgICAgIGlmICh0aGlzLl9fZmlsdGVyZWRfXykge1xuICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgICByZXN1bHQuX19kaXJfXyA9IC0xO1xuICAgICAgICByZXN1bHQuX19maWx0ZXJlZF9fID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IHRoaXMuY2xvbmUoKTtcbiAgICAgICAgcmVzdWx0Ll9fZGlyX18gKj0gLTE7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHRoZSB1bndyYXBwZWQgdmFsdWUgZnJvbSBpdHMgbGF6eSB3cmFwcGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSB2YWx1ZVxuICAgICAqIEBtZW1iZXJPZiBMYXp5V3JhcHBlclxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB1bndyYXBwZWQgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGF6eVZhbHVlKCkge1xuICAgICAgdmFyIGFycmF5ID0gdGhpcy5fX3dyYXBwZWRfXy52YWx1ZSgpLFxuICAgICAgICAgIGRpciA9IHRoaXMuX19kaXJfXyxcbiAgICAgICAgICBpc0FyciA9IGlzQXJyYXkoYXJyYXkpLFxuICAgICAgICAgIGlzUmlnaHQgPSBkaXIgPCAwLFxuICAgICAgICAgIGFyckxlbmd0aCA9IGlzQXJyID8gYXJyYXkubGVuZ3RoIDogMCxcbiAgICAgICAgICB2aWV3ID0gZ2V0VmlldygwLCBhcnJMZW5ndGgsIHRoaXMuX192aWV3c19fKSxcbiAgICAgICAgICBzdGFydCA9IHZpZXcuc3RhcnQsXG4gICAgICAgICAgZW5kID0gdmlldy5lbmQsXG4gICAgICAgICAgbGVuZ3RoID0gZW5kIC0gc3RhcnQsXG4gICAgICAgICAgaW5kZXggPSBpc1JpZ2h0ID8gZW5kIDogKHN0YXJ0IC0gMSksXG4gICAgICAgICAgaXRlcmF0ZWVzID0gdGhpcy5fX2l0ZXJhdGVlc19fLFxuICAgICAgICAgIGl0ZXJMZW5ndGggPSBpdGVyYXRlZXMubGVuZ3RoLFxuICAgICAgICAgIHJlc0luZGV4ID0gMCxcbiAgICAgICAgICB0YWtlQ291bnQgPSBuYXRpdmVNaW4obGVuZ3RoLCB0aGlzLl9fdGFrZUNvdW50X18pO1xuXG4gICAgICBpZiAoIWlzQXJyIHx8ICghaXNSaWdodCAmJiBhcnJMZW5ndGggPT0gbGVuZ3RoICYmIHRha2VDb3VudCA9PSBsZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBiYXNlV3JhcHBlclZhbHVlKGFycmF5LCB0aGlzLl9fYWN0aW9uc19fKTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgICAgb3V0ZXI6XG4gICAgICB3aGlsZSAobGVuZ3RoLS0gJiYgcmVzSW5kZXggPCB0YWtlQ291bnQpIHtcbiAgICAgICAgaW5kZXggKz0gZGlyO1xuXG4gICAgICAgIHZhciBpdGVySW5kZXggPSAtMSxcbiAgICAgICAgICAgIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuXG4gICAgICAgIHdoaWxlICgrK2l0ZXJJbmRleCA8IGl0ZXJMZW5ndGgpIHtcbiAgICAgICAgICB2YXIgZGF0YSA9IGl0ZXJhdGVlc1tpdGVySW5kZXhdLFxuICAgICAgICAgICAgICBpdGVyYXRlZSA9IGRhdGEuaXRlcmF0ZWUsXG4gICAgICAgICAgICAgIHR5cGUgPSBkYXRhLnR5cGUsXG4gICAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUodmFsdWUpO1xuXG4gICAgICAgICAgaWYgKHR5cGUgPT0gTEFaWV9NQVBfRkxBRykge1xuICAgICAgICAgICAgdmFsdWUgPSBjb21wdXRlZDtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFjb21wdXRlZCkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gTEFaWV9GSUxURVJfRkxBRykge1xuICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIGBMYXp5V3JhcHBlcmAgaXMgYW4gaW5zdGFuY2Ugb2YgYGJhc2VMb2Rhc2hgLlxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZSA9IGJhc2VDcmVhdGUoYmFzZUxvZGFzaC5wcm90b3R5cGUpO1xuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExhenlXcmFwcGVyO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGhhc2ggb2JqZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBIYXNoKGVudHJpZXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgaGFzaC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgSGFzaFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc2hDbGVhcigpIHtcbiAgICAgIHRoaXMuX19kYXRhX18gPSBuYXRpdmVDcmVhdGUgPyBuYXRpdmVDcmVhdGUobnVsbCkgOiB7fTtcbiAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIGhhc2guXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGRlbGV0ZVxuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGhhc2ggVGhlIGhhc2ggdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNoRGVsZXRlKGtleSkge1xuICAgICAgdmFyIHJlc3VsdCA9IHRoaXMuaGFzKGtleSkgJiYgZGVsZXRlIHRoaXMuX19kYXRhX19ba2V5XTtcbiAgICAgIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgaGFzaCB2YWx1ZSBmb3IgYGtleWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGdldFxuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc2hHZXQoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gICAgICBpZiAobmF0aXZlQ3JlYXRlKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBkYXRhW2tleV07XG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IEhBU0hfVU5ERUZJTkVEID8gdW5kZWZpbmVkIDogcmVzdWx0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoZGF0YSwga2V5KSA/IGRhdGFba2V5XSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBoYXNoIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGhhc1xuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc2hIYXMoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gICAgICByZXR1cm4gbmF0aXZlQ3JlYXRlID8gKGRhdGFba2V5XSAhPT0gdW5kZWZpbmVkKSA6IGhhc093blByb3BlcnR5LmNhbGwoZGF0YSwga2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBoYXNoIGBrZXlgIHRvIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHNldFxuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGhhc2ggaW5zdGFuY2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaFNldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gICAgICB0aGlzLnNpemUgKz0gdGhpcy5oYXMoa2V5KSA/IDAgOiAxO1xuICAgICAgZGF0YVtrZXldID0gKG5hdGl2ZUNyZWF0ZSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkKSA/IEhBU0hfVU5ERUZJTkVEIDogdmFsdWU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgSGFzaGAuXG4gICAgSGFzaC5wcm90b3R5cGUuY2xlYXIgPSBoYXNoQ2xlYXI7XG4gICAgSGFzaC5wcm90b3R5cGVbJ2RlbGV0ZSddID0gaGFzaERlbGV0ZTtcbiAgICBIYXNoLnByb3RvdHlwZS5nZXQgPSBoYXNoR2V0O1xuICAgIEhhc2gucHJvdG90eXBlLmhhcyA9IGhhc2hIYXM7XG4gICAgSGFzaC5wcm90b3R5cGUuc2V0ID0gaGFzaFNldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gbGlzdCBjYWNoZSBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIExpc3RDYWNoZShlbnRyaWVzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7XG5cbiAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdO1xuICAgICAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIGxpc3QgY2FjaGUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGNsZWFyXG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZUNsZWFyKCkge1xuICAgICAgdGhpcy5fX2RhdGFfXyA9IFtdO1xuICAgICAgdGhpcy5zaXplID0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsaXN0Q2FjaGVEZWxldGUoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTtcblxuICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxO1xuICAgICAgaWYgKGluZGV4ID09IGxhc3RJbmRleCkge1xuICAgICAgICBkYXRhLnBvcCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3BsaWNlLmNhbGwoZGF0YSwgaW5kZXgsIDEpO1xuICAgICAgfVxuICAgICAgLS10aGlzLnNpemU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBsaXN0IGNhY2hlIHZhbHVlIGZvciBga2V5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZ2V0XG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsaXN0Q2FjaGVHZXQoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTtcblxuICAgICAgcmV0dXJuIGluZGV4IDwgMCA/IHVuZGVmaW5lZCA6IGRhdGFbaW5kZXhdWzFdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIGxpc3QgY2FjaGUgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsaXN0Q2FjaGVIYXMoa2V5KSB7XG4gICAgICByZXR1cm4gYXNzb2NJbmRleE9mKHRoaXMuX19kYXRhX18sIGtleSkgPiAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBsaXN0IGNhY2hlIGBrZXlgIHRvIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHNldFxuICAgICAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbGlzdCBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsaXN0Q2FjaGVTZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLFxuICAgICAgICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7XG5cbiAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgKyt0aGlzLnNpemU7XG4gICAgICAgIGRhdGEucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGF0YVtpbmRleF1bMV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBMaXN0Q2FjaGVgLlxuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBsaXN0Q2FjaGVDbGVhcjtcbiAgICBMaXN0Q2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IGxpc3RDYWNoZURlbGV0ZTtcbiAgICBMaXN0Q2FjaGUucHJvdG90eXBlLmdldCA9IGxpc3RDYWNoZUdldDtcbiAgICBMaXN0Q2FjaGUucHJvdG90eXBlLmhhcyA9IGxpc3RDYWNoZUhhcztcbiAgICBMaXN0Q2FjaGUucHJvdG90eXBlLnNldCA9IGxpc3RDYWNoZVNldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBtYXAgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gTWFwQ2FjaGUoZW50cmllcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICAgICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGNsZWFyXG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFwQ2FjaGVDbGVhcigpIHtcbiAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgICB0aGlzLl9fZGF0YV9fID0ge1xuICAgICAgICAnaGFzaCc6IG5ldyBIYXNoLFxuICAgICAgICAnbWFwJzogbmV3IChNYXAgfHwgTGlzdENhY2hlKSxcbiAgICAgICAgJ3N0cmluZyc6IG5ldyBIYXNoXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGRlbGV0ZVxuICAgICAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZURlbGV0ZShrZXkpIHtcbiAgICAgIHZhciByZXN1bHQgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSlbJ2RlbGV0ZSddKGtleSk7XG4gICAgICB0aGlzLnNpemUgLT0gcmVzdWx0ID8gMSA6IDA7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG1hcCB2YWx1ZSBmb3IgYGtleWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGdldFxuICAgICAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZUdldChrZXkpIHtcbiAgICAgIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuZ2V0KGtleSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgbWFwIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGhhc1xuICAgICAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZUhhcyhrZXkpIHtcbiAgICAgIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuaGFzKGtleSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgbWFwIGBrZXlgIHRvIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHNldFxuICAgICAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBtYXAgY2FjaGUgaW5zdGFuY2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFwQ2FjaGVTZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgdmFyIGRhdGEgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSksXG4gICAgICAgICAgc2l6ZSA9IGRhdGEuc2l6ZTtcblxuICAgICAgZGF0YS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBNYXBDYWNoZWAuXG4gICAgTWFwQ2FjaGUucHJvdG90eXBlLmNsZWFyID0gbWFwQ2FjaGVDbGVhcjtcbiAgICBNYXBDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbWFwQ2FjaGVEZWxldGU7XG4gICAgTWFwQ2FjaGUucHJvdG90eXBlLmdldCA9IG1hcENhY2hlR2V0O1xuICAgIE1hcENhY2hlLnByb3RvdHlwZS5oYXMgPSBtYXBDYWNoZUhhcztcbiAgICBNYXBDYWNoZS5wcm90b3R5cGUuc2V0ID0gbWFwQ2FjaGVTZXQ7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIHVuaXF1ZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gU2V0Q2FjaGUodmFsdWVzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSB2YWx1ZXMgPT0gbnVsbCA/IDAgOiB2YWx1ZXMubGVuZ3RoO1xuXG4gICAgICB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdGhpcy5hZGQodmFsdWVzW2luZGV4XSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBgdmFsdWVgIHRvIHRoZSBhcnJheSBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgYWRkXG4gICAgICogQG1lbWJlck9mIFNldENhY2hlXG4gICAgICogQGFsaWFzIHB1c2hcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjYWNoZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXRDYWNoZUFkZCh2YWx1ZSkge1xuICAgICAgdGhpcy5fX2RhdGFfXy5zZXQodmFsdWUsIEhBU0hfVU5ERUZJTkVEKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGluIHRoZSBhcnJheSBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIFNldENhY2hlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2V0Q2FjaGVIYXModmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fZGF0YV9fLmhhcyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYFNldENhY2hlYC5cbiAgICBTZXRDYWNoZS5wcm90b3R5cGUuYWRkID0gU2V0Q2FjaGUucHJvdG90eXBlLnB1c2ggPSBzZXRDYWNoZUFkZDtcbiAgICBTZXRDYWNoZS5wcm90b3R5cGUuaGFzID0gc2V0Q2FjaGVIYXM7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc3RhY2sgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gU3RhY2soZW50cmllcykge1xuICAgICAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZShlbnRyaWVzKTtcbiAgICAgIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBzdGFjay5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja0NsZWFyKCkge1xuICAgICAgdGhpcy5fX2RhdGFfXyA9IG5ldyBMaXN0Q2FjaGU7XG4gICAgICB0aGlzLnNpemUgPSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBzdGFjay5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIFN0YWNrXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0YWNrRGVsZXRlKGtleSkge1xuICAgICAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLFxuICAgICAgICAgIHJlc3VsdCA9IGRhdGFbJ2RlbGV0ZSddKGtleSk7XG5cbiAgICAgIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgc3RhY2sgdmFsdWUgZm9yIGBrZXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBnZXRcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhY2tHZXQoa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2RhdGFfXy5nZXQoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBzdGFjayB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBoYXNcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhY2tIYXMoa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXMoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBzdGFjayBga2V5YCB0byBgdmFsdWVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBzZXRcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgc3RhY2sgY2FjaGUgaW5zdGFuY2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhY2tTZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBMaXN0Q2FjaGUpIHtcbiAgICAgICAgdmFyIHBhaXJzID0gZGF0YS5fX2RhdGFfXztcbiAgICAgICAgaWYgKCFNYXAgfHwgKHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSkge1xuICAgICAgICAgIHBhaXJzLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgICAgICAgICB0aGlzLnNpemUgPSArK2RhdGEuc2l6ZTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gdGhpcy5fX2RhdGFfXyA9IG5ldyBNYXBDYWNoZShwYWlycyk7XG4gICAgICB9XG4gICAgICBkYXRhLnNldChrZXksIHZhbHVlKTtcbiAgICAgIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBTdGFja2AuXG4gICAgU3RhY2sucHJvdG90eXBlLmNsZWFyID0gc3RhY2tDbGVhcjtcbiAgICBTdGFjay5wcm90b3R5cGVbJ2RlbGV0ZSddID0gc3RhY2tEZWxldGU7XG4gICAgU3RhY2sucHJvdG90eXBlLmdldCA9IHN0YWNrR2V0O1xuICAgIFN0YWNrLnByb3RvdHlwZS5oYXMgPSBzdGFja0hhcztcbiAgICBTdGFjay5wcm90b3R5cGUuc2V0ID0gc3RhY2tTZXQ7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIHRoZSBhcnJheS1saWtlIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gaW5oZXJpdGVkIFNwZWNpZnkgcmV0dXJuaW5nIGluaGVyaXRlZCBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFycmF5TGlrZUtleXModmFsdWUsIGluaGVyaXRlZCkge1xuICAgICAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSksXG4gICAgICAgICAgaXNBcmcgPSAhaXNBcnIgJiYgaXNBcmd1bWVudHModmFsdWUpLFxuICAgICAgICAgIGlzQnVmZiA9ICFpc0FyciAmJiAhaXNBcmcgJiYgaXNCdWZmZXIodmFsdWUpLFxuICAgICAgICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkodmFsdWUpLFxuICAgICAgICAgIHNraXBJbmRleGVzID0gaXNBcnIgfHwgaXNBcmcgfHwgaXNCdWZmIHx8IGlzVHlwZSxcbiAgICAgICAgICByZXN1bHQgPSBza2lwSW5kZXhlcyA/IGJhc2VUaW1lcyh2YWx1ZS5sZW5ndGgsIFN0cmluZykgOiBbXSxcbiAgICAgICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gdmFsdWUpIHtcbiAgICAgICAgaWYgKChpbmhlcml0ZWQgfHwgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwga2V5KSkgJiZcbiAgICAgICAgICAgICEoc2tpcEluZGV4ZXMgJiYgKFxuICAgICAgICAgICAgICAgLy8gU2FmYXJpIDkgaGFzIGVudW1lcmFibGUgYGFyZ3VtZW50cy5sZW5ndGhgIGluIHN0cmljdCBtb2RlLlxuICAgICAgICAgICAgICAga2V5ID09ICdsZW5ndGgnIHx8XG4gICAgICAgICAgICAgICAvLyBOb2RlLmpzIDAuMTAgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gYnVmZmVycy5cbiAgICAgICAgICAgICAgIChpc0J1ZmYgJiYgKGtleSA9PSAnb2Zmc2V0JyB8fCBrZXkgPT0gJ3BhcmVudCcpKSB8fFxuICAgICAgICAgICAgICAgLy8gUGhhbnRvbUpTIDIgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gdHlwZWQgYXJyYXlzLlxuICAgICAgICAgICAgICAgKGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykpIHx8XG4gICAgICAgICAgICAgICAvLyBTa2lwIGluZGV4IHByb3BlcnRpZXMuXG4gICAgICAgICAgICAgICBpc0luZGV4KGtleSwgbGVuZ3RoKVxuICAgICAgICAgICAgKSkpIHtcbiAgICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zYW1wbGVgIGZvciBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJhbmRvbSBlbGVtZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFycmF5U2FtcGxlKGFycmF5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGFycmF5W2Jhc2VSYW5kb20oMCwgbGVuZ3RoIC0gMSldIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zYW1wbGVTaXplYCBmb3IgYXJyYXlzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2FtcGxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gc2FtcGxlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFycmF5U2FtcGxlU2l6ZShhcnJheSwgbikge1xuICAgICAgcmV0dXJuIHNodWZmbGVTZWxmKGNvcHlBcnJheShhcnJheSksIGJhc2VDbGFtcChuLCAwLCBhcnJheS5sZW5ndGgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc2h1ZmZsZWAgZm9yIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNodWZmbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc2h1ZmZsZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlTaHVmZmxlKGFycmF5KSB7XG4gICAgICByZXR1cm4gc2h1ZmZsZVNlbGYoY29weUFycmF5KGFycmF5KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBhc3NpZ25WYWx1ZWAgZXhjZXB0IHRoYXQgaXQgZG9lc24ndCBhc3NpZ25cbiAgICAgKiBgdW5kZWZpbmVkYCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBhc3NpZ24uXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICBpZiAoKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgIWVxKG9iamVjdFtrZXldLCB2YWx1ZSkpIHx8XG4gICAgICAgICAgKHZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkpIHtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXNzaWducyBgdmFsdWVgIHRvIGBrZXlgIG9mIGBvYmplY3RgIGlmIHRoZSBleGlzdGluZyB2YWx1ZSBpcyBub3QgZXF1aXZhbGVudFxuICAgICAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldO1xuICAgICAgaWYgKCEoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkgJiYgZXEob2JqVmFsdWUsIHZhbHVlKSkgfHxcbiAgICAgICAgICAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSkge1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgYGtleWAgaXMgZm91bmQgaW4gYGFycmF5YCBvZiBrZXktdmFsdWUgcGFpcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0ga2V5IFRoZSBrZXkgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFzc29jSW5kZXhPZihhcnJheSwga2V5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGlmIChlcShhcnJheVtsZW5ndGhdWzBdLCBrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuIGxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFnZ3JlZ2F0ZXMgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gIG9uIGBhY2N1bXVsYXRvcmAgd2l0aCBrZXlzIHRyYW5zZm9ybWVkXG4gICAgICogYnkgYGl0ZXJhdGVlYCBhbmQgdmFsdWVzIHNldCBieSBgc2V0dGVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHNldHRlciBUaGUgZnVuY3Rpb24gdG8gc2V0IGBhY2N1bXVsYXRvcmAgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgYWdncmVnYXRlZCBvYmplY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBhY2N1bXVsYXRvcmAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUFnZ3JlZ2F0b3IoY29sbGVjdGlvbiwgc2V0dGVyLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgc2V0dGVyKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaXRlcmF0ZWUodmFsdWUpLCBjb2xsZWN0aW9uKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmFzc2lnbmAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzXG4gICAgICogb3IgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzKHNvdXJjZSksIG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduSW5gIHdpdGhvdXQgc3VwcG9ydCBmb3IgbXVsdGlwbGUgc291cmNlc1xuICAgICAqIG9yIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUFzc2lnbkluKG9iamVjdCwgc291cmNlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzSW4oc291cmNlKSwgb2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgYXNzaWduVmFsdWVgIGFuZCBgYXNzaWduTWVyZ2VWYWx1ZWAgd2l0aG91dFxuICAgICAqIHZhbHVlIGNoZWNrcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBhc3NpZ24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgICAgaWYgKGtleSA9PSAnX19wcm90b19fJyAmJiBkZWZpbmVQcm9wZXJ0eSkge1xuICAgICAgICBkZWZpbmVQcm9wZXJ0eShvYmplY3QsIGtleSwge1xuICAgICAgICAgICdjb25maWd1cmFibGUnOiB0cnVlLFxuICAgICAgICAgICdlbnVtZXJhYmxlJzogdHJ1ZSxcbiAgICAgICAgICAndmFsdWUnOiB2YWx1ZSxcbiAgICAgICAgICAnd3JpdGFibGUnOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hdGAgd2l0aG91dCBzdXBwb3J0IGZvciBpbmRpdmlkdWFsIHBhdGhzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGhzIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcGlja2VkIGVsZW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VBdChvYmplY3QsIHBhdGhzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYXRocy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgICBza2lwID0gb2JqZWN0ID09IG51bGw7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtpbmRleF0gPSBza2lwID8gdW5kZWZpbmVkIDogZ2V0KG9iamVjdCwgcGF0aHNbaW5kZXhdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY2xhbXBgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIGNsYW1wLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbG93ZXJdIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXBwZXIgVGhlIHVwcGVyIGJvdW5kLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNsYW1wZWQgbnVtYmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VDbGFtcChudW1iZXIsIGxvd2VyLCB1cHBlcikge1xuICAgICAgaWYgKG51bWJlciA9PT0gbnVtYmVyKSB7XG4gICAgICAgIGlmICh1cHBlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbnVtYmVyID0gbnVtYmVyIDw9IHVwcGVyID8gbnVtYmVyIDogdXBwZXI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxvd2VyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBudW1iZXIgPSBudW1iZXIgPj0gbG93ZXIgPyBudW1iZXIgOiBsb3dlcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgYW5kIGBfLmNsb25lRGVlcGAgd2hpY2ggdHJhY2tzXG4gICAgICogdHJhdmVyc2VkIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAgICAgKiAgMSAtIERlZXAgY2xvbmVcbiAgICAgKiAgMiAtIEZsYXR0ZW4gaW5oZXJpdGVkIHByb3BlcnRpZXNcbiAgICAgKiAgNCAtIENsb25lIHN5bWJvbHNcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjbG9uaW5nLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBba2V5XSBUaGUga2V5IG9mIGB2YWx1ZWAuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBwYXJlbnQgb2JqZWN0IG9mIGB2YWx1ZWAuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGFuZCB0aGVpciBjbG9uZSBjb3VudGVycGFydHMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGtleSwgb2JqZWN0LCBzdGFjaykge1xuICAgICAgdmFyIHJlc3VsdCxcbiAgICAgICAgICBpc0RlZXAgPSBiaXRtYXNrICYgQ0xPTkVfREVFUF9GTEFHLFxuICAgICAgICAgIGlzRmxhdCA9IGJpdG1hc2sgJiBDTE9ORV9GTEFUX0ZMQUcsXG4gICAgICAgICAgaXNGdWxsID0gYml0bWFzayAmIENMT05FX1NZTUJPTFNfRkxBRztcblxuICAgICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QsIHN0YWNrKSA6IGN1c3RvbWl6ZXIodmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKTtcbiAgICAgIGlmIChpc0Fycikge1xuICAgICAgICByZXN1bHQgPSBpbml0Q2xvbmVBcnJheSh2YWx1ZSk7XG4gICAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgICAgcmV0dXJuIGNvcHlBcnJheSh2YWx1ZSwgcmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHRhZyA9IGdldFRhZyh2YWx1ZSksXG4gICAgICAgICAgICBpc0Z1bmMgPSB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnO1xuXG4gICAgICAgIGlmIChpc0J1ZmZlcih2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gY2xvbmVCdWZmZXIodmFsdWUsIGlzRGVlcCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhZyA9PSBvYmplY3RUYWcgfHwgdGFnID09IGFyZ3NUYWcgfHwgKGlzRnVuYyAmJiAhb2JqZWN0KSkge1xuICAgICAgICAgIHJlc3VsdCA9IChpc0ZsYXQgfHwgaXNGdW5jKSA/IHt9IDogaW5pdENsb25lT2JqZWN0KHZhbHVlKTtcbiAgICAgICAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgICAgICAgcmV0dXJuIGlzRmxhdFxuICAgICAgICAgICAgICA/IGNvcHlTeW1ib2xzSW4odmFsdWUsIGJhc2VBc3NpZ25JbihyZXN1bHQsIHZhbHVlKSlcbiAgICAgICAgICAgICAgOiBjb3B5U3ltYm9scyh2YWx1ZSwgYmFzZUFzc2lnbihyZXN1bHQsIHZhbHVlKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICghY2xvbmVhYmxlVGFnc1t0YWddKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0ID8gdmFsdWUgOiB7fTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0ID0gaW5pdENsb25lQnlUYWcodmFsdWUsIHRhZywgaXNEZWVwKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gQ2hlY2sgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgYW5kIHJldHVybiBpdHMgY29ycmVzcG9uZGluZyBjbG9uZS5cbiAgICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjayk7XG4gICAgICB2YXIgc3RhY2tlZCA9IHN0YWNrLmdldCh2YWx1ZSk7XG4gICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICByZXR1cm4gc3RhY2tlZDtcbiAgICAgIH1cbiAgICAgIHN0YWNrLnNldCh2YWx1ZSwgcmVzdWx0KTtcblxuICAgICAgaWYgKGlzU2V0KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHN1YlZhbHVlKSB7XG4gICAgICAgICAgcmVzdWx0LmFkZChiYXNlQ2xvbmUoc3ViVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN1YlZhbHVlLCB2YWx1ZSwgc3RhY2spKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGlzTWFwKHZhbHVlKSkge1xuICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICAgICAgICByZXN1bHQuc2V0KGtleSwgYmFzZUNsb25lKHN1YlZhbHVlLCBiaXRtYXNrLCBjdXN0b21pemVyLCBrZXksIHZhbHVlLCBzdGFjaykpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdmFyIGtleXNGdW5jID0gaXNGdWxsXG4gICAgICAgID8gKGlzRmxhdCA/IGdldEFsbEtleXNJbiA6IGdldEFsbEtleXMpXG4gICAgICAgIDogKGlzRmxhdCA/IGtleXNJbiA6IGtleXMpO1xuXG4gICAgICB2YXIgcHJvcHMgPSBpc0FyciA/IHVuZGVmaW5lZCA6IGtleXNGdW5jKHZhbHVlKTtcbiAgICAgIGFycmF5RWFjaChwcm9wcyB8fCB2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgICAgICBpZiAocHJvcHMpIHtcbiAgICAgICAgICBrZXkgPSBzdWJWYWx1ZTtcbiAgICAgICAgICBzdWJWYWx1ZSA9IHZhbHVlW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgcG9wdWxhdGUgY2xvbmUgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgYXNzaWduVmFsdWUocmVzdWx0LCBrZXksIGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCB2YWx1ZSwgc3RhY2spKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jb25mb3Jtc2Agd2hpY2ggZG9lc24ndCBjbG9uZSBgc291cmNlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHByZWRpY2F0ZXMgdG8gY29uZm9ybSB0by5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VDb25mb3Jtcyhzb3VyY2UpIHtcbiAgICAgIHZhciBwcm9wcyA9IGtleXMoc291cmNlKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VDb25mb3Jtc1RvKG9iamVjdCwgc291cmNlLCBwcm9wcyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNvbmZvcm1zVG9gIHdoaWNoIGFjY2VwdHMgYHByb3BzYCB0byBjaGVjay5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHByZWRpY2F0ZXMgdG8gY29uZm9ybSB0by5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgY29uZm9ybXMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQ29uZm9ybXNUbyhvYmplY3QsIHNvdXJjZSwgcHJvcHMpIHtcbiAgICAgIHZhciBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICFsZW5ndGg7XG4gICAgICB9XG4gICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICB2YXIga2V5ID0gcHJvcHNbbGVuZ3RoXSxcbiAgICAgICAgICAgIHByZWRpY2F0ZSA9IHNvdXJjZVtrZXldLFxuICAgICAgICAgICAgdmFsdWUgPSBvYmplY3Rba2V5XTtcblxuICAgICAgICBpZiAoKHZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkgfHwgIXByZWRpY2F0ZSh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmRlbGF5YCBhbmQgYF8uZGVmZXJgIHdoaWNoIGFjY2VwdHMgYGFyZ3NgXG4gICAgICogdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlbGF5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB3YWl0IFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5IGludm9jYXRpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJncyBUaGUgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ8T2JqZWN0fSBSZXR1cm5zIHRoZSB0aW1lciBpZCBvciB0aW1lb3V0IG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRGVsYXkoZnVuYywgd2FpdCwgYXJncykge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGZ1bmMuYXBwbHkodW5kZWZpbmVkLCBhcmdzKTsgfSwgd2FpdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLmRpZmZlcmVuY2VgIHdpdGhvdXQgc3VwcG9ydFxuICAgICAqIGZvciBleGNsdWRpbmcgbXVsdGlwbGUgYXJyYXlzIG9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZURpZmZlcmVuY2UoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGluY2x1ZGVzID0gYXJyYXlJbmNsdWRlcyxcbiAgICAgICAgICBpc0NvbW1vbiA9IHRydWUsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IFtdLFxuICAgICAgICAgIHZhbHVlc0xlbmd0aCA9IHZhbHVlcy5sZW5ndGg7XG5cbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBpZiAoaXRlcmF0ZWUpIHtcbiAgICAgICAgdmFsdWVzID0gYXJyYXlNYXAodmFsdWVzLCBiYXNlVW5hcnkoaXRlcmF0ZWUpKTtcbiAgICAgIH1cbiAgICAgIGlmIChjb21wYXJhdG9yKSB7XG4gICAgICAgIGluY2x1ZGVzID0gYXJyYXlJbmNsdWRlc1dpdGg7XG4gICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBlbHNlIGlmICh2YWx1ZXMubGVuZ3RoID49IExBUkdFX0FSUkFZX1NJWkUpIHtcbiAgICAgICAgaW5jbHVkZXMgPSBjYWNoZUhhcztcbiAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgdmFsdWVzID0gbmV3IFNldENhY2hlKHZhbHVlcyk7XG4gICAgICB9XG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPT0gbnVsbCA/IHZhbHVlIDogaXRlcmF0ZWUodmFsdWUpO1xuXG4gICAgICAgIHZhbHVlID0gKGNvbXBhcmF0b3IgfHwgdmFsdWUgIT09IDApID8gdmFsdWUgOiAwO1xuICAgICAgICBpZiAoaXNDb21tb24gJiYgY29tcHV0ZWQgPT09IGNvbXB1dGVkKSB7XG4gICAgICAgICAgdmFyIHZhbHVlc0luZGV4ID0gdmFsdWVzTGVuZ3RoO1xuICAgICAgICAgIHdoaWxlICh2YWx1ZXNJbmRleC0tKSB7XG4gICAgICAgICAgICBpZiAodmFsdWVzW3ZhbHVlc0luZGV4XSA9PT0gY29tcHV0ZWQpIHtcbiAgICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghaW5jbHVkZXModmFsdWVzLCBjb21wdXRlZCwgY29tcGFyYXRvcikpIHtcbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yRWFjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUVhY2ggPSBjcmVhdGVCYXNlRWFjaChiYXNlRm9yT3duKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckVhY2hSaWdodGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUVhY2hSaWdodCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd25SaWdodCwgdHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5ldmVyeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFsbCBlbGVtZW50cyBwYXNzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VFdmVyeShjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0cnVlO1xuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJlc3VsdCA9ICEhcHJlZGljYXRlKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLm1heGAgYW5kIGBfLm1pbmAgd2hpY2ggYWNjZXB0cyBhXG4gICAgICogYGNvbXBhcmF0b3JgIHRvIGRldGVybWluZSB0aGUgZXh0cmVtdW0gdmFsdWUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJhdG9yIFRoZSBjb21wYXJhdG9yIHVzZWQgdG8gY29tcGFyZSB2YWx1ZXMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGV4dHJlbXVtIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VFeHRyZW11bShhcnJheSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY3VycmVudCA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICAgICAgICBpZiAoY3VycmVudCAhPSBudWxsICYmIChjb21wdXRlZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gKGN1cnJlbnQgPT09IGN1cnJlbnQgJiYgIWlzU3ltYm9sKGN1cnJlbnQpKVxuICAgICAgICAgICAgICA6IGNvbXBhcmF0b3IoY3VycmVudCwgY29tcHV0ZWQpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgdmFyIGNvbXB1dGVkID0gY3VycmVudCxcbiAgICAgICAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmlsbGAgd2l0aG91dCBhbiBpdGVyYXRlZSBjYWxsIGd1YXJkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmlsbC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBmaWxsIGBhcnJheWAgd2l0aC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBwb3NpdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZpbGwoYXJyYXksIHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICBzdGFydCA9IHRvSW50ZWdlcihzdGFydCk7XG4gICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgIHN0YXJ0ID0gLXN0YXJ0ID4gbGVuZ3RoID8gMCA6IChsZW5ndGggKyBzdGFydCk7XG4gICAgICB9XG4gICAgICBlbmQgPSAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gbGVuZ3RoKSA/IGxlbmd0aCA6IHRvSW50ZWdlcihlbmQpO1xuICAgICAgaWYgKGVuZCA8IDApIHtcbiAgICAgICAgZW5kICs9IGxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGVuZCA9IHN0YXJ0ID4gZW5kID8gMCA6IHRvTGVuZ3RoKGVuZCk7XG4gICAgICB3aGlsZSAoc3RhcnQgPCBlbmQpIHtcbiAgICAgICAgYXJyYXlbc3RhcnQrK10gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maWx0ZXJgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGaWx0ZXIoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmxhdHRlbmAgd2l0aCBzdXBwb3J0IGZvciByZXN0cmljdGluZyBmbGF0dGVuaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGVwdGggVGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3ByZWRpY2F0ZT1pc0ZsYXR0ZW5hYmxlXSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzU3RyaWN0XSBSZXN0cmljdCB0byB2YWx1ZXMgdGhhdCBwYXNzIGBwcmVkaWNhdGVgIGNoZWNrcy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcmVzdWx0PVtdXSBUaGUgaW5pdGlhbCByZXN1bHQgdmFsdWUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGbGF0dGVuKGFycmF5LCBkZXB0aCwgcHJlZGljYXRlLCBpc1N0cmljdCwgcmVzdWx0KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHByZWRpY2F0ZSB8fCAocHJlZGljYXRlID0gaXNGbGF0dGVuYWJsZSk7XG4gICAgICByZXN1bHQgfHwgKHJlc3VsdCA9IFtdKTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgICAgICBpZiAoZGVwdGggPiAwICYmIHByZWRpY2F0ZSh2YWx1ZSkpIHtcbiAgICAgICAgICBpZiAoZGVwdGggPiAxKSB7XG4gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBmbGF0dGVuIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICAgICAgYmFzZUZsYXR0ZW4odmFsdWUsIGRlcHRoIC0gMSwgcHJlZGljYXRlLCBpc1N0cmljdCwgcmVzdWx0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXJyYXlQdXNoKHJlc3VsdCwgdmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghaXNTdHJpY3QpIHtcbiAgICAgICAgICByZXN1bHRbcmVzdWx0Lmxlbmd0aF0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgYmFzZUZvck93bmAgd2hpY2ggaXRlcmF0ZXMgb3ZlciBgb2JqZWN0YFxuICAgICAqIHByb3BlcnRpZXMgcmV0dXJuZWQgYnkgYGtleXNGdW5jYCBhbmQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIHByb3BlcnR5LlxuICAgICAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUZvciA9IGNyZWF0ZUJhc2VGb3IoKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgbGlrZSBgYmFzZUZvcmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBwcm9wZXJ0aWVzXG4gICAgICogaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIHZhciBiYXNlRm9yUmlnaHQgPSBjcmVhdGVCYXNlRm9yKHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGb3JPd24ob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAmJiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93blJpZ2h0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGb3JPd25SaWdodChvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGJhc2VGb3JSaWdodChvYmplY3QsIGl0ZXJhdGVlLCBrZXlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mdW5jdGlvbnNgIHdoaWNoIGNyZWF0ZXMgYW4gYXJyYXkgb2ZcbiAgICAgKiBgb2JqZWN0YCBmdW5jdGlvbiBwcm9wZXJ0eSBuYW1lcyBmaWx0ZXJlZCBmcm9tIGBwcm9wc2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBmaWx0ZXIuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRnVuY3Rpb25zKG9iamVjdCwgcHJvcHMpIHtcbiAgICAgIHJldHVybiBhcnJheUZpbHRlcihwcm9wcywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKG9iamVjdFtrZXldKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWZhdWx0IHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoKSB7XG4gICAgICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcblxuICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdCA9IG9iamVjdFt0b0tleShwYXRoW2luZGV4KytdKV07XG4gICAgICB9XG4gICAgICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldEFsbEtleXNgIGFuZCBgZ2V0QWxsS2V5c0luYCB3aGljaCB1c2VzXG4gICAgICogYGtleXNGdW5jYCBhbmQgYHN5bWJvbHNGdW5jYCB0byBnZXQgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gICAgICogc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc3ltYm9sc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5c0Z1bmMsIHN5bWJvbHNGdW5jKSB7XG4gICAgICB2YXIgcmVzdWx0ID0ga2V5c0Z1bmMob2JqZWN0KTtcbiAgICAgIHJldHVybiBpc0FycmF5KG9iamVjdCkgPyByZXN1bHQgOiBhcnJheVB1c2gocmVzdWx0LCBzeW1ib2xzRnVuYyhvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgZ2V0VGFnYCB3aXRob3V0IGZhbGxiYWNrcyBmb3IgYnVnZ3kgZW52aXJvbm1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBgdG9TdHJpbmdUYWdgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VHZXRUYWcodmFsdWUpIHtcbiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkVGFnIDogbnVsbFRhZztcbiAgICAgIH1cbiAgICAgIHJldHVybiAoc3ltVG9TdHJpbmdUYWcgJiYgc3ltVG9TdHJpbmdUYWcgaW4gT2JqZWN0KHZhbHVlKSlcbiAgICAgICAgPyBnZXRSYXdUYWcodmFsdWUpXG4gICAgICAgIDogb2JqZWN0VG9TdHJpbmcodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmd0YCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBncmVhdGVyIHRoYW4gYG90aGVyYCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VHdCh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA+IG90aGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmhhc2Agd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30ga2V5IFRoZSBrZXkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VIYXMob2JqZWN0LCBrZXkpIHtcbiAgICAgIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5oYXNJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30ga2V5IFRoZSBrZXkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VIYXNJbihvYmplY3QsIGtleSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGtleSBpbiBPYmplY3Qob2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pblJhbmdlYCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgbnVtYmVyYCBpcyBpbiB0aGUgcmFuZ2UsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSW5SYW5nZShudW1iZXIsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHJldHVybiBudW1iZXIgPj0gbmF0aXZlTWluKHN0YXJ0LCBlbmQpICYmIG51bWJlciA8IG5hdGl2ZU1heChzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8uaW50ZXJzZWN0aW9uYCwgd2l0aG91dCBzdXBwb3J0XG4gICAgICogZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMsIHRoYXQgYWNjZXB0cyBhbiBhcnJheSBvZiBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXlzIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHNoYXJlZCB2YWx1ZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUludGVyc2VjdGlvbihhcnJheXMsIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgaW5jbHVkZXMgPSBjb21wYXJhdG9yID8gYXJyYXlJbmNsdWRlc1dpdGggOiBhcnJheUluY2x1ZGVzLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5c1swXS5sZW5ndGgsXG4gICAgICAgICAgb3RoTGVuZ3RoID0gYXJyYXlzLmxlbmd0aCxcbiAgICAgICAgICBvdGhJbmRleCA9IG90aExlbmd0aCxcbiAgICAgICAgICBjYWNoZXMgPSBBcnJheShvdGhMZW5ndGgpLFxuICAgICAgICAgIG1heExlbmd0aCA9IEluZmluaXR5LFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICB3aGlsZSAob3RoSW5kZXgtLSkge1xuICAgICAgICB2YXIgYXJyYXkgPSBhcnJheXNbb3RoSW5kZXhdO1xuICAgICAgICBpZiAob3RoSW5kZXggJiYgaXRlcmF0ZWUpIHtcbiAgICAgICAgICBhcnJheSA9IGFycmF5TWFwKGFycmF5LCBiYXNlVW5hcnkoaXRlcmF0ZWUpKTtcbiAgICAgICAgfVxuICAgICAgICBtYXhMZW5ndGggPSBuYXRpdmVNaW4oYXJyYXkubGVuZ3RoLCBtYXhMZW5ndGgpO1xuICAgICAgICBjYWNoZXNbb3RoSW5kZXhdID0gIWNvbXBhcmF0b3IgJiYgKGl0ZXJhdGVlIHx8IChsZW5ndGggPj0gMTIwICYmIGFycmF5Lmxlbmd0aCA+PSAxMjApKVxuICAgICAgICAgID8gbmV3IFNldENhY2hlKG90aEluZGV4ICYmIGFycmF5KVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgYXJyYXkgPSBhcnJheXNbMF07XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIHNlZW4gPSBjYWNoZXNbMF07XG5cbiAgICAgIG91dGVyOlxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGggJiYgcmVzdWx0Lmxlbmd0aCA8IG1heExlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID8gaXRlcmF0ZWUodmFsdWUpIDogdmFsdWU7XG5cbiAgICAgICAgdmFsdWUgPSAoY29tcGFyYXRvciB8fCB2YWx1ZSAhPT0gMCkgPyB2YWx1ZSA6IDA7XG4gICAgICAgIGlmICghKHNlZW5cbiAgICAgICAgICAgICAgPyBjYWNoZUhhcyhzZWVuLCBjb21wdXRlZClcbiAgICAgICAgICAgICAgOiBpbmNsdWRlcyhyZXN1bHQsIGNvbXB1dGVkLCBjb21wYXJhdG9yKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIG90aEluZGV4ID0gb3RoTGVuZ3RoO1xuICAgICAgICAgIHdoaWxlICgtLW90aEluZGV4KSB7XG4gICAgICAgICAgICB2YXIgY2FjaGUgPSBjYWNoZXNbb3RoSW5kZXhdO1xuICAgICAgICAgICAgaWYgKCEoY2FjaGVcbiAgICAgICAgICAgICAgICAgID8gY2FjaGVIYXMoY2FjaGUsIGNvbXB1dGVkKVxuICAgICAgICAgICAgICAgICAgOiBpbmNsdWRlcyhhcnJheXNbb3RoSW5kZXhdLCBjb21wdXRlZCwgY29tcGFyYXRvcikpXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc2Vlbikge1xuICAgICAgICAgICAgc2Vlbi5wdXNoKGNvbXB1dGVkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmludmVydGAgYW5kIGBfLmludmVydEJ5YCB3aGljaCBpbnZlcnRzXG4gICAgICogYG9iamVjdGAgd2l0aCB2YWx1ZXMgdHJhbnNmb3JtZWQgYnkgYGl0ZXJhdGVlYCBhbmQgc2V0IGJ5IGBzZXR0ZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHNldHRlciBUaGUgZnVuY3Rpb24gdG8gc2V0IGBhY2N1bXVsYXRvcmAgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0gdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBhY2N1bXVsYXRvciBUaGUgaW5pdGlhbCBpbnZlcnRlZCBvYmplY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBhY2N1bXVsYXRvcmAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUludmVydGVyKG9iamVjdCwgc2V0dGVyLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICAgIGJhc2VGb3JPd24ob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgICAgc2V0dGVyKGFjY3VtdWxhdG9yLCBpdGVyYXRlZSh2YWx1ZSksIGtleSwgb2JqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmludm9rZWAgd2l0aG91dCBzdXBwb3J0IGZvciBpbmRpdmlkdWFsXG4gICAgICogbWV0aG9kIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIGludm9rZWQgbWV0aG9kLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJbnZva2Uob2JqZWN0LCBwYXRoLCBhcmdzKSB7XG4gICAgICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHBhcmVudChvYmplY3QsIHBhdGgpO1xuICAgICAgdmFyIGZ1bmMgPSBvYmplY3QgPT0gbnVsbCA/IG9iamVjdCA6IG9iamVjdFt0b0tleShsYXN0KHBhdGgpKV07XG4gICAgICByZXR1cm4gZnVuYyA9PSBudWxsID8gdW5kZWZpbmVkIDogYXBwbHkoZnVuYywgb2JqZWN0LCBhcmdzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0FyZ3VtZW50c2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGBhcmd1bWVudHNgIG9iamVjdCxcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNBcmd1bWVudHModmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGFyZ3NUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNBcnJheUJ1ZmZlcmAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5IGJ1ZmZlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0FycmF5QnVmZmVyKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBhcnJheUJ1ZmZlclRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0RhdGVgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGRhdGUgb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzRGF0ZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gZGF0ZVRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aGljaCBzdXBwb3J0cyBwYXJ0aWFsIGNvbXBhcmlzb25zXG4gICAgICogYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAgICAgKiAgMSAtIFVub3JkZXJlZCBjb21wYXJpc29uXG4gICAgICogIDIgLSBQYXJ0aWFsIGNvbXBhcmlzb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0VxdWFsKHZhbHVlLCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCBvdGhlciA9PSBudWxsIHx8ICghaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgYmFzZUlzRXF1YWwsIHN0YWNrKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsYCBmb3IgYXJyYXlzIGFuZCBvYmplY3RzIHdoaWNoIHBlcmZvcm1zXG4gICAgICogZGVlcCBjb21wYXJpc29ucyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICAgICAqIHJlZmVyZW5jZXMgdG8gYmUgY29tcGFyZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHtcbiAgICAgIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgICAgICBvdGhJc0FyciA9IGlzQXJyYXkob3RoZXIpLFxuICAgICAgICAgIG9ialRhZyA9IG9iaklzQXJyID8gYXJyYXlUYWcgOiBnZXRUYWcob2JqZWN0KSxcbiAgICAgICAgICBvdGhUYWcgPSBvdGhJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG90aGVyKTtcblxuICAgICAgb2JqVGFnID0gb2JqVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvYmpUYWc7XG4gICAgICBvdGhUYWcgPSBvdGhUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG90aFRhZztcblxuICAgICAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyxcbiAgICAgICAgICBvdGhJc09iaiA9IG90aFRhZyA9PSBvYmplY3RUYWcsXG4gICAgICAgICAgaXNTYW1lVGFnID0gb2JqVGFnID09IG90aFRhZztcblxuICAgICAgaWYgKGlzU2FtZVRhZyAmJiBpc0J1ZmZlcihvYmplY3QpKSB7XG4gICAgICAgIGlmICghaXNCdWZmZXIob3RoZXIpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIG9iaklzQXJyID0gdHJ1ZTtcbiAgICAgICAgb2JqSXNPYmogPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1NhbWVUYWcgJiYgIW9iaklzT2JqKSB7XG4gICAgICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjayk7XG4gICAgICAgIHJldHVybiAob2JqSXNBcnIgfHwgaXNUeXBlZEFycmF5KG9iamVjdCkpXG4gICAgICAgICAgPyBlcXVhbEFycmF5cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKVxuICAgICAgICAgIDogZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCBvYmpUYWcsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spO1xuICAgICAgfVxuICAgICAgaWYgKCEoYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHKSkge1xuICAgICAgICB2YXIgb2JqSXNXcmFwcGVkID0gb2JqSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsICdfX3dyYXBwZWRfXycpLFxuICAgICAgICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7XG5cbiAgICAgICAgaWYgKG9iaklzV3JhcHBlZCB8fCBvdGhJc1dyYXBwZWQpIHtcbiAgICAgICAgICB2YXIgb2JqVW53cmFwcGVkID0gb2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsXG4gICAgICAgICAgICAgIG90aFVud3JhcHBlZCA9IG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlcjtcblxuICAgICAgICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjayk7XG4gICAgICAgICAgcmV0dXJuIGVxdWFsRnVuYyhvYmpVbndyYXBwZWQsIG90aFVud3JhcHBlZCwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWlzU2FtZVRhZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgcmV0dXJuIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc01hcGAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbWFwLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzTWFwKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBnZXRUYWcodmFsdWUpID09IG1hcFRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc01hdGNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ0eSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyB0byBtYXRjaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBtYXRjaERhdGEsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIHZhciBpbmRleCA9IG1hdGNoRGF0YS5sZW5ndGgsXG4gICAgICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICAgICAgbm9DdXN0b21pemVyID0gIWN1c3RvbWl6ZXI7XG5cbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gIWxlbmd0aDtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgdmFyIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdO1xuICAgICAgICBpZiAoKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKVxuICAgICAgICAgICAgICA/IGRhdGFbMV0gIT09IG9iamVjdFtkYXRhWzBdXVxuICAgICAgICAgICAgICA6ICEoZGF0YVswXSBpbiBvYmplY3QpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdO1xuICAgICAgICB2YXIga2V5ID0gZGF0YVswXSxcbiAgICAgICAgICAgIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgICAgICBzcmNWYWx1ZSA9IGRhdGFbMV07XG5cbiAgICAgICAgaWYgKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKSB7XG4gICAgICAgICAgaWYgKG9ialZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgc3RhY2sgPSBuZXcgU3RhY2s7XG4gICAgICAgICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSwgc3RhY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIShyZXN1bHQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcsIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICAgICAgICAgIDogcmVzdWx0XG4gICAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmF0aXZlYCB3aXRob3V0IGJhZCBzaGltIGNoZWNrcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNOYXRpdmUodmFsdWUpIHtcbiAgICAgIGlmICghaXNPYmplY3QodmFsdWUpIHx8IGlzTWFza2VkKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgcGF0dGVybiA9IGlzRnVuY3Rpb24odmFsdWUpID8gcmVJc05hdGl2ZSA6IHJlSXNIb3N0Q3RvcjtcbiAgICAgIHJldHVybiBwYXR0ZXJuLnRlc3QodG9Tb3VyY2UodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1JlZ0V4cGAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcmVnZXhwLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzUmVnRXhwKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSByZWdleHBUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNTZXRgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNldCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc1NldCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgZ2V0VGFnKHZhbHVlKSA9PSBzZXRUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNUeXBlZEFycmF5YCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc1R5cGVkQXJyYXkodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmXG4gICAgICAgIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tiYXNlR2V0VGFnKHZhbHVlKV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXRlcmF0ZWVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IFt2YWx1ZT1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhbiBpdGVyYXRlZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGl0ZXJhdGVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJdGVyYXRlZSh2YWx1ZSkge1xuICAgICAgLy8gRG9uJ3Qgc3RvcmUgdGhlIGB0eXBlb2ZgIHJlc3VsdCBpbiBhIHZhcmlhYmxlIHRvIGF2b2lkIGEgSklUIGJ1ZyBpbiBTYWZhcmkgOS5cbiAgICAgIC8vIFNlZSBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTU2MDM0IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGlkZW50aXR5O1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheSh2YWx1ZSlcbiAgICAgICAgICA/IGJhc2VNYXRjaGVzUHJvcGVydHkodmFsdWVbMF0sIHZhbHVlWzFdKVxuICAgICAgICAgIDogYmFzZU1hdGNoZXModmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByb3BlcnR5KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzYCB3aGljaCBkb2Vzbid0IHRyZWF0IHNwYXJzZSBhcnJheXMgYXMgZGVuc2UuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VLZXlzKG9iamVjdCkge1xuICAgICAgaWYgKCFpc1Byb3RvdHlwZShvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBuYXRpdmVLZXlzKG9iamVjdCk7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpICYmIGtleSAhPSAnY29uc3RydWN0b3InKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzSW5gIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUtleXNJbihvYmplY3QpIHtcbiAgICAgIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gbmF0aXZlS2V5c0luKG9iamVjdCk7XG4gICAgICB9XG4gICAgICB2YXIgaXNQcm90byA9IGlzUHJvdG90eXBlKG9iamVjdCksXG4gICAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgaWYgKCEoa2V5ID09ICdjb25zdHJ1Y3RvcicgJiYgKGlzUHJvdG8gfHwgIWhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSkpIHtcbiAgICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmx0YCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gYG90aGVyYCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VMdCh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA8IG90aGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hcGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgcmVzdWx0ID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBBcnJheShjb2xsZWN0aW9uLmxlbmd0aCkgOiBbXTtcblxuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgICAgICByZXN1bHRbKytpbmRleF0gPSBpdGVyYXRlZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzYCB3aGljaCBkb2Vzbid0IGNsb25lIGBzb3VyY2VgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7XG4gICAgICB2YXIgbWF0Y2hEYXRhID0gZ2V0TWF0Y2hEYXRhKHNvdXJjZSk7XG4gICAgICBpZiAobWF0Y2hEYXRhLmxlbmd0aCA9PSAxICYmIG1hdGNoRGF0YVswXVsyXSkge1xuICAgICAgICByZXR1cm4gbWF0Y2hlc1N0cmljdENvbXBhcmFibGUobWF0Y2hEYXRhWzBdWzBdLCBtYXRjaERhdGFbMF1bMV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gb2JqZWN0ID09PSBzb3VyY2UgfHwgYmFzZUlzTWF0Y2gob2JqZWN0LCBzb3VyY2UsIG1hdGNoRGF0YSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lc24ndCBjbG9uZSBgc3JjVmFsdWVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICAgICAgaWYgKGlzS2V5KHBhdGgpICYmIGlzU3RyaWN0Q29tcGFyYWJsZShzcmNWYWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKHRvS2V5KHBhdGgpLCBzcmNWYWx1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHZhciBvYmpWYWx1ZSA9IGdldChvYmplY3QsIHBhdGgpO1xuICAgICAgICByZXR1cm4gKG9ialZhbHVlID09PSB1bmRlZmluZWQgJiYgb2JqVmFsdWUgPT09IHNyY1ZhbHVlKVxuICAgICAgICAgID8gaGFzSW4ob2JqZWN0LCBwYXRoKVxuICAgICAgICAgIDogYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tZXJnZWAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3JjSW5kZXggVGhlIGluZGV4IG9mIGBzb3VyY2VgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIG1lcmdlZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2UgdmFsdWVzIGFuZCB0aGVpciBtZXJnZWRcbiAgICAgKiAgY291bnRlcnBhcnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNZXJnZShvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIsIHN0YWNrKSB7XG4gICAgICBpZiAob2JqZWN0ID09PSBzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYmFzZUZvcihzb3VyY2UsIGZ1bmN0aW9uKHNyY1ZhbHVlLCBrZXkpIHtcbiAgICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KHNyY1ZhbHVlKSkge1xuICAgICAgICAgIGJhc2VNZXJnZURlZXAob2JqZWN0LCBzb3VyY2UsIGtleSwgc3JjSW5kZXgsIGJhc2VNZXJnZSwgY3VzdG9taXplciwgc3RhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBuZXdWYWx1ZSA9IGN1c3RvbWl6ZXJcbiAgICAgICAgICAgID8gY3VzdG9taXplcihzYWZlR2V0KG9iamVjdCwga2V5KSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaylcbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gc3JjVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSwga2V5c0luKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VNZXJnZWAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICAgICAqIGRlZXAgbWVyZ2VzIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMgZW5hYmxpbmcgb2JqZWN0cyB3aXRoIGNpcmN1bGFyXG4gICAgICogcmVmZXJlbmNlcyB0byBiZSBtZXJnZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gbWVyZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNyY0luZGV4IFRoZSBpbmRleCBvZiBgc291cmNlYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXJnZUZ1bmMgVGhlIGZ1bmN0aW9uIHRvIG1lcmdlIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2UgdmFsdWVzIGFuZCB0aGVpciBtZXJnZWRcbiAgICAgKiAgY291bnRlcnBhcnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNZXJnZURlZXAob2JqZWN0LCBzb3VyY2UsIGtleSwgc3JjSW5kZXgsIG1lcmdlRnVuYywgY3VzdG9taXplciwgc3RhY2spIHtcbiAgICAgIHZhciBvYmpWYWx1ZSA9IHNhZmVHZXQob2JqZWN0LCBrZXkpLFxuICAgICAgICAgIHNyY1ZhbHVlID0gc2FmZUdldChzb3VyY2UsIGtleSksXG4gICAgICAgICAgc3RhY2tlZCA9IHN0YWNrLmdldChzcmNWYWx1ZSk7XG5cbiAgICAgIGlmIChzdGFja2VkKSB7XG4gICAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIHN0YWNrZWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICAgID8gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaylcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgIHZhciBpc0NvbW1vbiA9IG5ld1ZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChpc0NvbW1vbikge1xuICAgICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KHNyY1ZhbHVlKSxcbiAgICAgICAgICAgIGlzQnVmZiA9ICFpc0FyciAmJiBpc0J1ZmZlcihzcmNWYWx1ZSksXG4gICAgICAgICAgICBpc1R5cGVkID0gIWlzQXJyICYmICFpc0J1ZmYgJiYgaXNUeXBlZEFycmF5KHNyY1ZhbHVlKTtcblxuICAgICAgICBuZXdWYWx1ZSA9IHNyY1ZhbHVlO1xuICAgICAgICBpZiAoaXNBcnIgfHwgaXNCdWZmIHx8IGlzVHlwZWQpIHtcbiAgICAgICAgICBpZiAoaXNBcnJheShvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gb2JqVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KG9ialZhbHVlKSkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBjb3B5QXJyYXkob2JqVmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmIChpc0J1ZmYpIHtcbiAgICAgICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IGNsb25lQnVmZmVyKHNyY1ZhbHVlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAoaXNUeXBlZCkge1xuICAgICAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gY2xvbmVUeXBlZEFycmF5KHNyY1ZhbHVlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IFtdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHNyY1ZhbHVlKSB8fCBpc0FyZ3VtZW50cyhzcmNWYWx1ZSkpIHtcbiAgICAgICAgICBuZXdWYWx1ZSA9IG9ialZhbHVlO1xuICAgICAgICAgIGlmIChpc0FyZ3VtZW50cyhvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gdG9QbGFpbk9iamVjdChvYmpWYWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKCFpc09iamVjdChvYmpWYWx1ZSkgfHwgaXNGdW5jdGlvbihvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gaW5pdENsb25lT2JqZWN0KHNyY1ZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzQ29tbW9uKSB7XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IG1lcmdlIG9iamVjdHMgYW5kIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBzdGFjay5zZXQoc3JjVmFsdWUsIG5ld1ZhbHVlKTtcbiAgICAgICAgbWVyZ2VGdW5jKG5ld1ZhbHVlLCBzcmNWYWx1ZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKHNyY1ZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5udGhgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG50aCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU50aChhcnJheSwgbikge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIG4gKz0gbiA8IDAgPyBsZW5ndGggOiAwO1xuICAgICAgcmV0dXJuIGlzSW5kZXgobiwgbGVuZ3RoKSA/IGFycmF5W25dIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm9yZGVyQnlgIHdpdGhvdXQgcGFyYW0gZ3VhcmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfE9iamVjdFtdfHN0cmluZ1tdfSBpdGVyYXRlZXMgVGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IG9yZGVycyBUaGUgc29ydCBvcmRlcnMgb2YgYGl0ZXJhdGVlc2AuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc29ydGVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VPcmRlckJ5KGNvbGxlY3Rpb24sIGl0ZXJhdGVlcywgb3JkZXJzKSB7XG4gICAgICBpZiAoaXRlcmF0ZWVzLmxlbmd0aCkge1xuICAgICAgICBpdGVyYXRlZXMgPSBhcnJheU1hcChpdGVyYXRlZXMsIGZ1bmN0aW9uKGl0ZXJhdGVlKSB7XG4gICAgICAgICAgaWYgKGlzQXJyYXkoaXRlcmF0ZWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGJhc2VHZXQodmFsdWUsIGl0ZXJhdGVlLmxlbmd0aCA9PT0gMSA/IGl0ZXJhdGVlWzBdIDogaXRlcmF0ZWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gaXRlcmF0ZWU7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gW2lkZW50aXR5XTtcbiAgICAgIH1cblxuICAgICAgdmFyIGluZGV4ID0gLTE7XG4gICAgICBpdGVyYXRlZXMgPSBhcnJheU1hcChpdGVyYXRlZXMsIGJhc2VVbmFyeShnZXRJdGVyYXRlZSgpKSk7XG5cbiAgICAgIHZhciByZXN1bHQgPSBiYXNlTWFwKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgdmFyIGNyaXRlcmlhID0gYXJyYXlNYXAoaXRlcmF0ZWVzLCBmdW5jdGlvbihpdGVyYXRlZSkge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRlZSh2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4geyAnY3JpdGVyaWEnOiBjcml0ZXJpYSwgJ2luZGV4JzogKytpbmRleCwgJ3ZhbHVlJzogdmFsdWUgfTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gYmFzZVNvcnRCeShyZXN1bHQsIGZ1bmN0aW9uKG9iamVjdCwgb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIGNvbXBhcmVNdWx0aXBsZShvYmplY3QsIG90aGVyLCBvcmRlcnMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucGlja2Agd2l0aG91dCBzdXBwb3J0IGZvciBpbmRpdmlkdWFsXG4gICAgICogcHJvcGVydHkgaWRlbnRpZmllcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aHMgVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUGljayhvYmplY3QsIHBhdGhzKSB7XG4gICAgICByZXR1cm4gYmFzZVBpY2tCeShvYmplY3QsIHBhdGhzLCBmdW5jdGlvbih2YWx1ZSwgcGF0aCkge1xuICAgICAgICByZXR1cm4gaGFzSW4ob2JqZWN0LCBwYXRoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mICBgXy5waWNrQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXRocyBUaGUgcHJvcGVydHkgcGF0aHMgdG8gcGljay5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIHByb3BlcnR5LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVBpY2tCeShvYmplY3QsIHBhdGhzLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGhzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSB7fTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHBhdGggPSBwYXRoc1tpbmRleF0sXG4gICAgICAgICAgICB2YWx1ZSA9IGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcblxuICAgICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBwYXRoKSkge1xuICAgICAgICAgIGJhc2VTZXQocmVzdWx0LCBjYXN0UGF0aChwYXRoLCBvYmplY3QpLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnB1bGxBbGxCeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZVxuICAgICAqIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVB1bGxBbGwoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBpbmRleE9mID0gY29tcGFyYXRvciA/IGJhc2VJbmRleE9mV2l0aCA6IGJhc2VJbmRleE9mLFxuICAgICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgICAgICBzZWVuID0gYXJyYXk7XG5cbiAgICAgIGlmIChhcnJheSA9PT0gdmFsdWVzKSB7XG4gICAgICAgIHZhbHVlcyA9IGNvcHlBcnJheSh2YWx1ZXMpO1xuICAgICAgfVxuICAgICAgaWYgKGl0ZXJhdGVlKSB7XG4gICAgICAgIHNlZW4gPSBhcnJheU1hcChhcnJheSwgYmFzZVVuYXJ5KGl0ZXJhdGVlKSk7XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZnJvbUluZGV4ID0gMCxcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWVzW2luZGV4XSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSkgOiB2YWx1ZTtcblxuICAgICAgICB3aGlsZSAoKGZyb21JbmRleCA9IGluZGV4T2Yoc2VlbiwgY29tcHV0ZWQsIGZyb21JbmRleCwgY29tcGFyYXRvcikpID4gLTEpIHtcbiAgICAgICAgICBpZiAoc2VlbiAhPT0gYXJyYXkpIHtcbiAgICAgICAgICAgIHNwbGljZS5jYWxsKHNlZW4sIGZyb21JbmRleCwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNwbGljZS5jYWxsKGFycmF5LCBmcm9tSW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHVsbEF0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGluZGl2aWR1YWxcbiAgICAgKiBpbmRleGVzIG9yIGNhcHR1cmluZyB0aGUgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcltdfSBpbmRleGVzIFRoZSBpbmRleGVzIG9mIGVsZW1lbnRzIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUHVsbEF0KGFycmF5LCBpbmRleGVzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBpbmRleGVzLmxlbmd0aCA6IDAsXG4gICAgICAgICAgbGFzdEluZGV4ID0gbGVuZ3RoIC0gMTtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGluZGV4ZXNbbGVuZ3RoXTtcbiAgICAgICAgaWYgKGxlbmd0aCA9PSBsYXN0SW5kZXggfHwgaW5kZXggIT09IHByZXZpb3VzKSB7XG4gICAgICAgICAgdmFyIHByZXZpb3VzID0gaW5kZXg7XG4gICAgICAgICAgaWYgKGlzSW5kZXgoaW5kZXgpKSB7XG4gICAgICAgICAgICBzcGxpY2UuY2FsbChhcnJheSwgaW5kZXgsIDEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBiYXNlVW5zZXQoYXJyYXksIGluZGV4KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yYW5kb21gIHdpdGhvdXQgc3VwcG9ydCBmb3IgcmV0dXJuaW5nXG4gICAgICogZmxvYXRpbmctcG9pbnQgbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxvd2VyIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXBwZXIgVGhlIHVwcGVyIGJvdW5kLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJhbmRvbSBudW1iZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVJhbmRvbShsb3dlciwgdXBwZXIpIHtcbiAgICAgIHJldHVybiBsb3dlciArIG5hdGl2ZUZsb29yKG5hdGl2ZVJhbmRvbSgpICogKHVwcGVyIC0gbG93ZXIgKyAxKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmFuZ2VgIGFuZCBgXy5yYW5nZVJpZ2h0YCB3aGljaCBkb2Vzbid0XG4gICAgICogY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RlcCBUaGUgdmFsdWUgdG8gaW5jcmVtZW50IG9yIGRlY3JlbWVudCBieS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmdlIG9mIG51bWJlcnMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVJhbmdlKHN0YXJ0LCBlbmQsIHN0ZXAsIGZyb21SaWdodCkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KG5hdGl2ZUNlaWwoKGVuZCAtIHN0YXJ0KSAvIChzdGVwIHx8IDEpKSwgMCksXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHJlc3VsdFtmcm9tUmlnaHQgPyBsZW5ndGggOiArK2luZGV4XSA9IHN0YXJ0O1xuICAgICAgICBzdGFydCArPSBzdGVwO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yZXBlYXRgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIHJlcGVhdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdCB0aGUgc3RyaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJlcGVhdGVkIHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUmVwZWF0KHN0cmluZywgbikge1xuICAgICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgICAgaWYgKCFzdHJpbmcgfHwgbiA8IDEgfHwgbiA+IE1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIC8vIExldmVyYWdlIHRoZSBleHBvbmVudGlhdGlvbiBieSBzcXVhcmluZyBhbGdvcml0aG0gZm9yIGEgZmFzdGVyIHJlcGVhdC5cbiAgICAgIC8vIFNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FeHBvbmVudGlhdGlvbl9ieV9zcXVhcmluZyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgZG8ge1xuICAgICAgICBpZiAobiAlIDIpIHtcbiAgICAgICAgICByZXN1bHQgKz0gc3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIG4gPSBuYXRpdmVGbG9vcihuIC8gMik7XG4gICAgICAgIGlmIChuKSB7XG4gICAgICAgICAgc3RyaW5nICs9IHN0cmluZztcbiAgICAgICAgfVxuICAgICAgfSB3aGlsZSAobik7XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmVzdGAgd2hpY2ggZG9lc24ndCB2YWxpZGF0ZSBvciBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUmVzdChmdW5jLCBzdGFydCkge1xuICAgICAgcmV0dXJuIHNldFRvU3RyaW5nKG92ZXJSZXN0KGZ1bmMsIHN0YXJ0LCBpZGVudGl0eSksIGZ1bmMgKyAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2FtcGxlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2FtcGxlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU2FtcGxlKGNvbGxlY3Rpb24pIHtcbiAgICAgIHJldHVybiBhcnJheVNhbXBsZSh2YWx1ZXMoY29sbGVjdGlvbikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNhbXBsZVNpemVgIHdpdGhvdXQgcGFyYW0gZ3VhcmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNhbXBsZVNpemUoY29sbGVjdGlvbiwgbikge1xuICAgICAgdmFyIGFycmF5ID0gdmFsdWVzKGNvbGxlY3Rpb24pO1xuICAgICAgcmV0dXJuIHNodWZmbGVTZWxmKGFycmF5LCBiYXNlQ2xhbXAobiwgMCwgYXJyYXkubGVuZ3RoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2V0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBwYXRoIGNyZWF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNldChvYmplY3QsIHBhdGgsIHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH1cbiAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aCxcbiAgICAgICAgICBsYXN0SW5kZXggPSBsZW5ndGggLSAxLFxuICAgICAgICAgIG5lc3RlZCA9IG9iamVjdDtcblxuICAgICAgd2hpbGUgKG5lc3RlZCAhPSBudWxsICYmICsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHRvS2V5KHBhdGhbaW5kZXhdKSxcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gdmFsdWU7XG5cbiAgICAgICAgaWYgKGtleSA9PT0gJ19fcHJvdG9fXycgfHwga2V5ID09PSAnY29uc3RydWN0b3InIHx8IGtleSA9PT0gJ3Byb3RvdHlwZScpIHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluZGV4ICE9IGxhc3RJbmRleCkge1xuICAgICAgICAgIHZhciBvYmpWYWx1ZSA9IG5lc3RlZFtrZXldO1xuICAgICAgICAgIG5ld1ZhbHVlID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIob2JqVmFsdWUsIGtleSwgbmVzdGVkKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBpc09iamVjdChvYmpWYWx1ZSlcbiAgICAgICAgICAgICAgPyBvYmpWYWx1ZVxuICAgICAgICAgICAgICA6IChpc0luZGV4KHBhdGhbaW5kZXggKyAxXSkgPyBbXSA6IHt9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduVmFsdWUobmVzdGVkLCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgbmVzdGVkID0gbmVzdGVkW2tleV07XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXREYXRhYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIHNob3J0aW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhc3NvY2lhdGUgbWV0YWRhdGEgd2l0aC5cbiAgICAgKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIGJhc2VTZXREYXRhID0gIW1ldGFNYXAgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIGRhdGEpIHtcbiAgICAgIG1ldGFNYXAuc2V0KGZ1bmMsIGRhdGEpO1xuICAgICAgcmV0dXJuIGZ1bmM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXRUb1N0cmluZ2Agd2l0aG91dCBzdXBwb3J0IGZvciBob3QgbG9vcCBzaG9ydGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHN0cmluZyBUaGUgYHRvU3RyaW5nYCByZXN1bHQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZVNldFRvU3RyaW5nID0gIWRlZmluZVByb3BlcnR5ID8gaWRlbnRpdHkgOiBmdW5jdGlvbihmdW5jLCBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBkZWZpbmVQcm9wZXJ0eShmdW5jLCAndG9TdHJpbmcnLCB7XG4gICAgICAgICdjb25maWd1cmFibGUnOiB0cnVlLFxuICAgICAgICAnZW51bWVyYWJsZSc6IGZhbHNlLFxuICAgICAgICAndmFsdWUnOiBjb25zdGFudChzdHJpbmcpLFxuICAgICAgICAnd3JpdGFibGUnOiB0cnVlXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2h1ZmZsZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNodWZmbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc2h1ZmZsZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNodWZmbGUoY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIHNodWZmbGVTZWxmKHZhbHVlcyhjb2xsZWN0aW9uKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2xpY2VgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgc3RhcnQgPSAtc3RhcnQgPiBsZW5ndGggPyAwIDogKGxlbmd0aCArIHN0YXJ0KTtcbiAgICAgIH1cbiAgICAgIGVuZCA9IGVuZCA+IGxlbmd0aCA/IGxlbmd0aCA6IGVuZDtcbiAgICAgIGlmIChlbmQgPCAwKSB7XG4gICAgICAgIGVuZCArPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICBsZW5ndGggPSBzdGFydCA+IGVuZCA/IDAgOiAoKGVuZCAtIHN0YXJ0KSA+Pj4gMCk7XG4gICAgICBzdGFydCA+Pj49IDA7XG5cbiAgICAgIHZhciByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IGFycmF5W2luZGV4ICsgc3RhcnRdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb21lYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29tZShjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQ7XG5cbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICByZXN1bHQgPSBwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuICFyZXN1bHQ7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiAhIXJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0ZWRJbmRleGAgYW5kIGBfLnNvcnRlZExhc3RJbmRleGAgd2hpY2hcbiAgICAgKiBwZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAgICAgKiBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byBgYXJyYXlgIGluIG9yZGVyIHRvIG1haW50YWluIGl0cyBzb3J0IG9yZGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlLCByZXRIaWdoZXN0KSB7XG4gICAgICB2YXIgbG93ID0gMCxcbiAgICAgICAgICBoaWdoID0gYXJyYXkgPT0gbnVsbCA/IGxvdyA6IGFycmF5Lmxlbmd0aDtcblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA9PT0gdmFsdWUgJiYgaGlnaCA8PSBIQUxGX01BWF9BUlJBWV9MRU5HVEgpIHtcbiAgICAgICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgICAgICBjb21wdXRlZCA9IGFycmF5W21pZF07XG5cbiAgICAgICAgICBpZiAoY29tcHV0ZWQgIT09IG51bGwgJiYgIWlzU3ltYm9sKGNvbXB1dGVkKSAmJlxuICAgICAgICAgICAgICAocmV0SGlnaGVzdCA/IChjb21wdXRlZCA8PSB2YWx1ZSkgOiAoY29tcHV0ZWQgPCB2YWx1ZSkpKSB7XG4gICAgICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGlnaDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlU29ydGVkSW5kZXhCeShhcnJheSwgdmFsdWUsIGlkZW50aXR5LCByZXRIaWdoZXN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0ZWRJbmRleEJ5YCBhbmQgYF8uc29ydGVkTGFzdEluZGV4QnlgXG4gICAgICogd2hpY2ggaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBgdmFsdWVgIGFuZCBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCB0byBjb21wdXRlXG4gICAgICogdGhlaXIgc29ydCByYW5raW5nLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldEhpZ2hlc3RdIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBoaWdoZXN0IHF1YWxpZmllZCBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNvcnRlZEluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSwgcmV0SGlnaGVzdCkge1xuICAgICAgdmFyIGxvdyA9IDAsXG4gICAgICAgICAgaGlnaCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKGhpZ2ggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG5cbiAgICAgIHZhbHVlID0gaXRlcmF0ZWUodmFsdWUpO1xuICAgICAgdmFyIHZhbElzTmFOID0gdmFsdWUgIT09IHZhbHVlLFxuICAgICAgICAgIHZhbElzTnVsbCA9IHZhbHVlID09PSBudWxsLFxuICAgICAgICAgIHZhbElzU3ltYm9sID0gaXNTeW1ib2wodmFsdWUpLFxuICAgICAgICAgIHZhbElzVW5kZWZpbmVkID0gdmFsdWUgPT09IHVuZGVmaW5lZDtcblxuICAgICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgICAgdmFyIG1pZCA9IG5hdGl2ZUZsb29yKChsb3cgKyBoaWdoKSAvIDIpLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZShhcnJheVttaWRdKSxcbiAgICAgICAgICAgIG90aElzRGVmaW5lZCA9IGNvbXB1dGVkICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICBvdGhJc051bGwgPSBjb21wdXRlZCA9PT0gbnVsbCxcbiAgICAgICAgICAgIG90aElzUmVmbGV4aXZlID0gY29tcHV0ZWQgPT09IGNvbXB1dGVkLFxuICAgICAgICAgICAgb3RoSXNTeW1ib2wgPSBpc1N5bWJvbChjb21wdXRlZCk7XG5cbiAgICAgICAgaWYgKHZhbElzTmFOKSB7XG4gICAgICAgICAgdmFyIHNldExvdyA9IHJldEhpZ2hlc3QgfHwgb3RoSXNSZWZsZXhpdmU7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsSXNVbmRlZmluZWQpIHtcbiAgICAgICAgICBzZXRMb3cgPSBvdGhJc1JlZmxleGl2ZSAmJiAocmV0SGlnaGVzdCB8fCBvdGhJc0RlZmluZWQpO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbElzTnVsbCkge1xuICAgICAgICAgIHNldExvdyA9IG90aElzUmVmbGV4aXZlICYmIG90aElzRGVmaW5lZCAmJiAocmV0SGlnaGVzdCB8fCAhb3RoSXNOdWxsKTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWxJc1N5bWJvbCkge1xuICAgICAgICAgIHNldExvdyA9IG90aElzUmVmbGV4aXZlICYmIG90aElzRGVmaW5lZCAmJiAhb3RoSXNOdWxsICYmIChyZXRIaWdoZXN0IHx8ICFvdGhJc1N5bWJvbCk7XG4gICAgICAgIH0gZWxzZSBpZiAob3RoSXNOdWxsIHx8IG90aElzU3ltYm9sKSB7XG4gICAgICAgICAgc2V0TG93ID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0TG93ID0gcmV0SGlnaGVzdCA/IChjb21wdXRlZCA8PSB2YWx1ZSkgOiAoY29tcHV0ZWQgPCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNldExvdykge1xuICAgICAgICAgIGxvdyA9IG1pZCArIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGlnaCA9IG1pZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG5hdGl2ZU1pbihoaWdoLCBNQVhfQVJSQVlfSU5ERVgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNvcnRlZFVuaXFgIGFuZCBgXy5zb3J0ZWRVbmlxQnlgIHdpdGhvdXRcbiAgICAgKiBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTb3J0ZWRVbmlxKGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIHJlc0luZGV4ID0gMCxcbiAgICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA/IGl0ZXJhdGVlKHZhbHVlKSA6IHZhbHVlO1xuXG4gICAgICAgIGlmICghaW5kZXggfHwgIWVxKGNvbXB1dGVkLCBzZWVuKSkge1xuICAgICAgICAgIHZhciBzZWVuID0gY29tcHV0ZWQ7XG4gICAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gdmFsdWUgPT09IDAgPyAwIDogdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udG9OdW1iZXJgIHdoaWNoIGRvZXNuJ3QgZW5zdXJlIGNvcnJlY3RcbiAgICAgKiBjb252ZXJzaW9ucyBvZiBiaW5hcnksIGhleGFkZWNpbWFsLCBvciBvY3RhbCBzdHJpbmcgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlVG9OdW1iZXIodmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gTkFOO1xuICAgICAgfVxuICAgICAgcmV0dXJuICt2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50b1N0cmluZ2Agd2hpY2ggZG9lc24ndCBjb252ZXJ0IG51bGxpc2hcbiAgICAgKiB2YWx1ZXMgdG8gZW1wdHkgc3RyaW5ncy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVRvU3RyaW5nKHZhbHVlKSB7XG4gICAgICAvLyBFeGl0IGVhcmx5IGZvciBzdHJpbmdzIHRvIGF2b2lkIGEgcGVyZm9ybWFuY2UgaGl0IGluIHNvbWUgZW52aXJvbm1lbnRzLlxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgY29udmVydCB2YWx1ZXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgcmV0dXJuIGFycmF5TWFwKHZhbHVlLCBiYXNlVG9TdHJpbmcpICsgJyc7XG4gICAgICB9XG4gICAgICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBzeW1ib2xUb1N0cmluZyA/IHN5bWJvbFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gKHZhbHVlICsgJycpO1xuICAgICAgcmV0dXJuIChyZXN1bHQgPT0gJzAnICYmICgxIC8gdmFsdWUpID09IC1JTkZJTklUWSkgPyAnLTAnIDogcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuaXFCeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VVbmlxKGFycmF5LCBpdGVyYXRlZSwgY29tcGFyYXRvcikge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgaW5jbHVkZXMgPSBhcnJheUluY2x1ZGVzLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBpc0NvbW1vbiA9IHRydWUsXG4gICAgICAgICAgcmVzdWx0ID0gW10sXG4gICAgICAgICAgc2VlbiA9IHJlc3VsdDtcblxuICAgICAgaWYgKGNvbXBhcmF0b3IpIHtcbiAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgaW5jbHVkZXMgPSBhcnJheUluY2x1ZGVzV2l0aDtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGxlbmd0aCA+PSBMQVJHRV9BUlJBWV9TSVpFKSB7XG4gICAgICAgIHZhciBzZXQgPSBpdGVyYXRlZSA/IG51bGwgOiBjcmVhdGVTZXQoYXJyYXkpO1xuICAgICAgICBpZiAoc2V0KSB7XG4gICAgICAgICAgcmV0dXJuIHNldFRvQXJyYXkoc2V0KTtcbiAgICAgICAgfVxuICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgICBpbmNsdWRlcyA9IGNhY2hlSGFzO1xuICAgICAgICBzZWVuID0gbmV3IFNldENhY2hlO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHNlZW4gPSBpdGVyYXRlZSA/IFtdIDogcmVzdWx0O1xuICAgICAgfVxuICAgICAgb3V0ZXI6XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID8gaXRlcmF0ZWUodmFsdWUpIDogdmFsdWU7XG5cbiAgICAgICAgdmFsdWUgPSAoY29tcGFyYXRvciB8fCB2YWx1ZSAhPT0gMCkgPyB2YWx1ZSA6IDA7XG4gICAgICAgIGlmIChpc0NvbW1vbiAmJiBjb21wdXRlZCA9PT0gY29tcHV0ZWQpIHtcbiAgICAgICAgICB2YXIgc2VlbkluZGV4ID0gc2Vlbi5sZW5ndGg7XG4gICAgICAgICAgd2hpbGUgKHNlZW5JbmRleC0tKSB7XG4gICAgICAgICAgICBpZiAoc2VlbltzZWVuSW5kZXhdID09PSBjb21wdXRlZCkge1xuICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGl0ZXJhdGVlKSB7XG4gICAgICAgICAgICBzZWVuLnB1c2goY29tcHV0ZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWluY2x1ZGVzKHNlZW4sIGNvbXB1dGVkLCBjb21wYXJhdG9yKSkge1xuICAgICAgICAgIGlmIChzZWVuICE9PSByZXN1bHQpIHtcbiAgICAgICAgICAgIHNlZW4ucHVzaChjb21wdXRlZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51bnNldGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHByb3BlcnR5IHBhdGggdG8gdW5zZXQuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBwcm9wZXJ0eSBpcyBkZWxldGVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVVuc2V0KG9iamVjdCwgcGF0aCkge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG4gICAgICBvYmplY3QgPSBwYXJlbnQob2JqZWN0LCBwYXRoKTtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCB8fCBkZWxldGUgb2JqZWN0W3RvS2V5KGxhc3QocGF0aCkpXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51cGRhdGVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byB1cGRhdGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdXBkYXRlciBUaGUgZnVuY3Rpb24gdG8gcHJvZHVjZSB0aGUgdXBkYXRlZCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBwYXRoIGNyZWF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVVwZGF0ZShvYmplY3QsIHBhdGgsIHVwZGF0ZXIsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIHJldHVybiBiYXNlU2V0KG9iamVjdCwgcGF0aCwgdXBkYXRlcihiYXNlR2V0KG9iamVjdCwgcGF0aCkpLCBjdXN0b21pemVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8uZHJvcFdoaWxlYCBhbmQgYF8udGFrZVdoaWxlYFxuICAgICAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRHJvcF0gU3BlY2lmeSBkcm9wcGluZyBlbGVtZW50cyBpbnN0ZWFkIG9mIHRha2luZyB0aGVtLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlV2hpbGUoYXJyYXksIHByZWRpY2F0ZSwgaXNEcm9wLCBmcm9tUmlnaHQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMTtcblxuICAgICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkgJiZcbiAgICAgICAgcHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge31cblxuICAgICAgcmV0dXJuIGlzRHJvcFxuICAgICAgICA/IGJhc2VTbGljZShhcnJheSwgKGZyb21SaWdodCA/IDAgOiBpbmRleCksIChmcm9tUmlnaHQgPyBpbmRleCArIDEgOiBsZW5ndGgpKVxuICAgICAgICA6IGJhc2VTbGljZShhcnJheSwgKGZyb21SaWdodCA/IGluZGV4ICsgMSA6IDApLCAoZnJvbVJpZ2h0ID8gbGVuZ3RoIDogaW5kZXgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgd3JhcHBlclZhbHVlYCB3aGljaCByZXR1cm5zIHRoZSByZXN1bHQgb2ZcbiAgICAgKiBwZXJmb3JtaW5nIGEgc2VxdWVuY2Ugb2YgYWN0aW9ucyBvbiB0aGUgdW53cmFwcGVkIGB2YWx1ZWAsIHdoZXJlIGVhY2hcbiAgICAgKiBzdWNjZXNzaXZlIGFjdGlvbiBpcyBzdXBwbGllZCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwcmV2aW91cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdW53cmFwcGVkIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFjdGlvbnMgQWN0aW9ucyB0byBwZXJmb3JtIHRvIHJlc29sdmUgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVdyYXBwZXJWYWx1ZSh2YWx1ZSwgYWN0aW9ucykge1xuICAgICAgdmFyIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC52YWx1ZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5UmVkdWNlKGFjdGlvbnMsIGZ1bmN0aW9uKHJlc3VsdCwgYWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBhY3Rpb24uZnVuYy5hcHBseShhY3Rpb24udGhpc0FyZywgYXJyYXlQdXNoKFtyZXN1bHRdLCBhY3Rpb24uYXJncykpO1xuICAgICAgfSwgcmVzdWx0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8ueG9yYCwgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMsIHRoYXQgYWNjZXB0cyBhbiBhcnJheSBvZiBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXlzIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHZhbHVlcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlWG9yKGFycmF5cywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheXMubGVuZ3RoO1xuICAgICAgaWYgKGxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VVbmlxKGFycmF5c1swXSkgOiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBhcnJheSA9IGFycmF5c1tpbmRleF0sXG4gICAgICAgICAgICBvdGhJbmRleCA9IC0xO1xuXG4gICAgICAgIHdoaWxlICgrK290aEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgaWYgKG90aEluZGV4ICE9IGluZGV4KSB7XG4gICAgICAgICAgICByZXN1bHRbaW5kZXhdID0gYmFzZURpZmZlcmVuY2UocmVzdWx0W2luZGV4XSB8fCBhcnJheSwgYXJyYXlzW290aEluZGV4XSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VVbmlxKGJhc2VGbGF0dGVuKHJlc3VsdCwgMSksIGl0ZXJhdGVlLCBjb21wYXJhdG9yKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uemlwT2JqZWN0YCB3aGljaCBhc3NpZ25zIHZhbHVlcyB1c2luZyBgYXNzaWduRnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVycy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhc3NpZ25GdW5jIFRoZSBmdW5jdGlvbiB0byBhc3NpZ24gdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVppcE9iamVjdChwcm9wcywgdmFsdWVzLCBhc3NpZ25GdW5jKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICAgICAgdmFsc0xlbmd0aCA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0ge307XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGluZGV4IDwgdmFsc0xlbmd0aCA/IHZhbHVlc1tpbmRleF0gOiB1bmRlZmluZWQ7XG4gICAgICAgIGFzc2lnbkZ1bmMocmVzdWx0LCBwcm9wc1tpbmRleF0sIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FzdHMgYHZhbHVlYCB0byBhbiBlbXB0eSBhcnJheSBpZiBpdCdzIG5vdCBhbiBhcnJheSBsaWtlIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIHRoZSBjYXN0IGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhc3RBcnJheUxpa2VPYmplY3QodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0FycmF5TGlrZU9iamVjdCh2YWx1ZSkgPyB2YWx1ZSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGB2YWx1ZWAgdG8gYGlkZW50aXR5YCBpZiBpdCdzIG5vdCBhIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBjYXN0IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhc3RGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnZnVuY3Rpb24nID8gdmFsdWUgOiBpZGVudGl0eTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYXN0cyBgdmFsdWVgIHRvIGEgcGF0aCBhcnJheSBpZiBpdCdzIG5vdCBvbmUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkga2V5cyBvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNhc3QgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXN0UGF0aCh2YWx1ZSwgb2JqZWN0KSB7XG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzS2V5KHZhbHVlLCBvYmplY3QpID8gW3ZhbHVlXSA6IHN0cmluZ1RvUGF0aCh0b1N0cmluZyh2YWx1ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgYGJhc2VSZXN0YCBhbGlhcyB3aGljaCBjYW4gYmUgcmVwbGFjZWQgd2l0aCBgaWRlbnRpdHlgIGJ5IG1vZHVsZVxuICAgICAqIHJlcGxhY2VtZW50IHBsdWdpbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIHZhciBjYXN0UmVzdCA9IGJhc2VSZXN0O1xuXG4gICAgLyoqXG4gICAgICogQ2FzdHMgYGFycmF5YCB0byBhIHNsaWNlIGlmIGl0J3MgbmVlZGVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNhc3Qgc2xpY2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdFNsaWNlKGFycmF5LCBzdGFydCwgZW5kKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgICAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiBlbmQ7XG4gICAgICByZXR1cm4gKCFzdGFydCAmJiBlbmQgPj0gbGVuZ3RoKSA/IGFycmF5IDogYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNpbXBsZSB3cmFwcGVyIGFyb3VuZCB0aGUgZ2xvYmFsIFtgY2xlYXJUaW1lb3V0YF0oaHR0cHM6Ly9tZG4uaW8vY2xlYXJUaW1lb3V0KS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ8T2JqZWN0fSBpZCBUaGUgdGltZXIgaWQgb3IgdGltZW91dCBvYmplY3Qgb2YgdGhlIHRpbWVyIHRvIGNsZWFyLlxuICAgICAqL1xuICAgIHZhciBjbGVhclRpbWVvdXQgPSBjdHhDbGVhclRpbWVvdXQgfHwgZnVuY3Rpb24oaWQpIHtcbiAgICAgIHJldHVybiByb290LmNsZWFyVGltZW91dChpZCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiAgYGJ1ZmZlcmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QnVmZmVyfSBidWZmZXIgVGhlIGJ1ZmZlciB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBidWZmZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVCdWZmZXIoYnVmZmVyLCBpc0RlZXApIHtcbiAgICAgIGlmIChpc0RlZXApIHtcbiAgICAgICAgcmV0dXJuIGJ1ZmZlci5zbGljZSgpO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gYWxsb2NVbnNhZmUgPyBhbGxvY1Vuc2FmZShsZW5ndGgpIDogbmV3IGJ1ZmZlci5jb25zdHJ1Y3RvcihsZW5ndGgpO1xuXG4gICAgICBidWZmZXIuY29weShyZXN1bHQpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgYGFycmF5QnVmZmVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYXJyYXlCdWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXlCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBhcnJheSBidWZmZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVBcnJheUJ1ZmZlcihhcnJheUJ1ZmZlcikge1xuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBhcnJheUJ1ZmZlci5jb25zdHJ1Y3RvcihhcnJheUJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgIG5ldyBVaW50OEFycmF5KHJlc3VsdCkuc2V0KG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyKSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgZGF0YVZpZXdgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YVZpZXcgVGhlIGRhdGEgdmlldyB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCBkYXRhIHZpZXcuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVEYXRhVmlldyhkYXRhVmlldywgaXNEZWVwKSB7XG4gICAgICB2YXIgYnVmZmVyID0gaXNEZWVwID8gY2xvbmVBcnJheUJ1ZmZlcihkYXRhVmlldy5idWZmZXIpIDogZGF0YVZpZXcuYnVmZmVyO1xuICAgICAgcmV0dXJuIG5ldyBkYXRhVmlldy5jb25zdHJ1Y3RvcihidWZmZXIsIGRhdGFWaWV3LmJ5dGVPZmZzZXQsIGRhdGFWaWV3LmJ5dGVMZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgcmVnZXhwYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHJlZ2V4cCBUaGUgcmVnZXhwIHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCByZWdleHAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVSZWdFeHAocmVnZXhwKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IHJlZ2V4cC5jb25zdHJ1Y3RvcihyZWdleHAuc291cmNlLCByZUZsYWdzLmV4ZWMocmVnZXhwKSk7XG4gICAgICByZXN1bHQubGFzdEluZGV4ID0gcmVnZXhwLmxhc3RJbmRleDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBgc3ltYm9sYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzeW1ib2wgVGhlIHN5bWJvbCBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHN5bWJvbCBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVTeW1ib2woc3ltYm9sKSB7XG4gICAgICByZXR1cm4gc3ltYm9sVmFsdWVPZiA/IE9iamVjdChzeW1ib2xWYWx1ZU9mLmNhbGwoc3ltYm9sKSkgOiB7fTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHR5cGVkQXJyYXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gdHlwZWRBcnJheSBUaGUgdHlwZWQgYXJyYXkgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgdHlwZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVUeXBlZEFycmF5KHR5cGVkQXJyYXksIGlzRGVlcCkge1xuICAgICAgdmFyIGJ1ZmZlciA9IGlzRGVlcCA/IGNsb25lQXJyYXlCdWZmZXIodHlwZWRBcnJheS5idWZmZXIpIDogdHlwZWRBcnJheS5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IHR5cGVkQXJyYXkuY29uc3RydWN0b3IoYnVmZmVyLCB0eXBlZEFycmF5LmJ5dGVPZmZzZXQsIHR5cGVkQXJyYXkubGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wYXJlcyB2YWx1ZXMgdG8gc29ydCB0aGVtIGluIGFzY2VuZGluZyBvcmRlci5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHNvcnQgb3JkZXIgaW5kaWNhdG9yIGZvciBgdmFsdWVgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVBc2NlbmRpbmcodmFsdWUsIG90aGVyKSB7XG4gICAgICBpZiAodmFsdWUgIT09IG90aGVyKSB7XG4gICAgICAgIHZhciB2YWxJc0RlZmluZWQgPSB2YWx1ZSAhPT0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgdmFsSXNOdWxsID0gdmFsdWUgPT09IG51bGwsXG4gICAgICAgICAgICB2YWxJc1JlZmxleGl2ZSA9IHZhbHVlID09PSB2YWx1ZSxcbiAgICAgICAgICAgIHZhbElzU3ltYm9sID0gaXNTeW1ib2wodmFsdWUpO1xuXG4gICAgICAgIHZhciBvdGhJc0RlZmluZWQgPSBvdGhlciAhPT0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgb3RoSXNOdWxsID0gb3RoZXIgPT09IG51bGwsXG4gICAgICAgICAgICBvdGhJc1JlZmxleGl2ZSA9IG90aGVyID09PSBvdGhlcixcbiAgICAgICAgICAgIG90aElzU3ltYm9sID0gaXNTeW1ib2wob3RoZXIpO1xuXG4gICAgICAgIGlmICgoIW90aElzTnVsbCAmJiAhb3RoSXNTeW1ib2wgJiYgIXZhbElzU3ltYm9sICYmIHZhbHVlID4gb3RoZXIpIHx8XG4gICAgICAgICAgICAodmFsSXNTeW1ib2wgJiYgb3RoSXNEZWZpbmVkICYmIG90aElzUmVmbGV4aXZlICYmICFvdGhJc051bGwgJiYgIW90aElzU3ltYm9sKSB8fFxuICAgICAgICAgICAgKHZhbElzTnVsbCAmJiBvdGhJc0RlZmluZWQgJiYgb3RoSXNSZWZsZXhpdmUpIHx8XG4gICAgICAgICAgICAoIXZhbElzRGVmaW5lZCAmJiBvdGhJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICF2YWxJc1JlZmxleGl2ZSkge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoIXZhbElzTnVsbCAmJiAhdmFsSXNTeW1ib2wgJiYgIW90aElzU3ltYm9sICYmIHZhbHVlIDwgb3RoZXIpIHx8XG4gICAgICAgICAgICAob3RoSXNTeW1ib2wgJiYgdmFsSXNEZWZpbmVkICYmIHZhbElzUmVmbGV4aXZlICYmICF2YWxJc051bGwgJiYgIXZhbElzU3ltYm9sKSB8fFxuICAgICAgICAgICAgKG90aElzTnVsbCAmJiB2YWxJc0RlZmluZWQgJiYgdmFsSXNSZWZsZXhpdmUpIHx8XG4gICAgICAgICAgICAoIW90aElzRGVmaW5lZCAmJiB2YWxJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICFvdGhJc1JlZmxleGl2ZSkge1xuICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCBieSBgXy5vcmRlckJ5YCB0byBjb21wYXJlIG11bHRpcGxlIHByb3BlcnRpZXMgb2YgYSB2YWx1ZSB0byBhbm90aGVyXG4gICAgICogYW5kIHN0YWJsZSBzb3J0IHRoZW0uXG4gICAgICpcbiAgICAgKiBJZiBgb3JkZXJzYCBpcyB1bnNwZWNpZmllZCwgYWxsIHZhbHVlcyBhcmUgc29ydGVkIGluIGFzY2VuZGluZyBvcmRlci4gT3RoZXJ3aXNlLFxuICAgICAqIHNwZWNpZnkgYW4gb3JkZXIgb2YgXCJkZXNjXCIgZm9yIGRlc2NlbmRpbmcgb3IgXCJhc2NcIiBmb3IgYXNjZW5kaW5nIHNvcnQgb3JkZXJcbiAgICAgKiBvZiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW5bXXxzdHJpbmdbXX0gb3JkZXJzIFRoZSBvcmRlciB0byBzb3J0IGJ5IGZvciBlYWNoIHByb3BlcnR5LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHNvcnQgb3JkZXIgaW5kaWNhdG9yIGZvciBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wYXJlTXVsdGlwbGUob2JqZWN0LCBvdGhlciwgb3JkZXJzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBvYmpDcml0ZXJpYSA9IG9iamVjdC5jcml0ZXJpYSxcbiAgICAgICAgICBvdGhDcml0ZXJpYSA9IG90aGVyLmNyaXRlcmlhLFxuICAgICAgICAgIGxlbmd0aCA9IG9iakNyaXRlcmlhLmxlbmd0aCxcbiAgICAgICAgICBvcmRlcnNMZW5ndGggPSBvcmRlcnMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gY29tcGFyZUFzY2VuZGluZyhvYmpDcml0ZXJpYVtpbmRleF0sIG90aENyaXRlcmlhW2luZGV4XSk7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICBpZiAoaW5kZXggPj0gb3JkZXJzTGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgb3JkZXIgPSBvcmRlcnNbaW5kZXhdO1xuICAgICAgICAgIHJldHVybiByZXN1bHQgKiAob3JkZXIgPT0gJ2Rlc2MnID8gLTEgOiAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRml4ZXMgYW4gYEFycmF5I3NvcnRgIGJ1ZyBpbiB0aGUgSlMgZW5naW5lIGVtYmVkZGVkIGluIEFkb2JlIGFwcGxpY2F0aW9uc1xuICAgICAgLy8gdGhhdCBjYXVzZXMgaXQsIHVuZGVyIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcywgdG8gcHJvdmlkZSB0aGUgc2FtZSB2YWx1ZSBmb3JcbiAgICAgIC8vIGBvYmplY3RgIGFuZCBgb3RoZXJgLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2phc2hrZW5hcy91bmRlcnNjb3JlL3B1bGwvMTI0N1xuICAgICAgLy8gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgIC8vXG4gICAgICAvLyBUaGlzIGFsc28gZW5zdXJlcyBhIHN0YWJsZSBzb3J0IGluIFY4IGFuZCBvdGhlciBlbmdpbmVzLlxuICAgICAgLy8gU2VlIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTkwIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0LmluZGV4IC0gb3RoZXIuaW5kZXg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSB0aGF0IGlzIHRoZSBjb21wb3NpdGlvbiBvZiBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMsXG4gICAgICogcGxhY2Vob2xkZXJzLCBhbmQgcHJvdmlkZWQgYXJndW1lbnRzIGludG8gYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGhvbGRlcnMgVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAgICAgKiBAcGFyYW1zIHtib29sZWFufSBbaXNDdXJyaWVkXSBTcGVjaWZ5IGNvbXBvc2luZyBmb3IgYSBjdXJyaWVkIGZ1bmN0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbXBvc2VkIGFyZ3VtZW50cy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycywgaXNDdXJyaWVkKSB7XG4gICAgICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3MubGVuZ3RoLFxuICAgICAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgICAgICBsZWZ0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICAgIHJhbmdlTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3NMZW5ndGggLSBob2xkZXJzTGVuZ3RoLCAwKSxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgcmFuZ2VMZW5ndGgpLFxuICAgICAgICAgIGlzVW5jdXJyaWVkID0gIWlzQ3VycmllZDtcblxuICAgICAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgICAgICByZXN1bHRbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gICAgICB9XG4gICAgICB3aGlsZSAoKythcmdzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgICAgIGlmIChpc1VuY3VycmllZCB8fCBhcmdzSW5kZXggPCBhcmdzTGVuZ3RoKSB7XG4gICAgICAgICAgcmVzdWx0W2hvbGRlcnNbYXJnc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHdoaWxlIChyYW5nZUxlbmd0aC0tKSB7XG4gICAgICAgIHJlc3VsdFtsZWZ0SW5kZXgrK10gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBjb21wb3NlQXJnc2AgZXhjZXB0IHRoYXQgdGhlIGFyZ3VtZW50cyBjb21wb3NpdGlvblxuICAgICAqIGlzIHRhaWxvcmVkIGZvciBgXy5wYXJ0aWFsUmlnaHRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbXMge2Jvb2xlYW59IFtpc0N1cnJpZWRdIFNwZWNpZnkgY29tcG9zaW5nIGZvciBhIGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHMsIGhvbGRlcnMsIGlzQ3VycmllZCkge1xuICAgICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICAgIGFyZ3NMZW5ndGggPSBhcmdzLmxlbmd0aCxcbiAgICAgICAgICBob2xkZXJzSW5kZXggPSAtMSxcbiAgICAgICAgICBob2xkZXJzTGVuZ3RoID0gaG9sZGVycy5sZW5ndGgsXG4gICAgICAgICAgcmlnaHRJbmRleCA9IC0xLFxuICAgICAgICAgIHJpZ2h0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICAgIHJhbmdlTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3NMZW5ndGggLSBob2xkZXJzTGVuZ3RoLCAwKSxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShyYW5nZUxlbmd0aCArIHJpZ2h0TGVuZ3RoKSxcbiAgICAgICAgICBpc1VuY3VycmllZCA9ICFpc0N1cnJpZWQ7XG5cbiAgICAgIHdoaWxlICgrK2FyZ3NJbmRleCA8IHJhbmdlTGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFthcmdzSW5kZXhdID0gYXJnc1thcmdzSW5kZXhdO1xuICAgICAgfVxuICAgICAgdmFyIG9mZnNldCA9IGFyZ3NJbmRleDtcbiAgICAgIHdoaWxlICgrK3JpZ2h0SW5kZXggPCByaWdodExlbmd0aCkge1xuICAgICAgICByZXN1bHRbb2Zmc2V0ICsgcmlnaHRJbmRleF0gPSBwYXJ0aWFsc1tyaWdodEluZGV4XTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2hvbGRlcnNJbmRleCA8IGhvbGRlcnNMZW5ndGgpIHtcbiAgICAgICAgaWYgKGlzVW5jdXJyaWVkIHx8IGFyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICAgICAgICByZXN1bHRbb2Zmc2V0ICsgaG9sZGVyc1tob2xkZXJzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvcGllcyB0aGUgdmFsdWVzIG9mIGBzb3VyY2VgIHRvIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXk9W11dIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyB0by5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5QXJyYXkoc291cmNlLCBhcnJheSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcblxuICAgICAgYXJyYXkgfHwgKGFycmF5ID0gQXJyYXkobGVuZ3RoKSk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvcGllcyBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb20uXG4gICAgICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IGlkZW50aWZpZXJzIHRvIGNvcHkuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvcGllZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5T2JqZWN0KHNvdXJjZSwgcHJvcHMsIG9iamVjdCwgY3VzdG9taXplcikge1xuICAgICAgdmFyIGlzTmV3ID0gIW9iamVjdDtcbiAgICAgIG9iamVjdCB8fCAob2JqZWN0ID0ge30pO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG5cbiAgICAgICAgdmFyIG5ld1ZhbHVlID0gY3VzdG9taXplclxuICAgICAgICAgID8gY3VzdG9taXplcihvYmplY3Rba2V5XSwgc291cmNlW2tleV0sIGtleSwgb2JqZWN0LCBzb3VyY2UpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBuZXdWYWx1ZSA9IHNvdXJjZVtrZXldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc05ldykge1xuICAgICAgICAgIGJhc2VBc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgbmV3VmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBuZXdWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIG93biBzeW1ib2xzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBzeW1ib2xzIGZyb20uXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBzeW1ib2xzIHRvLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29weVN5bWJvbHMoc291cmNlLCBvYmplY3QpIHtcbiAgICAgIHJldHVybiBjb3B5T2JqZWN0KHNvdXJjZSwgZ2V0U3ltYm9scyhzb3VyY2UpLCBvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvcGllcyBvd24gYW5kIGluaGVyaXRlZCBzeW1ib2xzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBzeW1ib2xzIGZyb20uXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBzeW1ib2xzIHRvLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29weVN5bWJvbHNJbihzb3VyY2UsIG9iamVjdCkge1xuICAgICAgcmV0dXJuIGNvcHlPYmplY3Qoc291cmNlLCBnZXRTeW1ib2xzSW4oc291cmNlKSwgb2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5ncm91cEJ5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYWNjdW11bGF0b3IgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpbml0aWFsaXplcl0gVGhlIGFjY3VtdWxhdG9yIG9iamVjdCBpbml0aWFsaXplci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhZ2dyZWdhdG9yIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUFnZ3JlZ2F0b3Ioc2V0dGVyLCBpbml0aWFsaXplcikge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5QWdncmVnYXRvciA6IGJhc2VBZ2dyZWdhdG9yLFxuICAgICAgICAgICAgYWNjdW11bGF0b3IgPSBpbml0aWFsaXplciA/IGluaXRpYWxpemVyKCkgOiB7fTtcblxuICAgICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBzZXR0ZXIsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSwgYWNjdW11bGF0b3IpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5hc3NpZ25gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhc3NpZ25lciBUaGUgZnVuY3Rpb24gdG8gYXNzaWduIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhc3NpZ25lciBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVBc3NpZ25lcihhc3NpZ25lcikge1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKG9iamVjdCwgc291cmNlcykge1xuICAgICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICAgIGxlbmd0aCA9IHNvdXJjZXMubGVuZ3RoLFxuICAgICAgICAgICAgY3VzdG9taXplciA9IGxlbmd0aCA+IDEgPyBzb3VyY2VzW2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZ3VhcmQgPSBsZW5ndGggPiAyID8gc291cmNlc1syXSA6IHVuZGVmaW5lZDtcblxuICAgICAgICBjdXN0b21pemVyID0gKGFzc2lnbmVyLmxlbmd0aCA+IDMgJiYgdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICA/IChsZW5ndGgtLSwgY3VzdG9taXplcilcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwoc291cmNlc1swXSwgc291cmNlc1sxXSwgZ3VhcmQpKSB7XG4gICAgICAgICAgY3VzdG9taXplciA9IGxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiBjdXN0b21pemVyO1xuICAgICAgICAgIGxlbmd0aCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNbaW5kZXhdO1xuICAgICAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgICAgIGFzc2lnbmVyKG9iamVjdCwgc291cmNlLCBpbmRleCwgY3VzdG9taXplcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYGJhc2VFYWNoYCBvciBgYmFzZUVhY2hSaWdodGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQmFzZUVhY2goZWFjaEZ1bmMsIGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7XG4gICAgICAgICAgcmV0dXJuIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGgsXG4gICAgICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xLFxuICAgICAgICAgICAgaXRlcmFibGUgPSBPYmplY3QoY29sbGVjdGlvbik7XG5cbiAgICAgICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVbaW5kZXhdLCBpbmRleCwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgbWV0aG9kcyBsaWtlIGBfLmZvckluYCBhbmQgYF8uZm9yT3duYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYmFzZSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVCYXNlRm9yKGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCwgaXRlcmF0ZWUsIGtleXNGdW5jKSB7XG4gICAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgICAgaXRlcmFibGUgPSBPYmplY3Qob2JqZWN0KSxcbiAgICAgICAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcbiAgICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICAgICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgICB2YXIga2V5ID0gcHJvcHNbZnJvbVJpZ2h0ID8gbGVuZ3RoIDogKytpbmRleF07XG4gICAgICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2tleV0sIGtleSwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBpbnZva2UgaXQgd2l0aCB0aGUgb3B0aW9uYWwgYHRoaXNgXG4gICAgICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQmluZChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnKSB7XG4gICAgICB2YXIgaXNCaW5kID0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHLFxuICAgICAgICAgIEN0b3IgPSBjcmVhdGVDdG9yKGZ1bmMpO1xuXG4gICAgICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgICAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSByb290ICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkoaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gd3JhcHBlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5sb3dlckZpcnN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1ldGhvZE5hbWUgVGhlIG5hbWUgb2YgdGhlIGBTdHJpbmdgIGNhc2UgbWV0aG9kIHRvIHVzZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXNlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUNhc2VGaXJzdChtZXRob2ROYW1lKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG5cbiAgICAgICAgdmFyIHN0clN5bWJvbHMgPSBoYXNVbmljb2RlKHN0cmluZylcbiAgICAgICAgICA/IHN0cmluZ1RvQXJyYXkoc3RyaW5nKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIHZhciBjaHIgPSBzdHJTeW1ib2xzXG4gICAgICAgICAgPyBzdHJTeW1ib2xzWzBdXG4gICAgICAgICAgOiBzdHJpbmcuY2hhckF0KDApO1xuXG4gICAgICAgIHZhciB0cmFpbGluZyA9IHN0clN5bWJvbHNcbiAgICAgICAgICA/IGNhc3RTbGljZShzdHJTeW1ib2xzLCAxKS5qb2luKCcnKVxuICAgICAgICAgIDogc3RyaW5nLnNsaWNlKDEpO1xuXG4gICAgICAgIHJldHVybiBjaHJbbWV0aG9kTmFtZV0oKSArIHRyYWlsaW5nO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5jYW1lbENhc2VgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gY29tYmluZSBlYWNoIHdvcmQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29tcG91bmRlciBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVDb21wb3VuZGVyKGNhbGxiYWNrKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBhcnJheVJlZHVjZSh3b3JkcyhkZWJ1cnIoc3RyaW5nKS5yZXBsYWNlKHJlQXBvcywgJycpKSwgY2FsbGJhY2ssICcnKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAgICAgKiB3aGV0aGVyIGl0IHdhcyBpbnZva2VkIGFzIHBhcnQgb2YgYSBgbmV3YCBleHByZXNzaW9uIG9yIGJ5IGBjYWxsYCBvciBgYXBwbHlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBDdG9yIFRoZSBjb25zdHJ1Y3RvciB0byB3cmFwLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQ3RvcihDdG9yKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vIFVzZSBhIGBzd2l0Y2hgIHN0YXRlbWVudCB0byB3b3JrIHdpdGggY2xhc3MgY29uc3RydWN0b3JzLiBTZWVcbiAgICAgICAgLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtZWNtYXNjcmlwdC1mdW5jdGlvbi1vYmplY3RzLWNhbGwtdGhpc2FyZ3VtZW50LWFyZ3VtZW50c2xpc3RcbiAgICAgICAgLy8gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgICBjYXNlIDA6IHJldHVybiBuZXcgQ3RvcjtcbiAgICAgICAgICBjYXNlIDE6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdKTtcbiAgICAgICAgICBjYXNlIDI6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICBjYXNlIDM6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICBjYXNlIDQ6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgICAgICAgICBjYXNlIDU6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdKTtcbiAgICAgICAgICBjYXNlIDY6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdKTtcbiAgICAgICAgICBjYXNlIDc6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdLCBhcmdzWzZdKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGhpc0JpbmRpbmcgPSBiYXNlQ3JlYXRlKEN0b3IucHJvdG90eXBlKSxcbiAgICAgICAgICAgIHJlc3VsdCA9IEN0b3IuYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuXG4gICAgICAgIC8vIE1pbWljIHRoZSBjb25zdHJ1Y3RvcidzIGByZXR1cm5gIGJlaGF2aW9yLlxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTMuMi4yIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgIHJldHVybiBpc09iamVjdChyZXN1bHQpID8gcmVzdWx0IDogdGhpc0JpbmRpbmc7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBlbmFibGUgY3VycnlpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYXJpdHkgVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUN1cnJ5KGZ1bmMsIGJpdG1hc2ssIGFyaXR5KSB7XG4gICAgICB2YXIgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyID0gZ2V0SG9sZGVyKHdyYXBwZXIpO1xuXG4gICAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBob2xkZXJzID0gKGxlbmd0aCA8IDMgJiYgYXJnc1swXSAhPT0gcGxhY2Vob2xkZXIgJiYgYXJnc1tsZW5ndGggLSAxXSAhPT0gcGxhY2Vob2xkZXIpXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogcmVwbGFjZUhvbGRlcnMoYXJncywgcGxhY2Vob2xkZXIpO1xuXG4gICAgICAgIGxlbmd0aCAtPSBob2xkZXJzLmxlbmd0aDtcbiAgICAgICAgaWYgKGxlbmd0aCA8IGFyaXR5KSB7XG4gICAgICAgICAgcmV0dXJuIGNyZWF0ZVJlY3VycnkoXG4gICAgICAgICAgICBmdW5jLCBiaXRtYXNrLCBjcmVhdGVIeWJyaWQsIHdyYXBwZXIucGxhY2Vob2xkZXIsIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGFyZ3MsIGhvbGRlcnMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBhcml0eSAtIGxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICAgICAgcmV0dXJuIGFwcGx5KGZuLCB0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5maW5kYCBvciBgXy5maW5kTGFzdGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZpbmRJbmRleEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIGNvbGxlY3Rpb24gaW5kZXguXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGaW5kKGZpbmRJbmRleEZ1bmMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICAgICAgICB2YXIgaXRlcmFibGUgPSBPYmplY3QoY29sbGVjdGlvbik7XG4gICAgICAgIGlmICghaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgICAgICB2YXIgaXRlcmF0ZWUgPSBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpO1xuICAgICAgICAgIGNvbGxlY3Rpb24gPSBrZXlzKGNvbGxlY3Rpb24pO1xuICAgICAgICAgIHByZWRpY2F0ZSA9IGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSk7IH07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGluZGV4ID0gZmluZEluZGV4RnVuYyhjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21JbmRleCk7XG4gICAgICAgIHJldHVybiBpbmRleCA+IC0xID8gaXRlcmFibGVbaXRlcmF0ZWUgPyBjb2xsZWN0aW9uW2luZGV4XSA6IGluZGV4XSA6IHVuZGVmaW5lZDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBfLmZsb3dgIG9yIGBfLmZsb3dSaWdodGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZsb3cgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlRmxvdyhmcm9tUmlnaHQpIHtcbiAgICAgIHJldHVybiBmbGF0UmVzdChmdW5jdGlvbihmdW5jcykge1xuICAgICAgICB2YXIgbGVuZ3RoID0gZnVuY3MubGVuZ3RoLFxuICAgICAgICAgICAgaW5kZXggPSBsZW5ndGgsXG4gICAgICAgICAgICBwcmVyZXEgPSBMb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS50aHJ1O1xuXG4gICAgICAgIGlmIChmcm9tUmlnaHQpIHtcbiAgICAgICAgICBmdW5jcy5yZXZlcnNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgICB2YXIgZnVuYyA9IGZ1bmNzW2luZGV4XTtcbiAgICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocHJlcmVxICYmICF3cmFwcGVyICYmIGdldEZ1bmNOYW1lKGZ1bmMpID09ICd3cmFwcGVyJykge1xuICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSBuZXcgTG9kYXNoV3JhcHBlcihbXSwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gd3JhcHBlciA/IGluZGV4IDogbGVuZ3RoO1xuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGZ1bmMgPSBmdW5jc1tpbmRleF07XG5cbiAgICAgICAgICB2YXIgZnVuY05hbWUgPSBnZXRGdW5jTmFtZShmdW5jKSxcbiAgICAgICAgICAgICAgZGF0YSA9IGZ1bmNOYW1lID09ICd3cmFwcGVyJyA/IGdldERhdGEoZnVuYykgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICBpZiAoZGF0YSAmJiBpc0xhemlhYmxlKGRhdGFbMF0pICYmXG4gICAgICAgICAgICAgICAgZGF0YVsxXSA9PSAoV1JBUF9BUllfRkxBRyB8IFdSQVBfQ1VSUllfRkxBRyB8IFdSQVBfUEFSVElBTF9GTEFHIHwgV1JBUF9SRUFSR19GTEFHKSAmJlxuICAgICAgICAgICAgICAgICFkYXRhWzRdLmxlbmd0aCAmJiBkYXRhWzldID09IDFcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICB3cmFwcGVyID0gd3JhcHBlcltnZXRGdW5jTmFtZShkYXRhWzBdKV0uYXBwbHkod3JhcHBlciwgZGF0YVszXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdyYXBwZXIgPSAoZnVuYy5sZW5ndGggPT0gMSAmJiBpc0xhemlhYmxlKGZ1bmMpKVxuICAgICAgICAgICAgICA/IHdyYXBwZXJbZnVuY05hbWVdKClcbiAgICAgICAgICAgICAgOiB3cmFwcGVyLnRocnUoZnVuYyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICAgICAgdmFsdWUgPSBhcmdzWzBdO1xuXG4gICAgICAgICAgaWYgKHdyYXBwZXIgJiYgYXJncy5sZW5ndGggPT0gMSAmJiBpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHdyYXBwZXIucGxhbnQodmFsdWUpLnZhbHVlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgICAgIHJlc3VsdCA9IGxlbmd0aCA/IGZ1bmNzW2luZGV4XS5hcHBseSh0aGlzLCBhcmdzKSA6IHZhbHVlO1xuXG4gICAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGZ1bmNzW2luZGV4XS5jYWxsKHRoaXMsIHJlc3VsdCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gaW52b2tlIGl0IHdpdGggb3B0aW9uYWwgYHRoaXNgXG4gICAgICogYmluZGluZyBvZiBgdGhpc0FyZ2AsIHBhcnRpYWwgYXBwbGljYXRpb24sIGFuZCBjdXJyeWluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxzdHJpbmd9IGZ1bmMgVGhlIGZ1bmN0aW9uIG9yIG1ldGhvZCBuYW1lIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gICAgICogIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzUmlnaHRdIFRoZSBhcmd1bWVudHMgdG8gYXBwZW5kIHRvIHRob3NlIHByb3ZpZGVkXG4gICAgICogIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUh5YnJpZChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgICAgIHZhciBpc0FyeSA9IGJpdG1hc2sgJiBXUkFQX0FSWV9GTEFHLFxuICAgICAgICAgIGlzQmluZCA9IGJpdG1hc2sgJiBXUkFQX0JJTkRfRkxBRyxcbiAgICAgICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0tFWV9GTEFHLFxuICAgICAgICAgIGlzQ3VycmllZCA9IGJpdG1hc2sgJiAoV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKSxcbiAgICAgICAgICBpc0ZsaXAgPSBiaXRtYXNrICYgV1JBUF9GTElQX0ZMQUcsXG4gICAgICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgICAgICBpbmRleCA9IGxlbmd0aDtcblxuICAgICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICAgIGFyZ3NbaW5kZXhdID0gYXJndW1lbnRzW2luZGV4XTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNDdXJyaWVkKSB7XG4gICAgICAgICAgdmFyIHBsYWNlaG9sZGVyID0gZ2V0SG9sZGVyKHdyYXBwZXIpLFxuICAgICAgICAgICAgICBob2xkZXJzQ291bnQgPSBjb3VudEhvbGRlcnMoYXJncywgcGxhY2Vob2xkZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJ0aWFscykge1xuICAgICAgICAgIGFyZ3MgPSBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycywgaXNDdXJyaWVkKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFydGlhbHNSaWdodCkge1xuICAgICAgICAgIGFyZ3MgPSBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCwgaXNDdXJyaWVkKTtcbiAgICAgICAgfVxuICAgICAgICBsZW5ndGggLT0gaG9sZGVyc0NvdW50O1xuICAgICAgICBpZiAoaXNDdXJyaWVkICYmIGxlbmd0aCA8IGFyaXR5KSB7XG4gICAgICAgICAgdmFyIG5ld0hvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG4gICAgICAgICAgcmV0dXJuIGNyZWF0ZVJlY3VycnkoXG4gICAgICAgICAgICBmdW5jLCBiaXRtYXNrLCBjcmVhdGVIeWJyaWQsIHdyYXBwZXIucGxhY2Vob2xkZXIsIHRoaXNBcmcsXG4gICAgICAgICAgICBhcmdzLCBuZXdIb2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkgLSBsZW5ndGhcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0aGlzQmluZGluZyA9IGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLFxuICAgICAgICAgICAgZm4gPSBpc0JpbmRLZXkgPyB0aGlzQmluZGluZ1tmdW5jXSA6IGZ1bmM7XG5cbiAgICAgICAgbGVuZ3RoID0gYXJncy5sZW5ndGg7XG4gICAgICAgIGlmIChhcmdQb3MpIHtcbiAgICAgICAgICBhcmdzID0gcmVvcmRlcihhcmdzLCBhcmdQb3MpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzRmxpcCAmJiBsZW5ndGggPiAxKSB7XG4gICAgICAgICAgYXJncy5yZXZlcnNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzQXJ5ICYmIGFyeSA8IGxlbmd0aCkge1xuICAgICAgICAgIGFyZ3MubGVuZ3RoID0gYXJ5O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzICYmIHRoaXMgIT09IHJvb3QgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpIHtcbiAgICAgICAgICBmbiA9IEN0b3IgfHwgY3JlYXRlQ3Rvcihmbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXNCaW5kaW5nLCBhcmdzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmludmVydEJ5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYWNjdW11bGF0b3IgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHRvSXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIHRvIHJlc29sdmUgaXRlcmF0ZWVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGludmVydGVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUludmVydGVyKHNldHRlciwgdG9JdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VJbnZlcnRlcihvYmplY3QsIHNldHRlciwgdG9JdGVyYXRlZShpdGVyYXRlZSksIHt9KTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgYSBtYXRoZW1hdGljYWwgb3BlcmF0aW9uIG9uIHR3byB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9wZXJhdG9yIFRoZSBmdW5jdGlvbiB0byBwZXJmb3JtIHRoZSBvcGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtkZWZhdWx0VmFsdWVdIFRoZSB2YWx1ZSB1c2VkIGZvciBgdW5kZWZpbmVkYCBhcmd1bWVudHMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWF0aGVtYXRpY2FsIG9wZXJhdGlvbiBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVNYXRoT3BlcmF0aW9uKG9wZXJhdG9yLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSwgb3RoZXIpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgJiYgb3RoZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3RoZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG90aGVyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IHR5cGVvZiBvdGhlciA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdmFsdWUgPSBiYXNlVG9TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgb3RoZXIgPSBiYXNlVG9TdHJpbmcob3RoZXIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGJhc2VUb051bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICBvdGhlciA9IGJhc2VUb051bWJlcihvdGhlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdCA9IG9wZXJhdG9yKHZhbHVlLCBvdGhlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGxpa2UgYF8ub3ZlcmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFycmF5RnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGl0ZXJhdGVlcy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBvdmVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZU92ZXIoYXJyYXlGdW5jKSB7XG4gICAgICByZXR1cm4gZmxhdFJlc3QoZnVuY3Rpb24oaXRlcmF0ZWVzKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IGFycmF5TWFwKGl0ZXJhdGVlcywgYmFzZVVuYXJ5KGdldEl0ZXJhdGVlKCkpKTtcbiAgICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgICB2YXIgdGhpc0FyZyA9IHRoaXM7XG4gICAgICAgICAgcmV0dXJuIGFycmF5RnVuYyhpdGVyYXRlZXMsIGZ1bmN0aW9uKGl0ZXJhdGVlKSB7XG4gICAgICAgICAgICByZXR1cm4gYXBwbHkoaXRlcmF0ZWUsIHRoaXNBcmcsIGFyZ3MpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIHBhZGRpbmcgZm9yIGBzdHJpbmdgIGJhc2VkIG9uIGBsZW5ndGhgLiBUaGUgYGNoYXJzYCBzdHJpbmdcbiAgICAgKiBpcyB0cnVuY2F0ZWQgaWYgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGV4Y2VlZHMgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggVGhlIHBhZGRpbmcgbGVuZ3RoLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9JyAnXSBUaGUgc3RyaW5nIHVzZWQgYXMgcGFkZGluZy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBwYWRkaW5nIGZvciBgc3RyaW5nYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVQYWRkaW5nKGxlbmd0aCwgY2hhcnMpIHtcbiAgICAgIGNoYXJzID0gY2hhcnMgPT09IHVuZGVmaW5lZCA/ICcgJyA6IGJhc2VUb1N0cmluZyhjaGFycyk7XG5cbiAgICAgIHZhciBjaGFyc0xlbmd0aCA9IGNoYXJzLmxlbmd0aDtcbiAgICAgIGlmIChjaGFyc0xlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIGNoYXJzTGVuZ3RoID8gYmFzZVJlcGVhdChjaGFycywgbGVuZ3RoKSA6IGNoYXJzO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IGJhc2VSZXBlYXQoY2hhcnMsIG5hdGl2ZUNlaWwobGVuZ3RoIC8gc3RyaW5nU2l6ZShjaGFycykpKTtcbiAgICAgIHJldHVybiBoYXNVbmljb2RlKGNoYXJzKVxuICAgICAgICA/IGNhc3RTbGljZShzdHJpbmdUb0FycmF5KHJlc3VsdCksIDAsIGxlbmd0aCkuam9pbignJylcbiAgICAgICAgOiByZXN1bHQuc2xpY2UoMCwgbGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gaW52b2tlIGl0IHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nXG4gICAgICogb2YgYHRoaXNBcmdgIGFuZCBgcGFydGlhbHNgIHByZXBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gICAgICogIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVQYXJ0aWFsKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzKSB7XG4gICAgICB2YXIgaXNCaW5kID0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHLFxuICAgICAgICAgIEN0b3IgPSBjcmVhdGVDdG9yKGZ1bmMpO1xuXG4gICAgICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgICAgICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICAgICAgICBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgICAgICAgbGVmdExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgICAgICAgIGFyZ3MgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCksXG4gICAgICAgICAgICBmbiA9ICh0aGlzICYmIHRoaXMgIT09IHJvb3QgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpID8gQ3RvciA6IGZ1bmM7XG5cbiAgICAgICAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgICAgICAgIGFyZ3NbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgICAgICAgIGFyZ3NbbGVmdEluZGV4KytdID0gYXJndW1lbnRzWysrYXJnc0luZGV4XTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXBwbHkoZm4sIGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5yYW5nZWAgb3IgYF8ucmFuZ2VSaWdodGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJhbmdlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVJhbmdlKGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHN0YXJ0LCBlbmQsIHN0ZXApIHtcbiAgICAgICAgaWYgKHN0ZXAgJiYgdHlwZW9mIHN0ZXAgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoc3RhcnQsIGVuZCwgc3RlcCkpIHtcbiAgICAgICAgICBlbmQgPSBzdGVwID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIEVuc3VyZSB0aGUgc2lnbiBvZiBgLTBgIGlzIHByZXNlcnZlZC5cbiAgICAgICAgc3RhcnQgPSB0b0Zpbml0ZShzdGFydCk7XG4gICAgICAgIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGVuZCA9IHN0YXJ0O1xuICAgICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbmQgPSB0b0Zpbml0ZShlbmQpO1xuICAgICAgICB9XG4gICAgICAgIHN0ZXAgPSBzdGVwID09PSB1bmRlZmluZWQgPyAoc3RhcnQgPCBlbmQgPyAxIDogLTEpIDogdG9GaW5pdGUoc3RlcCk7XG4gICAgICAgIHJldHVybiBiYXNlUmFuZ2Uoc3RhcnQsIGVuZCwgc3RlcCwgZnJvbVJpZ2h0KTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgYSByZWxhdGlvbmFsIG9wZXJhdGlvbiBvbiB0d28gdmFsdWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcGVyYXRvciBUaGUgZnVuY3Rpb24gdG8gcGVyZm9ybSB0aGUgb3BlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlbGF0aW9uYWwgb3BlcmF0aW9uIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24ob3BlcmF0b3IpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSwgb3RoZXIpIHtcbiAgICAgICAgaWYgKCEodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnICYmIHR5cGVvZiBvdGhlciA9PSAnc3RyaW5nJykpIHtcbiAgICAgICAgICB2YWx1ZSA9IHRvTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICBvdGhlciA9IHRvTnVtYmVyKG90aGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3BlcmF0b3IodmFsdWUsIG90aGVyKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGNvbnRpbnVlIGN1cnJ5aW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gd3JhcEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNyZWF0ZSB0aGUgYGZ1bmNgIHdyYXBwZXIuXG4gICAgICogQHBhcmFtIHsqfSBwbGFjZWhvbGRlciBUaGUgcGxhY2Vob2xkZXIgdmFsdWUuXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0b1xuICAgICAqICB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtob2xkZXJzXSBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVJlY3VycnkoZnVuYywgYml0bWFzaywgd3JhcEZ1bmMsIHBsYWNlaG9sZGVyLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gICAgICB2YXIgaXNDdXJyeSA9IGJpdG1hc2sgJiBXUkFQX0NVUlJZX0ZMQUcsXG4gICAgICAgICAgbmV3SG9sZGVycyA9IGlzQ3VycnkgPyBob2xkZXJzIDogdW5kZWZpbmVkLFxuICAgICAgICAgIG5ld0hvbGRlcnNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBob2xkZXJzLFxuICAgICAgICAgIG5ld1BhcnRpYWxzID0gaXNDdXJyeSA/IHBhcnRpYWxzIDogdW5kZWZpbmVkLFxuICAgICAgICAgIG5ld1BhcnRpYWxzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogcGFydGlhbHM7XG5cbiAgICAgIGJpdG1hc2sgfD0gKGlzQ3VycnkgPyBXUkFQX1BBUlRJQUxfRkxBRyA6IFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHKTtcbiAgICAgIGJpdG1hc2sgJj0gfihpc0N1cnJ5ID8gV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcgOiBXUkFQX1BBUlRJQUxfRkxBRyk7XG5cbiAgICAgIGlmICghKGJpdG1hc2sgJiBXUkFQX0NVUlJZX0JPVU5EX0ZMQUcpKSB7XG4gICAgICAgIGJpdG1hc2sgJj0gfihXUkFQX0JJTkRfRkxBRyB8IFdSQVBfQklORF9LRVlfRkxBRyk7XG4gICAgICB9XG4gICAgICB2YXIgbmV3RGF0YSA9IFtcbiAgICAgICAgZnVuYywgYml0bWFzaywgdGhpc0FyZywgbmV3UGFydGlhbHMsIG5ld0hvbGRlcnMsIG5ld1BhcnRpYWxzUmlnaHQsXG4gICAgICAgIG5ld0hvbGRlcnNSaWdodCwgYXJnUG9zLCBhcnksIGFyaXR5XG4gICAgICBdO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gd3JhcEZ1bmMuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgICAgIGlmIChpc0xhemlhYmxlKGZ1bmMpKSB7XG4gICAgICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdC5wbGFjZWhvbGRlciA9IHBsYWNlaG9sZGVyO1xuICAgICAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhyZXN1bHQsIGZ1bmMsIGJpdG1hc2spO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLnJvdW5kYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1ldGhvZE5hbWUgVGhlIG5hbWUgb2YgdGhlIGBNYXRoYCBtZXRob2QgdG8gdXNlIHdoZW4gcm91bmRpbmcuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcm91bmQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUm91bmQobWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGZ1bmMgPSBNYXRoW21ldGhvZE5hbWVdO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG51bWJlciwgcHJlY2lzaW9uKSB7XG4gICAgICAgIG51bWJlciA9IHRvTnVtYmVyKG51bWJlcik7XG4gICAgICAgIHByZWNpc2lvbiA9IHByZWNpc2lvbiA9PSBudWxsID8gMCA6IG5hdGl2ZU1pbih0b0ludGVnZXIocHJlY2lzaW9uKSwgMjkyKTtcbiAgICAgICAgaWYgKHByZWNpc2lvbiAmJiBuYXRpdmVJc0Zpbml0ZShudW1iZXIpKSB7XG4gICAgICAgICAgLy8gU2hpZnQgd2l0aCBleHBvbmVudGlhbCBub3RhdGlvbiB0byBhdm9pZCBmbG9hdGluZy1wb2ludCBpc3N1ZXMuXG4gICAgICAgICAgLy8gU2VlIFtNRE5dKGh0dHBzOi8vbWRuLmlvL3JvdW5kI0V4YW1wbGVzKSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICAgIHZhciBwYWlyID0gKHRvU3RyaW5nKG51bWJlcikgKyAnZScpLnNwbGl0KCdlJyksXG4gICAgICAgICAgICAgIHZhbHVlID0gZnVuYyhwYWlyWzBdICsgJ2UnICsgKCtwYWlyWzFdICsgcHJlY2lzaW9uKSk7XG5cbiAgICAgICAgICBwYWlyID0gKHRvU3RyaW5nKHZhbHVlKSArICdlJykuc3BsaXQoJ2UnKTtcbiAgICAgICAgICByZXR1cm4gKyhwYWlyWzBdICsgJ2UnICsgKCtwYWlyWzFdIC0gcHJlY2lzaW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmMobnVtYmVyKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNldCBvYmplY3Qgb2YgYHZhbHVlc2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFkZCB0byB0aGUgc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBzZXQuXG4gICAgICovXG4gICAgdmFyIGNyZWF0ZVNldCA9ICEoU2V0ICYmICgxIC8gc2V0VG9BcnJheShuZXcgU2V0KFssLTBdKSlbMV0pID09IElORklOSVRZKSA/IG5vb3AgOiBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBuZXcgU2V0KHZhbHVlcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy50b1BhaXJzYCBvciBgXy50b1BhaXJzSW5gIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGEgZ2l2ZW4gb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhaXJzIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVRvUGFpcnMoa2V5c0Z1bmMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgdmFyIHRhZyA9IGdldFRhZyhvYmplY3QpO1xuICAgICAgICBpZiAodGFnID09IG1hcFRhZykge1xuICAgICAgICAgIHJldHVybiBtYXBUb0FycmF5KG9iamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhZyA9PSBzZXRUYWcpIHtcbiAgICAgICAgICByZXR1cm4gc2V0VG9QYWlycyhvYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNlVG9QYWlycyhvYmplY3QsIGtleXNGdW5jKG9iamVjdCkpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBlaXRoZXIgY3VycmllcyBvciBpbnZva2VzIGBmdW5jYCB3aXRoIG9wdGlvbmFsXG4gICAgICogYHRoaXNgIGJpbmRpbmcgYW5kIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxzdHJpbmd9IGZ1bmMgVGhlIGZ1bmN0aW9uIG9yIG1ldGhvZCBuYW1lIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gICAgICogICAgMSAtIGBfLmJpbmRgXG4gICAgICogICAgMiAtIGBfLmJpbmRLZXlgXG4gICAgICogICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gICAgICogICAgOCAtIGBfLmN1cnJ5YFxuICAgICAqICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICAgICAqICAgMzIgLSBgXy5wYXJ0aWFsYFxuICAgICAqICAgNjQgLSBgXy5wYXJ0aWFsUmlnaHRgXG4gICAgICogIDEyOCAtIGBfLnJlYXJnYFxuICAgICAqICAyNTYgLSBgXy5hcnlgXG4gICAgICogIDUxMiAtIGBfLmZsaXBgXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlV3JhcChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gICAgICB2YXIgaXNCaW5kS2V5ID0gYml0bWFzayAmIFdSQVBfQklORF9LRVlfRkxBRztcbiAgICAgIGlmICghaXNCaW5kS2V5ICYmIHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IHBhcnRpYWxzID8gcGFydGlhbHMubGVuZ3RoIDogMDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIGJpdG1hc2sgJj0gfihXUkFQX1BBUlRJQUxfRkxBRyB8IFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHKTtcbiAgICAgICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgYXJ5ID0gYXJ5ID09PSB1bmRlZmluZWQgPyBhcnkgOiBuYXRpdmVNYXgodG9JbnRlZ2VyKGFyeSksIDApO1xuICAgICAgYXJpdHkgPSBhcml0eSA9PT0gdW5kZWZpbmVkID8gYXJpdHkgOiB0b0ludGVnZXIoYXJpdHkpO1xuICAgICAgbGVuZ3RoIC09IGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDA7XG5cbiAgICAgIGlmIChiaXRtYXNrICYgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpIHtcbiAgICAgICAgdmFyIHBhcnRpYWxzUmlnaHQgPSBwYXJ0aWFscyxcbiAgICAgICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICAgICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgdmFyIGRhdGEgPSBpc0JpbmRLZXkgPyB1bmRlZmluZWQgOiBnZXREYXRhKGZ1bmMpO1xuXG4gICAgICB2YXIgbmV3RGF0YSA9IFtcbiAgICAgICAgZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCxcbiAgICAgICAgYXJnUG9zLCBhcnksIGFyaXR5XG4gICAgICBdO1xuXG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBtZXJnZURhdGEobmV3RGF0YSwgZGF0YSk7XG4gICAgICB9XG4gICAgICBmdW5jID0gbmV3RGF0YVswXTtcbiAgICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgICAgdGhpc0FyZyA9IG5ld0RhdGFbMl07XG4gICAgICBwYXJ0aWFscyA9IG5ld0RhdGFbM107XG4gICAgICBob2xkZXJzID0gbmV3RGF0YVs0XTtcbiAgICAgIGFyaXR5ID0gbmV3RGF0YVs5XSA9IG5ld0RhdGFbOV0gPT09IHVuZGVmaW5lZFxuICAgICAgICA/IChpc0JpbmRLZXkgPyAwIDogZnVuYy5sZW5ndGgpXG4gICAgICAgIDogbmF0aXZlTWF4KG5ld0RhdGFbOV0gLSBsZW5ndGgsIDApO1xuXG4gICAgICBpZiAoIWFyaXR5ICYmIGJpdG1hc2sgJiAoV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKSkge1xuICAgICAgICBiaXRtYXNrICY9IH4oV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKTtcbiAgICAgIH1cbiAgICAgIGlmICghYml0bWFzayB8fCBiaXRtYXNrID09IFdSQVBfQklORF9GTEFHKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcpO1xuICAgICAgfSBlbHNlIGlmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRyB8fCBiaXRtYXNrID09IFdSQVBfQ1VSUllfUklHSFRfRkxBRykge1xuICAgICAgICByZXN1bHQgPSBjcmVhdGVDdXJyeShmdW5jLCBiaXRtYXNrLCBhcml0eSk7XG4gICAgICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFdSQVBfUEFSVElBTF9GTEFHIHx8IGJpdG1hc2sgPT0gKFdSQVBfQklORF9GTEFHIHwgV1JBUF9QQVJUSUFMX0ZMQUcpKSAmJiAhaG9sZGVycy5sZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWQuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgICAgIH1cbiAgICAgIHZhciBzZXR0ZXIgPSBkYXRhID8gYmFzZVNldERhdGEgOiBzZXREYXRhO1xuICAgICAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKSwgZnVuYywgYml0bWFzayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCBieSBgXy5kZWZhdWx0c2AgdG8gY3VzdG9taXplIGl0cyBgXy5hc3NpZ25JbmAgdXNlIHRvIGFzc2lnbiBwcm9wZXJ0aWVzXG4gICAgICogb2Ygc291cmNlIG9iamVjdHMgdG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdCBmb3IgYWxsIGRlc3RpbmF0aW9uIHByb3BlcnRpZXNcbiAgICAgKiB0aGF0IHJlc29sdmUgdG8gYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gb2JqVmFsdWUgVGhlIGRlc3RpbmF0aW9uIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHNvdXJjZSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBwYXJlbnQgb2JqZWN0IG9mIGBvYmpWYWx1ZWAuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjdXN0b21EZWZhdWx0c0Fzc2lnbkluKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgIGlmIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgKGVxKG9ialZhbHVlLCBvYmplY3RQcm90b1trZXldKSAmJiAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSB7XG4gICAgICAgIHJldHVybiBzcmNWYWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLmRlZmF1bHRzRGVlcGAgdG8gY3VzdG9taXplIGl0cyBgXy5tZXJnZWAgdXNlIHRvIG1lcmdlIHNvdXJjZVxuICAgICAqIG9iamVjdHMgaW50byBkZXN0aW5hdGlvbiBvYmplY3RzIHRoYXQgYXJlIHBhc3NlZCB0aHJ1LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IG9ialZhbHVlIFRoZSBkZXN0aW5hdGlvbiB2YWx1ZS5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSBzb3VyY2UgdmFsdWUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBtZXJnZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBwYXJlbnQgb2JqZWN0IG9mIGBvYmpWYWx1ZWAuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgcGFyZW50IG9iamVjdCBvZiBgc3JjVmFsdWVgLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIHZhbHVlcyBhbmQgdGhlaXIgbWVyZ2VkXG4gICAgICogIGNvdW50ZXJwYXJ0cy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGN1c3RvbURlZmF1bHRzTWVyZ2Uob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjaykge1xuICAgICAgaWYgKGlzT2JqZWN0KG9ialZhbHVlKSAmJiBpc09iamVjdChzcmNWYWx1ZSkpIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgbWVyZ2Ugb2JqZWN0cyBhbmQgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIHN0YWNrLnNldChzcmNWYWx1ZSwgb2JqVmFsdWUpO1xuICAgICAgICBiYXNlTWVyZ2Uob2JqVmFsdWUsIHNyY1ZhbHVlLCB1bmRlZmluZWQsIGN1c3RvbURlZmF1bHRzTWVyZ2UsIHN0YWNrKTtcbiAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKHNyY1ZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLm9taXRgIHRvIGN1c3RvbWl6ZSBpdHMgYF8uY2xvbmVEZWVwYCB1c2UgdG8gb25seSBjbG9uZSBwbGFpblxuICAgICAqIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB1bmNsb25lZCB2YWx1ZSBvciBgdW5kZWZpbmVkYCB0byBkZWZlciBjbG9uaW5nIHRvIGBfLmNsb25lRGVlcGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3VzdG9tT21pdENsb25lKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNQbGFpbk9iamVjdCh2YWx1ZSkgPyB1bmRlZmluZWQgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGFycmF5cyB3aXRoIHN1cHBvcnQgZm9yXG4gICAgICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBhcnJheWAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFycmF5cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgb3RoTGVuZ3RoID0gb3RoZXIubGVuZ3RoO1xuXG4gICAgICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzUGFydGlhbCAmJiBvdGhMZW5ndGggPiBhcnJMZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gICAgICB2YXIgYXJyU3RhY2tlZCA9IHN0YWNrLmdldChhcnJheSk7XG4gICAgICB2YXIgb3RoU3RhY2tlZCA9IHN0YWNrLmdldChvdGhlcik7XG4gICAgICBpZiAoYXJyU3RhY2tlZCAmJiBvdGhTdGFja2VkKSB7XG4gICAgICAgIHJldHVybiBhcnJTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gYXJyYXk7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgICAgIHNlZW4gPSAoYml0bWFzayAmIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpID8gbmV3IFNldENhY2hlIDogdW5kZWZpbmVkO1xuXG4gICAgICBzdGFjay5zZXQoYXJyYXksIG90aGVyKTtcbiAgICAgIHN0YWNrLnNldChvdGhlciwgYXJyYXkpO1xuXG4gICAgICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGFyckxlbmd0aCkge1xuICAgICAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XTtcblxuICAgICAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgICAgIHZhciBjb21wYXJlZCA9IGlzUGFydGlhbFxuICAgICAgICAgICAgPyBjdXN0b21pemVyKG90aFZhbHVlLCBhcnJWYWx1ZSwgaW5kZXgsIG90aGVyLCBhcnJheSwgc3RhY2spXG4gICAgICAgICAgICA6IGN1c3RvbWl6ZXIoYXJyVmFsdWUsIG90aFZhbHVlLCBpbmRleCwgYXJyYXksIG90aGVyLCBzdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbXBhcmVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoY29tcGFyZWQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSBmYWxzZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBpZiAoc2Vlbikge1xuICAgICAgICAgIGlmICghYXJyYXlTb21lKG90aGVyLCBmdW5jdGlvbihvdGhWYWx1ZSwgb3RoSW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNhY2hlSGFzKHNlZW4sIG90aEluZGV4KSAmJlxuICAgICAgICAgICAgICAgICAgICAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBzZWVuLnB1c2gob3RoSW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSkpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEoXG4gICAgICAgICAgICAgIGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fFxuICAgICAgICAgICAgICAgIGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzdGFja1snZGVsZXRlJ10oYXJyYXkpO1xuICAgICAgc3RhY2tbJ2RlbGV0ZSddKG90aGVyKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBjb21wYXJpbmcgb2JqZWN0cyBvZlxuICAgICAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNvbXBhcmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gICAgICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0cyB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgc3dpdGNoICh0YWcpIHtcbiAgICAgICAgY2FzZSBkYXRhVmlld1RhZzpcbiAgICAgICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgICAgIChvYmplY3QuYnl0ZU9mZnNldCAhPSBvdGhlci5ieXRlT2Zmc2V0KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvYmplY3QgPSBvYmplY3QuYnVmZmVyO1xuICAgICAgICAgIG90aGVyID0gb3RoZXIuYnVmZmVyO1xuXG4gICAgICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICAgICAgaWYgKChvYmplY3QuYnl0ZUxlbmd0aCAhPSBvdGhlci5ieXRlTGVuZ3RoKSB8fFxuICAgICAgICAgICAgICAhZXF1YWxGdW5jKG5ldyBVaW50OEFycmF5KG9iamVjdCksIG5ldyBVaW50OEFycmF5KG90aGVyKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgY2FzZSBib29sVGFnOlxuICAgICAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgICAgICAgIC8vIENvZXJjZSBib29sZWFucyB0byBgMWAgb3IgYDBgIGFuZCBkYXRlcyB0byBtaWxsaXNlY29uZHMuXG4gICAgICAgICAgLy8gSW52YWxpZCBkYXRlcyBhcmUgY29lcmNlZCB0byBgTmFOYC5cbiAgICAgICAgICByZXR1cm4gZXEoK29iamVjdCwgK290aGVyKTtcblxuICAgICAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgICAgIHJldHVybiBvYmplY3QubmFtZSA9PSBvdGhlci5uYW1lICYmIG9iamVjdC5tZXNzYWdlID09IG90aGVyLm1lc3NhZ2U7XG5cbiAgICAgICAgY2FzZSByZWdleHBUYWc6XG4gICAgICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MsIHByaW1pdGl2ZXMgYW5kIG9iamVjdHMsXG4gICAgICAgICAgLy8gYXMgZXF1YWwuIFNlZSBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcmVnZXhwLnByb3RvdHlwZS50b3N0cmluZ1xuICAgICAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgICAgcmV0dXJuIG9iamVjdCA9PSAob3RoZXIgKyAnJyk7XG5cbiAgICAgICAgY2FzZSBtYXBUYWc6XG4gICAgICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5O1xuXG4gICAgICAgIGNhc2Ugc2V0VGFnOlxuICAgICAgICAgIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUc7XG4gICAgICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpO1xuXG4gICAgICAgICAgaWYgKG9iamVjdC5zaXplICE9IG90aGVyLnNpemUgJiYgIWlzUGFydGlhbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gICAgICAgICAgdmFyIHN0YWNrZWQgPSBzdGFjay5nZXQob2JqZWN0KTtcbiAgICAgICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHN0YWNrZWQgPT0gb3RoZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRztcblxuICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICAgIHN0YWNrLnNldChvYmplY3QsIG90aGVyKTtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gZXF1YWxBcnJheXMoY29udmVydChvYmplY3QpLCBjb252ZXJ0KG90aGVyKSwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKG9iamVjdCk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcblxuICAgICAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgICAgICBpZiAoc3ltYm9sVmFsdWVPZikge1xuICAgICAgICAgICAgcmV0dXJuIHN5bWJvbFZhbHVlT2YuY2FsbChvYmplY3QpID09IHN5bWJvbFZhbHVlT2YuY2FsbChvdGhlcik7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3Igb2JqZWN0cyB3aXRoIHN1cHBvcnQgZm9yXG4gICAgICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgICAgICBvYmpQcm9wcyA9IGdldEFsbEtleXMob2JqZWN0KSxcbiAgICAgICAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsXG4gICAgICAgICAgb3RoUHJvcHMgPSBnZXRBbGxLZXlzKG90aGVyKSxcbiAgICAgICAgICBvdGhMZW5ndGggPSBvdGhQcm9wcy5sZW5ndGg7XG5cbiAgICAgIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc1BhcnRpYWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gb2JqTGVuZ3RoO1xuICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgdmFyIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICAgICAgaWYgKCEoaXNQYXJ0aWFsID8ga2V5IGluIG90aGVyIDogaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwga2V5KSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gICAgICB2YXIgb2JqU3RhY2tlZCA9IHN0YWNrLmdldChvYmplY3QpO1xuICAgICAgdmFyIG90aFN0YWNrZWQgPSBzdGFjay5nZXQob3RoZXIpO1xuICAgICAgaWYgKG9ialN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgICAgICByZXR1cm4gb2JqU3RhY2tlZCA9PSBvdGhlciAmJiBvdGhTdGFja2VkID09IG9iamVjdDtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSB0cnVlO1xuICAgICAgc3RhY2suc2V0KG9iamVjdCwgb3RoZXIpO1xuICAgICAgc3RhY2suc2V0KG90aGVyLCBvYmplY3QpO1xuXG4gICAgICB2YXIgc2tpcEN0b3IgPSBpc1BhcnRpYWw7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IG9iakxlbmd0aCkge1xuICAgICAgICBrZXkgPSBvYmpQcm9wc1tpbmRleF07XG4gICAgICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldO1xuXG4gICAgICAgIGlmIChjdXN0b21pemVyKSB7XG4gICAgICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsXG4gICAgICAgICAgICA/IGN1c3RvbWl6ZXIob3RoVmFsdWUsIG9ialZhbHVlLCBrZXksIG90aGVyLCBvYmplY3QsIHN0YWNrKVxuICAgICAgICAgICAgOiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSwga2V5LCBvYmplY3QsIG90aGVyLCBzdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIGlmICghKGNvbXBhcmVkID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyAob2JqVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSlcbiAgICAgICAgICAgICAgOiBjb21wYXJlZFxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXN1bHQgJiYgIXNraXBDdG9yKSB7XG4gICAgICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICAgICAgb3RoQ3RvciA9IG90aGVyLmNvbnN0cnVjdG9yO1xuXG4gICAgICAgIC8vIE5vbiBgT2JqZWN0YCBvYmplY3QgaW5zdGFuY2VzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWFsLlxuICAgICAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICAgICAoJ2NvbnN0cnVjdG9yJyBpbiBvYmplY3QgJiYgJ2NvbnN0cnVjdG9yJyBpbiBvdGhlcikgJiZcbiAgICAgICAgICAgICEodHlwZW9mIG9iakN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBvYmpDdG9yIGluc3RhbmNlb2Ygb2JqQ3RvciAmJlxuICAgICAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTtcbiAgICAgIHN0YWNrWydkZWxldGUnXShvdGhlcik7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVJlc3RgIHdoaWNoIGZsYXR0ZW5zIHRoZSByZXN0IGFycmF5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXRSZXN0KGZ1bmMpIHtcbiAgICAgIHJldHVybiBzZXRUb1N0cmluZyhvdmVyUmVzdChmdW5jLCB1bmRlZmluZWQsIGZsYXR0ZW4pLCBmdW5jICsgJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldEFsbEtleXMob2JqZWN0KSB7XG4gICAgICByZXR1cm4gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzLCBnZXRTeW1ib2xzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gICAgICogc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0QWxsS2V5c0luKG9iamVjdCkge1xuICAgICAgcmV0dXJuIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5c0luLCBnZXRTeW1ib2xzSW4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIGdldERhdGEgPSAhbWV0YU1hcCA/IG5vb3AgOiBmdW5jdGlvbihmdW5jKSB7XG4gICAgICByZXR1cm4gbWV0YU1hcC5nZXQoZnVuYyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG5hbWUgb2YgYGZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldEZ1bmNOYW1lKGZ1bmMpIHtcbiAgICAgIHZhciByZXN1bHQgPSAoZnVuYy5uYW1lICsgJycpLFxuICAgICAgICAgIGFycmF5ID0gcmVhbE5hbWVzW3Jlc3VsdF0sXG4gICAgICAgICAgbGVuZ3RoID0gaGFzT3duUHJvcGVydHkuY2FsbChyZWFsTmFtZXMsIHJlc3VsdCkgPyBhcnJheS5sZW5ndGggOiAwO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGRhdGEgPSBhcnJheVtsZW5ndGhdLFxuICAgICAgICAgICAgb3RoZXJGdW5jID0gZGF0YS5mdW5jO1xuICAgICAgICBpZiAob3RoZXJGdW5jID09IG51bGwgfHwgb3RoZXJGdW5jID09IGZ1bmMpIHtcbiAgICAgICAgICByZXR1cm4gZGF0YS5uYW1lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGFyZ3VtZW50IHBsYWNlaG9sZGVyIHZhbHVlIGZvciBgZnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHBsYWNlaG9sZGVyIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldEhvbGRlcihmdW5jKSB7XG4gICAgICB2YXIgb2JqZWN0ID0gaGFzT3duUHJvcGVydHkuY2FsbChsb2Rhc2gsICdwbGFjZWhvbGRlcicpID8gbG9kYXNoIDogZnVuYztcbiAgICAgIHJldHVybiBvYmplY3QucGxhY2Vob2xkZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYXBwcm9wcmlhdGUgXCJpdGVyYXRlZVwiIGZ1bmN0aW9uLiBJZiBgXy5pdGVyYXRlZWAgaXMgY3VzdG9taXplZCxcbiAgICAgKiB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIGN1c3RvbSBtZXRob2QsIG90aGVyd2lzZSBpdCByZXR1cm5zIGBiYXNlSXRlcmF0ZWVgLlxuICAgICAqIElmIGFyZ3VtZW50cyBhcmUgcHJvdmlkZWQsIHRoZSBjaG9zZW4gZnVuY3Rpb24gaXMgaW52b2tlZCB3aXRoIHRoZW0gYW5kXG4gICAgICogaXRzIHJlc3VsdCBpcyByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSBbdmFsdWVdIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGFuIGl0ZXJhdGVlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiB0aGUgY3JlYXRlZCBpdGVyYXRlZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGNob3NlbiBmdW5jdGlvbiBvciBpdHMgcmVzdWx0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldEl0ZXJhdGVlKCkge1xuICAgICAgdmFyIHJlc3VsdCA9IGxvZGFzaC5pdGVyYXRlZSB8fCBpdGVyYXRlZTtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdCA9PT0gaXRlcmF0ZWUgPyBiYXNlSXRlcmF0ZWUgOiByZXN1bHQ7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHJlc3VsdChhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSkgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGF0YSBmb3IgYG1hcGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSByZWZlcmVuY2Uga2V5LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXAgZGF0YS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRNYXBEYXRhKG1hcCwga2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IG1hcC5fX2RhdGFfXztcbiAgICAgIHJldHVybiBpc0tleWFibGUoa2V5KVxuICAgICAgICA/IGRhdGFbdHlwZW9mIGtleSA9PSAnc3RyaW5nJyA/ICdzdHJpbmcnIDogJ2hhc2gnXVxuICAgICAgICA6IGRhdGEubWFwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHByb3BlcnR5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBtYXRjaCBkYXRhIG9mIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hdGNoRGF0YShvYmplY3QpIHtcbiAgICAgIHZhciByZXN1bHQgPSBrZXlzKG9iamVjdCksXG4gICAgICAgICAgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHZhciBrZXkgPSByZXN1bHRbbGVuZ3RoXSxcbiAgICAgICAgICAgIHZhbHVlID0gb2JqZWN0W2tleV07XG5cbiAgICAgICAgcmVzdWx0W2xlbmd0aF0gPSBba2V5LCB2YWx1ZSwgaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKV07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kIHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZnVuY3Rpb24gaWYgaXQncyBuYXRpdmUsIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TmF0aXZlKG9iamVjdCwga2V5KSB7XG4gICAgICB2YXIgdmFsdWUgPSBnZXRWYWx1ZShvYmplY3QsIGtleSk7XG4gICAgICByZXR1cm4gYmFzZUlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUdldFRhZ2Agd2hpY2ggaWdub3JlcyBgU3ltYm9sLnRvU3RyaW5nVGFnYCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJhdyBgdG9TdHJpbmdUYWdgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFJhd1RhZyh2YWx1ZSkge1xuICAgICAgdmFyIGlzT3duID0gaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgc3ltVG9TdHJpbmdUYWcpLFxuICAgICAgICAgIHRhZyA9IHZhbHVlW3N5bVRvU3RyaW5nVGFnXTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsdWVbc3ltVG9TdHJpbmdUYWddID0gdW5kZWZpbmVkO1xuICAgICAgICB2YXIgdW5tYXNrZWQgPSB0cnVlO1xuICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgdmFyIHJlc3VsdCA9IG5hdGl2ZU9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICAgICAgaWYgKHVubWFza2VkKSB7XG4gICAgICAgIGlmIChpc093bikge1xuICAgICAgICAgIHZhbHVlW3N5bVRvU3RyaW5nVGFnXSA9IHRhZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgdmFsdWVbc3ltVG9TdHJpbmdUYWddO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHN5bWJvbHMuXG4gICAgICovXG4gICAgdmFyIGdldFN5bWJvbHMgPSAhbmF0aXZlR2V0U3ltYm9scyA/IHN0dWJBcnJheSA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICAgICAgcmV0dXJuIGFycmF5RmlsdGVyKG5hdGl2ZUdldFN5bWJvbHMob2JqZWN0KSwgZnVuY3Rpb24oc3ltYm9sKSB7XG4gICAgICAgIHJldHVybiBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKG9iamVjdCwgc3ltYm9sKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHN5bWJvbHMuXG4gICAgICovXG4gICAgdmFyIGdldFN5bWJvbHNJbiA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICB3aGlsZSAob2JqZWN0KSB7XG4gICAgICAgIGFycmF5UHVzaChyZXN1bHQsIGdldFN5bWJvbHMob2JqZWN0KSk7XG4gICAgICAgIG9iamVjdCA9IGdldFByb3RvdHlwZShvYmplY3QpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYHRvU3RyaW5nVGFnYCBvZiBgdmFsdWVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBgdG9TdHJpbmdUYWdgLlxuICAgICAqL1xuICAgIHZhciBnZXRUYWcgPSBiYXNlR2V0VGFnO1xuXG4gICAgLy8gRmFsbGJhY2sgZm9yIGRhdGEgdmlld3MsIG1hcHMsIHNldHMsIGFuZCB3ZWFrIG1hcHMgaW4gSUUgMTEgYW5kIHByb21pc2VzIGluIE5vZGUuanMgPCA2LlxuICAgIGlmICgoRGF0YVZpZXcgJiYgZ2V0VGFnKG5ldyBEYXRhVmlldyhuZXcgQXJyYXlCdWZmZXIoMSkpKSAhPSBkYXRhVmlld1RhZykgfHxcbiAgICAgICAgKE1hcCAmJiBnZXRUYWcobmV3IE1hcCkgIT0gbWFwVGFnKSB8fFxuICAgICAgICAoUHJvbWlzZSAmJiBnZXRUYWcoUHJvbWlzZS5yZXNvbHZlKCkpICE9IHByb21pc2VUYWcpIHx8XG4gICAgICAgIChTZXQgJiYgZ2V0VGFnKG5ldyBTZXQpICE9IHNldFRhZykgfHxcbiAgICAgICAgKFdlYWtNYXAgJiYgZ2V0VGFnKG5ldyBXZWFrTWFwKSAhPSB3ZWFrTWFwVGFnKSkge1xuICAgICAgZ2V0VGFnID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGJhc2VHZXRUYWcodmFsdWUpLFxuICAgICAgICAgICAgQ3RvciA9IHJlc3VsdCA9PSBvYmplY3RUYWcgPyB2YWx1ZS5jb25zdHJ1Y3RvciA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGN0b3JTdHJpbmcgPSBDdG9yID8gdG9Tb3VyY2UoQ3RvcikgOiAnJztcblxuICAgICAgICBpZiAoY3RvclN0cmluZykge1xuICAgICAgICAgIHN3aXRjaCAoY3RvclN0cmluZykge1xuICAgICAgICAgICAgY2FzZSBkYXRhVmlld0N0b3JTdHJpbmc6IHJldHVybiBkYXRhVmlld1RhZztcbiAgICAgICAgICAgIGNhc2UgbWFwQ3RvclN0cmluZzogcmV0dXJuIG1hcFRhZztcbiAgICAgICAgICAgIGNhc2UgcHJvbWlzZUN0b3JTdHJpbmc6IHJldHVybiBwcm9taXNlVGFnO1xuICAgICAgICAgICAgY2FzZSBzZXRDdG9yU3RyaW5nOiByZXR1cm4gc2V0VGFnO1xuICAgICAgICAgICAgY2FzZSB3ZWFrTWFwQ3RvclN0cmluZzogcmV0dXJuIHdlYWtNYXBUYWc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZpZXcsIGFwcGx5aW5nIGFueSBgdHJhbnNmb3Jtc2AgdG8gdGhlIGBzdGFydGAgYW5kIGBlbmRgIHBvc2l0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBzdGFydCBvZiB0aGUgdmlldy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHZpZXcuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdHJhbnNmb3JtcyBUaGUgdHJhbnNmb3JtYXRpb25zIHRvIGFwcGx5IHRvIHRoZSB2aWV3LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGBzdGFydGAgYW5kIGBlbmRgXG4gICAgICogIHBvc2l0aW9ucyBvZiB0aGUgdmlldy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRWaWV3KHN0YXJ0LCBlbmQsIHRyYW5zZm9ybXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHRyYW5zZm9ybXMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZGF0YSA9IHRyYW5zZm9ybXNbaW5kZXhdLFxuICAgICAgICAgICAgc2l6ZSA9IGRhdGEuc2l6ZTtcblxuICAgICAgICBzd2l0Y2ggKGRhdGEudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2Ryb3AnOiAgICAgIHN0YXJ0ICs9IHNpemU7IGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2Ryb3BSaWdodCc6IGVuZCAtPSBzaXplOyBicmVhaztcbiAgICAgICAgICBjYXNlICd0YWtlJzogICAgICBlbmQgPSBuYXRpdmVNaW4oZW5kLCBzdGFydCArIHNpemUpOyBicmVhaztcbiAgICAgICAgICBjYXNlICd0YWtlUmlnaHQnOiBzdGFydCA9IG5hdGl2ZU1heChzdGFydCwgZW5kIC0gc2l6ZSk7IGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4geyAnc3RhcnQnOiBzdGFydCwgJ2VuZCc6IGVuZCB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHdyYXBwZXIgZGV0YWlscyBmcm9tIHRoZSBgc291cmNlYCBib2R5IGNvbW1lbnQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgVGhlIHNvdXJjZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgd3JhcHBlciBkZXRhaWxzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFdyYXBEZXRhaWxzKHNvdXJjZSkge1xuICAgICAgdmFyIG1hdGNoID0gc291cmNlLm1hdGNoKHJlV3JhcERldGFpbHMpO1xuICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0uc3BsaXQocmVTcGxpdERldGFpbHMpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwYXRoYCBleGlzdHMgb24gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYXNGdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjayBwcm9wZXJ0aWVzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgcGF0aGAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzUGF0aChvYmplY3QsIHBhdGgsIGhhc0Z1bmMpIHtcbiAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBmYWxzZTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHRvS2V5KHBhdGhbaW5kZXhdKTtcbiAgICAgICAgaWYgKCEocmVzdWx0ID0gb2JqZWN0ICE9IG51bGwgJiYgaGFzRnVuYyhvYmplY3QsIGtleSkpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W2tleV07XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0IHx8ICsraW5kZXggIT0gbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBsZW5ndGggPSBvYmplY3QgPT0gbnVsbCA/IDAgOiBvYmplY3QubGVuZ3RoO1xuICAgICAgcmV0dXJuICEhbGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiYgaXNJbmRleChrZXksIGxlbmd0aCkgJiZcbiAgICAgICAgKGlzQXJyYXkob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhbiBhcnJheSBjbG9uZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdENsb25lQXJyYXkoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gbmV3IGFycmF5LmNvbnN0cnVjdG9yKGxlbmd0aCk7XG5cbiAgICAgIC8vIEFkZCBwcm9wZXJ0aWVzIGFzc2lnbmVkIGJ5IGBSZWdFeHAjZXhlY2AuXG4gICAgICBpZiAobGVuZ3RoICYmIHR5cGVvZiBhcnJheVswXSA9PSAnc3RyaW5nJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCAnaW5kZXgnKSkge1xuICAgICAgICByZXN1bHQuaW5kZXggPSBhcnJheS5pbmRleDtcbiAgICAgICAgcmVzdWx0LmlucHV0ID0gYXJyYXkuaW5wdXQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGluaXRpYWxpemVkIGNsb25lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluaXRDbG9uZU9iamVjdChvYmplY3QpIHtcbiAgICAgIHJldHVybiAodHlwZW9mIG9iamVjdC5jb25zdHJ1Y3RvciA9PSAnZnVuY3Rpb24nICYmICFpc1Byb3RvdHlwZShvYmplY3QpKVxuICAgICAgICA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlKG9iamVjdCkpXG4gICAgICAgIDoge307XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lIGJhc2VkIG9uIGl0cyBgdG9TdHJpbmdUYWdgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjbG9uaW5nIHZhbHVlcyB3aXRoIHRhZ3Mgb2ZcbiAgICAgKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE1hcGAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgYFNldGAsIG9yIGBTdHJpbmdgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0IHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICAgICAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3I7XG4gICAgICBzd2l0Y2ggKHRhZykge1xuICAgICAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgICAgIHJldHVybiBjbG9uZUFycmF5QnVmZmVyKG9iamVjdCk7XG5cbiAgICAgICAgY2FzZSBib29sVGFnOlxuICAgICAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgICAgIGNhc2UgZGF0YVZpZXdUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lRGF0YVZpZXcob2JqZWN0LCBpc0RlZXApO1xuXG4gICAgICAgIGNhc2UgZmxvYXQzMlRhZzogY2FzZSBmbG9hdDY0VGFnOlxuICAgICAgICBjYXNlIGludDhUYWc6IGNhc2UgaW50MTZUYWc6IGNhc2UgaW50MzJUYWc6XG4gICAgICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lVHlwZWRBcnJheShvYmplY3QsIGlzRGVlcCk7XG5cbiAgICAgICAgY2FzZSBtYXBUYWc6XG4gICAgICAgICAgcmV0dXJuIG5ldyBDdG9yO1xuXG4gICAgICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgICAgICBjYXNlIHN0cmluZ1RhZzpcbiAgICAgICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgICAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICAgICAgICByZXR1cm4gY2xvbmVSZWdFeHAob2JqZWN0KTtcblxuICAgICAgICBjYXNlIHNldFRhZzpcbiAgICAgICAgICByZXR1cm4gbmV3IEN0b3I7XG5cbiAgICAgICAgY2FzZSBzeW1ib2xUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lU3ltYm9sKG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5zZXJ0cyB3cmFwcGVyIGBkZXRhaWxzYCBpbiBhIGNvbW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgYHNvdXJjZWAgYm9keS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSBUaGUgc291cmNlIHRvIG1vZGlmeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IGRldGFpbHMgVGhlIGRldGFpbHMgdG8gaW5zZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIG1vZGlmaWVkIHNvdXJjZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbnNlcnRXcmFwRGV0YWlscyhzb3VyY2UsIGRldGFpbHMpIHtcbiAgICAgIHZhciBsZW5ndGggPSBkZXRhaWxzLmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgICB9XG4gICAgICB2YXIgbGFzdEluZGV4ID0gbGVuZ3RoIC0gMTtcbiAgICAgIGRldGFpbHNbbGFzdEluZGV4XSA9IChsZW5ndGggPiAxID8gJyYgJyA6ICcnKSArIGRldGFpbHNbbGFzdEluZGV4XTtcbiAgICAgIGRldGFpbHMgPSBkZXRhaWxzLmpvaW4obGVuZ3RoID4gMiA/ICcsICcgOiAnICcpO1xuICAgICAgcmV0dXJuIHNvdXJjZS5yZXBsYWNlKHJlV3JhcENvbW1lbnQsICd7XFxuLyogW3dyYXBwZWQgd2l0aCAnICsgZGV0YWlscyArICddICovXFxuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBmbGF0dGVuYWJsZSBgYXJndW1lbnRzYCBvYmplY3Qgb3IgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZsYXR0ZW5hYmxlLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNGbGF0dGVuYWJsZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzQXJyYXkodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSB8fFxuICAgICAgICAhIShzcHJlYWRhYmxlU3ltYm9sICYmIHZhbHVlICYmIHZhbHVlW3NwcmVhZGFibGVTeW1ib2xdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPU1BWF9TQUZFX0lOVEVHRVJdIFRoZSB1cHBlciBib3VuZHMgb2YgYSB2YWxpZCBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGluZGV4LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNJbmRleCh2YWx1ZSwgbGVuZ3RoKSB7XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcblxuICAgICAgcmV0dXJuICEhbGVuZ3RoICYmXG4gICAgICAgICh0eXBlID09ICdudW1iZXInIHx8XG4gICAgICAgICAgKHR5cGUgIT0gJ3N5bWJvbCcgJiYgcmVJc1VpbnQudGVzdCh2YWx1ZSkpKSAmJlxuICAgICAgICAgICAgKHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAgICAgKiBAcGFyYW0geyp9IGluZGV4IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgaW5kZXggb3Iga2V5IGFyZ3VtZW50LlxuICAgICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgaW5kZXgsIG9iamVjdCkge1xuICAgICAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIGluZGV4O1xuICAgICAgaWYgKHR5cGUgPT0gJ251bWJlcidcbiAgICAgICAgICAgID8gKGlzQXJyYXlMaWtlKG9iamVjdCkgJiYgaXNJbmRleChpbmRleCwgb2JqZWN0Lmxlbmd0aCkpXG4gICAgICAgICAgICA6ICh0eXBlID09ICdzdHJpbmcnICYmIGluZGV4IGluIG9iamVjdClcbiAgICAgICAgICApIHtcbiAgICAgICAgcmV0dXJuIGVxKG9iamVjdFtpbmRleF0sIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUgYW5kIG5vdCBhIHByb3BlcnR5IHBhdGguXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5IGtleXMgb24uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNLZXkodmFsdWUsIG9iamVjdCkge1xuICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgICAgaWYgKHR5cGUgPT0gJ251bWJlcicgfHwgdHlwZSA9PSAnc3ltYm9sJyB8fCB0eXBlID09ICdib29sZWFuJyB8fFxuICAgICAgICAgIHZhbHVlID09IG51bGwgfHwgaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkgfHwgIXJlSXNEZWVwUHJvcC50ZXN0KHZhbHVlKSB8fFxuICAgICAgICAob2JqZWN0ICE9IG51bGwgJiYgdmFsdWUgaW4gT2JqZWN0KG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciB1c2UgYXMgdW5pcXVlIG9iamVjdCBrZXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNLZXlhYmxlKHZhbHVlKSB7XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIHJldHVybiAodHlwZSA9PSAnc3RyaW5nJyB8fCB0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicpXG4gICAgICAgID8gKHZhbHVlICE9PSAnX19wcm90b19fJylcbiAgICAgICAgOiAodmFsdWUgPT09IG51bGwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgZnVuY2AgaGFzIGEgbGF6eSBjb3VudGVycGFydC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNMYXppYWJsZShmdW5jKSB7XG4gICAgICB2YXIgZnVuY05hbWUgPSBnZXRGdW5jTmFtZShmdW5jKSxcbiAgICAgICAgICBvdGhlciA9IGxvZGFzaFtmdW5jTmFtZV07XG5cbiAgICAgIGlmICh0eXBlb2Ygb3RoZXIgIT0gJ2Z1bmN0aW9uJyB8fCAhKGZ1bmNOYW1lIGluIExhenlXcmFwcGVyLnByb3RvdHlwZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGZ1bmMgPT09IG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdmFyIGRhdGEgPSBnZXREYXRhKG90aGVyKTtcbiAgICAgIHJldHVybiAhIWRhdGEgJiYgZnVuYyA9PT0gZGF0YVswXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBpdHMgc291cmNlIG1hc2tlZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBpcyBtYXNrZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc01hc2tlZChmdW5jKSB7XG4gICAgICByZXR1cm4gISFtYXNrU3JjS2V5ICYmIChtYXNrU3JjS2V5IGluIGZ1bmMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgZnVuY2AgaXMgY2FwYWJsZSBvZiBiZWluZyBtYXNrZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2FibGUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICB2YXIgaXNNYXNrYWJsZSA9IGNvcmVKc0RhdGEgPyBpc0Z1bmN0aW9uIDogc3R1YkZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgcHJvdG90eXBlIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm90b3R5cGUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkge1xuICAgICAgdmFyIEN0b3IgPSB2YWx1ZSAmJiB2YWx1ZS5jb25zdHJ1Y3RvcixcbiAgICAgICAgICBwcm90byA9ICh0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IucHJvdG90eXBlKSB8fCBvYmplY3RQcm90bztcblxuICAgICAgcmV0dXJuIHZhbHVlID09PSBwcm90bztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSBmb3Igc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpLmUuIGA9PT1gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpZiBzdWl0YWJsZSBmb3Igc3RyaWN0XG4gICAgICogIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlICYmICFpc09iamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBtYXRjaGVzUHJvcGVydHlgIGZvciBzb3VyY2UgdmFsdWVzIHN1aXRhYmxlXG4gICAgICogZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXRjaGVzU3RyaWN0Q29tcGFyYWJsZShrZXksIHNyY1ZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IHNyY1ZhbHVlICYmXG4gICAgICAgICAgKHNyY1ZhbHVlICE9PSB1bmRlZmluZWQgfHwgKGtleSBpbiBPYmplY3Qob2JqZWN0KSkpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWVtb2l6ZWAgd2hpY2ggY2xlYXJzIHRoZSBtZW1vaXplZCBmdW5jdGlvbidzXG4gICAgICogY2FjaGUgd2hlbiBpdCBleGNlZWRzIGBNQVhfTUVNT0laRV9TSVpFYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaGF2ZSBpdHMgb3V0cHV0IG1lbW9pemVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG1lbW9pemVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1lbW9pemVDYXBwZWQoZnVuYykge1xuICAgICAgdmFyIHJlc3VsdCA9IG1lbW9pemUoZnVuYywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIGlmIChjYWNoZS5zaXplID09PSBNQVhfTUVNT0laRV9TSVpFKSB7XG4gICAgICAgICAgY2FjaGUuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgfSk7XG5cbiAgICAgIHZhciBjYWNoZSA9IHJlc3VsdC5jYWNoZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWVyZ2VzIHRoZSBmdW5jdGlvbiBtZXRhZGF0YSBvZiBgc291cmNlYCBpbnRvIGBkYXRhYC5cbiAgICAgKlxuICAgICAqIE1lcmdpbmcgbWV0YWRhdGEgcmVkdWNlcyB0aGUgbnVtYmVyIG9mIHdyYXBwZXJzIHVzZWQgdG8gaW52b2tlIGEgZnVuY3Rpb24uXG4gICAgICogVGhpcyBpcyBwb3NzaWJsZSBiZWNhdXNlIG1ldGhvZHMgbGlrZSBgXy5iaW5kYCwgYF8uY3VycnlgLCBhbmQgYF8ucGFydGlhbGBcbiAgICAgKiBtYXkgYmUgYXBwbGllZCByZWdhcmRsZXNzIG9mIGV4ZWN1dGlvbiBvcmRlci4gTWV0aG9kcyBsaWtlIGBfLmFyeWAgYW5kXG4gICAgICogYF8ucmVhcmdgIG1vZGlmeSBmdW5jdGlvbiBhcmd1bWVudHMsIG1ha2luZyB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmVcbiAgICAgKiBleGVjdXRlZCBpbXBvcnRhbnQsIHByZXZlbnRpbmcgdGhlIG1lcmdpbmcgb2YgbWV0YWRhdGEuIEhvd2V2ZXIsIHdlIG1ha2VcbiAgICAgKiBhbiBleGNlcHRpb24gZm9yIGEgc2FmZSBjb21iaW5lZCBjYXNlIHdoZXJlIGN1cnJpZWQgZnVuY3Rpb25zIGhhdmUgYF8uYXJ5YFxuICAgICAqIGFuZCBvciBgXy5yZWFyZ2AgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZGF0YSBUaGUgZGVzdGluYXRpb24gbWV0YWRhdGEuXG4gICAgICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBzb3VyY2UgbWV0YWRhdGEuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBkYXRhYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZXJnZURhdGEoZGF0YSwgc291cmNlKSB7XG4gICAgICB2YXIgYml0bWFzayA9IGRhdGFbMV0sXG4gICAgICAgICAgc3JjQml0bWFzayA9IHNvdXJjZVsxXSxcbiAgICAgICAgICBuZXdCaXRtYXNrID0gYml0bWFzayB8IHNyY0JpdG1hc2ssXG4gICAgICAgICAgaXNDb21tb24gPSBuZXdCaXRtYXNrIDwgKFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHIHwgV1JBUF9BUllfRkxBRyk7XG5cbiAgICAgIHZhciBpc0NvbWJvID1cbiAgICAgICAgKChzcmNCaXRtYXNrID09IFdSQVBfQVJZX0ZMQUcpICYmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRykpIHx8XG4gICAgICAgICgoc3JjQml0bWFzayA9PSBXUkFQX0FSWV9GTEFHKSAmJiAoYml0bWFzayA9PSBXUkFQX1JFQVJHX0ZMQUcpICYmIChkYXRhWzddLmxlbmd0aCA8PSBzb3VyY2VbOF0pKSB8fFxuICAgICAgICAoKHNyY0JpdG1hc2sgPT0gKFdSQVBfQVJZX0ZMQUcgfCBXUkFQX1JFQVJHX0ZMQUcpKSAmJiAoc291cmNlWzddLmxlbmd0aCA8PSBzb3VyY2VbOF0pICYmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRykpO1xuXG4gICAgICAvLyBFeGl0IGVhcmx5IGlmIG1ldGFkYXRhIGNhbid0IGJlIG1lcmdlZC5cbiAgICAgIGlmICghKGlzQ29tbW9uIHx8IGlzQ29tYm8pKSB7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgdGhpc0FyZ2AgaWYgYXZhaWxhYmxlLlxuICAgICAgaWYgKHNyY0JpdG1hc2sgJiBXUkFQX0JJTkRfRkxBRykge1xuICAgICAgICBkYXRhWzJdID0gc291cmNlWzJdO1xuICAgICAgICAvLyBTZXQgd2hlbiBjdXJyeWluZyBhIGJvdW5kIGZ1bmN0aW9uLlxuICAgICAgICBuZXdCaXRtYXNrIHw9IGJpdG1hc2sgJiBXUkFQX0JJTkRfRkxBRyA/IDAgOiBXUkFQX0NVUlJZX0JPVU5EX0ZMQUc7XG4gICAgICB9XG4gICAgICAvLyBDb21wb3NlIHBhcnRpYWwgYXJndW1lbnRzLlxuICAgICAgdmFyIHZhbHVlID0gc291cmNlWzNdO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHZhciBwYXJ0aWFscyA9IGRhdGFbM107XG4gICAgICAgIGRhdGFbM10gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzKHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzRdKSA6IHZhbHVlO1xuICAgICAgICBkYXRhWzRdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzNdLCBQTEFDRUhPTERFUikgOiBzb3VyY2VbNF07XG4gICAgICB9XG4gICAgICAvLyBDb21wb3NlIHBhcnRpYWwgcmlnaHQgYXJndW1lbnRzLlxuICAgICAgdmFsdWUgPSBzb3VyY2VbNV07XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgcGFydGlhbHMgPSBkYXRhWzVdO1xuICAgICAgICBkYXRhWzVdID0gcGFydGlhbHMgPyBjb21wb3NlQXJnc1JpZ2h0KHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzZdKSA6IHZhbHVlO1xuICAgICAgICBkYXRhWzZdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzVdLCBQTEFDRUhPTERFUikgOiBzb3VyY2VbNl07XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGBhcmdQb3NgIGlmIGF2YWlsYWJsZS5cbiAgICAgIHZhbHVlID0gc291cmNlWzddO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIGRhdGFbN10gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYGFyeWAgaWYgaXQncyBzbWFsbGVyLlxuICAgICAgaWYgKHNyY0JpdG1hc2sgJiBXUkFQX0FSWV9GTEFHKSB7XG4gICAgICAgIGRhdGFbOF0gPSBkYXRhWzhdID09IG51bGwgPyBzb3VyY2VbOF0gOiBuYXRpdmVNaW4oZGF0YVs4XSwgc291cmNlWzhdKTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYGFyaXR5YCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkLlxuICAgICAgaWYgKGRhdGFbOV0gPT0gbnVsbCkge1xuICAgICAgICBkYXRhWzldID0gc291cmNlWzldO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgZnVuY2AgYW5kIG1lcmdlIGJpdG1hc2tzLlxuICAgICAgZGF0YVswXSA9IHNvdXJjZVswXTtcbiAgICAgIGRhdGFbMV0gPSBuZXdCaXRtYXNrO1xuXG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2VcbiAgICAgKiBbYE9iamVjdC5rZXlzYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LmtleXMpXG4gICAgICogZXhjZXB0IHRoYXQgaXQgaW5jbHVkZXMgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbmF0aXZlS2V5c0luKG9iamVjdCkge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgaWYgKG9iamVjdCAhPSBudWxsKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyB1c2luZyBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBvYmplY3RUb1N0cmluZyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIG5hdGl2ZU9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVJlc3RgIHdoaWNoIHRyYW5zZm9ybXMgdGhlIHJlc3QgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD1mdW5jLmxlbmd0aC0xXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJlc3QgcGFyYW1ldGVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZm9ybSBUaGUgcmVzdCBhcnJheSB0cmFuc2Zvcm0uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gb3ZlclJlc3QoZnVuYywgc3RhcnQsIHRyYW5zZm9ybSkge1xuICAgICAgc3RhcnQgPSBuYXRpdmVNYXgoc3RhcnQgPT09IHVuZGVmaW5lZCA/IChmdW5jLmxlbmd0aCAtIDEpIDogc3RhcnQsIDApO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBzdGFydCwgMCksXG4gICAgICAgICAgICBhcnJheSA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICBhcnJheVtpbmRleF0gPSBhcmdzW3N0YXJ0ICsgaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gLTE7XG4gICAgICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpO1xuICAgICAgICB3aGlsZSAoKytpbmRleCA8IHN0YXJ0KSB7XG4gICAgICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIG90aGVyQXJnc1tzdGFydF0gPSB0cmFuc2Zvcm0oYXJyYXkpO1xuICAgICAgICByZXR1cm4gYXBwbHkoZnVuYywgdGhpcywgb3RoZXJBcmdzKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcGFyZW50IHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhdGggVGhlIHBhdGggdG8gZ2V0IHRoZSBwYXJlbnQgdmFsdWUgb2YuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHBhcmVudCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYXJlbnQob2JqZWN0LCBwYXRoKSB7XG4gICAgICByZXR1cm4gcGF0aC5sZW5ndGggPCAyID8gb2JqZWN0IDogYmFzZUdldChvYmplY3QsIGJhc2VTbGljZShwYXRoLCAwLCAtMSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlb3JkZXIgYGFycmF5YCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBpbmRleGVzIHdoZXJlIHRoZSBlbGVtZW50IGF0XG4gICAgICogdGhlIGZpcnN0IGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBmaXJzdCBlbGVtZW50LCB0aGUgZWxlbWVudCBhdFxuICAgICAqIHRoZSBzZWNvbmQgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIHNlY29uZCBlbGVtZW50LCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byByZW9yZGVyLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGluZGV4ZXMgVGhlIGFycmFuZ2VkIGFycmF5IGluZGV4ZXMuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVvcmRlcihhcnJheSwgaW5kZXhlcykge1xuICAgICAgdmFyIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNaW4oaW5kZXhlcy5sZW5ndGgsIGFyckxlbmd0aCksXG4gICAgICAgICAgb2xkQXJyYXkgPSBjb3B5QXJyYXkoYXJyYXkpO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGluZGV4ID0gaW5kZXhlc1tsZW5ndGhdO1xuICAgICAgICBhcnJheVtsZW5ndGhdID0gaXNJbmRleChpbmRleCwgYXJyTGVuZ3RoKSA/IG9sZEFycmF5W2luZGV4XSA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSB2YWx1ZSBhdCBga2V5YCwgdW5sZXNzIGBrZXlgIGlzIFwiX19wcm90b19fXCIgb3IgXCJjb25zdHJ1Y3RvclwiLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNhZmVHZXQob2JqZWN0LCBrZXkpIHtcbiAgICAgIGlmIChrZXkgPT09ICdjb25zdHJ1Y3RvcicgJiYgdHlwZW9mIG9iamVjdFtrZXldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGtleSA9PSAnX19wcm90b19fJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvYmplY3Rba2V5XTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSWYgdGhpcyBmdW5jdGlvbiBiZWNvbWVzIGhvdCwgaS5lLiBpcyBpbnZva2VkIGEgbG90IGluIGEgc2hvcnRcbiAgICAgKiBwZXJpb2Qgb2YgdGltZSwgaXQgd2lsbCB0cmlwIGl0cyBicmVha2VyIGFuZCB0cmFuc2l0aW9uIHRvIGFuIGlkZW50aXR5XG4gICAgICogZnVuY3Rpb24gdG8gYXZvaWQgZ2FyYmFnZSBjb2xsZWN0aW9uIHBhdXNlcyBpbiBWOC4gU2VlXG4gICAgICogW1Y4IGlzc3VlIDIwNzBdKGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTIwNzApXG4gICAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gICAgICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICAgICAqL1xuICAgIHZhciBzZXREYXRhID0gc2hvcnRPdXQoYmFzZVNldERhdGEpO1xuXG4gICAgLyoqXG4gICAgICogQSBzaW1wbGUgd3JhcHBlciBhcm91bmQgdGhlIGdsb2JhbCBbYHNldFRpbWVvdXRgXShodHRwczovL21kbi5pby9zZXRUaW1lb3V0KS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVsYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdhaXQgVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkgaW52b2NhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfE9iamVjdH0gUmV0dXJucyB0aGUgdGltZXIgaWQgb3IgdGltZW91dCBvYmplY3QuXG4gICAgICovXG4gICAgdmFyIHNldFRpbWVvdXQgPSBjdHhTZXRUaW1lb3V0IHx8IGZ1bmN0aW9uKGZ1bmMsIHdhaXQpIHtcbiAgICAgIHJldHVybiByb290LnNldFRpbWVvdXQoZnVuYywgd2FpdCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGB0b1N0cmluZ2AgbWV0aG9kIG9mIGBmdW5jYCB0byByZXR1cm4gYHN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzdHJpbmcgVGhlIGB0b1N0cmluZ2AgcmVzdWx0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIHNldFRvU3RyaW5nID0gc2hvcnRPdXQoYmFzZVNldFRvU3RyaW5nKTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGB0b1N0cmluZ2AgbWV0aG9kIG9mIGB3cmFwcGVyYCB0byBtaW1pYyB0aGUgc291cmNlIG9mIGByZWZlcmVuY2VgXG4gICAgICogd2l0aCB3cmFwcGVyIGRldGFpbHMgaW4gYSBjb21tZW50IGF0IHRoZSB0b3Agb2YgdGhlIHNvdXJjZSBib2R5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB3cmFwcGVyIFRoZSBmdW5jdGlvbiB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcmVmZXJlbmNlIFRoZSByZWZlcmVuY2UgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYHdyYXBwZXJgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldFdyYXBUb1N0cmluZyh3cmFwcGVyLCByZWZlcmVuY2UsIGJpdG1hc2spIHtcbiAgICAgIHZhciBzb3VyY2UgPSAocmVmZXJlbmNlICsgJycpO1xuICAgICAgcmV0dXJuIHNldFRvU3RyaW5nKHdyYXBwZXIsIGluc2VydFdyYXBEZXRhaWxzKHNvdXJjZSwgdXBkYXRlV3JhcERldGFpbHMoZ2V0V3JhcERldGFpbHMoc291cmNlKSwgYml0bWFzaykpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCdsbCBzaG9ydCBvdXQgYW5kIGludm9rZSBgaWRlbnRpdHlgIGluc3RlYWRcbiAgICAgKiBvZiBgZnVuY2Agd2hlbiBpdCdzIGNhbGxlZCBgSE9UX0NPVU5UYCBvciBtb3JlIHRpbWVzIGluIGBIT1RfU1BBTmBcbiAgICAgKiBtaWxsaXNlY29uZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNob3J0YWJsZSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzaG9ydE91dChmdW5jKSB7XG4gICAgICB2YXIgY291bnQgPSAwLFxuICAgICAgICAgIGxhc3RDYWxsZWQgPSAwO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBzdGFtcCA9IG5hdGl2ZU5vdygpLFxuICAgICAgICAgICAgcmVtYWluaW5nID0gSE9UX1NQQU4gLSAoc3RhbXAgLSBsYXN0Q2FsbGVkKTtcblxuICAgICAgICBsYXN0Q2FsbGVkID0gc3RhbXA7XG4gICAgICAgIGlmIChyZW1haW5pbmcgPiAwKSB7XG4gICAgICAgICAgaWYgKCsrY291bnQgPj0gSE9UX0NPVU5UKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJndW1lbnRzWzBdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb3VudCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodW5kZWZpbmVkLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc2h1ZmZsZWAgd2hpY2ggbXV0YXRlcyBhbmQgc2V0cyB0aGUgc2l6ZSBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2h1ZmZsZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3NpemU9YXJyYXkubGVuZ3RoXSBUaGUgc2l6ZSBvZiBgYXJyYXlgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNodWZmbGVTZWxmKGFycmF5LCBzaXplKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgbGFzdEluZGV4ID0gbGVuZ3RoIC0gMTtcblxuICAgICAgc2l6ZSA9IHNpemUgPT09IHVuZGVmaW5lZCA/IGxlbmd0aCA6IHNpemU7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IHNpemUpIHtcbiAgICAgICAgdmFyIHJhbmQgPSBiYXNlUmFuZG9tKGluZGV4LCBsYXN0SW5kZXgpLFxuICAgICAgICAgICAgdmFsdWUgPSBhcnJheVtyYW5kXTtcblxuICAgICAgICBhcnJheVtyYW5kXSA9IGFycmF5W2luZGV4XTtcbiAgICAgICAgYXJyYXlbaW5kZXhdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBhcnJheS5sZW5ndGggPSBzaXplO1xuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIGEgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICAgICAqL1xuICAgIHZhciBzdHJpbmdUb1BhdGggPSBtZW1vaXplQ2FwcGVkKGZ1bmN0aW9uKHN0cmluZykge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgaWYgKHN0cmluZy5jaGFyQ29kZUF0KDApID09PSA0NiAvKiAuICovKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKCcnKTtcbiAgICAgIH1cbiAgICAgIHN0cmluZy5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdWJTdHJpbmcpIHtcbiAgICAgICAgcmVzdWx0LnB1c2gocXVvdGUgPyBzdWJTdHJpbmcucmVwbGFjZShyZUVzY2FwZUNoYXIsICckMScpIDogKG51bWJlciB8fCBtYXRjaCkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBrZXkgaWYgaXQncyBub3QgYSBzdHJpbmcgb3Igc3ltYm9sLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8c3ltYm9sfSBSZXR1cm5zIHRoZSBrZXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9LZXkodmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSAodmFsdWUgKyAnJyk7XG4gICAgICByZXR1cm4gKHJlc3VsdCA9PSAnMCcgJiYgKDEgLyB2YWx1ZSkgPT0gLUlORklOSVRZKSA/ICctMCcgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYGZ1bmNgIHRvIGl0cyBzb3VyY2UgY29kZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzb3VyY2UgY29kZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1NvdXJjZShmdW5jKSB7XG4gICAgICBpZiAoZnVuYyAhPSBudWxsKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmNUb1N0cmluZy5jYWxsKGZ1bmMpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiAoZnVuYyArICcnKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgIH1cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIHdyYXBwZXIgYGRldGFpbHNgIGJhc2VkIG9uIGBiaXRtYXNrYCBmbGFncy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybnMge0FycmF5fSBkZXRhaWxzIFRoZSBkZXRhaWxzIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGV0YWlsc2AuXG4gICAgICovXG4gICAgZnVuY3Rpb24gdXBkYXRlV3JhcERldGFpbHMoZGV0YWlscywgYml0bWFzaykge1xuICAgICAgYXJyYXlFYWNoKHdyYXBGbGFncywgZnVuY3Rpb24ocGFpcikge1xuICAgICAgICB2YXIgdmFsdWUgPSAnXy4nICsgcGFpclswXTtcbiAgICAgICAgaWYgKChiaXRtYXNrICYgcGFpclsxXSkgJiYgIWFycmF5SW5jbHVkZXMoZGV0YWlscywgdmFsdWUpKSB7XG4gICAgICAgICAgZGV0YWlscy5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gZGV0YWlscy5zb3J0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGB3cmFwcGVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHdyYXBwZXIgVGhlIHdyYXBwZXIgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHdyYXBwZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNsb25lKHdyYXBwZXIpIHtcbiAgICAgIGlmICh3cmFwcGVyIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHtcbiAgICAgICAgcmV0dXJuIHdyYXBwZXIuY2xvbmUoKTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBuZXcgTG9kYXNoV3JhcHBlcih3cmFwcGVyLl9fd3JhcHBlZF9fLCB3cmFwcGVyLl9fY2hhaW5fXyk7XG4gICAgICByZXN1bHQuX19hY3Rpb25zX18gPSBjb3B5QXJyYXkod3JhcHBlci5fX2FjdGlvbnNfXyk7XG4gICAgICByZXN1bHQuX19pbmRleF9fICA9IHdyYXBwZXIuX19pbmRleF9fO1xuICAgICAgcmVzdWx0Ll9fdmFsdWVzX18gPSB3cmFwcGVyLl9fdmFsdWVzX187XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgc3BsaXQgaW50byBncm91cHMgdGhlIGxlbmd0aCBvZiBgc2l6ZWAuXG4gICAgICogSWYgYGFycmF5YCBjYW4ndCBiZSBzcGxpdCBldmVubHksIHRoZSBmaW5hbCBjaHVuayB3aWxsIGJlIHRoZSByZW1haW5pbmdcbiAgICAgKiBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT0xXSBUaGUgbGVuZ3RoIG9mIGVhY2ggY2h1bmtcbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNodW5rcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jaHVuayhbJ2EnLCAnYicsICdjJywgJ2QnXSwgMik7XG4gICAgICogLy8gPT4gW1snYScsICdiJ10sIFsnYycsICdkJ11dXG4gICAgICpcbiAgICAgKiBfLmNodW5rKFsnYScsICdiJywgJ2MnLCAnZCddLCAzKTtcbiAgICAgKiAvLyA9PiBbWydhJywgJ2InLCAnYyddLCBbJ2QnXV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjaHVuayhhcnJheSwgc2l6ZSwgZ3VhcmQpIHtcbiAgICAgIGlmICgoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc2l6ZSwgZ3VhcmQpIDogc2l6ZSA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICBzaXplID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNpemUgPSBuYXRpdmVNYXgodG9JbnRlZ2VyKHNpemUpLCAwKTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoIHx8IHNpemUgPCAxKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KG5hdGl2ZUNlaWwobGVuZ3RoIC8gc2l6ZSkpO1xuXG4gICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gYmFzZVNsaWNlKGFycmF5LCBpbmRleCwgKGluZGV4ICs9IHNpemUpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSB3aXRoIGFsbCBmYWxzZXkgdmFsdWVzIHJlbW92ZWQuIFRoZSB2YWx1ZXMgYGZhbHNlYCwgYG51bGxgLFxuICAgICAqIGAwYCwgYFwiXCJgLCBgdW5kZWZpbmVkYCwgYW5kIGBOYU5gIGFyZSBmYWxzZXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY29tcGFjdChbMCwgMSwgZmFsc2UsIDIsICcnLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29tcGFjdChhcnJheSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgYXJyYXkgY29uY2F0ZW5hdGluZyBgYXJyYXlgIHdpdGggYW55IGFkZGl0aW9uYWwgYXJyYXlzXG4gICAgICogYW5kL29yIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb25jYXRlbmF0ZS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY29uY2F0ZW5hdGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgY29uY2F0ZW5hdGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMV07XG4gICAgICogdmFyIG90aGVyID0gXy5jb25jYXQoYXJyYXksIDIsIFszXSwgW1s0XV0pO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob3RoZXIpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzLCBbNF1dXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uY2F0KCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgYXJncyA9IEFycmF5KGxlbmd0aCAtIDEpLFxuICAgICAgICAgIGFycmF5ID0gYXJndW1lbnRzWzBdLFxuICAgICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICBhcmdzW2luZGV4IC0gMV0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5UHVzaChpc0FycmF5KGFycmF5KSA/IGNvcHlBcnJheShhcnJheSkgOiBbYXJyYXldLCBiYXNlRmxhdHRlbihhcmdzLCAxKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBgYXJyYXlgIHZhbHVlcyBub3QgaW5jbHVkZWQgaW4gdGhlIG90aGVyIGdpdmVuIGFycmF5c1xuICAgICAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmVcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ucHVsbEFsbGAsIHRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBzZWUgXy53aXRob3V0LCBfLnhvclxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRpZmZlcmVuY2UoWzIsIDFdLCBbMiwgM10pO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqL1xuICAgIHZhciBkaWZmZXJlbmNlID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXksIHZhbHVlcykge1xuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlT2JqZWN0KGFycmF5KVxuICAgICAgICA/IGJhc2VEaWZmZXJlbmNlKGFycmF5LCBiYXNlRmxhdHRlbih2YWx1ZXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSlcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZGlmZmVyZW5jZWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgYW5kIGB2YWx1ZXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb25cbiAgICAgKiBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmVcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ucHVsbEFsbEJ5YCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRpZmZlcmVuY2VCeShbMi4xLCAxLjJdLCBbMi4zLCAzLjRdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMS4yXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kaWZmZXJlbmNlQnkoW3sgJ3gnOiAyIH0sIHsgJ3gnOiAxIH1dLCBbeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgdmFyIGRpZmZlcmVuY2VCeSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgIHZhciBpdGVyYXRlZSA9IGxhc3QodmFsdWVzKTtcbiAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChpdGVyYXRlZSkpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2VPYmplY3QoYXJyYXkpXG4gICAgICAgID8gYmFzZURpZmZlcmVuY2UoYXJyYXksIGJhc2VGbGF0dGVuKHZhbHVlcywgMSwgaXNBcnJheUxpa2VPYmplY3QsIHRydWUpLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpXG4gICAgICAgIDogW107XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmRpZmZlcmVuY2VgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheWAgdG8gYHZhbHVlc2AuIFRoZSBvcmRlciBhbmRcbiAgICAgKiByZWZlcmVuY2VzIG9mIHJlc3VsdCB2YWx1ZXMgYXJlIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LiBUaGUgY29tcGFyYXRvclxuICAgICAqIGlzIGludm9rZWQgd2l0aCB0d28gYXJndW1lbnRzOiAoYXJyVmFsLCBvdGhWYWwpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsQWxsV2l0aGAsIHRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfV07XG4gICAgICpcbiAgICAgKiBfLmRpZmZlcmVuY2VXaXRoKG9iamVjdHMsIFt7ICd4JzogMSwgJ3knOiAyIH1dLCBfLmlzRXF1YWwpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMiwgJ3knOiAxIH1dXG4gICAgICovXG4gICAgdmFyIGRpZmZlcmVuY2VXaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXksIHZhbHVlcykge1xuICAgICAgdmFyIGNvbXBhcmF0b3IgPSBsYXN0KHZhbHVlcyk7XG4gICAgICBpZiAoaXNBcnJheUxpa2VPYmplY3QoY29tcGFyYXRvcikpIHtcbiAgICAgICAgY29tcGFyYXRvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc0FycmF5TGlrZU9iamVjdChhcnJheSlcbiAgICAgICAgPyBiYXNlRGlmZmVyZW5jZShhcnJheSwgYmFzZUZsYXR0ZW4odmFsdWVzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSksIHVuZGVmaW5lZCwgY29tcGFyYXRvcilcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIGRyb3BwZWQgZnJvbSB0aGUgYmVnaW5uaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIGRyb3AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZHJvcChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFsyLCAzXVxuICAgICAqXG4gICAgICogXy5kcm9wKFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzNdXG4gICAgICpcbiAgICAgKiBfLmRyb3AoWzEsIDIsIDNdLCA1KTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqXG4gICAgICogXy5kcm9wKFsxLCAyLCAzXSwgMCk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZHJvcChhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCBuIDwgMCA/IDAgOiBuLCBsZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIGRyb3BwZWQgZnJvbSB0aGUgZW5kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIGRyb3AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZHJvcFJpZ2h0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodChbMSwgMiwgM10sIDIpO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHQoWzEsIDIsIDNdLCA1KTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHQoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wUmlnaHQoYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBuID0gKGd1YXJkIHx8IG4gPT09IHVuZGVmaW5lZCkgPyAxIDogdG9JbnRlZ2VyKG4pO1xuICAgICAgbiA9IGxlbmd0aCAtIG47XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCAwLCBuIDwgMCA/IDAgOiBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCBleGNsdWRpbmcgZWxlbWVudHMgZHJvcHBlZCBmcm9tIHRoZSBlbmQuXG4gICAgICogRWxlbWVudHMgYXJlIGRyb3BwZWQgdW50aWwgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHRXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFJpZ2h0V2hpbGUodXNlcnMsIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRyb3BSaWdodFdoaWxlKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kcm9wUmlnaHRXaGlsZSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5JywgJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZHJvcFJpZ2h0V2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCB0cnVlLCB0cnVlKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIGV4Y2x1ZGluZyBlbGVtZW50cyBkcm9wcGVkIGZyb20gdGhlIGJlZ2lubmluZy5cbiAgICAgKiBFbGVtZW50cyBhcmUgZHJvcHBlZCB1bnRpbCBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXgsIGFycmF5KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmRyb3BXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRyb3BXaGlsZSh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydwZWJibGVzJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknLCAnZnJlZCcsICdwZWJibGVzJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wV2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCB0cnVlKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbGxzIGVsZW1lbnRzIG9mIGBhcnJheWAgd2l0aCBgdmFsdWVgIGZyb20gYHN0YXJ0YCB1cCB0bywgYnV0IG5vdFxuICAgICAqIGluY2x1ZGluZywgYGVuZGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMi4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbGwuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZmlsbCBgYXJyYXlgIHdpdGguXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgMiwgM107XG4gICAgICpcbiAgICAgKiBfLmZpbGwoYXJyYXksICdhJyk7XG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsnYScsICdhJywgJ2EnXVxuICAgICAqXG4gICAgICogXy5maWxsKEFycmF5KDMpLCAyKTtcbiAgICAgKiAvLyA9PiBbMiwgMiwgMl1cbiAgICAgKlxuICAgICAqIF8uZmlsbChbNCwgNiwgOCwgMTBdLCAnKicsIDEsIDMpO1xuICAgICAqIC8vID0+IFs0LCAnKicsICcqJywgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmlsbChhcnJheSwgdmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFydCAmJiB0eXBlb2Ygc3RhcnQgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoYXJyYXksIHZhbHVlLCBzdGFydCkpIHtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICBlbmQgPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUZpbGwoYXJyYXksIHZhbHVlLCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRgIGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdFxuICAgICAqIGVsZW1lbnQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZm91bmQgZWxlbWVudCwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbmRJbmRleCh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby51c2VyID09ICdiYXJuZXknOyB9KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEluZGV4KHVzZXJzLCB7ICd1c2VyJzogJ2ZyZWQnLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEluZGV4KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gMFxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kSW5kZXgodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gZnJvbUluZGV4ID09IG51bGwgPyAwIDogdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgIGluZGV4ID0gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlRmluZEluZGV4KGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBpbmRleCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kSW5kZXhgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHNcbiAgICAgKiBvZiBgY29sbGVjdGlvbmAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PWFycmF5Lmxlbmd0aC0xXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZvdW5kIGVsZW1lbnQsIGVsc2UgYC0xYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLnVzZXIgPT0gJ3BlYmJsZXMnOyB9KTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZExhc3RJbmRleCh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbmRMYXN0SW5kZXgoYXJyYXksIHByZWRpY2F0ZSwgZnJvbUluZGV4KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBsZW5ndGggLSAxO1xuICAgICAgaWYgKGZyb21JbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluZGV4ID0gdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICAgIGluZGV4ID0gZnJvbUluZGV4IDwgMFxuICAgICAgICAgID8gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKVxuICAgICAgICAgIDogbmF0aXZlTWluKGluZGV4LCBsZW5ndGggLSAxKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlRmluZEluZGV4KGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBpbmRleCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmxhdHRlbnMgYGFycmF5YCBhIHNpbmdsZSBsZXZlbCBkZWVwLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmZsYXR0ZW4oWzEsIFsyLCBbMywgWzRdXSwgNV1dKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgWzMsIFs0XV0sIDVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdHRlbihhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VGbGF0dGVuKGFycmF5LCAxKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3Vyc2l2ZWx5IGZsYXR0ZW5zIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxhdHRlbkRlZXAoWzEsIFsyLCBbMywgWzRdXSwgNV1dKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgNCwgNV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0dGVuRGVlcChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VGbGF0dGVuKGFycmF5LCBJTkZJTklUWSkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWN1cnNpdmVseSBmbGF0dGVuIGBhcnJheWAgdXAgdG8gYGRlcHRoYCB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjQuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZGVwdGg9MV0gVGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIFsyLCBbMywgWzRdXSwgNV1dO1xuICAgICAqXG4gICAgICogXy5mbGF0dGVuRGVwdGgoYXJyYXksIDEpO1xuICAgICAqIC8vID0+IFsxLCAyLCBbMywgWzRdXSwgNV1cbiAgICAgKlxuICAgICAqIF8uZmxhdHRlbkRlcHRoKGFycmF5LCAyKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgWzRdLCA1XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXR0ZW5EZXB0aChhcnJheSwgZGVwdGgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGRlcHRoID0gZGVwdGggPT09IHVuZGVmaW5lZCA/IDEgOiB0b0ludGVnZXIoZGVwdGgpO1xuICAgICAgcmV0dXJuIGJhc2VGbGF0dGVuKGFycmF5LCBkZXB0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGludmVyc2Ugb2YgYF8udG9QYWlyc2A7IHRoaXMgbWV0aG9kIHJldHVybnMgYW4gb2JqZWN0IGNvbXBvc2VkXG4gICAgICogZnJvbSBrZXktdmFsdWUgYHBhaXJzYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhaXJzIFRoZSBrZXktdmFsdWUgcGFpcnMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mcm9tUGFpcnMoW1snYScsIDFdLCBbJ2InLCAyXV0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZyb21QYWlycyhwYWlycykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gcGFpcnMgPT0gbnVsbCA/IDAgOiBwYWlycy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0ge307XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBwYWlyID0gcGFpcnNbaW5kZXhdO1xuICAgICAgICByZXN1bHRbcGFpclswXV0gPSBwYWlyWzFdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBmaXJzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAYWxpYXMgZmlyc3RcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5oZWFkKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogXy5oZWFkKFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoZWFkKGFycmF5KSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkgPyBhcnJheVswXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgdmFsdWVgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAgICAgKiB1c2luZyBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGVcbiAgICAgKiBvZmZzZXQgZnJvbSB0aGUgZW5kIG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiAvLyBTZWFyY2ggZnJvbSB0aGUgYGZyb21JbmRleGAuXG4gICAgICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMiwgMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IGZyb21JbmRleCA9PSBudWxsID8gMCA6IHRvSW50ZWdlcihmcm9tSW5kZXgpO1xuICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICBpbmRleCA9IG5hdGl2ZU1heChsZW5ndGggKyBpbmRleCwgMCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCBpbmRleCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbGwgYnV0IHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW5pdGlhbChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluaXRpYWwoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIHJldHVybiBsZW5ndGggPyBiYXNlU2xpY2UoYXJyYXksIDAsIC0xKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdW5pcXVlIHZhbHVlcyB0aGF0IGFyZSBpbmNsdWRlZCBpbiBhbGwgZ2l2ZW4gYXJyYXlzXG4gICAgICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIFRoZSBvcmRlciBhbmQgcmVmZXJlbmNlcyBvZiByZXN1bHQgdmFsdWVzIGFyZVxuICAgICAqIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGludGVyc2VjdGluZyB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW50ZXJzZWN0aW9uKFsyLCAxXSwgWzIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMl1cbiAgICAgKi9cbiAgICB2YXIgaW50ZXJzZWN0aW9uID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgbWFwcGVkID0gYXJyYXlNYXAoYXJyYXlzLCBjYXN0QXJyYXlMaWtlT2JqZWN0KTtcbiAgICAgIHJldHVybiAobWFwcGVkLmxlbmd0aCAmJiBtYXBwZWRbMF0gPT09IGFycmF5c1swXSlcbiAgICAgICAgPyBiYXNlSW50ZXJzZWN0aW9uKG1hcHBlZClcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW50ZXJzZWN0aW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgZWFjaCBgYXJyYXlzYCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uXG4gICAgICogYnkgd2hpY2ggdGhleSdyZSBjb21wYXJlZC4gVGhlIG9yZGVyIGFuZCByZWZlcmVuY2VzIG9mIHJlc3VsdCB2YWx1ZXMgYXJlXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OlxuICAgICAqICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGludGVyc2VjdGluZyB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW50ZXJzZWN0aW9uQnkoWzIuMSwgMS4yXSwgWzIuMywgMy40XSwgTWF0aC5mbG9vcik7XG4gICAgICogLy8gPT4gWzIuMV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uaW50ZXJzZWN0aW9uQnkoW3sgJ3gnOiAxIH1dLCBbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAxIH1dXG4gICAgICovXG4gICAgdmFyIGludGVyc2VjdGlvbkJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgaXRlcmF0ZWUgPSBsYXN0KGFycmF5cyksXG4gICAgICAgICAgbWFwcGVkID0gYXJyYXlNYXAoYXJyYXlzLCBjYXN0QXJyYXlMaWtlT2JqZWN0KTtcblxuICAgICAgaWYgKGl0ZXJhdGVlID09PSBsYXN0KG1hcHBlZCkpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXBwZWQucG9wKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKG1hcHBlZC5sZW5ndGggJiYgbWFwcGVkWzBdID09PSBhcnJheXNbMF0pXG4gICAgICAgID8gYmFzZUludGVyc2VjdGlvbihtYXBwZWQsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSlcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW50ZXJzZWN0aW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjb21wYXJhdG9yYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgdG8gY29tcGFyZSBlbGVtZW50cyBvZiBgYXJyYXlzYC4gVGhlIG9yZGVyIGFuZCByZWZlcmVuY2VzXG4gICAgICogb2YgcmVzdWx0IHZhbHVlcyBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuIFRoZSBjb21wYXJhdG9yIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6IChhcnJWYWwsIG90aFZhbCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgaW50ZXJzZWN0aW5nIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dO1xuICAgICAqIHZhciBvdGhlcnMgPSBbeyAneCc6IDEsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAyIH1dO1xuICAgICAqXG4gICAgICogXy5pbnRlcnNlY3Rpb25XaXRoKG9iamVjdHMsIG90aGVycywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9XVxuICAgICAqL1xuICAgIHZhciBpbnRlcnNlY3Rpb25XaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QoYXJyYXlzKSxcbiAgICAgICAgICBtYXBwZWQgPSBhcnJheU1hcChhcnJheXMsIGNhc3RBcnJheUxpa2VPYmplY3QpO1xuXG4gICAgICBjb21wYXJhdG9yID0gdHlwZW9mIGNvbXBhcmF0b3IgPT0gJ2Z1bmN0aW9uJyA/IGNvbXBhcmF0b3IgOiB1bmRlZmluZWQ7XG4gICAgICBpZiAoY29tcGFyYXRvcikge1xuICAgICAgICBtYXBwZWQucG9wKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKG1hcHBlZC5sZW5ndGggJiYgbWFwcGVkWzBdID09PSBhcnJheXNbMF0pXG4gICAgICAgID8gYmFzZUludGVyc2VjdGlvbihtYXBwZWQsIHVuZGVmaW5lZCwgY29tcGFyYXRvcilcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGFsbCBlbGVtZW50cyBpbiBgYXJyYXlgIGludG8gYSBzdHJpbmcgc2VwYXJhdGVkIGJ5IGBzZXBhcmF0b3JgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbnZlcnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzZXBhcmF0b3I9JywnXSBUaGUgZWxlbWVudCBzZXBhcmF0b3IuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgam9pbmVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5qb2luKFsnYScsICdiJywgJ2MnXSwgJ34nKTtcbiAgICAgKiAvLyA9PiAnYX5ifmMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gam9pbihhcnJheSwgc2VwYXJhdG9yKSB7XG4gICAgICByZXR1cm4gYXJyYXkgPT0gbnVsbCA/ICcnIDogbmF0aXZlSm9pbi5jYWxsKGFycmF5LCBzZXBhcmF0b3IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sYXN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIHJldHVybiBsZW5ndGggPyBhcnJheVtsZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmluZGV4T2ZgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBgYXJyYXlgIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9YXJyYXkubGVuZ3RoLTFdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmxhc3RJbmRleE9mKFsxLCAyLCAxLCAyXSwgMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogLy8gU2VhcmNoIGZyb20gdGhlIGBmcm9tSW5kZXhgLlxuICAgICAqIF8ubGFzdEluZGV4T2YoWzEsIDIsIDEsIDJdLCAyLCAyKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGFzdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IGxlbmd0aDtcbiAgICAgIGlmIChmcm9tSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpbmRleCA9IHRvSW50ZWdlcihmcm9tSW5kZXgpO1xuICAgICAgICBpbmRleCA9IGluZGV4IDwgMCA/IG5hdGl2ZU1heChsZW5ndGggKyBpbmRleCwgMCkgOiBuYXRpdmVNaW4oaW5kZXgsIGxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZVxuICAgICAgICA/IHN0cmljdExhc3RJbmRleE9mKGFycmF5LCB2YWx1ZSwgaW5kZXgpXG4gICAgICAgIDogYmFzZUZpbmRJbmRleChhcnJheSwgYmFzZUlzTmFOLCBpbmRleCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZWxlbWVudCBhdCBpbmRleCBgbmAgb2YgYGFycmF5YC4gSWYgYG5gIGlzIG5lZ2F0aXZlLCB0aGUgbnRoXG4gICAgICogZWxlbWVudCBmcm9tIHRoZSBlbmQgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0wXSBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBudGggZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2QnXTtcbiAgICAgKlxuICAgICAqIF8ubnRoKGFycmF5LCAxKTtcbiAgICAgKiAvLyA9PiAnYidcbiAgICAgKlxuICAgICAqIF8ubnRoKGFycmF5LCAtMik7XG4gICAgICogLy8gPT4gJ2MnO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIG50aChhcnJheSwgbikge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZU50aChhcnJheSwgdG9JbnRlZ2VyKG4pKSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBnaXZlbiB2YWx1ZXMgZnJvbSBgYXJyYXlgIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLndpdGhvdXRgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuIFVzZSBgXy5yZW1vdmVgXG4gICAgICogdG8gcmVtb3ZlIGVsZW1lbnRzIGZyb20gYW4gYXJyYXkgYnkgcHJlZGljYXRlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2EnLCAnYicsICdjJ107XG4gICAgICpcbiAgICAgKiBfLnB1bGwoYXJyYXksICdhJywgJ2MnKTtcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWydiJywgJ2InXVxuICAgICAqL1xuICAgIHZhciBwdWxsID0gYmFzZVJlc3QocHVsbEFsbCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnB1bGxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYW4gYXJyYXkgb2YgdmFsdWVzIHRvIHJlbW92ZS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uZGlmZmVyZW5jZWAsIHRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2EnLCAnYicsICdjJ107XG4gICAgICpcbiAgICAgKiBfLnB1bGxBbGwoYXJyYXksIFsnYScsICdjJ10pO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbJ2InLCAnYiddXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHVsbEFsbChhcnJheSwgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCAmJiB2YWx1ZXMgJiYgdmFsdWVzLmxlbmd0aClcbiAgICAgICAgPyBiYXNlUHVsbEFsbChhcnJheSwgdmFsdWVzKVxuICAgICAgICA6IGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucHVsbEFsbGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgYW5kIGB2YWx1ZXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb25cbiAgICAgKiBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uZGlmZmVyZW5jZUJ5YCwgdGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbeyAneCc6IDEgfSwgeyAneCc6IDIgfSwgeyAneCc6IDMgfSwgeyAneCc6IDEgfV07XG4gICAgICpcbiAgICAgKiBfLnB1bGxBbGxCeShhcnJheSwgW3sgJ3gnOiAxIH0sIHsgJ3gnOiAzIH1dLCAneCcpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwdWxsQWxsQnkoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoICYmIHZhbHVlcyAmJiB2YWx1ZXMubGVuZ3RoKVxuICAgICAgICA/IGJhc2VQdWxsQWxsKGFycmF5LCB2YWx1ZXMsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSlcbiAgICAgICAgOiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnB1bGxBbGxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheWAgdG8gYHZhbHVlc2AuIFRoZSBjb21wYXJhdG9yIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6IChhcnJWYWwsIG90aFZhbCkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLmRpZmZlcmVuY2VXaXRoYCwgdGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNi4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAzLCAneSc6IDQgfSwgeyAneCc6IDUsICd5JzogNiB9XTtcbiAgICAgKlxuICAgICAqIF8ucHVsbEFsbFdpdGgoYXJyYXksIFt7ICd4JzogMywgJ3knOiA0IH1dLCBfLmlzRXF1YWwpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogNSwgJ3knOiA2IH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHVsbEFsbFdpdGgoYXJyYXksIHZhbHVlcywgY29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGggJiYgdmFsdWVzICYmIHZhbHVlcy5sZW5ndGgpXG4gICAgICAgID8gYmFzZVB1bGxBbGwoYXJyYXksIHZhbHVlcywgdW5kZWZpbmVkLCBjb21wYXJhdG9yKVxuICAgICAgICA6IGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgZWxlbWVudHMgZnJvbSBgYXJyYXlgIGNvcnJlc3BvbmRpbmcgdG8gYGluZGV4ZXNgIGFuZCByZXR1cm5zIGFuXG4gICAgICogYXJyYXkgb2YgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uYXRgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7Li4uKG51bWJlcnxudW1iZXJbXSl9IFtpbmRleGVzXSBUaGUgaW5kZXhlcyBvZiBlbGVtZW50cyB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWydhJywgJ2InLCAnYycsICdkJ107XG4gICAgICogdmFyIHB1bGxlZCA9IF8ucHVsbEF0KGFycmF5LCBbMSwgM10pO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsnYScsICdjJ11cbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKHB1bGxlZCk7XG4gICAgICogLy8gPT4gWydiJywgJ2QnXVxuICAgICAqL1xuICAgIHZhciBwdWxsQXQgPSBmbGF0UmVzdChmdW5jdGlvbihhcnJheSwgaW5kZXhlcykge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IGJhc2VBdChhcnJheSwgaW5kZXhlcyk7XG5cbiAgICAgIGJhc2VQdWxsQXQoYXJyYXksIGFycmF5TWFwKGluZGV4ZXMsIGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICAgIHJldHVybiBpc0luZGV4KGluZGV4LCBsZW5ndGgpID8gK2luZGV4IDogaW5kZXg7XG4gICAgICB9KS5zb3J0KGNvbXBhcmVBc2NlbmRpbmcpKTtcblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gYGFycmF5YCB0aGF0IGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvclxuICAgICAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZSByZW1vdmVkIGVsZW1lbnRzLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5maWx0ZXJgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuIFVzZSBgXy5wdWxsYFxuICAgICAqIHRvIHB1bGwgZWxlbWVudHMgZnJvbSBhbiBhcnJheSBieSB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHJlbW92ZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzLCA0XTtcbiAgICAgKiB2YXIgZXZlbnMgPSBfLnJlbW92ZShhcnJheSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIG4gJSAyID09IDA7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDNdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhldmVucyk7XG4gICAgICogLy8gPT4gWzIsIDRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVtb3ZlKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGluZGV4ZXMgPSBbXSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHByZWRpY2F0ZSA9IGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgaW5kZXhlcy5wdXNoKGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYmFzZVB1bGxBdChhcnJheSwgaW5kZXhlcyk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldmVyc2VzIGBhcnJheWAgc28gdGhhdCB0aGUgZmlyc3QgZWxlbWVudCBiZWNvbWVzIHRoZSBsYXN0LCB0aGUgc2Vjb25kXG4gICAgICogZWxlbWVudCBiZWNvbWVzIHRoZSBzZWNvbmQgdG8gbGFzdCwgYW5kIHNvIG9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YCBhbmQgaXMgYmFzZWQgb25cbiAgICAgKiBbYEFycmF5I3JldmVyc2VgXShodHRwczovL21kbi5pby9BcnJheS9yZXZlcnNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKlxuICAgICAqIF8ucmV2ZXJzZShhcnJheSk7XG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmV2ZXJzZShhcnJheSkge1xuICAgICAgcmV0dXJuIGFycmF5ID09IG51bGwgPyBhcnJheSA6IG5hdGl2ZVJldmVyc2UuY2FsbChhcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgZnJvbSBgc3RhcnRgIHVwIHRvLCBidXQgbm90IGluY2x1ZGluZywgYGVuZGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgdXNlZCBpbnN0ZWFkIG9mXG4gICAgICogW2BBcnJheSNzbGljZWBdKGh0dHBzOi8vbWRuLmlvL0FycmF5L3NsaWNlKSB0byBlbnN1cmUgZGVuc2UgYXJyYXlzIGFyZVxuICAgICAqIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmQgJiYgdHlwZW9mIGVuZCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc3RhcnQsIGVuZCkpIHtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICBlbmQgPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6IHRvSW50ZWdlcihzdGFydCk7XG4gICAgICAgIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogdG9JbnRlZ2VyKGVuZCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VzIGEgYmluYXJ5IHNlYXJjaCB0byBkZXRlcm1pbmUgdGhlIGxvd2VzdCBpbmRleCBhdCB3aGljaCBgdmFsdWVgXG4gICAgICogc2hvdWxkIGJlIGluc2VydGVkIGludG8gYGFycmF5YCBpbiBvcmRlciB0byBtYWludGFpbiBpdHMgc29ydCBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc29ydGVkSW5kZXgoWzMwLCA1MF0sIDQwKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkSW5kZXgoYXJyYXksIHZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zb3J0ZWRJbmRleGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCBmb3IgYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpclxuICAgICAqIHNvcnQgcmFua2luZy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDQgfSwgeyAneCc6IDUgfV07XG4gICAgICpcbiAgICAgKiBfLnNvcnRlZEluZGV4Qnkob2JqZWN0cywgeyAneCc6IDQgfSwgZnVuY3Rpb24obykgeyByZXR1cm4gby54OyB9KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnNvcnRlZEluZGV4Qnkob2JqZWN0cywgeyAneCc6IDQgfSwgJ3gnKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkSW5kZXhCeShhcnJheSwgdmFsdWUsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4QnkoYXJyYXksIHZhbHVlLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW5kZXhPZmAgZXhjZXB0IHRoYXQgaXQgcGVyZm9ybXMgYSBiaW5hcnlcbiAgICAgKiBzZWFyY2ggb24gYSBzb3J0ZWQgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRJbmRleE9mKFs0LCA1LCA1LCA1LCA2XSwgNSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZEluZGV4T2YoYXJyYXksIHZhbHVlKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGJhc2VTb3J0ZWRJbmRleChhcnJheSwgdmFsdWUpO1xuICAgICAgICBpZiAoaW5kZXggPCBsZW5ndGggJiYgZXEoYXJyYXlbaW5kZXhdLCB2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRlZEluZGV4YCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHRoZSBoaWdoZXN0XG4gICAgICogaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byBgYXJyYXlgIGluIG9yZGVyIHRvXG4gICAgICogbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAgICAgKiAgaW50byBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZExhc3RJbmRleChbNCwgNSwgNSwgNSwgNl0sIDUpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRMYXN0SW5kZXgoYXJyYXksIHZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4KGFycmF5LCB2YWx1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zb3J0ZWRMYXN0SW5kZXhgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgZm9yIGB2YWx1ZWAgYW5kIGVhY2ggZWxlbWVudCBvZiBgYXJyYXlgIHRvIGNvbXB1dGUgdGhlaXJcbiAgICAgKiBzb3J0IHJhbmtpbmcuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiA0IH0sIHsgJ3gnOiA1IH1dO1xuICAgICAqXG4gICAgICogXy5zb3J0ZWRMYXN0SW5kZXhCeShvYmplY3RzLCB7ICd4JzogNCB9LCBmdW5jdGlvbihvKSB7IHJldHVybiBvLng7IH0pO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29ydGVkTGFzdEluZGV4Qnkob2JqZWN0cywgeyAneCc6IDQgfSwgJ3gnKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkTGFzdEluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGJhc2VTb3J0ZWRJbmRleEJ5KGFycmF5LCB2YWx1ZSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmxhc3RJbmRleE9mYCBleGNlcHQgdGhhdCBpdCBwZXJmb3JtcyBhIGJpbmFyeVxuICAgICAqIHNlYXJjaCBvbiBhIHNvcnRlZCBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZExhc3RJbmRleE9mKFs0LCA1LCA1LCA1LCA2XSwgNSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZExhc3RJbmRleE9mKGFycmF5LCB2YWx1ZSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKGxlbmd0aCkge1xuICAgICAgICB2YXIgaW5kZXggPSBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlLCB0cnVlKSAtIDE7XG4gICAgICAgIGlmIChlcShhcnJheVtpbmRleF0sIHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW5pcWAgZXhjZXB0IHRoYXQgaXQncyBkZXNpZ25lZCBhbmQgb3B0aW1pemVkXG4gICAgICogZm9yIHNvcnRlZCBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRVbmlxKFsxLCAxLCAyXSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkVW5pcShhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVNvcnRlZFVuaXEoYXJyYXkpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlxQnlgIGV4Y2VwdCB0aGF0IGl0J3MgZGVzaWduZWQgYW5kIG9wdGltaXplZFxuICAgICAqIGZvciBzb3J0ZWQgYXJyYXlzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRVbmlxQnkoWzEuMSwgMS4yLCAyLjMsIDIuNF0sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsxLjEsIDIuM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRVbmlxQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlU29ydGVkVW5pcShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYWxsIGJ1dCB0aGUgZmlyc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50YWlsKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFpbChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VTbGljZShhcnJheSwgMSwgbGVuZ3RoKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGJlZ2lubmluZy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byB0YWtlLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRha2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMV1cbiAgICAgKlxuICAgICAqIF8udGFrZShbMSwgMiwgM10sIDIpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqXG4gICAgICogXy50YWtlKFsxLCAyLCAzXSwgNSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBfLnRha2UoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2UoYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgICBpZiAoIShhcnJheSAmJiBhcnJheS5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCAwLCBuIDwgMCA/IDAgOiBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGBuYCBlbGVtZW50cyB0YWtlbiBmcm9tIHRoZSBlbmQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gdGFrZS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50YWtlUmlnaHQoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbM11cbiAgICAgKlxuICAgICAqIF8udGFrZVJpZ2h0KFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodChbMSwgMiwgM10sIDUpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogXy50YWtlUmlnaHQoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2VSaWdodChhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICBuID0gbGVuZ3RoIC0gbjtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIG4gPCAwID8gMCA6IG4sIGxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBlbGVtZW50cyB0YWtlbiBmcm9tIHRoZSBlbmQuIEVsZW1lbnRzIGFyZVxuICAgICAqIHRha2VuIHVudGlsIGBwcmVkaWNhdGVgIHJldHVybnMgZmFsc2V5LiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aFxuICAgICAqIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8udGFrZVJpZ2h0V2hpbGUodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VSaWdodFdoaWxlKHVzZXJzLCB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydwZWJibGVzJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VSaWdodFdoaWxlKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlUmlnaHRXaGlsZSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFrZVJpZ2h0V2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBmYWxzZSwgdHJ1ZSlcbiAgICAgICAgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGJlZ2lubmluZy4gRWxlbWVudHNcbiAgICAgKiBhcmUgdGFrZW4gdW50aWwgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoXG4gICAgICogdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknLCAnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVdoaWxlKHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YWtlV2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdW5pcXVlIHZhbHVlcywgaW4gb3JkZXIsIGZyb20gYWxsIGdpdmVuIGFycmF5cyB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlvbihbMl0sIFsxLCAyXSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICovXG4gICAgdmFyIHVuaW9uID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4oYXJyYXlzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSkpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlvbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IG9mIGVhY2ggYGFycmF5c2AgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvbiBieVxuICAgICAqIHdoaWNoIHVuaXF1ZW5lc3MgaXMgY29tcHV0ZWQuIFJlc3VsdCB2YWx1ZXMgYXJlIGNob3NlbiBmcm9tIHRoZSBmaXJzdFxuICAgICAqIGFycmF5IGluIHdoaWNoIHRoZSB2YWx1ZSBvY2N1cnMuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OlxuICAgICAqICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlvbkJ5KFsyLjFdLCBbMS4yLCAyLjNdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMi4xLCAxLjJdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnVuaW9uQnkoW3sgJ3gnOiAxIH1dLCBbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAxIH0sIHsgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgdmFyIHVuaW9uQnkgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBpdGVyYXRlZSA9IGxhc3QoYXJyYXlzKTtcbiAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChpdGVyYXRlZSkpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4oYXJyYXlzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjb21wYXJhdG9yYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gY29tcGFyZSBlbGVtZW50cyBvZiBgYXJyYXlzYC4gUmVzdWx0IHZhbHVlcyBhcmUgY2hvc2VuIGZyb21cbiAgICAgKiB0aGUgZmlyc3QgYXJyYXkgaW4gd2hpY2ggdGhlIHZhbHVlIG9jY3Vycy4gVGhlIGNvbXBhcmF0b3IgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21iaW5lZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9XTtcbiAgICAgKiB2YXIgb3RoZXJzID0gW3sgJ3gnOiAxLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMiB9XTtcbiAgICAgKlxuICAgICAqIF8udW5pb25XaXRoKG9iamVjdHMsIG90aGVycywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH0sIHsgJ3gnOiAxLCAneSc6IDEgfV1cbiAgICAgKi9cbiAgICB2YXIgdW5pb25XaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QoYXJyYXlzKTtcbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlVW5pcShiYXNlRmxhdHRlbihhcnJheXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSwgdW5kZWZpbmVkLCBjb21wYXJhdG9yKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBkdXBsaWNhdGUtZnJlZSB2ZXJzaW9uIG9mIGFuIGFycmF5LCB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpbiB3aGljaCBvbmx5IHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGVhY2ggZWxlbWVudFxuICAgICAqIGlzIGtlcHQuIFRoZSBvcmRlciBvZiByZXN1bHQgdmFsdWVzIGlzIGRldGVybWluZWQgYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXJcbiAgICAgKiBpbiB0aGUgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlxKFsyLCAxLCAyXSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcShhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZVVuaXEoYXJyYXkpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlxYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgaW4gYGFycmF5YCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uIGJ5IHdoaWNoXG4gICAgICogdW5pcXVlbmVzcyBpcyBjb21wdXRlZC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGVcbiAgICAgKiBvcmRlciB0aGV5IG9jY3VyIGluIHRoZSBhcnJheS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlxQnkoWzIuMSwgMS4yLCAyLjNdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMi4xLCAxLjJdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnVuaXFCeShbeyAneCc6IDEgfSwgeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAxIH0sIHsgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcUJ5KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZVVuaXEoYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaXFgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheWAuIFRoZSBvcmRlciBvZiByZXN1bHQgdmFsdWVzIGlzXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXIgdGhleSBvY2N1ciBpbiB0aGUgYXJyYXkuVGhlIGNvbXBhcmF0b3IgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMiB9XTtcbiAgICAgKlxuICAgICAqIF8udW5pcVdpdGgob2JqZWN0cywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcVdpdGgoYXJyYXksIGNvbXBhcmF0b3IpIHtcbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSA/IGJhc2VVbmlxKGFycmF5LCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy56aXBgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYW4gYXJyYXkgb2YgZ3JvdXBlZFxuICAgICAqIGVsZW1lbnRzIGFuZCBjcmVhdGVzIGFuIGFycmF5IHJlZ3JvdXBpbmcgdGhlIGVsZW1lbnRzIHRvIHRoZWlyIHByZS16aXBcbiAgICAgKiBjb25maWd1cmF0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMi4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiByZWdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB6aXBwZWQgPSBfLnppcChbJ2EnLCAnYiddLCBbMSwgMl0sIFt0cnVlLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IFtbJ2EnLCAxLCB0cnVlXSwgWydiJywgMiwgZmFsc2VdXVxuICAgICAqXG4gICAgICogXy51bnppcCh6aXBwZWQpO1xuICAgICAqIC8vID0+IFtbJ2EnLCAnYiddLCBbMSwgMl0sIFt0cnVlLCBmYWxzZV1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW56aXAoYXJyYXkpIHtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IDA7XG4gICAgICBhcnJheSA9IGFycmF5RmlsdGVyKGFycmF5LCBmdW5jdGlvbihncm91cCkge1xuICAgICAgICBpZiAoaXNBcnJheUxpa2VPYmplY3QoZ3JvdXApKSB7XG4gICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KGdyb3VwLmxlbmd0aCwgbGVuZ3RoKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gYmFzZVRpbWVzKGxlbmd0aCwgZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5TWFwKGFycmF5LCBiYXNlUHJvcGVydHkoaW5kZXgpKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW56aXBgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB0byBzcGVjaWZ5XG4gICAgICogaG93IHJlZ3JvdXBlZCB2YWx1ZXMgc2hvdWxkIGJlIGNvbWJpbmVkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRoZVxuICAgICAqIGVsZW1lbnRzIG9mIGVhY2ggZ3JvdXA6ICguLi5ncm91cCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy44LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cyB0byBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gdG8gY29tYmluZVxuICAgICAqICByZWdyb3VwZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHJlZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHppcHBlZCA9IF8uemlwKFsxLCAyXSwgWzEwLCAyMF0sIFsxMDAsIDIwMF0pO1xuICAgICAqIC8vID0+IFtbMSwgMTAsIDEwMF0sIFsyLCAyMCwgMjAwXV1cbiAgICAgKlxuICAgICAqIF8udW56aXBXaXRoKHppcHBlZCwgXy5hZGQpO1xuICAgICAqIC8vID0+IFszLCAzMCwgMzAwXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuemlwV2l0aChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IHVuemlwKGFycmF5KTtcbiAgICAgIGlmIChpdGVyYXRlZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXlNYXAocmVzdWx0LCBmdW5jdGlvbihncm91cCkge1xuICAgICAgICByZXR1cm4gYXBwbHkoaXRlcmF0ZWUsIHVuZGVmaW5lZCwgZ3JvdXApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBleGNsdWRpbmcgYWxsIGdpdmVuIHZhbHVlcyB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBleGNsdWRlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAc2VlIF8uZGlmZmVyZW5jZSwgXy54b3JcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy53aXRob3V0KFsyLCAxLCAyLCAzXSwgMSwgMik7XG4gICAgICogLy8gPT4gWzNdXG4gICAgICovXG4gICAgdmFyIHdpdGhvdXQgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheSwgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2VPYmplY3QoYXJyYXkpXG4gICAgICAgID8gYmFzZURpZmZlcmVuY2UoYXJyYXksIHZhbHVlcylcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdW5pcXVlIHZhbHVlcyB0aGF0IGlzIHRoZVxuICAgICAqIFtzeW1tZXRyaWMgZGlmZmVyZW5jZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3ltbWV0cmljX2RpZmZlcmVuY2UpXG4gICAgICogb2YgdGhlIGdpdmVuIGFycmF5cy4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXJcbiAgICAgKiB0aGV5IG9jY3VyIGluIHRoZSBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBzZWUgXy5kaWZmZXJlbmNlLCBfLndpdGhvdXRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy54b3IoWzIsIDFdLCBbMiwgM10pO1xuICAgICAqIC8vID0+IFsxLCAzXVxuICAgICAqL1xuICAgIHZhciB4b3IgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHJldHVybiBiYXNlWG9yKGFycmF5RmlsdGVyKGFycmF5cywgaXNBcnJheUxpa2VPYmplY3QpKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ueG9yYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgZWFjaCBgYXJyYXlzYCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uIGJ5XG4gICAgICogd2hpY2ggYnkgd2hpY2ggdGhleSdyZSBjb21wYXJlZC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZFxuICAgICAqIGJ5IHRoZSBvcmRlciB0aGV5IG9jY3VyIGluIHRoZSBhcnJheXMuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lXG4gICAgICogYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy54b3JCeShbMi4xLCAxLjJdLCBbMi4zLCAzLjRdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMS4yLCAzLjRdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnhvckJ5KFt7ICd4JzogMSB9XSwgW3sgJ3gnOiAyIH0sIHsgJ3gnOiAxIH1dLCAneCcpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMiB9XVxuICAgICAqL1xuICAgIHZhciB4b3JCeSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgdmFyIGl0ZXJhdGVlID0gbGFzdChhcnJheXMpO1xuICAgICAgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KGl0ZXJhdGVlKSkge1xuICAgICAgICBpdGVyYXRlZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlWG9yKGFycmF5RmlsdGVyKGFycmF5cywgaXNBcnJheUxpa2VPYmplY3QpLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy54b3JgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheXNgLiBUaGUgb3JkZXIgb2YgcmVzdWx0IHZhbHVlcyBpc1xuICAgICAqIGRldGVybWluZWQgYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5cy4gVGhlIGNvbXBhcmF0b3IgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9XTtcbiAgICAgKiB2YXIgb3RoZXJzID0gW3sgJ3gnOiAxLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMiB9XTtcbiAgICAgKlxuICAgICAqIF8ueG9yV2l0aChvYmplY3RzLCBvdGhlcnMsIF8uaXNFcXVhbCk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMSB9XVxuICAgICAqL1xuICAgIHZhciB4b3JXaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QoYXJyYXlzKTtcbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlWG9yKGFycmF5RmlsdGVyKGFycmF5cywgaXNBcnJheUxpa2VPYmplY3QpLCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBncm91cGVkIGVsZW1lbnRzLCB0aGUgZmlyc3Qgb2Ygd2hpY2ggY29udGFpbnMgdGhlXG4gICAgICogZmlyc3QgZWxlbWVudHMgb2YgdGhlIGdpdmVuIGFycmF5cywgdGhlIHNlY29uZCBvZiB3aGljaCBjb250YWlucyB0aGVcbiAgICAgKiBzZWNvbmQgZWxlbWVudHMgb2YgdGhlIGdpdmVuIGFycmF5cywgYW5kIHNvIG9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwKFsnYScsICdiJ10sIFsxLCAyXSwgW3RydWUsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gW1snYScsIDEsIHRydWVdLCBbJ2InLCAyLCBmYWxzZV1dXG4gICAgICovXG4gICAgdmFyIHppcCA9IGJhc2VSZXN0KHVuemlwKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZnJvbVBhaXJzYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIHR3byBhcnJheXMsXG4gICAgICogb25lIG9mIHByb3BlcnR5IGlkZW50aWZpZXJzIGFuZCBvbmUgb2YgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC40LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcHJvcHM9W11dIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVycy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzPVtdXSBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwT2JqZWN0KFsnYScsICdiJ10sIFsxLCAyXSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gemlwT2JqZWN0KHByb3BzLCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBiYXNlWmlwT2JqZWN0KHByb3BzIHx8IFtdLCB2YWx1ZXMgfHwgW10sIGFzc2lnblZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnppcE9iamVjdGAgZXhjZXB0IHRoYXQgaXQgc3VwcG9ydHMgcHJvcGVydHkgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcHJvcHM9W11dIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVycy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzPVtdXSBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwT2JqZWN0RGVlcChbJ2EuYlswXS5jJywgJ2EuYlsxXS5kJ10sIFsxLCAyXSk7XG4gICAgICogLy8gPT4geyAnYSc6IHsgJ2InOiBbeyAnYyc6IDEgfSwgeyAnZCc6IDIgfV0gfSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gemlwT2JqZWN0RGVlcChwcm9wcywgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gYmFzZVppcE9iamVjdChwcm9wcyB8fCBbXSwgdmFsdWVzIHx8IFtdLCBiYXNlU2V0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnppcGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHRvIHNwZWNpZnlcbiAgICAgKiBob3cgZ3JvdXBlZCB2YWx1ZXMgc2hvdWxkIGJlIGNvbWJpbmVkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRoZVxuICAgICAqIGVsZW1lbnRzIG9mIGVhY2ggZ3JvdXA6ICguLi5ncm91cCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy44LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIHByb2Nlc3MuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiB0byBjb21iaW5lXG4gICAgICogIGdyb3VwZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwV2l0aChbMSwgMl0sIFsxMCwgMjBdLCBbMTAwLCAyMDBdLCBmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gYSArIGIgKyBjO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IFsxMTEsIDIyMl1cbiAgICAgKi9cbiAgICB2YXIgemlwV2l0aCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5cy5sZW5ndGgsXG4gICAgICAgICAgaXRlcmF0ZWUgPSBsZW5ndGggPiAxID8gYXJyYXlzW2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICBpdGVyYXRlZSA9IHR5cGVvZiBpdGVyYXRlZSA9PSAnZnVuY3Rpb24nID8gKGFycmF5cy5wb3AoKSwgaXRlcmF0ZWUpIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHVuemlwV2l0aChhcnJheXMsIGl0ZXJhdGVlKTtcbiAgICB9KTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlIHRoYXQgd3JhcHMgYHZhbHVlYCB3aXRoIGV4cGxpY2l0IG1ldGhvZFxuICAgICAqIGNoYWluIHNlcXVlbmNlcyBlbmFibGVkLiBUaGUgcmVzdWx0IG9mIHN1Y2ggc2VxdWVuY2VzIG11c3QgYmUgdW53cmFwcGVkXG4gICAgICogd2l0aCBgXyN2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogdmFyIHlvdW5nZXN0ID0gX1xuICAgICAqICAgLmNoYWluKHVzZXJzKVxuICAgICAqICAgLnNvcnRCeSgnYWdlJylcbiAgICAgKiAgIC5tYXAoZnVuY3Rpb24obykge1xuICAgICAqICAgICByZXR1cm4gby51c2VyICsgJyBpcyAnICsgby5hZ2U7XG4gICAgICogICB9KVxuICAgICAqICAgLmhlYWQoKVxuICAgICAqICAgLnZhbHVlKCk7XG4gICAgICogLy8gPT4gJ3BlYmJsZXMgaXMgMSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjaGFpbih2YWx1ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IGxvZGFzaCh2YWx1ZSk7XG4gICAgICByZXN1bHQuX19jaGFpbl9fID0gdHJ1ZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaW52b2tlcyBgaW50ZXJjZXB0b3JgIGFuZCByZXR1cm5zIGB2YWx1ZWAuIFRoZSBpbnRlcmNlcHRvclxuICAgICAqIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ7ICh2YWx1ZSkuIFRoZSBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIHRvXG4gICAgICogXCJ0YXAgaW50b1wiIGEgbWV0aG9kIGNoYWluIHNlcXVlbmNlIGluIG9yZGVyIHRvIG1vZGlmeSBpbnRlcm1lZGlhdGUgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm92aWRlIHRvIGBpbnRlcmNlcHRvcmAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaW50ZXJjZXB0b3IgVGhlIGZ1bmN0aW9uIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyBgdmFsdWVgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfKFsxLCAyLCAzXSlcbiAgICAgKiAgLnRhcChmdW5jdGlvbihhcnJheSkge1xuICAgICAqICAgIC8vIE11dGF0ZSBpbnB1dCBhcnJheS5cbiAgICAgKiAgICBhcnJheS5wb3AoKTtcbiAgICAgKiAgfSlcbiAgICAgKiAgLnJldmVyc2UoKVxuICAgICAqICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YXAodmFsdWUsIGludGVyY2VwdG9yKSB7XG4gICAgICBpbnRlcmNlcHRvcih2YWx1ZSk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy50YXBgIGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgdGhlIHJlc3VsdCBvZiBgaW50ZXJjZXB0b3JgLlxuICAgICAqIFRoZSBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIHRvIFwicGFzcyB0aHJ1XCIgdmFsdWVzIHJlcGxhY2luZyBpbnRlcm1lZGlhdGVcbiAgICAgKiByZXN1bHRzIGluIGEgbWV0aG9kIGNoYWluIHNlcXVlbmNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb3ZpZGUgdG8gYGludGVyY2VwdG9yYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpbnRlcmNlcHRvciBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgYGludGVyY2VwdG9yYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXygnICBhYmMgICcpXG4gICAgICogIC5jaGFpbigpXG4gICAgICogIC50cmltKClcbiAgICAgKiAgLnRocnUoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgICByZXR1cm4gW3ZhbHVlXTtcbiAgICAgKiAgfSlcbiAgICAgKiAgLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWydhYmMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRocnUodmFsdWUsIGludGVyY2VwdG9yKSB7XG4gICAgICByZXR1cm4gaW50ZXJjZXB0b3IodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIHRoZSB3cmFwcGVyIHZlcnNpb24gb2YgYF8uYXRgLlxuICAgICAqXG4gICAgICogQG5hbWUgYXRcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBbcGF0aHNdIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9LCA0XSB9O1xuICAgICAqXG4gICAgICogXyhvYmplY3QpLmF0KFsnYVswXS5iLmMnLCAnYVsxXSddKS52YWx1ZSgpO1xuICAgICAqIC8vID0+IFszLCA0XVxuICAgICAqL1xuICAgIHZhciB3cmFwcGVyQXQgPSBmbGF0UmVzdChmdW5jdGlvbihwYXRocykge1xuICAgICAgdmFyIGxlbmd0aCA9IHBhdGhzLmxlbmd0aCxcbiAgICAgICAgICBzdGFydCA9IGxlbmd0aCA/IHBhdGhzWzBdIDogMCxcbiAgICAgICAgICB2YWx1ZSA9IHRoaXMuX193cmFwcGVkX18sXG4gICAgICAgICAgaW50ZXJjZXB0b3IgPSBmdW5jdGlvbihvYmplY3QpIHsgcmV0dXJuIGJhc2VBdChvYmplY3QsIHBhdGhzKTsgfTtcblxuICAgICAgaWYgKGxlbmd0aCA+IDEgfHwgdGhpcy5fX2FjdGlvbnNfXy5sZW5ndGggfHxcbiAgICAgICAgICAhKHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHx8ICFpc0luZGV4KHN0YXJ0KSkge1xuICAgICAgICByZXR1cm4gdGhpcy50aHJ1KGludGVyY2VwdG9yKTtcbiAgICAgIH1cbiAgICAgIHZhbHVlID0gdmFsdWUuc2xpY2Uoc3RhcnQsICtzdGFydCArIChsZW5ndGggPyAxIDogMCkpO1xuICAgICAgdmFsdWUuX19hY3Rpb25zX18ucHVzaCh7XG4gICAgICAgICdmdW5jJzogdGhydSxcbiAgICAgICAgJ2FyZ3MnOiBbaW50ZXJjZXB0b3JdLFxuICAgICAgICAndGhpc0FyZyc6IHVuZGVmaW5lZFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIodmFsdWUsIHRoaXMuX19jaGFpbl9fKS50aHJ1KGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgICAgIGlmIChsZW5ndGggJiYgIWFycmF5Lmxlbmd0aCkge1xuICAgICAgICAgIGFycmF5LnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXJyYXk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlIHdpdGggZXhwbGljaXQgbWV0aG9kIGNoYWluIHNlcXVlbmNlcyBlbmFibGVkLlxuICAgICAqXG4gICAgICogQG5hbWUgY2hhaW5cbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gQSBzZXF1ZW5jZSB3aXRob3V0IGV4cGxpY2l0IGNoYWluaW5nLlxuICAgICAqIF8odXNlcnMpLmhlYWQoKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9XG4gICAgICpcbiAgICAgKiAvLyBBIHNlcXVlbmNlIHdpdGggZXhwbGljaXQgY2hhaW5pbmcuXG4gICAgICogXyh1c2VycylcbiAgICAgKiAgIC5jaGFpbigpXG4gICAgICogICAuaGVhZCgpXG4gICAgICogICAucGljaygndXNlcicpXG4gICAgICogICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJDaGFpbigpIHtcbiAgICAgIHJldHVybiBjaGFpbih0aGlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyB0aGUgY2hhaW4gc2VxdWVuY2UgYW5kIHJldHVybnMgdGhlIHdyYXBwZWQgcmVzdWx0LlxuICAgICAqXG4gICAgICogQG5hbWUgY29tbWl0XG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyXTtcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oYXJyYXkpLnB1c2goMyk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkID0gd3JhcHBlZC5jb21taXQoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkLmxhc3QoKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNvbW1pdCgpIHtcbiAgICAgIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih0aGlzLnZhbHVlKCksIHRoaXMuX19jaGFpbl9fKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBuZXh0IHZhbHVlIG9uIGEgd3JhcHBlZCBvYmplY3QgZm9sbG93aW5nIHRoZVxuICAgICAqIFtpdGVyYXRvciBwcm90b2NvbF0oaHR0cHM6Ly9tZG4uaW8vaXRlcmF0aW9uX3Byb3RvY29scyNpdGVyYXRvcikuXG4gICAgICpcbiAgICAgKiBAbmFtZSBuZXh0XG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV4dCBpdGVyYXRvciB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyXSk7XG4gICAgICpcbiAgICAgKiB3cmFwcGVkLm5leHQoKTtcbiAgICAgKiAvLyA9PiB7ICdkb25lJzogZmFsc2UsICd2YWx1ZSc6IDEgfVxuICAgICAqXG4gICAgICogd3JhcHBlZC5uZXh0KCk7XG4gICAgICogLy8gPT4geyAnZG9uZSc6IGZhbHNlLCAndmFsdWUnOiAyIH1cbiAgICAgKlxuICAgICAqIHdyYXBwZWQubmV4dCgpO1xuICAgICAqIC8vID0+IHsgJ2RvbmUnOiB0cnVlLCAndmFsdWUnOiB1bmRlZmluZWQgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJOZXh0KCkge1xuICAgICAgaWYgKHRoaXMuX192YWx1ZXNfXyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX192YWx1ZXNfXyA9IHRvQXJyYXkodGhpcy52YWx1ZSgpKTtcbiAgICAgIH1cbiAgICAgIHZhciBkb25lID0gdGhpcy5fX2luZGV4X18gPj0gdGhpcy5fX3ZhbHVlc19fLmxlbmd0aCxcbiAgICAgICAgICB2YWx1ZSA9IGRvbmUgPyB1bmRlZmluZWQgOiB0aGlzLl9fdmFsdWVzX19bdGhpcy5fX2luZGV4X18rK107XG5cbiAgICAgIHJldHVybiB7ICdkb25lJzogZG9uZSwgJ3ZhbHVlJzogdmFsdWUgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmFibGVzIHRoZSB3cmFwcGVyIHRvIGJlIGl0ZXJhYmxlLlxuICAgICAqXG4gICAgICogQG5hbWUgU3ltYm9sLml0ZXJhdG9yXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgd3JhcHBlciBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB3cmFwcGVkID0gXyhbMSwgMl0pO1xuICAgICAqXG4gICAgICogd3JhcHBlZFtTeW1ib2wuaXRlcmF0b3JdKCkgPT09IHdyYXBwZWQ7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogQXJyYXkuZnJvbSh3cmFwcGVkKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3cmFwcGVyVG9JdGVyYXRvcigpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiB0aGUgY2hhaW4gc2VxdWVuY2UgcGxhbnRpbmcgYHZhbHVlYCBhcyB0aGUgd3JhcHBlZCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYW50XG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcGxhbnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyXSkubWFwKHNxdWFyZSk7XG4gICAgICogdmFyIG90aGVyID0gd3JhcHBlZC5wbGFudChbMywgNF0pO1xuICAgICAqXG4gICAgICogb3RoZXIudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbOSwgMTZdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWzEsIDRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclBsYW50KHZhbHVlKSB7XG4gICAgICB2YXIgcmVzdWx0LFxuICAgICAgICAgIHBhcmVudCA9IHRoaXM7XG5cbiAgICAgIHdoaWxlIChwYXJlbnQgaW5zdGFuY2VvZiBiYXNlTG9kYXNoKSB7XG4gICAgICAgIHZhciBjbG9uZSA9IHdyYXBwZXJDbG9uZShwYXJlbnQpO1xuICAgICAgICBjbG9uZS5fX2luZGV4X18gPSAwO1xuICAgICAgICBjbG9uZS5fX3ZhbHVlc19fID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcHJldmlvdXMuX193cmFwcGVkX18gPSBjbG9uZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHQgPSBjbG9uZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcHJldmlvdXMgPSBjbG9uZTtcbiAgICAgICAgcGFyZW50ID0gcGFyZW50Ll9fd3JhcHBlZF9fO1xuICAgICAgfVxuICAgICAgcHJldmlvdXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgdGhlIHdyYXBwZXIgdmVyc2lvbiBvZiBgXy5yZXZlcnNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIHRoZSB3cmFwcGVkIGFycmF5LlxuICAgICAqXG4gICAgICogQG5hbWUgcmV2ZXJzZVxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgMiwgM107XG4gICAgICpcbiAgICAgKiBfKGFycmF5KS5yZXZlcnNlKCkudmFsdWUoKVxuICAgICAqIC8vID0+IFszLCAyLCAxXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFszLCAyLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJSZXZlcnNlKCkge1xuICAgICAgdmFyIHZhbHVlID0gdGhpcy5fX3dyYXBwZWRfXztcbiAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSB7XG4gICAgICAgIHZhciB3cmFwcGVkID0gdmFsdWU7XG4gICAgICAgIGlmICh0aGlzLl9fYWN0aW9uc19fLmxlbmd0aCkge1xuICAgICAgICAgIHdyYXBwZWQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgd3JhcHBlZCA9IHdyYXBwZWQucmV2ZXJzZSgpO1xuICAgICAgICB3cmFwcGVkLl9fYWN0aW9uc19fLnB1c2goe1xuICAgICAgICAgICdmdW5jJzogdGhydSxcbiAgICAgICAgICAnYXJncyc6IFtyZXZlcnNlXSxcbiAgICAgICAgICAndGhpc0FyZyc6IHVuZGVmaW5lZFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZWQsIHRoaXMuX19jaGFpbl9fKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnRocnUocmV2ZXJzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZXMgdGhlIGNoYWluIHNlcXVlbmNlIHRvIHJlc29sdmUgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBuYW1lIHZhbHVlXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAYWxpYXMgdG9KU09OLCB2YWx1ZU9mXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB1bndyYXBwZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8oWzEsIDIsIDNdKS52YWx1ZSgpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJWYWx1ZSgpIHtcbiAgICAgIHJldHVybiBiYXNlV3JhcHBlclZhbHVlKHRoaXMuX193cmFwcGVkX18sIHRoaXMuX19hY3Rpb25zX18pO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIGtleXMgZ2VuZXJhdGVkIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZ1xuICAgICAqIGVhY2ggZWxlbWVudCBvZiBgY29sbGVjdGlvbmAgdGhydSBgaXRlcmF0ZWVgLiBUaGUgY29ycmVzcG9uZGluZyB2YWx1ZSBvZlxuICAgICAqIGVhY2gga2V5IGlzIHRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGtleSB3YXMgcmV0dXJuZWQgYnkgYGl0ZXJhdGVlYC4gVGhlXG4gICAgICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjUuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29tcG9zZWQgYWdncmVnYXRlIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jb3VudEJ5KFs2LjEsIDQuMiwgNi4zXSwgTWF0aC5mbG9vcik7XG4gICAgICogLy8gPT4geyAnNCc6IDEsICc2JzogMiB9XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmNvdW50QnkoWydvbmUnLCAndHdvJywgJ3RocmVlJ10sICdsZW5ndGgnKTtcbiAgICAgKiAvLyA9PiB7ICczJzogMiwgJzUnOiAxIH1cbiAgICAgKi9cbiAgICB2YXIgY291bnRCeSA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsIGtleSkpIHtcbiAgICAgICAgKytyZXN1bHRba2V5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGtleSwgMSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yICoqYWxsKiogZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLlxuICAgICAqIEl0ZXJhdGlvbiBpcyBzdG9wcGVkIG9uY2UgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgcmV0dXJucyBgdHJ1ZWAgZm9yXG4gICAgICogW2VtcHR5IGNvbGxlY3Rpb25zXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FbXB0eV9zZXQpIGJlY2F1c2VcbiAgICAgKiBbZXZlcnl0aGluZyBpcyB0cnVlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9WYWN1b3VzX3RydXRoKSBvZlxuICAgICAqIGVsZW1lbnRzIG9mIGVtcHR5IGNvbGxlY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFsbCBlbGVtZW50cyBwYXNzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5ldmVyeShbdHJ1ZSwgMSwgbnVsbCwgJ3llcyddLCBCb29sZWFuKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5ldmVyeSh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmV2ZXJ5KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5ldmVyeSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXZlcnkoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBndWFyZCkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlFdmVyeSA6IGJhc2VFdmVyeTtcbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGd1YXJkKSkge1xuICAgICAgICBwcmVkaWNhdGUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nIGFuIGFycmF5IG9mIGFsbCBlbGVtZW50c1xuICAgICAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdGhyZWVcbiAgICAgKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ucmVtb3ZlYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS5cbiAgICAgKiBAc2VlIF8ucmVqZWN0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiAhby5hY3RpdmU7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gQ29tYmluaW5nIHNldmVyYWwgcHJlZGljYXRlcyB1c2luZyBgXy5vdmVyRXZlcnlgIG9yIGBfLm92ZXJTb21lYC5cbiAgICAgKiBfLmZpbHRlcih1c2VycywgXy5vdmVyU29tZShbeyAnYWdlJzogMzYgfSwgWydhZ2UnLCA0MF1dKSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ2Jhcm5leSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAsIHJldHVybmluZyB0aGUgZmlyc3QgZWxlbWVudFxuICAgICAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdGhyZWVcbiAgICAgKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maW5kKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZSA8IDQwOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3QgZm9yICdiYXJuZXknXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZCh1c2VycywgeyAnYWdlJzogMSwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0IGZvciAncGViYmxlcydcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmQodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3QgZm9yICdmcmVkJ1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0IGZvciAnYmFybmV5J1xuICAgICAqL1xuICAgIHZhciBmaW5kID0gY3JlYXRlRmluZChmaW5kSW5kZXgpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYGNvbGxlY3Rpb25gIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9Y29sbGVjdGlvbi5sZW5ndGgtMV0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmluZExhc3QoWzEsIDIsIDMsIDRdLCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gbiAlIDIgPT0gMTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgdmFyIGZpbmRMYXN0ID0gY3JlYXRlRmluZChmaW5kTGFzdEluZGV4KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmbGF0dGVuZWQgYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYFxuICAgICAqIHRocnUgYGl0ZXJhdGVlYCBhbmQgZmxhdHRlbmluZyB0aGUgbWFwcGVkIHJlc3VsdHMuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZHVwbGljYXRlKG4pIHtcbiAgICAgKiAgIHJldHVybiBbbiwgbl07XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5mbGF0TWFwKFsxLCAyXSwgZHVwbGljYXRlKTtcbiAgICAgKiAvLyA9PiBbMSwgMSwgMiwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0TWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4obWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSwgMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mbGF0TWFwYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBmbGF0dGVucyB0aGVcbiAgICAgKiBtYXBwZWQgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjcuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZHVwbGljYXRlKG4pIHtcbiAgICAgKiAgIHJldHVybiBbW1tuLCBuXV1dO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmxhdE1hcERlZXAoWzEsIDJdLCBkdXBsaWNhdGUpO1xuICAgICAqIC8vID0+IFsxLCAxLCAyLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXRNYXBEZWVwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4obWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSwgSU5GSU5JVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmxhdE1hcGAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgZmxhdHRlbnMgdGhlXG4gICAgICogbWFwcGVkIHJlc3VsdHMgdXAgdG8gYGRlcHRoYCB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjcuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZGVwdGg9MV0gVGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZHVwbGljYXRlKG4pIHtcbiAgICAgKiAgIHJldHVybiBbW1tuLCBuXV1dO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmxhdE1hcERlcHRoKFsxLCAyXSwgZHVwbGljYXRlLCAyKTtcbiAgICAgKiAvLyA9PiBbWzEsIDFdLCBbMiwgMl1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdE1hcERlcHRoKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBkZXB0aCkge1xuICAgICAgZGVwdGggPSBkZXB0aCA9PT0gdW5kZWZpbmVkID8gMSA6IHRvSW50ZWdlcihkZXB0aCk7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4obWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSwgZGVwdGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggZWxlbWVudC5cbiAgICAgKiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiXG4gICAgICogcHJvcGVydHkgYXJlIGl0ZXJhdGVkIGxpa2UgYXJyYXlzLiBUbyBhdm9pZCB0aGlzIGJlaGF2aW9yIHVzZSBgXy5mb3JJbmBcbiAgICAgKiBvciBgXy5mb3JPd25gIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGFsaWFzIGVhY2hcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKiBAc2VlIF8uZm9yRWFjaFJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZm9yRWFjaChbMSwgMl0sIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICogICBjb25zb2xlLmxvZyh2YWx1ZSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyBgMWAgdGhlbiBgMmAuXG4gICAgICpcbiAgICAgKiBfLmZvckVhY2goeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2EnIHRoZW4gJ2InIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvckVhY2goY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5RWFjaCA6IGJhc2VFYWNoO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZvckVhY2hgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBgY29sbGVjdGlvbmAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGFsaWFzIGVhY2hSaWdodFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICAgICAqIEBzZWUgXy5mb3JFYWNoXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZm9yRWFjaFJpZ2h0KFsxLCAyXSwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKHZhbHVlKTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzIGAyYCB0aGVuIGAxYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JFYWNoUmlnaHQoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5RWFjaFJpZ2h0IDogYmFzZUVhY2hSaWdodDtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2Yga2V5cyBnZW5lcmF0ZWQgZnJvbSB0aGUgcmVzdWx0cyBvZiBydW5uaW5nXG4gICAgICogZWFjaCBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBvcmRlciBvZiBncm91cGVkIHZhbHVlc1xuICAgICAqIGlzIGRldGVybWluZWQgYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXIgaW4gYGNvbGxlY3Rpb25gLiBUaGUgY29ycmVzcG9uZGluZ1xuICAgICAqIHZhbHVlIG9mIGVhY2gga2V5IGlzIGFuIGFycmF5IG9mIGVsZW1lbnRzIHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZVxuICAgICAqIGtleS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3JvdXBCeShbNi4xLCA0LjIsIDYuM10sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IHsgJzQnOiBbNC4yXSwgJzYnOiBbNi4xLCA2LjNdIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZ3JvdXBCeShbJ29uZScsICd0d28nLCAndGhyZWUnXSwgJ2xlbmd0aCcpO1xuICAgICAqIC8vID0+IHsgJzMnOiBbJ29uZScsICd0d28nXSwgJzUnOiBbJ3RocmVlJ10gfVxuICAgICAqL1xuICAgIHZhciBncm91cEJ5ID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwga2V5KSkge1xuICAgICAgICByZXN1bHRba2V5XS5wdXNoKHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGtleSwgW3ZhbHVlXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBpbiBgY29sbGVjdGlvbmAuIElmIGBjb2xsZWN0aW9uYCBpcyBhIHN0cmluZywgaXQnc1xuICAgICAqIGNoZWNrZWQgZm9yIGEgc3Vic3RyaW5nIG9mIGB2YWx1ZWAsIG90aGVyd2lzZVxuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogaXMgdXNlZCBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIElmIGBmcm9tSW5kZXhgIGlzIG5lZ2F0aXZlLCBpdCdzIHVzZWQgYXNcbiAgICAgKiB0aGUgb2Zmc2V0IGZyb20gdGhlIGVuZCBvZiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLnJlZHVjZWAuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxLCAyKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcyh7ICdhJzogMSwgJ2InOiAyIH0sIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5jbHVkZXMoJ2FiY2QnLCAnYmMnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5jbHVkZXMoY29sbGVjdGlvbiwgdmFsdWUsIGZyb21JbmRleCwgZ3VhcmQpIHtcbiAgICAgIGNvbGxlY3Rpb24gPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IGNvbGxlY3Rpb24gOiB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgICBmcm9tSW5kZXggPSAoZnJvbUluZGV4ICYmICFndWFyZCkgPyB0b0ludGVnZXIoZnJvbUluZGV4KSA6IDA7XG5cbiAgICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDtcbiAgICAgIGlmIChmcm9tSW5kZXggPCAwKSB7XG4gICAgICAgIGZyb21JbmRleCA9IG5hdGl2ZU1heChsZW5ndGggKyBmcm9tSW5kZXgsIDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzU3RyaW5nKGNvbGxlY3Rpb24pXG4gICAgICAgID8gKGZyb21JbmRleCA8PSBsZW5ndGggJiYgY29sbGVjdGlvbi5pbmRleE9mKHZhbHVlLCBmcm9tSW5kZXgpID4gLTEpXG4gICAgICAgIDogKCEhbGVuZ3RoICYmIGJhc2VJbmRleE9mKGNvbGxlY3Rpb24sIHZhbHVlLCBmcm9tSW5kZXgpID4gLTEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIG1ldGhvZCBhdCBgcGF0aGAgb2YgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nXG4gICAgICogYW4gYXJyYXkgb2YgdGhlIHJlc3VsdHMgb2YgZWFjaCBpbnZva2VkIG1ldGhvZC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzXG4gICAgICogYXJlIHByb3ZpZGVkIHRvIGVhY2ggaW52b2tlZCBtZXRob2QuIElmIGBwYXRoYCBpcyBhIGZ1bmN0aW9uLCBpdCdzIGludm9rZWRcbiAgICAgKiBmb3IsIGFuZCBgdGhpc2AgYm91bmQgdG8sIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0FycmF5fEZ1bmN0aW9ufHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgbWV0aG9kIHRvIGludm9rZSBvclxuICAgICAqICB0aGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIGVhY2ggbWV0aG9kIHdpdGguXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmludm9rZU1hcChbWzUsIDEsIDddLCBbMywgMiwgMV1dLCAnc29ydCcpO1xuICAgICAqIC8vID0+IFtbMSwgNSwgN10sIFsxLCAyLCAzXV1cbiAgICAgKlxuICAgICAqIF8uaW52b2tlTWFwKFsxMjMsIDQ1Nl0sIFN0cmluZy5wcm90b3R5cGUuc3BsaXQsICcnKTtcbiAgICAgKiAvLyA9PiBbWycxJywgJzInLCAnMyddLCBbJzQnLCAnNScsICc2J11dXG4gICAgICovXG4gICAgdmFyIGludm9rZU1hcCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHBhdGgsIGFyZ3MpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGlzRnVuYyA9IHR5cGVvZiBwYXRoID09ICdmdW5jdGlvbicsXG4gICAgICAgICAgcmVzdWx0ID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBBcnJheShjb2xsZWN0aW9uLmxlbmd0aCkgOiBbXTtcblxuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmVzdWx0WysraW5kZXhdID0gaXNGdW5jID8gYXBwbHkocGF0aCwgdmFsdWUsIGFyZ3MpIDogYmFzZUludm9rZSh2YWx1ZSwgcGF0aCwgYXJncyk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiBrZXlzIGdlbmVyYXRlZCBmcm9tIHRoZSByZXN1bHRzIG9mIHJ1bm5pbmdcbiAgICAgKiBlYWNoIGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gIHRocnUgYGl0ZXJhdGVlYC4gVGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUgb2ZcbiAgICAgKiBlYWNoIGtleSBpcyB0aGUgbGFzdCBlbGVtZW50IHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZSBrZXkuIFRoZVxuICAgICAqIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFtcbiAgICAgKiAgIHsgJ2Rpcic6ICdsZWZ0JywgJ2NvZGUnOiA5NyB9LFxuICAgICAqICAgeyAnZGlyJzogJ3JpZ2h0JywgJ2NvZGUnOiAxMDAgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmtleUJ5KGFycmF5LCBmdW5jdGlvbihvKSB7XG4gICAgICogICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShvLmNvZGUpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiB7ICdkaXInOiAnbGVmdCcsICdjb2RlJzogOTcgfSwgJ2QnOiB7ICdkaXInOiAncmlnaHQnLCAnY29kZSc6IDEwMCB9IH1cbiAgICAgKlxuICAgICAqIF8ua2V5QnkoYXJyYXksICdkaXInKTtcbiAgICAgKiAvLyA9PiB7ICdsZWZ0JzogeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sICdyaWdodCc6IHsgJ2Rpcic6ICdyaWdodCcsICdjb2RlJzogMTAwIH0gfVxuICAgICAqL1xuICAgIHZhciBrZXlCeSA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBiYXNlQXNzaWduVmFsdWUocmVzdWx0LCBrZXksIHZhbHVlKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCB0aHJ1XG4gICAgICogYGl0ZXJhdGVlYC4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gICAgICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogTWFueSBsb2Rhc2ggbWV0aG9kcyBhcmUgZ3VhcmRlZCB0byB3b3JrIGFzIGl0ZXJhdGVlcyBmb3IgbWV0aG9kcyBsaWtlXG4gICAgICogYF8uZXZlcnlgLCBgXy5maWx0ZXJgLCBgXy5tYXBgLCBgXy5tYXBWYWx1ZXNgLCBgXy5yZWplY3RgLCBhbmQgYF8uc29tZWAuXG4gICAgICpcbiAgICAgKiBUaGUgZ3VhcmRlZCBtZXRob2RzIGFyZTpcbiAgICAgKiBgYXJ5YCwgYGNodW5rYCwgYGN1cnJ5YCwgYGN1cnJ5UmlnaHRgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLFxuICAgICAqIGBmaWxsYCwgYGludmVydGAsIGBwYXJzZUludGAsIGByYW5kb21gLCBgcmFuZ2VgLCBgcmFuZ2VSaWdodGAsIGByZXBlYXRgLFxuICAgICAqIGBzYW1wbGVTaXplYCwgYHNsaWNlYCwgYHNvbWVgLCBgc29ydEJ5YCwgYHNwbGl0YCwgYHRha2VgLCBgdGFrZVJpZ2h0YCxcbiAgICAgKiBgdGVtcGxhdGVgLCBgdHJpbWAsIGB0cmltRW5kYCwgYHRyaW1TdGFydGAsIGFuZCBgd29yZHNgXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5tYXAoWzQsIDhdLCBzcXVhcmUpO1xuICAgICAqIC8vID0+IFsxNiwgNjRdXG4gICAgICpcbiAgICAgKiBfLm1hcCh7ICdhJzogNCwgJ2InOiA4IH0sIHNxdWFyZSk7XG4gICAgICogLy8gPT4gWzE2LCA2NF0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJyB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWFwKHVzZXJzLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlNYXAgOiBiYXNlTWFwO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRCeWAgZXhjZXB0IHRoYXQgaXQgYWxsb3dzIHNwZWNpZnlpbmcgdGhlIHNvcnRcbiAgICAgKiBvcmRlcnMgb2YgdGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LiBJZiBgb3JkZXJzYCBpcyB1bnNwZWNpZmllZCwgYWxsIHZhbHVlc1xuICAgICAqIGFyZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyLiBPdGhlcndpc2UsIHNwZWNpZnkgYW4gb3JkZXIgb2YgXCJkZXNjXCIgZm9yXG4gICAgICogZGVzY2VuZGluZyBvciBcImFzY1wiIGZvciBhc2NlbmRpbmcgc29ydCBvcmRlciBvZiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7QXJyYXlbXXxGdW5jdGlvbltdfE9iamVjdFtdfHN0cmluZ1tdfSBbaXRlcmF0ZWVzPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IFtvcmRlcnNdIFRoZSBzb3J0IG9yZGVycyBvZiBgaXRlcmF0ZWVzYC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5yZWR1Y2VgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IHNvcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDggfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM0IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCB9LFxuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBTb3J0IGJ5IGB1c2VyYCBpbiBhc2NlbmRpbmcgb3JkZXIgYW5kIGJ5IGBhZ2VgIGluIGRlc2NlbmRpbmcgb3JkZXIuXG4gICAgICogXy5vcmRlckJ5KHVzZXJzLCBbJ3VzZXInLCAnYWdlJ10sIFsnYXNjJywgJ2Rlc2MnXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snYmFybmV5JywgMzZdLCBbJ2Jhcm5leScsIDM0XSwgWydmcmVkJywgNDhdLCBbJ2ZyZWQnLCA0MF1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gb3JkZXJCeShjb2xsZWN0aW9uLCBpdGVyYXRlZXMsIG9yZGVycywgZ3VhcmQpIHtcbiAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0FycmF5KGl0ZXJhdGVlcykpIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gaXRlcmF0ZWVzID09IG51bGwgPyBbXSA6IFtpdGVyYXRlZXNdO1xuICAgICAgfVxuICAgICAgb3JkZXJzID0gZ3VhcmQgPyB1bmRlZmluZWQgOiBvcmRlcnM7XG4gICAgICBpZiAoIWlzQXJyYXkob3JkZXJzKSkge1xuICAgICAgICBvcmRlcnMgPSBvcmRlcnMgPT0gbnVsbCA/IFtdIDogW29yZGVyc107XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZU9yZGVyQnkoY29sbGVjdGlvbiwgaXRlcmF0ZWVzLCBvcmRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgc3BsaXQgaW50byB0d28gZ3JvdXBzLCB0aGUgZmlyc3Qgb2Ygd2hpY2hcbiAgICAgKiBjb250YWlucyBlbGVtZW50cyBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IsIHRoZSBzZWNvbmQgb2Ygd2hpY2hcbiAgICAgKiBjb250YWlucyBlbGVtZW50cyBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleSBmb3IuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydmcmVkJ10sIFsnYmFybmV5JywgJ3BlYmJsZXMnXV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydwZWJibGVzJ10sIFsnYmFybmV5JywgJ2ZyZWQnXV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnBhcnRpdGlvbih1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFtbJ2Jhcm5leScsICdwZWJibGVzJ10sIFsnZnJlZCddXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydmcmVkJ10sIFsnYmFybmV5JywgJ3BlYmJsZXMnXV1cbiAgICAgKi9cbiAgICB2YXIgcGFydGl0aW9uID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIHJlc3VsdFtrZXkgPyAwIDogMV0ucHVzaCh2YWx1ZSk7XG4gICAgfSwgZnVuY3Rpb24oKSB7IHJldHVybiBbW10sIFtdXTsgfSk7XG5cbiAgICAvKipcbiAgICAgKiBSZWR1Y2VzIGBjb2xsZWN0aW9uYCB0byBhIHZhbHVlIHdoaWNoIGlzIHRoZSBhY2N1bXVsYXRlZCByZXN1bHQgb2YgcnVubmluZ1xuICAgICAqIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhydSBgaXRlcmF0ZWVgLCB3aGVyZSBlYWNoIHN1Y2Nlc3NpdmVcbiAgICAgKiBpbnZvY2F0aW9uIGlzIHN1cHBsaWVkIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHByZXZpb3VzLiBJZiBgYWNjdW11bGF0b3JgXG4gICAgICogaXMgbm90IGdpdmVuLCB0aGUgZmlyc3QgZWxlbWVudCBvZiBgY29sbGVjdGlvbmAgaXMgdXNlZCBhcyB0aGUgaW5pdGlhbFxuICAgICAqIHZhbHVlLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIGZvdXIgYXJndW1lbnRzOlxuICAgICAqIChhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAgICAgKiBgXy5yZWR1Y2VgLCBgXy5yZWR1Y2VSaWdodGAsIGFuZCBgXy50cmFuc2Zvcm1gLlxuICAgICAqXG4gICAgICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6XG4gICAgICogYGFzc2lnbmAsIGBkZWZhdWx0c2AsIGBkZWZhdWx0c0RlZXBgLCBgaW5jbHVkZXNgLCBgbWVyZ2VgLCBgb3JkZXJCeWAsXG4gICAgICogYW5kIGBzb3J0QnlgXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5yZWR1Y2VSaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJlZHVjZShbMSwgMl0sIGZ1bmN0aW9uKHN1bSwgbikge1xuICAgICAqICAgcmV0dXJuIHN1bSArIG47XG4gICAgICogfSwgMCk7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy5yZWR1Y2UoeyAnYSc6IDEsICdiJzogMiwgJ2MnOiAxIH0sIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAqICAgKHJlc3VsdFt2YWx1ZV0gfHwgKHJlc3VsdFt2YWx1ZV0gPSBbXSkpLnB1c2goa2V5KTtcbiAgICAgKiAgIHJldHVybiByZXN1bHQ7XG4gICAgICogfSwge30pO1xuICAgICAqIC8vID0+IHsgJzEnOiBbJ2EnLCAnYyddLCAnMic6IFsnYiddIH0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZWR1Y2UoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVJlZHVjZSA6IGJhc2VSZWR1Y2UsXG4gICAgICAgICAgaW5pdEFjY3VtID0gYXJndW1lbnRzLmxlbmd0aCA8IDM7XG5cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCA0KSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSwgYmFzZUVhY2gpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucmVkdWNlYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYGNvbGxlY3Rpb25gIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAgICogQHNlZSBfLnJlZHVjZVxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbWzAsIDFdLCBbMiwgM10sIFs0LCA1XV07XG4gICAgICpcbiAgICAgKiBfLnJlZHVjZVJpZ2h0KGFycmF5LCBmdW5jdGlvbihmbGF0dGVuZWQsIG90aGVyKSB7XG4gICAgICogICByZXR1cm4gZmxhdHRlbmVkLmNvbmNhdChvdGhlcik7XG4gICAgICogfSwgW10pO1xuICAgICAqIC8vID0+IFs0LCA1LCAyLCAzLCAwLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlSZWR1Y2VSaWdodCA6IGJhc2VSZWR1Y2UsXG4gICAgICAgICAgaW5pdEFjY3VtID0gYXJndW1lbnRzLmxlbmd0aCA8IDM7XG5cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCA0KSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSwgYmFzZUVhY2hSaWdodCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLmZpbHRlcmA7IHRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYFxuICAgICAqIHRoYXQgYHByZWRpY2F0ZWAgZG9lcyAqKm5vdCoqIHJldHVybiB0cnV0aHkgZm9yLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqIEBzZWUgXy5maWx0ZXJcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5yZWplY3QodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5yZWplY3QodXNlcnMsIHsgJ2FnZSc6IDQwLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5yZWplY3QodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5yZWplY3QodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVqZWN0KGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgbmVnYXRlKGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGEgcmFuZG9tIGVsZW1lbnQgZnJvbSBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNhbXBsZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2FtcGxlKFsxLCAyLCAzLCA0XSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNhbXBsZShjb2xsZWN0aW9uKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVNhbXBsZSA6IGJhc2VTYW1wbGU7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGBuYCByYW5kb20gZWxlbWVudHMgYXQgdW5pcXVlIGtleXMgZnJvbSBgY29sbGVjdGlvbmAgdXAgdG8gdGhlXG4gICAgICogc2l6ZSBvZiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNhbXBsZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmRvbSBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zYW1wbGVTaXplKFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzMsIDFdXG4gICAgICpcbiAgICAgKiBfLnNhbXBsZVNpemUoWzEsIDIsIDNdLCA0KTtcbiAgICAgKiAvLyA9PiBbMiwgMywgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzYW1wbGVTaXplKGNvbGxlY3Rpb24sIG4sIGd1YXJkKSB7XG4gICAgICBpZiAoKGd1YXJkID8gaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgbiwgZ3VhcmQpIDogbiA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICBuID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICB9XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVNhbXBsZVNpemUgOiBiYXNlU2FtcGxlU2l6ZTtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygc2h1ZmZsZWQgdmFsdWVzLCB1c2luZyBhIHZlcnNpb24gb2YgdGhlXG4gICAgICogW0Zpc2hlci1ZYXRlcyBzaHVmZmxlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GaXNoZXItWWF0ZXNfc2h1ZmZsZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNodWZmbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc2h1ZmZsZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2h1ZmZsZShbMSwgMiwgMywgNF0pO1xuICAgICAqIC8vID0+IFs0LCAxLCAzLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNodWZmbGUoY29sbGVjdGlvbikge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlTaHVmZmxlIDogYmFzZVNodWZmbGU7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBzaXplIG9mIGBjb2xsZWN0aW9uYCBieSByZXR1cm5pbmcgaXRzIGxlbmd0aCBmb3IgYXJyYXktbGlrZVxuICAgICAqIHZhbHVlcyBvciB0aGUgbnVtYmVyIG9mIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIGZvciBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIHNpemUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2l6ZShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8uc2l6ZSh7ICdhJzogMSwgJ2InOiAyIH0pO1xuICAgICAqIC8vID0+IDJcbiAgICAgKlxuICAgICAqIF8uc2l6ZSgncGViYmxlcycpO1xuICAgICAqIC8vID0+IDdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzaXplKGNvbGxlY3Rpb24pIHtcbiAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBpZiAoaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgICAgcmV0dXJuIGlzU3RyaW5nKGNvbGxlY3Rpb24pID8gc3RyaW5nU2l6ZShjb2xsZWN0aW9uKSA6IGNvbGxlY3Rpb24ubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdmFyIHRhZyA9IGdldFRhZyhjb2xsZWN0aW9uKTtcbiAgICAgIGlmICh0YWcgPT0gbWFwVGFnIHx8IHRhZyA9PSBzZXRUYWcpIHtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb24uc2l6ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlS2V5cyhjb2xsZWN0aW9uKS5sZW5ndGg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvciAqKmFueSoqIGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gLlxuICAgICAqIEl0ZXJhdGlvbiBpcyBzdG9wcGVkIG9uY2UgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb21lKFtudWxsLCAwLCAneWVzJywgZmFsc2VdLCBCb29sZWFuKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5zb21lKHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29tZSh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29tZSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb21lKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZ3VhcmQpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5U29tZSA6IGJhc2VTb21lO1xuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZ3VhcmQpKSB7XG4gICAgICAgIHByZWRpY2F0ZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMsIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIgYnkgdGhlIHJlc3VsdHMgb2ZcbiAgICAgKiBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBhIGNvbGxlY3Rpb24gdGhydSBlYWNoIGl0ZXJhdGVlLiBUaGlzIG1ldGhvZFxuICAgICAqIHBlcmZvcm1zIGEgc3RhYmxlIHNvcnQsIHRoYXQgaXMsIGl0IHByZXNlcnZlcyB0aGUgb3JpZ2luYWwgc29ydCBvcmRlciBvZlxuICAgICAqIGVxdWFsIGVsZW1lbnRzLiBUaGUgaXRlcmF0ZWVzIGFyZSBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFtpdGVyYXRlZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgaXRlcmF0ZWVzIHRvIHNvcnQgYnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc29ydGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0OCB9LFxuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDMwIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNCB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uc29ydEJ5KHVzZXJzLCBbZnVuY3Rpb24obykgeyByZXR1cm4gby51c2VyOyB9XSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snYmFybmV5JywgMzZdLCBbJ2Jhcm5leScsIDM0XSwgWydmcmVkJywgNDhdLCBbJ2ZyZWQnLCAzMF1dXG4gICAgICpcbiAgICAgKiBfLnNvcnRCeSh1c2VycywgWyd1c2VyJywgJ2FnZSddKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydiYXJuZXknLCAzNF0sIFsnYmFybmV5JywgMzZdLCBbJ2ZyZWQnLCAzMF0sIFsnZnJlZCcsIDQ4XV1cbiAgICAgKi9cbiAgICB2YXIgc29ydEJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWVzKSB7XG4gICAgICBpZiAoY29sbGVjdGlvbiA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBpdGVyYXRlZXMubGVuZ3RoO1xuICAgICAgaWYgKGxlbmd0aCA+IDEgJiYgaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgaXRlcmF0ZWVzWzBdLCBpdGVyYXRlZXNbMV0pKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IFtdO1xuICAgICAgfSBlbHNlIGlmIChsZW5ndGggPiAyICYmIGlzSXRlcmF0ZWVDYWxsKGl0ZXJhdGVlc1swXSwgaXRlcmF0ZWVzWzFdLCBpdGVyYXRlZXNbMl0pKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IFtpdGVyYXRlZXNbMF1dO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VPcmRlckJ5KGNvbGxlY3Rpb24sIGJhc2VGbGF0dGVuKGl0ZXJhdGVlcywgMSksIFtdKTtcbiAgICB9KTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHRpbWVzdGFtcCBvZiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZVxuICAgICAqIHRoZSBVbml4IGVwb2NoICgxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVEMpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuNC4wXG4gICAgICogQGNhdGVnb3J5IERhdGVcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lc3RhbXAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKF8ubm93KCkgLSBzdGFtcCk7XG4gICAgICogfSwgXy5ub3coKSk7XG4gICAgICogLy8gPT4gTG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgaW52b2NhdGlvbi5cbiAgICAgKi9cbiAgICB2YXIgbm93ID0gY3R4Tm93IHx8IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJvb3QuRGF0ZS5ub3coKTtcbiAgICB9O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLmJlZm9yZWA7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXNcbiAgICAgKiBgZnVuY2Agb25jZSBpdCdzIGNhbGxlZCBgbmAgb3IgbW9yZSB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgY2FsbHMgYmVmb3JlIGBmdW5jYCBpcyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlc3RyaWN0ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBzYXZlcyA9IFsncHJvZmlsZScsICdzZXR0aW5ncyddO1xuICAgICAqXG4gICAgICogdmFyIGRvbmUgPSBfLmFmdGVyKHNhdmVzLmxlbmd0aCwgZnVuY3Rpb24oKSB7XG4gICAgICogICBjb25zb2xlLmxvZygnZG9uZSBzYXZpbmchJyk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBfLmZvckVhY2goc2F2ZXMsIGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgKiAgIGFzeW5jU2F2ZSh7ICd0eXBlJzogdHlwZSwgJ2NvbXBsZXRlJzogZG9uZSB9KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdkb25lIHNhdmluZyEnIGFmdGVyIHRoZSB0d28gYXN5bmMgc2F2ZXMgaGF2ZSBjb21wbGV0ZWQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWZ0ZXIobiwgZnVuYykge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKC0tbiA8IDEpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgLCB3aXRoIHVwIHRvIGBuYCBhcmd1bWVudHMsXG4gICAgICogaWdub3JpbmcgYW55IGFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2FwIGFyZ3VtZW50cyBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPWZ1bmMubGVuZ3RoXSBUaGUgYXJpdHkgY2FwLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1hcChbJzYnLCAnOCcsICcxMCddLCBfLmFyeShwYXJzZUludCwgMSkpO1xuICAgICAqIC8vID0+IFs2LCA4LCAxMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnkoZnVuYywgbiwgZ3VhcmQpIHtcbiAgICAgIG4gPSBndWFyZCA/IHVuZGVmaW5lZCA6IG47XG4gICAgICBuID0gKGZ1bmMgJiYgbiA9PSBudWxsKSA/IGZ1bmMubGVuZ3RoIDogbjtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfQVJZX0ZMQUcsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2AsIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIGFuZCBhcmd1bWVudHNcbiAgICAgKiBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbiwgd2hpbGUgaXQncyBjYWxsZWQgbGVzcyB0aGFuIGBuYCB0aW1lcy4gU3Vic2VxdWVudFxuICAgICAqIGNhbGxzIHRvIHRoZSBjcmVhdGVkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBjYWxscyBhdCB3aGljaCBgZnVuY2AgaXMgbm8gbG9uZ2VyIGludm9rZWQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcmVzdHJpY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmVzdHJpY3RlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIF8uYmVmb3JlKDUsIGFkZENvbnRhY3RUb0xpc3QpKTtcbiAgICAgKiAvLyA9PiBBbGxvd3MgYWRkaW5nIHVwIHRvIDQgY29udGFjdHMgdG8gdGhlIGxpc3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmVmb3JlKG4sIGZ1bmMpIHtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBuID0gdG9JbnRlZ2VyKG4pO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoLS1uID4gMCkge1xuICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobiA8PSAxKSB7XG4gICAgICAgICAgZnVuYyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiBgdGhpc0FyZ2BcbiAgICAgKiBhbmQgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5iaW5kLnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWMgYnVpbGRzLFxuICAgICAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgbmF0aXZlIGBGdW5jdGlvbiNiaW5kYCwgdGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCJcbiAgICAgKiBwcm9wZXJ0eSBvZiBib3VuZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICAgICAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJvdW5kIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBncmVldChncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICcgJyArIHRoaXMudXNlciArIHB1bmN0dWF0aW9uO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gICAgICpcbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gICAgICogYm91bmQoJyEnKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICpcbiAgICAgKiAvLyBCb3VuZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgXywgJyEnKTtcbiAgICAgKiBib3VuZCgnaGknKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICovXG4gICAgdmFyIGJpbmQgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICAgICAgdmFyIGJpdG1hc2sgPSBXUkFQX0JJTkRfRkxBRztcbiAgICAgIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKGJpbmQpKTtcbiAgICAgICAgYml0bWFzayB8PSBXUkFQX1BBUlRJQUxfRkxBRztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgdGhlIG1ldGhvZCBhdCBgb2JqZWN0W2tleV1gIHdpdGggYHBhcnRpYWxzYFxuICAgICAqIHByZXBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgZGlmZmVycyBmcm9tIGBfLmJpbmRgIGJ5IGFsbG93aW5nIGJvdW5kIGZ1bmN0aW9ucyB0byByZWZlcmVuY2VcbiAgICAgKiBtZXRob2RzIHRoYXQgbWF5IGJlIHJlZGVmaW5lZCBvciBkb24ndCB5ZXQgZXhpc3QuIFNlZVxuICAgICAqIFtQZXRlciBNaWNoYXV4J3MgYXJ0aWNsZV0oaHR0cDovL3BldGVyLm1pY2hhdXguY2EvYXJ0aWNsZXMvbGF6eS1mdW5jdGlvbi1kZWZpbml0aW9uLXBhdHRlcm4pXG4gICAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5iaW5kS2V5LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWNcbiAgICAgKiBidWlsZHMsIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW52b2tlIHRoZSBtZXRob2Qgb24uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7XG4gICAgICogICAndXNlcic6ICdmcmVkJyxcbiAgICAgKiAgICdncmVldCc6IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICAgICAqICAgICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAgICAgKiAgIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIGJvdW5kID0gXy5iaW5kS2V5KG9iamVjdCwgJ2dyZWV0JywgJ2hpJyk7XG4gICAgICogYm91bmQoJyEnKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICpcbiAgICAgKiBvYmplY3QuZ3JlZXQgPSBmdW5jdGlvbihncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICd5YSAnICsgdGhpcy51c2VyICsgcHVuY3R1YXRpb247XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIGJvdW5kKCchJyk7XG4gICAgICogLy8gPT4gJ2hpeWEgZnJlZCEnXG4gICAgICpcbiAgICAgKiAvLyBCb3VuZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmRLZXkob2JqZWN0LCAnZ3JlZXQnLCBfLCAnIScpO1xuICAgICAqIGJvdW5kKCdoaScpO1xuICAgICAqIC8vID0+ICdoaXlhIGZyZWQhJ1xuICAgICAqL1xuICAgIHZhciBiaW5kS2V5ID0gYmFzZVJlc3QoZnVuY3Rpb24ob2JqZWN0LCBrZXksIHBhcnRpYWxzKSB7XG4gICAgICB2YXIgYml0bWFzayA9IFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHO1xuICAgICAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgICAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBnZXRIb2xkZXIoYmluZEtleSkpO1xuICAgICAgICBiaXRtYXNrIHw9IFdSQVBfUEFSVElBTF9GTEFHO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoa2V5LCBiaXRtYXNrLCBvYmplY3QsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgYXJndW1lbnRzIG9mIGBmdW5jYCBhbmQgZWl0aGVyIGludm9rZXNcbiAgICAgKiBgZnVuY2AgcmV0dXJuaW5nIGl0cyByZXN1bHQsIGlmIGF0IGxlYXN0IGBhcml0eWAgbnVtYmVyIG9mIGFyZ3VtZW50cyBoYXZlXG4gICAgICogYmVlbiBwcm92aWRlZCwgb3IgcmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyB0aGUgcmVtYWluaW5nIGBmdW5jYFxuICAgICAqIGFyZ3VtZW50cywgYW5kIHNvIG9uLiBUaGUgYXJpdHkgb2YgYGZ1bmNgIG1heSBiZSBzcGVjaWZpZWQgaWYgYGZ1bmMubGVuZ3RoYFxuICAgICAqIGlzIG5vdCBzdWZmaWNpZW50LlxuICAgICAqXG4gICAgICogVGhlIGBfLmN1cnJ5LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWMgYnVpbGRzLFxuICAgICAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBkb2Vzbid0IHNldCB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSBvZiBjdXJyaWVkIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHk9ZnVuYy5sZW5ndGhdIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjdXJyaWVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYWJjID0gZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAqICAgcmV0dXJuIFthLCBiLCBjXTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIGN1cnJpZWQgPSBfLmN1cnJ5KGFiYyk7XG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEpKDIpKDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogY3VycmllZCgxLCAyKSgzKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMSwgMiwgMyk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiAvLyBDdXJyaWVkIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIGN1cnJpZWQoMSkoXywgMykoMik7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3VycnkoZnVuYywgYXJpdHksIGd1YXJkKSB7XG4gICAgICBhcml0eSA9IGd1YXJkID8gdW5kZWZpbmVkIDogYXJpdHk7XG4gICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlV3JhcChmdW5jLCBXUkFQX0NVUlJZX0ZMQUcsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBhcml0eSk7XG4gICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBjdXJyeS5wbGFjZWhvbGRlcjtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5jdXJyeWAgZXhjZXB0IHRoYXQgYXJndW1lbnRzIGFyZSBhcHBsaWVkIHRvIGBmdW5jYFxuICAgICAqIGluIHRoZSBtYW5uZXIgb2YgYF8ucGFydGlhbFJpZ2h0YCBpbnN0ZWFkIG9mIGBfLnBhcnRpYWxgLlxuICAgICAqXG4gICAgICogVGhlIGBfLmN1cnJ5UmlnaHQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpY1xuICAgICAqIGJ1aWxkcywgbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcHJvdmlkZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIGN1cnJpZWQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eT1mdW5jLmxlbmd0aF0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhYmMgPSBmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gW2EsIGIsIGNdO1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgY3VycmllZCA9IF8uY3VycnlSaWdodChhYmMpO1xuICAgICAqXG4gICAgICogY3VycmllZCgzKSgyKSgxKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMiwgMykoMSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEsIDIsIDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogLy8gQ3VycmllZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiBjdXJyaWVkKDMpKDEsIF8pKDIpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGN1cnJ5UmlnaHQoZnVuYywgYXJpdHksIGd1YXJkKSB7XG4gICAgICBhcml0eSA9IGd1YXJkID8gdW5kZWZpbmVkIDogYXJpdHk7XG4gICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlV3JhcChmdW5jLCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBhcml0eSk7XG4gICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBjdXJyeVJpZ2h0LnBsYWNlaG9sZGVyO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZGVib3VuY2VkIGZ1bmN0aW9uIHRoYXQgZGVsYXlzIGludm9raW5nIGBmdW5jYCB1bnRpbCBhZnRlciBgd2FpdGBcbiAgICAgKiBtaWxsaXNlY29uZHMgaGF2ZSBlbGFwc2VkIHNpbmNlIHRoZSBsYXN0IHRpbWUgdGhlIGRlYm91bmNlZCBmdW5jdGlvbiB3YXNcbiAgICAgKiBpbnZva2VkLiBUaGUgZGVib3VuY2VkIGZ1bmN0aW9uIGNvbWVzIHdpdGggYSBgY2FuY2VsYCBtZXRob2QgdG8gY2FuY2VsXG4gICAgICogZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG8gaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uXG4gICAgICogUHJvdmlkZSBgb3B0aW9uc2AgdG8gaW5kaWNhdGUgd2hldGhlciBgZnVuY2Agc2hvdWxkIGJlIGludm9rZWQgb24gdGhlXG4gICAgICogbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnRcbiAgICAgKiBjYWxscyB0byB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYFxuICAgICAqIGludm9jYXRpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzXG4gICAgICogaW52b2tlZCBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dCBvbmx5IGlmIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb25cbiAgICAgKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gICAgICpcbiAgICAgKiBJZiBgd2FpdGAgaXMgYDBgIGFuZCBgbGVhZGluZ2AgaXMgYGZhbHNlYCwgYGZ1bmNgIGludm9jYXRpb24gaXMgZGVmZXJyZWRcbiAgICAgKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gICAgICpcbiAgICAgKiBTZWUgW0RhdmlkIENvcmJhY2hvJ3MgYXJ0aWNsZV0oaHR0cHM6Ly9jc3MtdHJpY2tzLmNvbS9kZWJvdW5jaW5nLXRocm90dGxpbmctZXhwbGFpbmVkLWV4YW1wbGVzLylcbiAgICAgKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLmRlYm91bmNlYCBhbmQgYF8udGhyb3R0bGVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVib3VuY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz1mYWxzZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhXYWl0XVxuICAgICAqICBUaGUgbWF4aW11bSB0aW1lIGBmdW5jYCBpcyBhbGxvd2VkIHRvIGJlIGRlbGF5ZWQgYmVmb3JlIGl0J3MgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWlsaW5nPXRydWVdXG4gICAgICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZGVib3VuY2VkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAvLyBBdm9pZCBjb3N0bHkgY2FsY3VsYXRpb25zIHdoaWxlIHRoZSB3aW5kb3cgc2l6ZSBpcyBpbiBmbHV4LlxuICAgICAqIGpRdWVyeSh3aW5kb3cpLm9uKCdyZXNpemUnLCBfLmRlYm91bmNlKGNhbGN1bGF0ZUxheW91dCwgMTUwKSk7XG4gICAgICpcbiAgICAgKiAvLyBJbnZva2UgYHNlbmRNYWlsYCB3aGVuIGNsaWNrZWQsIGRlYm91bmNpbmcgc3Vic2VxdWVudCBjYWxscy5cbiAgICAgKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgXy5kZWJvdW5jZShzZW5kTWFpbCwgMzAwLCB7XG4gICAgICogICAnbGVhZGluZyc6IHRydWUsXG4gICAgICogICAndHJhaWxpbmcnOiBmYWxzZVxuICAgICAqIH0pKTtcbiAgICAgKlxuICAgICAqIC8vIEVuc3VyZSBgYmF0Y2hMb2dgIGlzIGludm9rZWQgb25jZSBhZnRlciAxIHNlY29uZCBvZiBkZWJvdW5jZWQgY2FsbHMuXG4gICAgICogdmFyIGRlYm91bmNlZCA9IF8uZGVib3VuY2UoYmF0Y2hMb2csIDI1MCwgeyAnbWF4V2FpdCc6IDEwMDAgfSk7XG4gICAgICogdmFyIHNvdXJjZSA9IG5ldyBFdmVudFNvdXJjZSgnL3N0cmVhbScpO1xuICAgICAqIGpRdWVyeShzb3VyY2UpLm9uKCdtZXNzYWdlJywgZGVib3VuY2VkKTtcbiAgICAgKlxuICAgICAqIC8vIENhbmNlbCB0aGUgdHJhaWxpbmcgZGVib3VuY2VkIGludm9jYXRpb24uXG4gICAgICogalF1ZXJ5KHdpbmRvdykub24oJ3BvcHN0YXRlJywgZGVib3VuY2VkLmNhbmNlbCk7XG4gICAgICovXG4gICAgZnVuY3Rpb24gZGVib3VuY2UoZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICAgICAgdmFyIGxhc3RBcmdzLFxuICAgICAgICAgIGxhc3RUaGlzLFxuICAgICAgICAgIG1heFdhaXQsXG4gICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgIHRpbWVySWQsXG4gICAgICAgICAgbGFzdENhbGxUaW1lLFxuICAgICAgICAgIGxhc3RJbnZva2VUaW1lID0gMCxcbiAgICAgICAgICBsZWFkaW5nID0gZmFsc2UsXG4gICAgICAgICAgbWF4aW5nID0gZmFsc2UsXG4gICAgICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICB3YWl0ID0gdG9OdW1iZXIod2FpdCkgfHwgMDtcbiAgICAgIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgICAgICBsZWFkaW5nID0gISFvcHRpb25zLmxlYWRpbmc7XG4gICAgICAgIG1heGluZyA9ICdtYXhXYWl0JyBpbiBvcHRpb25zO1xuICAgICAgICBtYXhXYWl0ID0gbWF4aW5nID8gbmF0aXZlTWF4KHRvTnVtYmVyKG9wdGlvbnMubWF4V2FpdCkgfHwgMCwgd2FpdCkgOiBtYXhXYWl0O1xuICAgICAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBpbnZva2VGdW5jKHRpbWUpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBsYXN0QXJncyxcbiAgICAgICAgICAgIHRoaXNBcmcgPSBsYXN0VGhpcztcblxuICAgICAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICAgICAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGxlYWRpbmdFZGdlKHRpbWUpIHtcbiAgICAgICAgLy8gUmVzZXQgYW55IGBtYXhXYWl0YCB0aW1lci5cbiAgICAgICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgICAgICAvLyBTdGFydCB0aGUgdGltZXIgZm9yIHRoZSB0cmFpbGluZyBlZGdlLlxuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICAvLyBJbnZva2UgdGhlIGxlYWRpbmcgZWRnZS5cbiAgICAgICAgcmV0dXJuIGxlYWRpbmcgPyBpbnZva2VGdW5jKHRpbWUpIDogcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiByZW1haW5pbmdXYWl0KHRpbWUpIHtcbiAgICAgICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWUsXG4gICAgICAgICAgICB0aW1lV2FpdGluZyA9IHdhaXQgLSB0aW1lU2luY2VMYXN0Q2FsbDtcblxuICAgICAgICByZXR1cm4gbWF4aW5nXG4gICAgICAgICAgPyBuYXRpdmVNaW4odGltZVdhaXRpbmcsIG1heFdhaXQgLSB0aW1lU2luY2VMYXN0SW52b2tlKVxuICAgICAgICAgIDogdGltZVdhaXRpbmc7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHNob3VsZEludm9rZSh0aW1lKSB7XG4gICAgICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lO1xuXG4gICAgICAgIC8vIEVpdGhlciB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsLCBhY3Rpdml0eSBoYXMgc3RvcHBlZCBhbmQgd2UncmUgYXQgdGhlXG4gICAgICAgIC8vIHRyYWlsaW5nIGVkZ2UsIHRoZSBzeXN0ZW0gdGltZSBoYXMgZ29uZSBiYWNrd2FyZHMgYW5kIHdlJ3JlIHRyZWF0aW5nXG4gICAgICAgIC8vIGl0IGFzIHRoZSB0cmFpbGluZyBlZGdlLCBvciB3ZSd2ZSBoaXQgdGhlIGBtYXhXYWl0YCBsaW1pdC5cbiAgICAgICAgcmV0dXJuIChsYXN0Q2FsbFRpbWUgPT09IHVuZGVmaW5lZCB8fCAodGltZVNpbmNlTGFzdENhbGwgPj0gd2FpdCkgfHxcbiAgICAgICAgICAodGltZVNpbmNlTGFzdENhbGwgPCAwKSB8fCAobWF4aW5nICYmIHRpbWVTaW5jZUxhc3RJbnZva2UgPj0gbWF4V2FpdCkpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiB0aW1lckV4cGlyZWQoKSB7XG4gICAgICAgIHZhciB0aW1lID0gbm93KCk7XG4gICAgICAgIGlmIChzaG91bGRJbnZva2UodGltZSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJhaWxpbmdFZGdlKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlc3RhcnQgdGhlIHRpbWVyLlxuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHJlbWFpbmluZ1dhaXQodGltZSkpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiB0cmFpbGluZ0VkZ2UodGltZSkge1xuICAgICAgICB0aW1lcklkID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIE9ubHkgaW52b2tlIGlmIHdlIGhhdmUgYGxhc3RBcmdzYCB3aGljaCBtZWFucyBgZnVuY2AgaGFzIGJlZW5cbiAgICAgICAgLy8gZGVib3VuY2VkIGF0IGxlYXN0IG9uY2UuXG4gICAgICAgIGlmICh0cmFpbGluZyAmJiBsYXN0QXJncykge1xuICAgICAgICAgIHJldHVybiBpbnZva2VGdW5jKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGNhbmNlbCgpIHtcbiAgICAgICAgaWYgKHRpbWVySWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcklkKTtcbiAgICAgICAgfVxuICAgICAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdENhbGxUaW1lID0gbGFzdFRoaXMgPSB0aW1lcklkID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICAgICAgcmV0dXJuIHRpbWVySWQgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IHRyYWlsaW5nRWRnZShub3coKSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICAgICAgdmFyIHRpbWUgPSBub3coKSxcbiAgICAgICAgICAgIGlzSW52b2tpbmcgPSBzaG91bGRJbnZva2UodGltZSk7XG5cbiAgICAgICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIGxhc3RUaGlzID0gdGhpcztcbiAgICAgICAgbGFzdENhbGxUaW1lID0gdGltZTtcblxuICAgICAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBsZWFkaW5nRWRnZShsYXN0Q2FsbFRpbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobWF4aW5nKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgaW52b2NhdGlvbnMgaW4gYSB0aWdodCBsb29wLlxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgICAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAgICAgICAgIHJldHVybiBpbnZva2VGdW5jKGxhc3RDYWxsVGltZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBkZWJvdW5jZWQuY2FuY2VsID0gY2FuY2VsO1xuICAgICAgZGVib3VuY2VkLmZsdXNoID0gZmx1c2g7XG4gICAgICByZXR1cm4gZGVib3VuY2VkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmVycyBpbnZva2luZyB0aGUgYGZ1bmNgIHVudGlsIHRoZSBjdXJyZW50IGNhbGwgc3RhY2sgaGFzIGNsZWFyZWQuIEFueVxuICAgICAqIGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byBgZnVuY2Agd2hlbiBpdCdzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWZlci5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lciBpZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZlcihmdW5jdGlvbih0ZXh0KSB7XG4gICAgICogICBjb25zb2xlLmxvZyh0ZXh0KTtcbiAgICAgKiB9LCAnZGVmZXJyZWQnKTtcbiAgICAgKiAvLyA9PiBMb2dzICdkZWZlcnJlZCcgYWZ0ZXIgb25lIG1pbGxpc2Vjb25kLlxuICAgICAqL1xuICAgIHZhciBkZWZlciA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBiYXNlRGVsYXkoZnVuYywgMSwgYXJncyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIGBmdW5jYCBhZnRlciBgd2FpdGAgbWlsbGlzZWNvbmRzLiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlXG4gICAgICogcHJvdmlkZWQgdG8gYGZ1bmNgIHdoZW4gaXQncyBpbnZva2VkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVsYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdhaXQgVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkgaW52b2NhdGlvbi5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lciBpZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWxheShmdW5jdGlvbih0ZXh0KSB7XG4gICAgICogICBjb25zb2xlLmxvZyh0ZXh0KTtcbiAgICAgKiB9LCAxMDAwLCAnbGF0ZXInKTtcbiAgICAgKiAvLyA9PiBMb2dzICdsYXRlcicgYWZ0ZXIgb25lIHNlY29uZC5cbiAgICAgKi9cbiAgICB2YXIgZGVsYXkgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCB3YWl0LCBhcmdzKSB7XG4gICAgICByZXR1cm4gYmFzZURlbGF5KGZ1bmMsIHRvTnVtYmVyKHdhaXQpIHx8IDAsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBhcmd1bWVudHMgcmV2ZXJzZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBmbGlwIGFyZ3VtZW50cyBmb3IuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmxpcHBlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZsaXBwZWQgPSBfLmZsaXAoZnVuY3Rpb24oKSB7XG4gICAgICogICByZXR1cm4gXy50b0FycmF5KGFyZ3VtZW50cyk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBmbGlwcGVkKCdhJywgJ2InLCAnYycsICdkJyk7XG4gICAgICogLy8gPT4gWydkJywgJ2MnLCAnYicsICdhJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGlwKGZ1bmMpIHtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfRkxJUF9GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBtZW1vaXplcyB0aGUgcmVzdWx0IG9mIGBmdW5jYC4gSWYgYHJlc29sdmVyYCBpc1xuICAgICAqIHByb3ZpZGVkLCBpdCBkZXRlcm1pbmVzIHRoZSBjYWNoZSBrZXkgZm9yIHN0b3JpbmcgdGhlIHJlc3VsdCBiYXNlZCBvbiB0aGVcbiAgICAgKiBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uLiBCeSBkZWZhdWx0LCB0aGUgZmlyc3QgYXJndW1lbnRcbiAgICAgKiBwcm92aWRlZCB0byB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24gaXMgdXNlZCBhcyB0aGUgbWFwIGNhY2hlIGtleS4gVGhlIGBmdW5jYFxuICAgICAqIGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIG1lbW9pemVkIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjYWNoZSBpcyBleHBvc2VkIGFzIHRoZSBgY2FjaGVgIHByb3BlcnR5IG9uIHRoZSBtZW1vaXplZFxuICAgICAqIGZ1bmN0aW9uLiBJdHMgY3JlYXRpb24gbWF5IGJlIGN1c3RvbWl6ZWQgYnkgcmVwbGFjaW5nIHRoZSBgXy5tZW1vaXplLkNhY2hlYFxuICAgICAqIGNvbnN0cnVjdG9yIHdpdGggb25lIHdob3NlIGluc3RhbmNlcyBpbXBsZW1lbnQgdGhlXG4gICAgICogW2BNYXBgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1wcm9wZXJ0aWVzLW9mLXRoZS1tYXAtcHJvdG90eXBlLW9iamVjdClcbiAgICAgKiBtZXRob2QgaW50ZXJmYWNlIG9mIGBjbGVhcmAsIGBkZWxldGVgLCBgZ2V0YCwgYGhhc2AsIGFuZCBgc2V0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcmVzb2x2ZXJdIFRoZSBmdW5jdGlvbiB0byByZXNvbHZlIHRoZSBjYWNoZSBrZXkuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWVtb2l6ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAyIH07XG4gICAgICogdmFyIG90aGVyID0geyAnYyc6IDMsICdkJzogNCB9O1xuICAgICAqXG4gICAgICogdmFyIHZhbHVlcyA9IF8ubWVtb2l6ZShfLnZhbHVlcyk7XG4gICAgICogdmFsdWVzKG9iamVjdCk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiB2YWx1ZXMob3RoZXIpO1xuICAgICAqIC8vID0+IFszLCA0XVxuICAgICAqXG4gICAgICogb2JqZWN0LmEgPSAyO1xuICAgICAqIHZhbHVlcyhvYmplY3QpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqXG4gICAgICogLy8gTW9kaWZ5IHRoZSByZXN1bHQgY2FjaGUuXG4gICAgICogdmFsdWVzLmNhY2hlLnNldChvYmplY3QsIFsnYScsICdiJ10pO1xuICAgICAqIHZhbHVlcyhvYmplY3QpO1xuICAgICAqIC8vID0+IFsnYScsICdiJ11cbiAgICAgKlxuICAgICAqIC8vIFJlcGxhY2UgYF8ubWVtb2l6ZS5DYWNoZWAuXG4gICAgICogXy5tZW1vaXplLkNhY2hlID0gV2Vha01hcDtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZW1vaXplKGZ1bmMsIHJlc29sdmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJyB8fCAocmVzb2x2ZXIgIT0gbnVsbCAmJiB0eXBlb2YgcmVzb2x2ZXIgIT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgdmFyIG1lbW9pemVkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAga2V5ID0gcmVzb2x2ZXIgPyByZXNvbHZlci5hcHBseSh0aGlzLCBhcmdzKSA6IGFyZ3NbMF0sXG4gICAgICAgICAgICBjYWNoZSA9IG1lbW9pemVkLmNhY2hlO1xuXG4gICAgICAgIGlmIChjYWNoZS5oYXMoa2V5KSkge1xuICAgICAgICAgIHJldHVybiBjYWNoZS5nZXQoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgbWVtb2l6ZWQuY2FjaGUgPSBjYWNoZS5zZXQoa2V5LCByZXN1bHQpIHx8IGNhY2hlO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICAgIG1lbW9pemVkLmNhY2hlID0gbmV3IChtZW1vaXplLkNhY2hlIHx8IE1hcENhY2hlKTtcbiAgICAgIHJldHVybiBtZW1vaXplZDtcbiAgICB9XG5cbiAgICAvLyBFeHBvc2UgYE1hcENhY2hlYC5cbiAgICBtZW1vaXplLkNhY2hlID0gTWFwQ2FjaGU7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBuZWdhdGVzIHRoZSByZXN1bHQgb2YgdGhlIHByZWRpY2F0ZSBgZnVuY2AuIFRoZVxuICAgICAqIGBmdW5jYCBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBhbmQgYXJndW1lbnRzIG9mIHRoZVxuICAgICAqIGNyZWF0ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIHByZWRpY2F0ZSB0byBuZWdhdGUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbmVnYXRlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNFdmVuKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKFsxLCAyLCAzLCA0LCA1LCA2XSwgXy5uZWdhdGUoaXNFdmVuKSk7XG4gICAgICogLy8gPT4gWzEsIDMsIDVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gbmVnYXRlKHByZWRpY2F0ZSkge1xuICAgICAgaWYgKHR5cGVvZiBwcmVkaWNhdGUgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgICAgY2FzZSAwOiByZXR1cm4gIXByZWRpY2F0ZS5jYWxsKHRoaXMpO1xuICAgICAgICAgIGNhc2UgMTogcmV0dXJuICFwcmVkaWNhdGUuY2FsbCh0aGlzLCBhcmdzWzBdKTtcbiAgICAgICAgICBjYXNlIDI6IHJldHVybiAhcHJlZGljYXRlLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgY2FzZSAzOiByZXR1cm4gIXByZWRpY2F0ZS5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhcHJlZGljYXRlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpcyByZXN0cmljdGVkIHRvIGludm9raW5nIGBmdW5jYCBvbmNlLiBSZXBlYXQgY2FsbHNcbiAgICAgKiB0byB0aGUgZnVuY3Rpb24gcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgaW52b2NhdGlvbi4gVGhlIGBmdW5jYCBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgYW5kIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlc3RyaWN0ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBpbml0aWFsaXplID0gXy5vbmNlKGNyZWF0ZUFwcGxpY2F0aW9uKTtcbiAgICAgKiBpbml0aWFsaXplKCk7XG4gICAgICogaW5pdGlhbGl6ZSgpO1xuICAgICAqIC8vID0+IGBjcmVhdGVBcHBsaWNhdGlvbmAgaXMgaW52b2tlZCBvbmNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gb25jZShmdW5jKSB7XG4gICAgICByZXR1cm4gYmVmb3JlKDIsIGZ1bmMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50cyB0cmFuc2Zvcm1lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFt0cmFuc2Zvcm1zPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGFyZ3VtZW50IHRyYW5zZm9ybXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGRvdWJsZWQobikge1xuICAgICAqICAgcmV0dXJuIG4gKiAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJBcmdzKGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgKiAgIHJldHVybiBbeCwgeV07XG4gICAgICogfSwgW3NxdWFyZSwgZG91YmxlZF0pO1xuICAgICAqXG4gICAgICogZnVuYyg5LCAzKTtcbiAgICAgKiAvLyA9PiBbODEsIDZdXG4gICAgICpcbiAgICAgKiBmdW5jKDEwLCA1KTtcbiAgICAgKiAvLyA9PiBbMTAwLCAxMF1cbiAgICAgKi9cbiAgICB2YXIgb3ZlckFyZ3MgPSBjYXN0UmVzdChmdW5jdGlvbihmdW5jLCB0cmFuc2Zvcm1zKSB7XG4gICAgICB0cmFuc2Zvcm1zID0gKHRyYW5zZm9ybXMubGVuZ3RoID09IDEgJiYgaXNBcnJheSh0cmFuc2Zvcm1zWzBdKSlcbiAgICAgICAgPyBhcnJheU1hcCh0cmFuc2Zvcm1zWzBdLCBiYXNlVW5hcnkoZ2V0SXRlcmF0ZWUoKSkpXG4gICAgICAgIDogYXJyYXlNYXAoYmFzZUZsYXR0ZW4odHJhbnNmb3JtcywgMSksIGJhc2VVbmFyeShnZXRJdGVyYXRlZSgpKSk7XG5cbiAgICAgIHZhciBmdW5jc0xlbmd0aCA9IHRyYW5zZm9ybXMubGVuZ3RoO1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNaW4oYXJncy5sZW5ndGgsIGZ1bmNzTGVuZ3RoKTtcblxuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGFyZ3NbaW5kZXhdID0gdHJhbnNmb3Jtc1tpbmRleF0uY2FsbCh0aGlzLCBhcmdzW2luZGV4XSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIGFyZ3MpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRoZVxuICAgICAqIGFyZ3VtZW50cyBpdCByZWNlaXZlcy4gVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5iaW5kYCBleGNlcHQgaXQgZG9lcyAqKm5vdCoqXG4gICAgICogYWx0ZXIgdGhlIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWwucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpY1xuICAgICAqIGJ1aWxkcywgbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIHBhcnRpYWxseVxuICAgICAqIGFwcGxpZWQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMi4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5IGFyZ3VtZW50cyB0by5cbiAgICAgKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBwYXJ0aWFsbHkgYXBwbGllZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZ3JlZXQoZ3JlZXRpbmcsIG5hbWUpIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICcgJyArIG5hbWU7XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHNheUhlbGxvVG8gPSBfLnBhcnRpYWwoZ3JlZXQsICdoZWxsbycpO1xuICAgICAqIHNheUhlbGxvVG8oJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIFBhcnRpYWxseSBhcHBsaWVkIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIHZhciBncmVldEZyZWQgPSBfLnBhcnRpYWwoZ3JlZXQsIF8sICdmcmVkJyk7XG4gICAgICogZ3JlZXRGcmVkKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkJ1xuICAgICAqL1xuICAgIHZhciBwYXJ0aWFsID0gYmFzZVJlc3QoZnVuY3Rpb24oZnVuYywgcGFydGlhbHMpIHtcbiAgICAgIHZhciBob2xkZXJzID0gcmVwbGFjZUhvbGRlcnMocGFydGlhbHMsIGdldEhvbGRlcihwYXJ0aWFsKSk7XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcChmdW5jLCBXUkFQX1BBUlRJQUxfRkxBRywgdW5kZWZpbmVkLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnBhcnRpYWxgIGV4Y2VwdCB0aGF0IHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50c1xuICAgICAqIGFyZSBhcHBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWxSaWdodC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljXG4gICAgICogYnVpbGRzLCBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgcGFydGlhbGx5XG4gICAgICogYXBwbGllZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhcnRpYWxseSBhcHBsaWVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBncmVldChncmVldGluZywgbmFtZSkge1xuICAgICAqICAgcmV0dXJuIGdyZWV0aW5nICsgJyAnICsgbmFtZTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgZ3JlZXRGcmVkID0gXy5wYXJ0aWFsUmlnaHQoZ3JlZXQsICdmcmVkJyk7XG4gICAgICogZ3JlZXRGcmVkKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkJ1xuICAgICAqXG4gICAgICogLy8gUGFydGlhbGx5IGFwcGxpZWQgd2l0aCBwbGFjZWhvbGRlcnMuXG4gICAgICogdmFyIHNheUhlbGxvVG8gPSBfLnBhcnRpYWxSaWdodChncmVldCwgJ2hlbGxvJywgXyk7XG4gICAgICogc2F5SGVsbG9UbygnZnJlZCcpO1xuICAgICAqIC8vID0+ICdoZWxsbyBmcmVkJ1xuICAgICAqL1xuICAgIHZhciBwYXJ0aWFsUmlnaHQgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCBwYXJ0aWFscykge1xuICAgICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKHBhcnRpYWxSaWdodCkpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoZnVuYywgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcsIHVuZGVmaW5lZCwgcGFydGlhbHMsIGhvbGRlcnMpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBhcmd1bWVudHMgYXJyYW5nZWQgYWNjb3JkaW5nXG4gICAgICogdG8gdGhlIHNwZWNpZmllZCBgaW5kZXhlc2Agd2hlcmUgdGhlIGFyZ3VtZW50IHZhbHVlIGF0IHRoZSBmaXJzdCBpbmRleCBpc1xuICAgICAqIHByb3ZpZGVkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCwgdGhlIGFyZ3VtZW50IHZhbHVlIGF0IHRoZSBzZWNvbmQgaW5kZXggaXNcbiAgICAgKiBwcm92aWRlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byByZWFycmFuZ2UgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcGFyYW0gey4uLihudW1iZXJ8bnVtYmVyW10pfSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcmd1bWVudCBpbmRleGVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgcmVhcmdlZCA9IF8ucmVhcmcoZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAqICAgcmV0dXJuIFthLCBiLCBjXTtcbiAgICAgKiB9LCBbMiwgMCwgMV0pO1xuICAgICAqXG4gICAgICogcmVhcmdlZCgnYicsICdjJywgJ2EnKVxuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqL1xuICAgIHZhciByZWFyZyA9IGZsYXRSZXN0KGZ1bmN0aW9uKGZ1bmMsIGluZGV4ZXMpIHtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfUkVBUkdfRkxBRywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgaW5kZXhlcyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAgICAgKiBjcmVhdGVkIGZ1bmN0aW9uIGFuZCBhcmd1bWVudHMgZnJvbSBgc3RhcnRgIGFuZCBiZXlvbmQgcHJvdmlkZWQgYXNcbiAgICAgKiBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiB0aGVcbiAgICAgKiBbcmVzdCBwYXJhbWV0ZXJdKGh0dHBzOi8vbWRuLmlvL3Jlc3RfcGFyYW1ldGVycykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNheSA9IF8ucmVzdChmdW5jdGlvbih3aGF0LCBuYW1lcykge1xuICAgICAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICAgICAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGZyZWQsIGJhcm5leSwgJiBwZWJibGVzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlc3QoZnVuYywgc3RhcnQpIHtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0ID0gc3RhcnQgPT09IHVuZGVmaW5lZCA/IHN0YXJ0IDogdG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgIHJldHVybiBiYXNlUmVzdChmdW5jLCBzdGFydCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlXG4gICAgICogY3JlYXRlIGZ1bmN0aW9uIGFuZCBhbiBhcnJheSBvZiBhcmd1bWVudHMgbXVjaCBsaWtlXG4gICAgICogW2BGdW5jdGlvbiNhcHBseWBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1mdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uIHRoZVxuICAgICAqIFtzcHJlYWQgb3BlcmF0b3JdKGh0dHBzOi8vbWRuLmlvL3NwcmVhZF9vcGVyYXRvcikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBzcHJlYWQgYXJndW1lbnRzIG92ZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHNwcmVhZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNheSA9IF8uc3ByZWFkKGZ1bmN0aW9uKHdobywgd2hhdCkge1xuICAgICAqICAgcmV0dXJuIHdobyArICcgc2F5cyAnICsgd2hhdDtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHNheShbJ2ZyZWQnLCAnaGVsbG8nXSk7XG4gICAgICogLy8gPT4gJ2ZyZWQgc2F5cyBoZWxsbydcbiAgICAgKlxuICAgICAqIHZhciBudW1iZXJzID0gUHJvbWlzZS5hbGwoW1xuICAgICAqICAgUHJvbWlzZS5yZXNvbHZlKDQwKSxcbiAgICAgKiAgIFByb21pc2UucmVzb2x2ZSgzNilcbiAgICAgKiBdKTtcbiAgICAgKlxuICAgICAqIG51bWJlcnMudGhlbihfLnNwcmVhZChmdW5jdGlvbih4LCB5KSB7XG4gICAgICogICByZXR1cm4geCArIHk7XG4gICAgICogfSkpO1xuICAgICAqIC8vID0+IGEgUHJvbWlzZSBvZiA3NlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNwcmVhZChmdW5jLCBzdGFydCkge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6IG5hdGl2ZU1heCh0b0ludGVnZXIoc3RhcnQpLCAwKTtcbiAgICAgIHJldHVybiBiYXNlUmVzdChmdW5jdGlvbihhcmdzKSB7XG4gICAgICAgIHZhciBhcnJheSA9IGFyZ3Nbc3RhcnRdLFxuICAgICAgICAgICAgb3RoZXJBcmdzID0gY2FzdFNsaWNlKGFyZ3MsIDAsIHN0YXJ0KTtcblxuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBhcnJheVB1c2gob3RoZXJBcmdzLCBhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIG90aGVyQXJncyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgdGhyb3R0bGVkIGZ1bmN0aW9uIHRoYXQgb25seSBpbnZva2VzIGBmdW5jYCBhdCBtb3N0IG9uY2UgcGVyXG4gICAgICogZXZlcnkgYHdhaXRgIG1pbGxpc2Vjb25kcy4gVGhlIHRocm90dGxlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGBcbiAgICAgKiBtZXRob2QgdG8gY2FuY2VsIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvXG4gICAgICogaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgXG4gICAgICogc2hvdWxkIGJlIGludm9rZWQgb24gdGhlIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YFxuICAgICAqIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZCB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGVcbiAgICAgKiB0aHJvdHRsZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnQgY2FsbHMgdG8gdGhlIHRocm90dGxlZCBmdW5jdGlvbiByZXR1cm4gdGhlXG4gICAgICogcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpc1xuICAgICAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uXG4gICAgICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICAgICAqXG4gICAgICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gICAgICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICAgICAqXG4gICAgICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gICAgICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy50aHJvdHRsZWAgYW5kIGBfLmRlYm91bmNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHRocm90dGxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB0aHJvdHRsZSBpbnZvY2F0aW9ucyB0by5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9dHJ1ZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB0aHJvdHRsZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIC8vIEF2b2lkIGV4Y2Vzc2l2ZWx5IHVwZGF0aW5nIHRoZSBwb3NpdGlvbiB3aGlsZSBzY3JvbGxpbmcuXG4gICAgICogalF1ZXJ5KHdpbmRvdykub24oJ3Njcm9sbCcsIF8udGhyb3R0bGUodXBkYXRlUG9zaXRpb24sIDEwMCkpO1xuICAgICAqXG4gICAgICogLy8gSW52b2tlIGByZW5ld1Rva2VuYCB3aGVuIHRoZSBjbGljayBldmVudCBpcyBmaXJlZCwgYnV0IG5vdCBtb3JlIHRoYW4gb25jZSBldmVyeSA1IG1pbnV0ZXMuXG4gICAgICogdmFyIHRocm90dGxlZCA9IF8udGhyb3R0bGUocmVuZXdUb2tlbiwgMzAwMDAwLCB7ICd0cmFpbGluZyc6IGZhbHNlIH0pO1xuICAgICAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCB0aHJvdHRsZWQpO1xuICAgICAqXG4gICAgICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyB0aHJvdHRsZWQgaW52b2NhdGlvbi5cbiAgICAgKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCB0aHJvdHRsZWQuY2FuY2VsKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0aHJvdHRsZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgICB2YXIgbGVhZGluZyA9IHRydWUsXG4gICAgICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgbGVhZGluZyA9ICdsZWFkaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLmxlYWRpbmcgOiBsZWFkaW5nO1xuICAgICAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlYm91bmNlKGZ1bmMsIHdhaXQsIHtcbiAgICAgICAgJ2xlYWRpbmcnOiBsZWFkaW5nLFxuICAgICAgICAnbWF4V2FpdCc6IHdhaXQsXG4gICAgICAgICd0cmFpbGluZyc6IHRyYWlsaW5nXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIHVwIHRvIG9uZSBhcmd1bWVudCwgaWdub3JpbmcgYW55XG4gICAgICogYWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXBwZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnNicsICc4JywgJzEwJ10sIF8udW5hcnkocGFyc2VJbnQpKTtcbiAgICAgKiAvLyA9PiBbNiwgOCwgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5hcnkoZnVuYykge1xuICAgICAgcmV0dXJuIGFyeShmdW5jLCAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwcm92aWRlcyBgdmFsdWVgIHRvIGB3cmFwcGVyYCBhcyBpdHMgZmlyc3RcbiAgICAgKiBhcmd1bWVudC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBmdW5jdGlvbiBhcmUgYXBwZW5kZWRcbiAgICAgKiB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgYHdyYXBwZXJgLiBUaGUgd3JhcHBlciBpcyBpbnZva2VkIHdpdGggdGhlIGB0aGlzYFxuICAgICAqIGJpbmRpbmcgb2YgdGhlIGNyZWF0ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFt3cmFwcGVyPWlkZW50aXR5XSBUaGUgd3JhcHBlciBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHAgPSBfLndyYXAoXy5lc2NhcGUsIGZ1bmN0aW9uKGZ1bmMsIHRleHQpIHtcbiAgICAgKiAgIHJldHVybiAnPHA+JyArIGZ1bmModGV4dCkgKyAnPC9wPic7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBwKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICc8cD5mcmVkLCBiYXJuZXksICZhbXA7IHBlYmJsZXM8L3A+J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXAodmFsdWUsIHdyYXBwZXIpIHtcbiAgICAgIHJldHVybiBwYXJ0aWFsKGNhc3RGdW5jdGlvbih3cmFwcGVyKSwgdmFsdWUpO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGB2YWx1ZWAgYXMgYW4gYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY2FzdCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYXN0QXJyYXkoMSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICpcbiAgICAgKiBfLmNhc3RBcnJheSh7ICdhJzogMSB9KTtcbiAgICAgKiAvLyA9PiBbeyAnYSc6IDEgfV1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBbJ2FiYyddXG4gICAgICpcbiAgICAgKiBfLmNhc3RBcnJheShudWxsKTtcbiAgICAgKiAvLyA9PiBbbnVsbF1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KHVuZGVmaW5lZCk7XG4gICAgICogLy8gPT4gW3VuZGVmaW5lZF1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKiBjb25zb2xlLmxvZyhfLmNhc3RBcnJheShhcnJheSkgPT09IGFycmF5KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdEFycmF5KCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciB2YWx1ZSA9IGFyZ3VtZW50c1swXTtcbiAgICAgIHJldHVybiBpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2hhbGxvdyBjbG9uZSBvZiBgdmFsdWVgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlXG4gICAgICogW3N0cnVjdHVyZWQgY2xvbmUgYWxnb3JpdGhtXShodHRwczovL21kbi5pby9TdHJ1Y3R1cmVkX2Nsb25lX2FsZ29yaXRobSlcbiAgICAgKiBhbmQgc3VwcG9ydHMgY2xvbmluZyBhcnJheXMsIGFycmF5IGJ1ZmZlcnMsIGJvb2xlYW5zLCBkYXRlIG9iamVjdHMsIG1hcHMsXG4gICAgICogbnVtYmVycywgYE9iamVjdGAgb2JqZWN0cywgcmVnZXhlcywgc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkXG4gICAgICogYXJyYXlzLiBUaGUgb3duIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFyZSBjbG9uZWRcbiAgICAgKiBhcyBwbGFpbiBvYmplY3RzLiBBbiBlbXB0eSBvYmplY3QgaXMgcmV0dXJuZWQgZm9yIHVuY2xvbmVhYmxlIHZhbHVlcyBzdWNoXG4gICAgICogYXMgZXJyb3Igb2JqZWN0cywgZnVuY3Rpb25zLCBET00gbm9kZXMsIGFuZCBXZWFrTWFwcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8uY2xvbmVEZWVwXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ2EnOiAxIH0sIHsgJ2InOiAyIH1dO1xuICAgICAqXG4gICAgICogdmFyIHNoYWxsb3cgPSBfLmNsb25lKG9iamVjdHMpO1xuICAgICAqIGNvbnNvbGUubG9nKHNoYWxsb3dbMF0gPT09IG9iamVjdHNbMF0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VDbG9uZSh2YWx1ZSwgQ0xPTkVfU1lNQk9MU19GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgY2xvbmVkIHZhbHVlLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCxcbiAgICAgKiBjbG9uaW5nIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aFxuICAgICAqIHVwIHRvIGZvdXIgYXJndW1lbnRzOyAodmFsdWUgWywgaW5kZXh8a2V5LCBvYmplY3QsIHN0YWNrXSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8uY2xvbmVEZWVwV2l0aFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKHZhbHVlKSB7XG4gICAgICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB2YWx1ZS5jbG9uZU5vZGUoZmFsc2UpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBlbCA9IF8uY2xvbmVXaXRoKGRvY3VtZW50LmJvZHksIGN1c3RvbWl6ZXIpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coZWwgPT09IGRvY3VtZW50LmJvZHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICogY29uc29sZS5sb2coZWwubm9kZU5hbWUpO1xuICAgICAqIC8vID0+ICdCT0RZJ1xuICAgICAqIGNvbnNvbGUubG9nKGVsLmNoaWxkTm9kZXMubGVuZ3RoKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVXaXRoKHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9TWU1CT0xTX0ZMQUcsIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uY2xvbmVgIGV4Y2VwdCB0aGF0IGl0IHJlY3Vyc2l2ZWx5IGNsb25lcyBgdmFsdWVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byByZWN1cnNpdmVseSBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gICAgICogQHNlZSBfLmNsb25lXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ2EnOiAxIH0sIHsgJ2InOiAyIH1dO1xuICAgICAqXG4gICAgICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcChvYmplY3RzKTtcbiAgICAgKiBjb25zb2xlLmxvZyhkZWVwWzBdID09PSBvYmplY3RzWzBdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lRGVlcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VDbG9uZSh2YWx1ZSwgQ0xPTkVfREVFUF9GTEFHIHwgQ0xPTkVfU1lNQk9MU19GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lV2l0aGAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgY2xvbmVzIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHJlY3Vyc2l2ZWx5IGNsb25lLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGRlZXAgY2xvbmVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5jbG9uZVdpdGhcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcih2YWx1ZSkge1xuICAgICAqICAgaWYgKF8uaXNFbGVtZW50KHZhbHVlKSkge1xuICAgICAqICAgICByZXR1cm4gdmFsdWUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBlbCA9IF8uY2xvbmVEZWVwV2l0aChkb2N1bWVudC5ib2R5LCBjdXN0b21pemVyKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGVsID09PSBkb2N1bWVudC5ib2R5KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqIGNvbnNvbGUubG9nKGVsLm5vZGVOYW1lKTtcbiAgICAgKiAvLyA9PiAnQk9EWSdcbiAgICAgKiBjb25zb2xlLmxvZyhlbC5jaGlsZE5vZGVzLmxlbmd0aCk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZURlZXBXaXRoKHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9ERUVQX0ZMQUcgfCBDTE9ORV9TWU1CT0xTX0ZMQUcsIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgb2JqZWN0YCBjb25mb3JtcyB0byBgc291cmNlYCBieSBpbnZva2luZyB0aGUgcHJlZGljYXRlXG4gICAgICogcHJvcGVydGllcyBvZiBgc291cmNlYCB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGBfLmNvbmZvcm1zYCB3aGVuIGBzb3VyY2VgIGlzXG4gICAgICogcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xNC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgcHJlZGljYXRlcyB0byBjb25mb3JtIHRvLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBjb25mb3JtcywgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiB9O1xuICAgICAqXG4gICAgICogXy5jb25mb3Jtc1RvKG9iamVjdCwgeyAnYic6IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gPiAxOyB9IH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uY29uZm9ybXNUbyhvYmplY3QsIHsgJ2InOiBmdW5jdGlvbihuKSB7IHJldHVybiBuID4gMjsgfSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbmZvcm1zVG8ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBzb3VyY2UgPT0gbnVsbCB8fCBiYXNlQ29uZm9ybXNUbyhvYmplY3QsIHNvdXJjZSwga2V5cyhzb3VyY2UpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBhXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUgZXF1aXZhbGVudC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmVxKG9iamVjdCwgb2JqZWN0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmVxKG9iamVjdCwgb3RoZXIpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmVxKCdhJywgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmVxKCdhJywgT2JqZWN0KCdhJykpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmVxKE5hTiwgTmFOKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXEodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG90aGVyIHx8ICh2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBncmVhdGVyIHRoYW4gYG90aGVyYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjkuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBgb3RoZXJgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLmx0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3QoMywgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5ndCgzLCAzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5ndCgxLCAzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBndCA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oYmFzZUd0KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgb3RoZXJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuOS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvXG4gICAgICogIGBvdGhlcmAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAc2VlIF8ubHRlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDMsIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDMsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDEsIDMpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGd0ZSA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oZnVuY3Rpb24odmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPj0gb3RoZXI7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FyZ3VtZW50cyhmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJndW1lbnRzKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcmd1bWVudHMgPSBiYXNlSXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPyBiYXNlSXNBcmd1bWVudHMgOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmXG4gICAgICAgICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KF8ubm9vcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheUJ1ZmZlcmAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheSBidWZmZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5QnVmZmVyKG5ldyBBcnJheUJ1ZmZlcigyKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5QnVmZmVyKG5ldyBBcnJheSgyKSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcnJheUJ1ZmZlciA9IG5vZGVJc0FycmF5QnVmZmVyID8gYmFzZVVuYXJ5KG5vZGVJc0FycmF5QnVmZmVyKSA6IGJhc2VJc0FycmF5QnVmZmVyO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFycmF5LWxpa2UgaWYgaXQnc1xuICAgICAqIG5vdCBhIGZ1bmN0aW9uIGFuZCBoYXMgYSBgdmFsdWUubGVuZ3RoYCB0aGF0J3MgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gb3JcbiAgICAgKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlKGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoJ2FiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoXy5ub29wKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmICFpc0Z1bmN0aW9uKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzQXJyYXlMaWtlYCBleGNlcHQgdGhhdCBpdCBhbHNvIGNoZWNrcyBpZiBgdmFsdWVgXG4gICAgICogaXMgYW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheS1saWtlIG9iamVjdCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZU9iamVjdChkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZU9iamVjdChfLm5vb3ApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNBcnJheUxpa2VPYmplY3QodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYm9vbGVhbiBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJvb2xlYW4sIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0Jvb2xlYW4oZmFsc2UpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNCb29sZWFuKG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNCb29sZWFuKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHRydWUgfHwgdmFsdWUgPT09IGZhbHNlIHx8XG4gICAgICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGJvb2xUYWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJ1ZmZlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQnVmZmVyKG5ldyBCdWZmZXIoMikpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNCdWZmZXIobmV3IFVpbnQ4QXJyYXkoMikpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzQnVmZmVyID0gbmF0aXZlSXNCdWZmZXIgfHwgc3R1YkZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBEYXRlYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZGF0ZSBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0RhdGUobmV3IERhdGUpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNEYXRlKCdNb24gQXByaWwgMjMgMjAxMicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzRGF0ZSA9IG5vZGVJc0RhdGUgPyBiYXNlVW5hcnkobm9kZUlzRGF0ZSkgOiBiYXNlSXNEYXRlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgRE9NIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgRE9NIGVsZW1lbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoZG9jdW1lbnQuYm9keSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoJzxib2R5PicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFbGVtZW50KHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiB2YWx1ZS5ub2RlVHlwZSA9PT0gMSAmJiAhaXNQbGFpbk9iamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gZW1wdHkgb2JqZWN0LCBjb2xsZWN0aW9uLCBtYXAsIG9yIHNldC5cbiAgICAgKlxuICAgICAqIE9iamVjdHMgYXJlIGNvbnNpZGVyZWQgZW1wdHkgaWYgdGhleSBoYXZlIG5vIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZFxuICAgICAqIHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiBBcnJheS1saWtlIHZhbHVlcyBzdWNoIGFzIGBhcmd1bWVudHNgIG9iamVjdHMsIGFycmF5cywgYnVmZmVycywgc3RyaW5ncywgb3JcbiAgICAgKiBqUXVlcnktbGlrZSBjb2xsZWN0aW9ucyBhcmUgY29uc2lkZXJlZCBlbXB0eSBpZiB0aGV5IGhhdmUgYSBgbGVuZ3RoYCBvZiBgMGAuXG4gICAgICogU2ltaWxhcmx5LCBtYXBzIGFuZCBzZXRzIGFyZSBjb25zaWRlcmVkIGVtcHR5IGlmIHRoZXkgaGF2ZSBhIGBzaXplYCBvZiBgMGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkodHJ1ZSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VtcHR5KDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkgJiZcbiAgICAgICAgICAoaXNBcnJheSh2YWx1ZSkgfHwgdHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWx1ZS5zcGxpY2UgPT0gJ2Z1bmN0aW9uJyB8fFxuICAgICAgICAgICAgaXNCdWZmZXIodmFsdWUpIHx8IGlzVHlwZWRBcnJheSh2YWx1ZSkgfHwgaXNBcmd1bWVudHModmFsdWUpKSkge1xuICAgICAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBnZXRUYWcodmFsdWUpO1xuICAgICAgaWYgKHRhZyA9PSBtYXBUYWcgfHwgdGFnID09IHNldFRhZykge1xuICAgICAgICByZXR1cm4gIXZhbHVlLnNpemU7XG4gICAgICB9XG4gICAgICBpZiAoaXNQcm90b3R5cGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiAhYmFzZUtleXModmFsdWUpLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwga2V5KSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZVxuICAgICAqIGVxdWl2YWxlbnQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2Qgc3VwcG9ydHMgY29tcGFyaW5nIGFycmF5cywgYXJyYXkgYnVmZmVycywgYm9vbGVhbnMsXG4gICAgICogZGF0ZSBvYmplY3RzLCBlcnJvciBvYmplY3RzLCBtYXBzLCBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLFxuICAgICAqIHNldHMsIHN0cmluZ3MsIHN5bWJvbHMsIGFuZCB0eXBlZCBhcnJheXMuIGBPYmplY3RgIG9iamVjdHMgYXJlIGNvbXBhcmVkXG4gICAgICogYnkgdGhlaXIgb3duLCBub3QgaW5oZXJpdGVkLCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIEZ1bmN0aW9ucyBhbmQgRE9NXG4gICAgICogbm9kZXMgYXJlIGNvbXBhcmVkIGJ5IHN0cmljdCBlcXVhbGl0eSwgaS5lLiBgPT09YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmlzRXF1YWwob2JqZWN0LCBvdGhlcik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogb2JqZWN0ID09PSBvdGhlcjtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzRXF1YWwodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzRXF1YWxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIHZhbHVlcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAsIGNvbXBhcmlzb25zXG4gICAgICogYXJlIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aCB1cCB0b1xuICAgICAqIHNpeCBhcmd1bWVudHM6IChvYmpWYWx1ZSwgb3RoVmFsdWUgWywgaW5kZXh8a2V5LCBvYmplY3QsIG90aGVyLCBzdGFja10pLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNHcmVldGluZyh2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSkge1xuICAgICAqICAgaWYgKGlzR3JlZXRpbmcob2JqVmFsdWUpICYmIGlzR3JlZXRpbmcob3RoVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB0cnVlO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnaGVsbG8nLCAnZ29vZGJ5ZSddO1xuICAgICAqIHZhciBvdGhlciA9IFsnaGknLCAnZ29vZGJ5ZSddO1xuICAgICAqXG4gICAgICogXy5pc0VxdWFsV2l0aChhcnJheSwgb3RoZXIsIGN1c3RvbWl6ZXIpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VxdWFsV2l0aCh2YWx1ZSwgb3RoZXIsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHZhciByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcih2YWx1ZSwgb3RoZXIpIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCB1bmRlZmluZWQsIGN1c3RvbWl6ZXIpIDogISFyZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gYEVycm9yYCwgYEV2YWxFcnJvcmAsIGBSYW5nZUVycm9yYCwgYFJlZmVyZW5jZUVycm9yYCxcbiAgICAgKiBgU3ludGF4RXJyb3JgLCBgVHlwZUVycm9yYCwgb3IgYFVSSUVycm9yYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGVycm9yIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IobmV3IEVycm9yKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IoRXJyb3IpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFcnJvcih2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdExpa2UodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgICAgIHJldHVybiB0YWcgPT0gZXJyb3JUYWcgfHwgdGFnID09IGRvbUV4Y1RhZyB8fFxuICAgICAgICAodHlwZW9mIHZhbHVlLm1lc3NhZ2UgPT0gJ3N0cmluZycgJiYgdHlwZW9mIHZhbHVlLm5hbWUgPT0gJ3N0cmluZycgJiYgIWlzUGxhaW5PYmplY3QodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBwcmltaXRpdmUgbnVtYmVyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BOdW1iZXIuaXNGaW5pdGVgXShodHRwczovL21kbi5pby9OdW1iZXIvaXNGaW5pdGUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBudW1iZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0Zpbml0ZSgzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNGaW5pdGUoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0Zpbml0ZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiBuYXRpdmVJc0Zpbml0ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBGdW5jdGlvbmAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNGdW5jdGlvbihfKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gICAgICAvLyBpbiBTYWZhcmkgOSB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheXMgYW5kIG90aGVyIGNvbnN0cnVjdG9ycy5cbiAgICAgIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgICAgIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnIHx8IHRhZyA9PSBhc3luY1RhZyB8fCB0YWcgPT0gcHJveHlUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gaW50ZWdlci5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgTnVtYmVyLmlzSW50ZWdlcmBdKGh0dHBzOi8vbWRuLmlvL051bWJlci9pc0ludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBpbnRlZ2VyLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzSW50ZWdlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0ludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiYgdmFsdWUgPT0gdG9JbnRlZ2VyKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAgICAgKiBbYFRvTGVuZ3RoYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtdG9sZW5ndGgpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTGVuZ3RoKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzTGVuZ3RoKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJlxuICAgICAgICB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gICAgICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICAgICAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3Qoe30pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdChudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gICAgICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgTWFwYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbWFwLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNNYXAobmV3IE1hcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc01hcChuZXcgV2Vha01hcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNNYXAgPSBub2RlSXNNYXAgPyBiYXNlVW5hcnkobm9kZUlzTWFwKSA6IGJhc2VJc01hcDtcblxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIGEgcGFydGlhbCBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiBgb2JqZWN0YCBhbmQgYHNvdXJjZWAgdG9cbiAgICAgKiBkZXRlcm1pbmUgaWYgYG9iamVjdGAgY29udGFpbnMgZXF1aXZhbGVudCBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBgXy5tYXRjaGVzYCB3aGVuIGBzb3VyY2VgIGlzXG4gICAgICogcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBQYXJ0aWFsIGNvbXBhcmlzb25zIHdpbGwgbWF0Y2ggZW1wdHkgYXJyYXkgYW5kIGVtcHR5IG9iamVjdCBgc291cmNlYFxuICAgICAqIHZhbHVlcyBhZ2FpbnN0IGFueSBhcnJheSBvciBvYmplY3QgdmFsdWUsIHJlc3BlY3RpdmVseS4gU2VlIGBfLmlzRXF1YWxgXG4gICAgICogZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQgdmFsdWUgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIgfTtcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2InOiAyIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2InOiAxIH0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNYXRjaChvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PT0gc291cmNlIHx8IGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBnZXRNYXRjaERhdGEoc291cmNlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pc01hdGNoYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gY29tcGFyZSB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgLCBjb21wYXJpc29uc1xuICAgICAqIGFyZSBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBpbnZva2VkIHdpdGggZml2ZVxuICAgICAqIGFyZ3VtZW50czogKG9ialZhbHVlLCBzcmNWYWx1ZSwgaW5kZXh8a2V5LCBvYmplY3QsIHNvdXJjZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNHcmVldGluZyh2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSkge1xuICAgICAqICAgaWYgKGlzR3JlZXRpbmcob2JqVmFsdWUpICYmIGlzR3JlZXRpbmcoc3JjVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB0cnVlO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdncmVldGluZyc6ICdoZWxsbycgfTtcbiAgICAgKiB2YXIgc291cmNlID0geyAnZ3JlZXRpbmcnOiAnaGknIH07XG4gICAgICpcbiAgICAgKiBfLmlzTWF0Y2hXaXRoKG9iamVjdCwgc291cmNlLCBjdXN0b21pemVyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNYXRjaFdpdGgob2JqZWN0LCBzb3VyY2UsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgZ2V0TWF0Y2hEYXRhKHNvdXJjZSksIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGBOYU5gLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BOdW1iZXIuaXNOYU5gXShodHRwczovL21kbi5pby9OdW1iZXIvaXNOYU4pIGFuZCBpcyBub3QgdGhlIHNhbWUgYXNcbiAgICAgKiBnbG9iYWwgW2Bpc05hTmBdKGh0dHBzOi8vbWRuLmlvL2lzTmFOKSB3aGljaCByZXR1cm5zIGB0cnVlYCBmb3JcbiAgICAgKiBgdW5kZWZpbmVkYCBhbmQgb3RoZXIgbm9uLW51bWJlciB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBOYU5gLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOYU4oTmFOKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmFOKG5ldyBOdW1iZXIoTmFOKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogaXNOYU4odW5kZWZpbmVkKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmFOKHVuZGVmaW5lZCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc05hTih2YWx1ZSkge1xuICAgICAgLy8gQW4gYE5hTmAgcHJpbWl0aXZlIGlzIHRoZSBvbmx5IHZhbHVlIHRoYXQgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi5cbiAgICAgIC8vIFBlcmZvcm0gdGhlIGB0b1N0cmluZ1RhZ2AgY2hlY2sgZmlyc3QgdG8gYXZvaWQgZXJyb3JzIHdpdGggc29tZVxuICAgICAgLy8gQWN0aXZlWCBvYmplY3RzIGluIElFLlxuICAgICAgcmV0dXJuIGlzTnVtYmVyKHZhbHVlKSAmJiB2YWx1ZSAhPSArdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcmlzdGluZSBuYXRpdmUgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgY2FuJ3QgcmVsaWFibHkgZGV0ZWN0IG5hdGl2ZSBmdW5jdGlvbnMgaW4gdGhlIHByZXNlbmNlXG4gICAgICogb2YgdGhlIGNvcmUtanMgcGFja2FnZSBiZWNhdXNlIGNvcmUtanMgY2lyY3VtdmVudHMgdGhpcyBraW5kIG9mIGRldGVjdGlvbi5cbiAgICAgKiBEZXNwaXRlIG11bHRpcGxlIHJlcXVlc3RzLCB0aGUgY29yZS1qcyBtYWludGFpbmVyIGhhcyBtYWRlIGl0IGNsZWFyOiBhbnlcbiAgICAgKiBhdHRlbXB0IHRvIGZpeCB0aGUgZGV0ZWN0aW9uIHdpbGwgYmUgb2JzdHJ1Y3RlZC4gQXMgYSByZXN1bHQsIHdlJ3JlIGxlZnRcbiAgICAgKiB3aXRoIGxpdHRsZSBjaG9pY2UgYnV0IHRvIHRocm93IGFuIGVycm9yLiBVbmZvcnR1bmF0ZWx5LCB0aGlzIGFsc28gYWZmZWN0c1xuICAgICAqIHBhY2thZ2VzLCBsaWtlIFtiYWJlbC1wb2x5ZmlsbF0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvYmFiZWwtcG9seWZpbGwpLFxuICAgICAqIHdoaWNoIHJlbHkgb24gY29yZS1qcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05hdGl2ZShfKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gICAgICBpZiAoaXNNYXNrYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKENPUkVfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUlzTmF0aXZlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgbnVsbGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBudWxsYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTnVsbChudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTnVsbCh2b2lkIDApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOdWxsKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYG51bGxgIG9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBudWxsaXNoLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOaWwobnVsbCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05pbCh2b2lkIDApO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOaWwoTmFOKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmlsKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYE51bWJlcmAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUbyBleGNsdWRlIGBJbmZpbml0eWAsIGAtSW5maW5pdHlgLCBhbmQgYE5hTmAsIHdoaWNoIGFyZVxuICAgICAqIGNsYXNzaWZpZWQgYXMgbnVtYmVycywgdXNlIHRoZSBgXy5pc0Zpbml0ZWAgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG51bWJlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTnVtYmVyKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOdW1iZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcignMycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOdW1iZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHxcbiAgICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gbnVtYmVyVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgdGhhdCBpcywgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlXG4gICAgICogYE9iamVjdGAgY29uc3RydWN0b3Igb3Igb25lIHdpdGggYSBgW1tQcm90b3R5cGVdXWAgb2YgYG51bGxgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuOC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc1BsYWluT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdCh7ICd4JzogMCwgJ3knOiAwIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdExpa2UodmFsdWUpIHx8IGJhc2VHZXRUYWcodmFsdWUpICE9IG9iamVjdFRhZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgcHJvdG8gPSBnZXRQcm90b3R5cGUodmFsdWUpO1xuICAgICAgaWYgKHByb3RvID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdmFyIEN0b3IgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3RvLCAnY29uc3RydWN0b3InKSAmJiBwcm90by5jb25zdHJ1Y3RvcjtcbiAgICAgIHJldHVybiB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IgaW5zdGFuY2VvZiBDdG9yICYmXG4gICAgICAgIGZ1bmNUb1N0cmluZy5jYWxsKEN0b3IpID09IG9iamVjdEN0b3JTdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBSZWdFeHBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSByZWdleHAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1JlZ0V4cCgvYWJjLyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1JlZ0V4cCgnL2FiYy8nKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1JlZ0V4cCA9IG5vZGVJc1JlZ0V4cCA/IGJhc2VVbmFyeShub2RlSXNSZWdFeHApIDogYmFzZUlzUmVnRXhwO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBzYWZlIGludGVnZXIuIEFuIGludGVnZXIgaXMgc2FmZSBpZiBpdCdzIGFuIElFRUUtNzU0XG4gICAgICogZG91YmxlIHByZWNpc2lvbiBudW1iZXIgd2hpY2ggaXNuJ3QgdGhlIHJlc3VsdCBvZiBhIHJvdW5kZWQgdW5zYWZlIGludGVnZXIuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYE51bWJlci5pc1NhZmVJbnRlZ2VyYF0oaHR0cHM6Ly9tZG4uaW8vTnVtYmVyL2lzU2FmZUludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNhZmUgaW50ZWdlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1NhZmVJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoJzMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzU2FmZUludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0ludGVnZXIodmFsdWUpICYmIHZhbHVlID49IC1NQVhfU0FGRV9JTlRFR0VSICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTZXRgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzZXQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1NldChuZXcgU2V0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzU2V0KG5ldyBXZWFrU2V0KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1NldCA9IG5vZGVJc1NldCA/IGJhc2VVbmFyeShub2RlSXNTZXQpIDogYmFzZUlzU2V0O1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTdHJpbmdgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3RyaW5nLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoJ2FiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fFxuICAgICAgICAoIWlzQXJyYXkodmFsdWUpICYmIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzeW1ib2wsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHxcbiAgICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gc3ltYm9sVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1R5cGVkQXJyYXkobmV3IFVpbnQ4QXJyYXkpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNUeXBlZEFycmF5KFtdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1R5cGVkQXJyYXkgPSBub2RlSXNUeXBlZEFycmF5ID8gYmFzZVVuYXJ5KG5vZGVJc1R5cGVkQXJyYXkpIDogYmFzZUlzVHlwZWRBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzVW5kZWZpbmVkKHZvaWQgMCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1VuZGVmaW5lZChudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFdlYWtNYXBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB3ZWFrIG1hcCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha01hcChuZXcgV2Vha01hcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1dlYWtNYXAobmV3IE1hcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1dlYWtNYXAodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGdldFRhZyh2YWx1ZSkgPT0gd2Vha01hcFRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFdlYWtTZXRgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB3ZWFrIHNldCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha1NldChuZXcgV2Vha1NldCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1dlYWtTZXQobmV3IFNldCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1dlYWtTZXQodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHdlYWtTZXRUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIGBvdGhlcmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy45LjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gYG90aGVyYCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBzZWUgXy5ndFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmx0KDEsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgbHQgPSBjcmVhdGVSZWxhdGlvbmFsT3BlcmF0aW9uKGJhc2VMdCk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYG90aGVyYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjkuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0b1xuICAgICAqICBgb3RoZXJgLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLmd0ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgxLCAzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgzLCAzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgzLCAxKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBsdGUgPSBjcmVhdGVSZWxhdGlvbmFsT3BlcmF0aW9uKGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgcmV0dXJuIHZhbHVlIDw9IG90aGVyO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b0FycmF5KHsgJ2EnOiAxLCAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkoJ2FiYycpO1xuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqXG4gICAgICogXy50b0FycmF5KDEpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkobnVsbCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0FycmF5KHZhbHVlKSB7XG4gICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGlzU3RyaW5nKHZhbHVlKSA/IHN0cmluZ1RvQXJyYXkodmFsdWUpIDogY29weUFycmF5KHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmIChzeW1JdGVyYXRvciAmJiB2YWx1ZVtzeW1JdGVyYXRvcl0pIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVG9BcnJheSh2YWx1ZVtzeW1JdGVyYXRvcl0oKSk7XG4gICAgICB9XG4gICAgICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKSxcbiAgICAgICAgICBmdW5jID0gdGFnID09IG1hcFRhZyA/IG1hcFRvQXJyYXkgOiAodGFnID09IHNldFRhZyA/IHNldFRvQXJyYXkgOiB2YWx1ZXMpO1xuXG4gICAgICByZXR1cm4gZnVuYyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMi4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9GaW5pdGUoMy4yKTtcbiAgICAgKiAvLyA9PiAzLjJcbiAgICAgKlxuICAgICAqIF8udG9GaW5pdGUoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gNWUtMzI0XG4gICAgICpcbiAgICAgKiBfLnRvRmluaXRlKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICAgICAqXG4gICAgICogXy50b0Zpbml0ZSgnMy4yJyk7XG4gICAgICogLy8gPT4gMy4yXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9GaW5pdGUodmFsdWUpIHtcbiAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiAwO1xuICAgICAgfVxuICAgICAgdmFsdWUgPSB0b051bWJlcih2YWx1ZSk7XG4gICAgICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHtcbiAgICAgICAgdmFyIHNpZ24gPSAodmFsdWUgPCAwID8gLTEgOiAxKTtcbiAgICAgICAgcmV0dXJuIHNpZ24gKiBNQVhfSU5URUdFUjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgPyB2YWx1ZSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBpbnRlZ2VyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAgICAgKiBbYFRvSW50ZWdlcmBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2ludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBpbnRlZ2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvSW50ZWdlcigzLjIpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8udG9JbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9JbnRlZ2VyKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICAgICAqXG4gICAgICogXy50b0ludGVnZXIoJzMuMicpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0ludGVnZXIodmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0b0Zpbml0ZSh2YWx1ZSksXG4gICAgICAgICAgcmVtYWluZGVyID0gcmVzdWx0ICUgMTtcblxuICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gcmVzdWx0ID8gKHJlbWFpbmRlciA/IHJlc3VsdCAtIHJlbWFpbmRlciA6IHJlc3VsdCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYW4gaW50ZWdlciBzdWl0YWJsZSBmb3IgdXNlIGFzIHRoZSBsZW5ndGggb2YgYW5cbiAgICAgKiBhcnJheS1saWtlIG9iamVjdC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoMy4yKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLnRvTGVuZ3RoKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IDQyOTQ5NjcyOTVcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoJzMuMicpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0xlbmd0aCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID8gYmFzZUNsYW1wKHRvSW50ZWdlcih2YWx1ZSksIDAsIE1BWF9BUlJBWV9MRU5HVEgpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b051bWJlcigzLjIpO1xuICAgICAqIC8vID0+IDMuMlxuICAgICAqXG4gICAgICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAgICAgKiAvLyA9PiA1ZS0zMjRcbiAgICAgKlxuICAgICAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IEluZmluaXR5XG4gICAgICpcbiAgICAgKiBfLnRvTnVtYmVyKCczLjInKTtcbiAgICAgKiAvLyA9PiAzLjJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBOQU47XG4gICAgICB9XG4gICAgICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gICAgICB9XG4gICAgICB2YWx1ZSA9IGJhc2VUcmltKHZhbHVlKTtcbiAgICAgIHZhciBpc0JpbmFyeSA9IHJlSXNCaW5hcnkudGVzdCh2YWx1ZSk7XG4gICAgICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICAgICAgPyBmcmVlUGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIGlzQmluYXJ5ID8gMiA6IDgpXG4gICAgICAgIDogKHJlSXNCYWRIZXgudGVzdCh2YWx1ZSkgPyBOQU4gOiArdmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBwbGFpbiBvYmplY3QgZmxhdHRlbmluZyBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmdcbiAgICAgKiBrZXllZCBwcm9wZXJ0aWVzIG9mIGB2YWx1ZWAgdG8gb3duIHByb3BlcnRpZXMgb2YgdGhlIHBsYWluIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgcGxhaW4gb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmFzc2lnbih7ICdhJzogMSB9LCBuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKlxuICAgICAqIF8uYXNzaWduKHsgJ2EnOiAxIH0sIF8udG9QbGFpbk9iamVjdChuZXcgRm9vKSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiwgJ2MnOiAzIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gICAgICByZXR1cm4gY29weU9iamVjdCh2YWx1ZSwga2V5c0luKHZhbHVlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHNhZmUgaW50ZWdlci4gQSBzYWZlIGludGVnZXIgY2FuIGJlIGNvbXBhcmVkIGFuZFxuICAgICAqIHJlcHJlc2VudGVkIGNvcnJlY3RseS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW50ZWdlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b1NhZmVJbnRlZ2VyKDMuMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy50b1NhZmVJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9TYWZlSW50ZWdlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gOTAwNzE5OTI1NDc0MDk5MVxuICAgICAqXG4gICAgICogXy50b1NhZmVJbnRlZ2VyKCczLjInKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9TYWZlSW50ZWdlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlXG4gICAgICAgID8gYmFzZUNsYW1wKHRvSW50ZWdlcih2YWx1ZSksIC1NQVhfU0FGRV9JTlRFR0VSLCBNQVhfU0FGRV9JTlRFR0VSKVxuICAgICAgICA6ICh2YWx1ZSA9PT0gMCA/IHZhbHVlIDogMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZy4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkIGZvciBgbnVsbGBcbiAgICAgKiBhbmQgYHVuZGVmaW5lZGAgdmFsdWVzLiBUaGUgc2lnbiBvZiBgLTBgIGlzIHByZXNlcnZlZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvU3RyaW5nKG51bGwpO1xuICAgICAqIC8vID0+ICcnXG4gICAgICpcbiAgICAgKiBfLnRvU3RyaW5nKC0wKTtcbiAgICAgKiAvLyA9PiAnLTAnXG4gICAgICpcbiAgICAgKiBfLnRvU3RyaW5nKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gJzEsMiwzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvU3RyaW5nKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogYmFzZVRvU3RyaW5nKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBBc3NpZ25zIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIHNvdXJjZSBvYmplY3RzIHRvIHRoZVxuICAgICAqIGRlc3RpbmF0aW9uIG9iamVjdC4gU291cmNlIG9iamVjdHMgYXJlIGFwcGxpZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0LlxuICAgICAqIFN1YnNlcXVlbnQgc291cmNlcyBvdmVyd3JpdGUgcHJvcGVydHkgYXNzaWdubWVudHMgb2YgcHJldmlvdXMgc291cmNlcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgIGFuZCBpcyBsb29zZWx5IGJhc2VkIG9uXG4gICAgICogW2BPYmplY3QuYXNzaWduYF0oaHR0cHM6Ly9tZG4uaW8vT2JqZWN0L2Fzc2lnbikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gW3NvdXJjZXNdIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5hc3NpZ25JblxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEJhcigpIHtcbiAgICAgKiAgIHRoaXMuYyA9IDM7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5iID0gMjtcbiAgICAgKiBCYXIucHJvdG90eXBlLmQgPSA0O1xuICAgICAqXG4gICAgICogXy5hc3NpZ24oeyAnYSc6IDAgfSwgbmV3IEZvbywgbmV3IEJhcik7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdjJzogMyB9XG4gICAgICovXG4gICAgdmFyIGFzc2lnbiA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlKSB7XG4gICAgICBpZiAoaXNQcm90b3R5cGUoc291cmNlKSB8fCBpc0FycmF5TGlrZShzb3VyY2UpKSB7XG4gICAgICAgIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzKHNvdXJjZSksIG9iamVjdCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHNvdXJjZVtrZXldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5hc3NpZ25gIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgb3duIGFuZFxuICAgICAqIGluaGVyaXRlZCBzb3VyY2UgcHJvcGVydGllcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGFsaWFzIGV4dGVuZFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uYXNzaWduXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gQmFyKCkge1xuICAgICAqICAgdGhpcy5jID0gMztcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmIgPSAyO1xuICAgICAqIEJhci5wcm90b3R5cGUuZCA9IDQ7XG4gICAgICpcbiAgICAgKiBfLmFzc2lnbkluKHsgJ2EnOiAwIH0sIG5ldyBGb28sIG5ldyBCYXIpO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMywgJ2QnOiA0IH1cbiAgICAgKi9cbiAgICB2YXIgYXNzaWduSW4gPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSkge1xuICAgICAgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5hc3NpZ25JbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY3VzdG9taXplcmBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIHRvIHByb2R1Y2UgdGhlIGFzc2lnbmVkIHZhbHVlcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnNcbiAgICAgKiBgdW5kZWZpbmVkYCwgYXNzaWdubWVudCBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYFxuICAgICAqIGlzIGludm9rZWQgd2l0aCBmaXZlIGFyZ3VtZW50czogKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBhbGlhcyBleHRlbmRXaXRoXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gc291cmNlcyBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmFzc2lnbldpdGhcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUpIHtcbiAgICAgKiAgIHJldHVybiBfLmlzVW5kZWZpbmVkKG9ialZhbHVlKSA/IHNyY1ZhbHVlIDogb2JqVmFsdWU7XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGRlZmF1bHRzID0gXy5wYXJ0aWFsUmlnaHQoXy5hc3NpZ25JbldpdGgsIGN1c3RvbWl6ZXIpO1xuICAgICAqXG4gICAgICogZGVmYXVsdHMoeyAnYSc6IDEgfSwgeyAnYic6IDIgfSwgeyAnYSc6IDMgfSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgdmFyIGFzc2lnbkluV2l0aCA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcikge1xuICAgICAgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QsIGN1c3RvbWl6ZXIpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5hc3NpZ25gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBhc3NpZ25lZCB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zXG4gICAgICogYHVuZGVmaW5lZGAsIGFzc2lnbm1lbnQgaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmBcbiAgICAgKiBpcyBpbnZva2VkIHdpdGggZml2ZSBhcmd1bWVudHM6IChvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBzb3VyY2VzIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uYXNzaWduSW5XaXRoXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlKSB7XG4gICAgICogICByZXR1cm4gXy5pc1VuZGVmaW5lZChvYmpWYWx1ZSkgPyBzcmNWYWx1ZSA6IG9ialZhbHVlO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBkZWZhdWx0cyA9IF8ucGFydGlhbFJpZ2h0KF8uYXNzaWduV2l0aCwgY3VzdG9taXplcik7XG4gICAgICpcbiAgICAgKiBkZWZhdWx0cyh7ICdhJzogMSB9LCB7ICdiJzogMiB9LCB7ICdhJzogMyB9KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKi9cbiAgICB2YXIgYXNzaWduV2l0aCA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcikge1xuICAgICAgY29weU9iamVjdChzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0LCBjdXN0b21pemVyKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdmFsdWVzIGNvcnJlc3BvbmRpbmcgdG8gYHBhdGhzYCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7Li4uKHN0cmluZ3xzdHJpbmdbXSl9IFtwYXRoc10gVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwaWNrZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9LCA0XSB9O1xuICAgICAqXG4gICAgICogXy5hdChvYmplY3QsIFsnYVswXS5iLmMnLCAnYVsxXSddKTtcbiAgICAgKiAvLyA9PiBbMywgNF1cbiAgICAgKi9cbiAgICB2YXIgYXQgPSBmbGF0UmVzdChiYXNlQXQpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgdGhhdCBpbmhlcml0cyBmcm9tIHRoZSBgcHJvdG90eXBlYCBvYmplY3QuIElmIGFcbiAgICAgKiBgcHJvcGVydGllc2Agb2JqZWN0IGlzIGdpdmVuLCBpdHMgb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXNcbiAgICAgKiBhcmUgYXNzaWduZWQgdG8gdGhlIGNyZWF0ZWQgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwcm90b3R5cGUgVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtwcm9wZXJ0aWVzXSBUaGUgcHJvcGVydGllcyB0byBhc3NpZ24gdG8gdGhlIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBTaGFwZSgpIHtcbiAgICAgKiAgIHRoaXMueCA9IDA7XG4gICAgICogICB0aGlzLnkgPSAwO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIENpcmNsZSgpIHtcbiAgICAgKiAgIFNoYXBlLmNhbGwodGhpcyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogQ2lyY2xlLnByb3RvdHlwZSA9IF8uY3JlYXRlKFNoYXBlLnByb3RvdHlwZSwge1xuICAgICAqICAgJ2NvbnN0cnVjdG9yJzogQ2lyY2xlXG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiB2YXIgY2lyY2xlID0gbmV3IENpcmNsZTtcbiAgICAgKiBjaXJjbGUgaW5zdGFuY2VvZiBDaXJjbGU7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogY2lyY2xlIGluc3RhbmNlb2YgU2hhcGU7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZShwcm90b3R5cGUsIHByb3BlcnRpZXMpIHtcbiAgICAgIHZhciByZXN1bHQgPSBiYXNlQ3JlYXRlKHByb3RvdHlwZSk7XG4gICAgICByZXR1cm4gcHJvcGVydGllcyA9PSBudWxsID8gcmVzdWx0IDogYmFzZUFzc2lnbihyZXN1bHQsIHByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFzc2lnbnMgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBzb3VyY2VcbiAgICAgKiBvYmplY3RzIHRvIHRoZSBkZXN0aW5hdGlvbiBvYmplY3QgZm9yIGFsbCBkZXN0aW5hdGlvbiBwcm9wZXJ0aWVzIHRoYXRcbiAgICAgKiByZXNvbHZlIHRvIGB1bmRlZmluZWRgLiBTb3VyY2Ugb2JqZWN0cyBhcmUgYXBwbGllZCBmcm9tIGxlZnQgdG8gcmlnaHQuXG4gICAgICogT25jZSBhIHByb3BlcnR5IGlzIHNldCwgYWRkaXRpb25hbCB2YWx1ZXMgb2YgdGhlIHNhbWUgcHJvcGVydHkgYXJlIGlnbm9yZWQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZGVmYXVsdHNEZWVwXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVmYXVsdHMoeyAnYSc6IDEgfSwgeyAnYic6IDIgfSwgeyAnYSc6IDMgfSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgdmFyIGRlZmF1bHRzID0gYmFzZVJlc3QoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2VzKSB7XG4gICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcblxuICAgICAgdmFyIGluZGV4ID0gLTE7XG4gICAgICB2YXIgbGVuZ3RoID0gc291cmNlcy5sZW5ndGg7XG4gICAgICB2YXIgZ3VhcmQgPSBsZW5ndGggPiAyID8gc291cmNlc1syXSA6IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHNvdXJjZXNbMF0sIHNvdXJjZXNbMV0sIGd1YXJkKSkge1xuICAgICAgICBsZW5ndGggPSAxO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgc291cmNlID0gc291cmNlc1tpbmRleF07XG4gICAgICAgIHZhciBwcm9wcyA9IGtleXNJbihzb3VyY2UpO1xuICAgICAgICB2YXIgcHJvcHNJbmRleCA9IC0xO1xuICAgICAgICB2YXIgcHJvcHNMZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgICAgICAgd2hpbGUgKCsrcHJvcHNJbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIGtleSA9IHByb3BzW3Byb3BzSW5kZXhdO1xuICAgICAgICAgIHZhciB2YWx1ZSA9IG9iamVjdFtrZXldO1xuXG4gICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgICAgKGVxKHZhbHVlLCBvYmplY3RQcm90b1trZXldKSAmJiAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSB7XG4gICAgICAgICAgICBvYmplY3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5kZWZhdWx0c2AgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgYXNzaWduc1xuICAgICAqIGRlZmF1bHQgcHJvcGVydGllcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZGVmYXVsdHNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZhdWx0c0RlZXAoeyAnYSc6IHsgJ2InOiAyIH0gfSwgeyAnYSc6IHsgJ2InOiAxLCAnYyc6IDMgfSB9KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogeyAnYic6IDIsICdjJzogMyB9IH1cbiAgICAgKi9cbiAgICB2YXIgZGVmYXVsdHNEZWVwID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgYXJncy5wdXNoKHVuZGVmaW5lZCwgY3VzdG9tRGVmYXVsdHNNZXJnZSk7XG4gICAgICByZXR1cm4gYXBwbHkobWVyZ2VXaXRoLCB1bmRlZmluZWQsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kYCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHRoZSBrZXkgb2YgdGhlIGZpcnN0XG4gICAgICogZWxlbWVudCBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IgaW5zdGVhZCBvZiB0aGUgZWxlbWVudCBpdHNlbGYuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfSBSZXR1cm5zIHRoZSBrZXkgb2YgdGhlIG1hdGNoZWQgZWxlbWVudCxcbiAgICAgKiAgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0ge1xuICAgICAqICAgJ2Jhcm5leSc6ICB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgICdmcmVkJzogICAgeyAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgJ3BlYmJsZXMnOiB7ICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBfLmZpbmRLZXkodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWdlIDwgNDA7IH0pO1xuICAgICAqIC8vID0+ICdiYXJuZXknIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEtleSh1c2VycywgeyAnYWdlJzogMSwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gJ3BlYmJsZXMnXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kS2V5KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gJ2ZyZWQnXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRLZXkodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAnYmFybmV5J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbmRLZXkob2JqZWN0LCBwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiBiYXNlRmluZEtleShvYmplY3QsIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGJhc2VGb3JPd24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmluZEtleWAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZlxuICAgICAqIGEgY29sbGVjdGlvbiBpbiB0aGUgb3Bwb3NpdGUgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfSBSZXR1cm5zIHRoZSBrZXkgb2YgdGhlIG1hdGNoZWQgZWxlbWVudCxcbiAgICAgKiAgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0ge1xuICAgICAqICAgJ2Jhcm5leSc6ICB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgICdmcmVkJzogICAgeyAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgJ3BlYmJsZXMnOiB7ICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZSA8IDQwOyB9KTtcbiAgICAgKiAvLyA9PiByZXR1cm5zICdwZWJibGVzJyBhc3N1bWluZyBgXy5maW5kS2V5YCByZXR1cm5zICdiYXJuZXknXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZExhc3RLZXkodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiAnYmFybmV5J1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZExhc3RLZXkodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiAnZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZExhc3RLZXkodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAncGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaW5kTGFzdEtleShvYmplY3QsIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIGJhc2VGaW5kS2V5KG9iamVjdCwgZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKSwgYmFzZUZvck93blJpZ2h0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlcyBvdmVyIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2YgYW5cbiAgICAgKiBvYmplY3QgYW5kIGludm9rZXMgYGl0ZXJhdGVlYCBmb3IgZWFjaCBwcm9wZXJ0eS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBrZXksIG9iamVjdCkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdFxuICAgICAqIGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZm9ySW5SaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5mb3JJbihuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2EnLCAnYicsIHRoZW4gJ2MnIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvckluKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbFxuICAgICAgICA/IG9iamVjdFxuICAgICAgICA6IGJhc2VGb3Iob2JqZWN0LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyksIGtleXNJbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mb3JJbmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBwcm9wZXJ0aWVzIG9mXG4gICAgICogYG9iamVjdGAgaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZm9ySW5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8uZm9ySW5SaWdodChuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2MnLCAnYicsIHRoZW4gJ2EnIGFzc3VtaW5nIGBfLmZvckluYCBsb2dzICdhJywgJ2InLCB0aGVuICdjJy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JJblJpZ2h0KG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbFxuICAgICAgICA/IG9iamVjdFxuICAgICAgICA6IGJhc2VGb3JSaWdodChvYmplY3QsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSwga2V5c0luKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlcyBvdmVyIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCBhbmRcbiAgICAgKiBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggcHJvcGVydHkuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWVcbiAgICAgKiBhcmd1bWVudHM6ICh2YWx1ZSwga2V5LCBvYmplY3QpLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uXG4gICAgICogZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjMuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmZvck93blJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmZvck93bihuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2EnIHRoZW4gJ2InIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGJhc2VGb3JPd24ob2JqZWN0LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZm9yT3duYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIHByb3BlcnRpZXMgb2ZcbiAgICAgKiBgb2JqZWN0YCBpbiB0aGUgb3Bwb3NpdGUgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5mb3JPd25cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8uZm9yT3duUmlnaHQobmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdiJyB0aGVuICdhJyBhc3N1bWluZyBgXy5mb3JPd25gIGxvZ3MgJ2EnIHRoZW4gJ2InLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvck93blJpZ2h0KG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgYmFzZUZvck93blJpZ2h0KG9iamVjdCwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGZ1bmN0aW9uIHByb3BlcnR5IG5hbWVzIGZyb20gb3duIGVudW1lcmFibGUgcHJvcGVydGllc1xuICAgICAqIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZXMuXG4gICAgICogQHNlZSBfLmZ1bmN0aW9uc0luXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IF8uY29uc3RhbnQoJ2EnKTtcbiAgICAgKiAgIHRoaXMuYiA9IF8uY29uc3RhbnQoJ2InKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSBfLmNvbnN0YW50KCdjJyk7XG4gICAgICpcbiAgICAgKiBfLmZ1bmN0aW9ucyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYiddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZnVuY3Rpb25zKG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gW10gOiBiYXNlRnVuY3Rpb25zKG9iamVjdCwga2V5cyhvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGZ1bmN0aW9uIHByb3BlcnR5IG5hbWVzIGZyb20gb3duIGFuZCBpbmhlcml0ZWRcbiAgICAgKiBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lcy5cbiAgICAgKiBAc2VlIF8uZnVuY3Rpb25zXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IF8uY29uc3RhbnQoJ2EnKTtcbiAgICAgKiAgIHRoaXMuYiA9IF8uY29uc3RhbnQoJ2InKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSBfLmNvbnN0YW50KCdjJyk7XG4gICAgICpcbiAgICAgKiBfLmZ1bmN0aW9uc0luKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZ1bmN0aW9uc0luKG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gW10gOiBiYXNlRnVuY3Rpb25zKG9iamVjdCwga2V5c0luKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC4gSWYgdGhlIHJlc29sdmVkIHZhbHVlIGlzXG4gICAgICogYHVuZGVmaW5lZGAsIHRoZSBgZGVmYXVsdFZhbHVlYCBpcyByZXR1cm5lZCBpbiBpdHMgcGxhY2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy43LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHBhcmFtIHsqfSBbZGVmYXVsdFZhbHVlXSBUaGUgdmFsdWUgcmV0dXJuZWQgZm9yIGB1bmRlZmluZWRgIHJlc29sdmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLmdldChvYmplY3QsICdhWzBdLmIuYycpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8uZ2V0KG9iamVjdCwgWydhJywgJzAnLCAnYicsICdjJ10pO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8uZ2V0KG9iamVjdCwgJ2EuYi5jJywgJ2RlZmF1bHQnKTtcbiAgICAgKiAvLyA9PiAnZGVmYXVsdCdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXQob2JqZWN0LCBwYXRoLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcbiAgICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRWYWx1ZSA6IHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHBhdGhgIGlzIGEgZGlyZWN0IHByb3BlcnR5IG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHBhdGhgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IHsgJ2InOiAyIH0gfTtcbiAgICAgKiB2YXIgb3RoZXIgPSBfLmNyZWF0ZSh7ICdhJzogXy5jcmVhdGUoeyAnYic6IDIgfSkgfSk7XG4gICAgICpcbiAgICAgKiBfLmhhcyhvYmplY3QsICdhJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXMob2JqZWN0LCAnYS5iJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXMob2JqZWN0LCBbJ2EnLCAnYiddKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhcyhvdGhlciwgJ2EnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhcyhvYmplY3QsIHBhdGgpIHtcbiAgICAgIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBoYXNQYXRoKG9iamVjdCwgcGF0aCwgYmFzZUhhcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwYXRoYCBpcyBhIGRpcmVjdCBvciBpbmhlcml0ZWQgcHJvcGVydHkgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgcGF0aGAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSBfLmNyZWF0ZSh7ICdhJzogXy5jcmVhdGUoeyAnYic6IDIgfSkgfSk7XG4gICAgICpcbiAgICAgKiBfLmhhc0luKG9iamVjdCwgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhc0luKG9iamVjdCwgJ2EuYicpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzSW4ob2JqZWN0LCBbJ2EnLCAnYiddKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhc0luKG9iamVjdCwgJ2InKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc0luKG9iamVjdCwgcGF0aCkge1xuICAgICAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGhhc1BhdGgob2JqZWN0LCBwYXRoLCBiYXNlSGFzSW4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBpbnZlcnRlZCBrZXlzIGFuZCB2YWx1ZXMgb2YgYG9iamVjdGAuXG4gICAgICogSWYgYG9iamVjdGAgY29udGFpbnMgZHVwbGljYXRlIHZhbHVlcywgc3Vic2VxdWVudCB2YWx1ZXMgb3ZlcndyaXRlXG4gICAgICogcHJvcGVydHkgYXNzaWdubWVudHMgb2YgcHJldmlvdXMgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnZlcnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGludmVydGVkIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMSB9O1xuICAgICAqXG4gICAgICogXy5pbnZlcnQob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICcxJzogJ2MnLCAnMic6ICdiJyB9XG4gICAgICovXG4gICAgdmFyIGludmVydCA9IGNyZWF0ZUludmVydGVyKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgaWYgKHZhbHVlICE9IG51bGwgJiZcbiAgICAgICAgICB0eXBlb2YgdmFsdWUudG9TdHJpbmcgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YWx1ZSA9IG5hdGl2ZU9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXN1bHRbdmFsdWVdID0ga2V5O1xuICAgIH0sIGNvbnN0YW50KGlkZW50aXR5KSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmludmVydGAgZXhjZXB0IHRoYXQgdGhlIGludmVydGVkIG9iamVjdCBpcyBnZW5lcmF0ZWRcbiAgICAgKiBmcm9tIHRoZSByZXN1bHRzIG9mIHJ1bm5pbmcgZWFjaCBlbGVtZW50IG9mIGBvYmplY3RgIHRocnUgYGl0ZXJhdGVlYC4gVGhlXG4gICAgICogY29ycmVzcG9uZGluZyBpbnZlcnRlZCB2YWx1ZSBvZiBlYWNoIGludmVydGVkIGtleSBpcyBhbiBhcnJheSBvZiBrZXlzXG4gICAgICogcmVzcG9uc2libGUgZm9yIGdlbmVyYXRpbmcgdGhlIGludmVydGVkIHZhbHVlLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZFxuICAgICAqIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMS4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnZlcnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBpbnZlcnRlZCBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDEgfTtcbiAgICAgKlxuICAgICAqIF8uaW52ZXJ0Qnkob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICcxJzogWydhJywgJ2MnXSwgJzInOiBbJ2InXSB9XG4gICAgICpcbiAgICAgKiBfLmludmVydEJ5KG9iamVjdCwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgIHJldHVybiAnZ3JvdXAnICsgdmFsdWU7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4geyAnZ3JvdXAxJzogWydhJywgJ2MnXSwgJ2dyb3VwMic6IFsnYiddIH1cbiAgICAgKi9cbiAgICB2YXIgaW52ZXJ0QnkgPSBjcmVhdGVJbnZlcnRlcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmXG4gICAgICAgICAgdHlwZW9mIHZhbHVlLnRvU3RyaW5nICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdmFsdWUgPSBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwocmVzdWx0LCB2YWx1ZSkpIHtcbiAgICAgICAgcmVzdWx0W3ZhbHVlXS5wdXNoKGtleSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbdmFsdWVdID0gW2tleV07XG4gICAgICB9XG4gICAgfSwgZ2V0SXRlcmF0ZWUpO1xuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUgbWV0aG9kIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIG1ldGhvZCB0byBpbnZva2UuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIGludm9rZWQgbWV0aG9kLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IFsxLCAyLCAzLCA0XSB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLmludm9rZShvYmplY3QsICdhWzBdLmIuYy5zbGljZScsIDEsIDMpO1xuICAgICAqIC8vID0+IFsyLCAzXVxuICAgICAqL1xuICAgIHZhciBpbnZva2UgPSBiYXNlUmVzdChiYXNlSW52b2tlKTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAgICAgKiBbRVMgc3BlY10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LmtleXMpXG4gICAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8ua2V5cyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiBfLmtleXMoJ2hpJyk7XG4gICAgICogLy8gPT4gWycwJywgJzEnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5rZXlzSW4obmV3IEZvbyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgZnVuY3Rpb24ga2V5c0luKG9iamVjdCkge1xuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlKG9iamVjdCkgPyBhcnJheUxpa2VLZXlzKG9iamVjdCwgdHJ1ZSkgOiBiYXNlS2V5c0luKG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLm1hcFZhbHVlc2A7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IHdpdGggdGhlXG4gICAgICogc2FtZSB2YWx1ZXMgYXMgYG9iamVjdGAgYW5kIGtleXMgZ2VuZXJhdGVkIGJ5IHJ1bm5pbmcgZWFjaCBvd24gZW51bWVyYWJsZVxuICAgICAqIHN0cmluZyBrZXllZCBwcm9wZXJ0eSBvZiBgb2JqZWN0YCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwga2V5LCBvYmplY3QpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuOC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBvYmplY3QuXG4gICAgICogQHNlZSBfLm1hcFZhbHVlc1xuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1hcEtleXMoeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICByZXR1cm4ga2V5ICsgdmFsdWU7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4geyAnYTEnOiAxLCAnYjInOiAyIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBLZXlzKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgIGl0ZXJhdGVlID0gZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpO1xuXG4gICAgICBiYXNlRm9yT3duKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqZWN0KSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGl0ZXJhdGVlKHZhbHVlLCBrZXksIG9iamVjdCksIHZhbHVlKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCB3aXRoIHRoZSBzYW1lIGtleXMgYXMgYG9iamVjdGAgYW5kIHZhbHVlcyBnZW5lcmF0ZWRcbiAgICAgKiBieSBydW5uaW5nIGVhY2ggb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnR5IG9mIGBvYmplY3RgIHRocnVcbiAgICAgKiBgaXRlcmF0ZWVgLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czpcbiAgICAgKiAodmFsdWUsIGtleSwgb2JqZWN0KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjQuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgb2JqZWN0LlxuICAgICAqIEBzZWUgXy5tYXBLZXlzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IHtcbiAgICAgKiAgICdmcmVkJzogICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FnZSc6IDQwIH0sXG4gICAgICogICAncGViYmxlcyc6IHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5tYXBWYWx1ZXModXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWdlOyB9KTtcbiAgICAgKiAvLyA9PiB7ICdmcmVkJzogNDAsICdwZWJibGVzJzogMSB9IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLm1hcFZhbHVlcyh1c2VycywgJ2FnZScpO1xuICAgICAqIC8vID0+IHsgJ2ZyZWQnOiA0MCwgJ3BlYmJsZXMnOiAxIH0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBWYWx1ZXMob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgaXRlcmF0ZWUgPSBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyk7XG5cbiAgICAgIGJhc2VGb3JPd24ob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCBpdGVyYXRlZSh2YWx1ZSwga2V5LCBvYmplY3QpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmFzc2lnbmAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgbWVyZ2VzIG93biBhbmRcbiAgICAgKiBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBzb3VyY2Ugb2JqZWN0cyBpbnRvIHRoZVxuICAgICAqIGRlc3RpbmF0aW9uIG9iamVjdC4gU291cmNlIHByb3BlcnRpZXMgdGhhdCByZXNvbHZlIHRvIGB1bmRlZmluZWRgIGFyZVxuICAgICAqIHNraXBwZWQgaWYgYSBkZXN0aW5hdGlvbiB2YWx1ZSBleGlzdHMuIEFycmF5IGFuZCBwbGFpbiBvYmplY3QgcHJvcGVydGllc1xuICAgICAqIGFyZSBtZXJnZWQgcmVjdXJzaXZlbHkuIE90aGVyIG9iamVjdHMgYW5kIHZhbHVlIHR5cGVzIGFyZSBvdmVycmlkZGVuIGJ5XG4gICAgICogYXNzaWdubWVudC4gU291cmNlIG9iamVjdHMgYXJlIGFwcGxpZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0LiBTdWJzZXF1ZW50XG4gICAgICogc291cmNlcyBvdmVyd3JpdGUgcHJvcGVydHkgYXNzaWdubWVudHMgb2YgcHJldmlvdXMgc291cmNlcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNS4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gW3NvdXJjZXNdIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0ge1xuICAgICAqICAgJ2EnOiBbeyAnYic6IDIgfSwgeyAnZCc6IDQgfV1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIG90aGVyID0ge1xuICAgICAqICAgJ2EnOiBbeyAnYyc6IDMgfSwgeyAnZSc6IDUgfV1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5tZXJnZShvYmplY3QsIG90aGVyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogW3sgJ2InOiAyLCAnYyc6IDMgfSwgeyAnZCc6IDQsICdlJzogNSB9XSB9XG4gICAgICovXG4gICAgdmFyIG1lcmdlID0gY3JlYXRlQXNzaWduZXIoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4KSB7XG4gICAgICBiYXNlTWVyZ2Uob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ubWVyZ2VgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBtZXJnZWQgdmFsdWVzIG9mIHRoZSBkZXN0aW5hdGlvbiBhbmQgc291cmNlXG4gICAgICogcHJvcGVydGllcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAsIG1lcmdpbmcgaXMgaGFuZGxlZCBieSB0aGVcbiAgICAgKiBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBpbnZva2VkIHdpdGggc2l4IGFyZ3VtZW50czpcbiAgICAgKiAob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjaykuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IHNvdXJjZXMgVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUpIHtcbiAgICAgKiAgIGlmIChfLmlzQXJyYXkob2JqVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiBvYmpWYWx1ZS5jb25jYXQoc3JjVmFsdWUpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogWzFdLCAnYic6IFsyXSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiBbM10sICdiJzogWzRdIH07XG4gICAgICpcbiAgICAgKiBfLm1lcmdlV2l0aChvYmplY3QsIG90aGVyLCBjdXN0b21pemVyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogWzEsIDNdLCAnYic6IFsyLCA0XSB9XG4gICAgICovXG4gICAgdmFyIG1lcmdlV2l0aCA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcikge1xuICAgICAgYmFzZU1lcmdlKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcik7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ucGlja2A7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZVxuICAgICAqIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgcGF0aHMgb2YgYG9iamVjdGAgdGhhdCBhcmUgbm90IG9taXR0ZWQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgY29uc2lkZXJhYmx5IHNsb3dlciB0aGFuIGBfLnBpY2tgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi4oc3RyaW5nfHN0cmluZ1tdKX0gW3BhdGhzXSBUaGUgcHJvcGVydHkgcGF0aHMgdG8gb21pdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ub21pdChvYmplY3QsIFsnYScsICdjJ10pO1xuICAgICAqIC8vID0+IHsgJ2InOiAnMicgfVxuICAgICAqL1xuICAgIHZhciBvbWl0ID0gZmxhdFJlc3QoZnVuY3Rpb24ob2JqZWN0LCBwYXRocykge1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICB2YXIgaXNEZWVwID0gZmFsc2U7XG4gICAgICBwYXRocyA9IGFycmF5TWFwKHBhdGhzLCBmdW5jdGlvbihwYXRoKSB7XG4gICAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuICAgICAgICBpc0RlZXAgfHwgKGlzRGVlcCA9IHBhdGgubGVuZ3RoID4gMSk7XG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgICAgfSk7XG4gICAgICBjb3B5T2JqZWN0KG9iamVjdCwgZ2V0QWxsS2V5c0luKG9iamVjdCksIHJlc3VsdCk7XG4gICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgIHJlc3VsdCA9IGJhc2VDbG9uZShyZXN1bHQsIENMT05FX0RFRVBfRkxBRyB8IENMT05FX0ZMQVRfRkxBRyB8IENMT05FX1NZTUJPTFNfRkxBRywgY3VzdG9tT21pdENsb25lKTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBwYXRocy5sZW5ndGg7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgYmFzZVVuc2V0KHJlc3VsdCwgcGF0aHNbbGVuZ3RoXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLnBpY2tCeWA7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mXG4gICAgICogdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2YgYG9iamVjdGAgdGhhdFxuICAgICAqIGBwcmVkaWNhdGVgIGRvZXNuJ3QgcmV0dXJuIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHR3b1xuICAgICAqIGFyZ3VtZW50czogKHZhbHVlLCBrZXkpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgcHJvcGVydHkuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6ICcyJywgJ2MnOiAzIH07XG4gICAgICpcbiAgICAgKiBfLm9taXRCeShvYmplY3QsIF8uaXNOdW1iZXIpO1xuICAgICAqIC8vID0+IHsgJ2InOiAnMicgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG9taXRCeShvYmplY3QsIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHBpY2tCeShvYmplY3QsIG5lZ2F0ZShnZXRJdGVyYXRlZShwcmVkaWNhdGUpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2YgdGhlIHBpY2tlZCBgb2JqZWN0YCBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi4oc3RyaW5nfHN0cmluZ1tdKX0gW3BhdGhzXSBUaGUgcHJvcGVydHkgcGF0aHMgdG8gcGljay5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ucGljayhvYmplY3QsIFsnYScsICdjJ10pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYyc6IDMgfVxuICAgICAqL1xuICAgIHZhciBwaWNrID0gZmxhdFJlc3QoZnVuY3Rpb24ob2JqZWN0LCBwYXRocykge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8ge30gOiBiYXNlUGljayhvYmplY3QsIHBhdGhzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBgb2JqZWN0YCBwcm9wZXJ0aWVzIGBwcmVkaWNhdGVgIHJldHVybnNcbiAgICAgKiB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aCB0d28gYXJndW1lbnRzOiAodmFsdWUsIGtleSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBwcm9wZXJ0eS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ucGlja0J5KG9iamVjdCwgXy5pc051bWJlcik7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdjJzogMyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gcGlja0J5KG9iamVjdCwgcHJlZGljYXRlKSB7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgfVxuICAgICAgdmFyIHByb3BzID0gYXJyYXlNYXAoZ2V0QWxsS2V5c0luKG9iamVjdCksIGZ1bmN0aW9uKHByb3ApIHtcbiAgICAgICAgcmV0dXJuIFtwcm9wXTtcbiAgICAgIH0pO1xuICAgICAgcHJlZGljYXRlID0gZ2V0SXRlcmF0ZWUocHJlZGljYXRlKTtcbiAgICAgIHJldHVybiBiYXNlUGlja0J5KG9iamVjdCwgcHJvcHMsIGZ1bmN0aW9uKHZhbHVlLCBwYXRoKSB7XG4gICAgICAgIHJldHVybiBwcmVkaWNhdGUodmFsdWUsIHBhdGhbMF0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5nZXRgIGV4Y2VwdCB0aGF0IGlmIHRoZSByZXNvbHZlZCB2YWx1ZSBpcyBhXG4gICAgICogZnVuY3Rpb24gaXQncyBpbnZva2VkIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIGl0cyBwYXJlbnQgb2JqZWN0IGFuZFxuICAgICAqIGl0cyByZXN1bHQgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byByZXNvbHZlLlxuICAgICAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGZvciBgdW5kZWZpbmVkYCByZXNvbHZlZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYzEnOiAzLCAnYzInOiBfLmNvbnN0YW50KDQpIH0gfV0gfTtcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMScpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMicpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMycsICdkZWZhdWx0Jyk7XG4gICAgICogLy8gPT4gJ2RlZmF1bHQnXG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhWzBdLmIuYzMnLCBfLmNvbnN0YW50KCdkZWZhdWx0JykpO1xuICAgICAqIC8vID0+ICdkZWZhdWx0J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlc3VsdChvYmplY3QsIHBhdGgsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoO1xuXG4gICAgICAvLyBFbnN1cmUgdGhlIGxvb3AgaXMgZW50ZXJlZCB3aGVuIHBhdGggaXMgZW1wdHkuXG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICBsZW5ndGggPSAxO1xuICAgICAgICBvYmplY3QgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFt0b0tleShwYXRoW2luZGV4XSldO1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuICAgICAgICAgIHZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIG9iamVjdCA9IGlzRnVuY3Rpb24odmFsdWUpID8gdmFsdWUuY2FsbChvYmplY3QpIDogdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC4gSWYgYSBwb3J0aW9uIG9mIGBwYXRoYCBkb2Vzbid0IGV4aXN0LFxuICAgICAqIGl0J3MgY3JlYXRlZC4gQXJyYXlzIGFyZSBjcmVhdGVkIGZvciBtaXNzaW5nIGluZGV4IHByb3BlcnRpZXMgd2hpbGUgb2JqZWN0c1xuICAgICAqIGFyZSBjcmVhdGVkIGZvciBhbGwgb3RoZXIgbWlzc2luZyBwcm9wZXJ0aWVzLiBVc2UgYF8uc2V0V2l0aGAgdG8gY3VzdG9taXplXG4gICAgICogYHBhdGhgIGNyZWF0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy43LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9XSB9O1xuICAgICAqXG4gICAgICogXy5zZXQob2JqZWN0LCAnYVswXS5iLmMnLCA0KTtcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QuYVswXS5iLmMpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8uc2V0KG9iamVjdCwgWyd4JywgJzAnLCAneScsICd6J10sIDUpO1xuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdC54WzBdLnkueik7XG4gICAgICogLy8gPT4gNVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldChvYmplY3QsIHBhdGgsIHZhbHVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBiYXNlU2V0KG9iamVjdCwgcGF0aCwgdmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc2V0YCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgb2JqZWN0cyBvZiBgcGF0aGAuICBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYFxuICAgICAqIHBhdGggY3JlYXRpb24gaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmAgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAobnNWYWx1ZSwga2V5LCBuc09iamVjdCkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0ge307XG4gICAgICpcbiAgICAgKiBfLnNldFdpdGgob2JqZWN0LCAnWzBdWzFdJywgJ2EnLCBPYmplY3QpO1xuICAgICAqIC8vID0+IHsgJzAnOiB7ICcxJzogJ2EnIH0gfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldFdpdGgob2JqZWN0LCBwYXRoLCB2YWx1ZSwgY3VzdG9taXplcikge1xuICAgICAgY3VzdG9taXplciA9IHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbicgPyBjdXN0b21pemVyIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gb2JqZWN0IDogYmFzZVNldChvYmplY3QsIHBhdGgsIHZhbHVlLCBjdXN0b21pemVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZC12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGBcbiAgICAgKiB3aGljaCBjYW4gYmUgY29uc3VtZWQgYnkgYF8uZnJvbVBhaXJzYC4gSWYgYG9iamVjdGAgaXMgYSBtYXAgb3Igc2V0LCBpdHNcbiAgICAgKiBlbnRyaWVzIGFyZSByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBhbGlhcyBlbnRyaWVzXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8udG9QYWlycyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbWydhJywgMV0sIFsnYicsIDJdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIHZhciB0b1BhaXJzID0gY3JlYXRlVG9QYWlycyhrZXlzKTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQtdmFsdWUgcGFpcnNcbiAgICAgKiBmb3IgYG9iamVjdGAgd2hpY2ggY2FuIGJlIGNvbnN1bWVkIGJ5IGBfLmZyb21QYWlyc2AuIElmIGBvYmplY3RgIGlzIGEgbWFwXG4gICAgICogb3Igc2V0LCBpdHMgZW50cmllcyBhcmUgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAYWxpYXMgZW50cmllc0luXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8udG9QYWlyc0luKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFtbJ2EnLCAxXSwgWydiJywgMl0sIFsnYycsIDNdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIHZhciB0b1BhaXJzSW4gPSBjcmVhdGVUb1BhaXJzKGtleXNJbik7XG5cbiAgICAvKipcbiAgICAgKiBBbiBhbHRlcm5hdGl2ZSB0byBgXy5yZWR1Y2VgOyB0aGlzIG1ldGhvZCB0cmFuc2Zvcm1zIGBvYmplY3RgIHRvIGEgbmV3XG4gICAgICogYGFjY3VtdWxhdG9yYCBvYmplY3Qgd2hpY2ggaXMgdGhlIHJlc3VsdCBvZiBydW5uaW5nIGVhY2ggb2YgaXRzIG93blxuICAgICAqIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgdGhydSBgaXRlcmF0ZWVgLCB3aXRoIGVhY2ggaW52b2NhdGlvblxuICAgICAqIHBvdGVudGlhbGx5IG11dGF0aW5nIHRoZSBgYWNjdW11bGF0b3JgIG9iamVjdC4gSWYgYGFjY3VtdWxhdG9yYCBpcyBub3RcbiAgICAgKiBwcm92aWRlZCwgYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUgYFtbUHJvdG90eXBlXV1gIHdpbGwgYmUgdXNlZC4gVGhlXG4gICAgICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIGZvdXIgYXJndW1lbnRzOiAoYWNjdW11bGF0b3IsIHZhbHVlLCBrZXksIG9iamVjdCkuXG4gICAgICogSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIFRoZSBjdXN0b20gYWNjdW11bGF0b3IgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRyYW5zZm9ybShbMiwgMywgNF0sIGZ1bmN0aW9uKHJlc3VsdCwgbikge1xuICAgICAqICAgcmVzdWx0LnB1c2gobiAqPSBuKTtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH0sIFtdKTtcbiAgICAgKiAvLyA9PiBbNCwgOV1cbiAgICAgKlxuICAgICAqIF8udHJhbnNmb3JtKHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMSB9LCBmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIChyZXN1bHRbdmFsdWVdIHx8IChyZXN1bHRbdmFsdWVdID0gW10pKS5wdXNoKGtleSk7XG4gICAgICogfSwge30pO1xuICAgICAqIC8vID0+IHsgJzEnOiBbJ2EnLCAnYyddLCAnMic6IFsnYiddIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmFuc2Zvcm0ob2JqZWN0LCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICAgIHZhciBpc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgICAgICBpc0Fyckxpa2UgPSBpc0FyciB8fCBpc0J1ZmZlcihvYmplY3QpIHx8IGlzVHlwZWRBcnJheShvYmplY3QpO1xuXG4gICAgICBpdGVyYXRlZSA9IGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCA0KTtcbiAgICAgIGlmIChhY2N1bXVsYXRvciA9PSBudWxsKSB7XG4gICAgICAgIHZhciBDdG9yID0gb2JqZWN0ICYmIG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgICAgICAgaWYgKGlzQXJyTGlrZSkge1xuICAgICAgICAgIGFjY3VtdWxhdG9yID0gaXNBcnIgPyBuZXcgQ3RvciA6IFtdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgICBhY2N1bXVsYXRvciA9IGlzRnVuY3Rpb24oQ3RvcikgPyBiYXNlQ3JlYXRlKGdldFByb3RvdHlwZShvYmplY3QpKSA6IHt9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGFjY3VtdWxhdG9yID0ge307XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIChpc0Fyckxpa2UgPyBhcnJheUVhY2ggOiBiYXNlRm9yT3duKShvYmplY3QsIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgb2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBpdGVyYXRlZShhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBvYmplY3QpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgcHJvcGVydHkgYXQgYHBhdGhgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gdW5zZXQuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBwcm9wZXJ0eSBpcyBkZWxldGVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogNyB9IH1dIH07XG4gICAgICogXy51bnNldChvYmplY3QsICdhWzBdLmIuYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdCk7XG4gICAgICogLy8gPT4geyAnYSc6IFt7ICdiJzoge30gfV0gfTtcbiAgICAgKlxuICAgICAqIF8udW5zZXQob2JqZWN0LCBbJ2EnLCAnMCcsICdiJywgJ2MnXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogW3sgJ2InOiB7fSB9XSB9O1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuc2V0KG9iamVjdCwgcGF0aCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdHJ1ZSA6IGJhc2VVbnNldChvYmplY3QsIHBhdGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc2V0YCBleGNlcHQgdGhhdCBhY2NlcHRzIGB1cGRhdGVyYCB0byBwcm9kdWNlIHRoZVxuICAgICAqIHZhbHVlIHRvIHNldC4gVXNlIGBfLnVwZGF0ZVdpdGhgIHRvIGN1c3RvbWl6ZSBgcGF0aGAgY3JlYXRpb24uIFRoZSBgdXBkYXRlcmBcbiAgICAgKiBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHVwZGF0ZXIgVGhlIGZ1bmN0aW9uIHRvIHByb2R1Y2UgdGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiAzIH0gfV0gfTtcbiAgICAgKlxuICAgICAqIF8udXBkYXRlKG9iamVjdCwgJ2FbMF0uYi5jJywgZnVuY3Rpb24obikgeyByZXR1cm4gbiAqIG47IH0pO1xuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdC5hWzBdLmIuYyk7XG4gICAgICogLy8gPT4gOVxuICAgICAqXG4gICAgICogXy51cGRhdGUob2JqZWN0LCAneFswXS55LnonLCBmdW5jdGlvbihuKSB7IHJldHVybiBuID8gbiArIDEgOiAwOyB9KTtcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QueFswXS55LnopO1xuICAgICAqIC8vID0+IDBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1cGRhdGUob2JqZWN0LCBwYXRoLCB1cGRhdGVyKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBiYXNlVXBkYXRlKG9iamVjdCwgcGF0aCwgY2FzdEZ1bmN0aW9uKHVwZGF0ZXIpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVwZGF0ZWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY3VzdG9taXplcmAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIHRvIHByb2R1Y2UgdGhlIG9iamVjdHMgb2YgYHBhdGhgLiAgSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGBcbiAgICAgKiBwYXRoIGNyZWF0aW9uIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKG5zVmFsdWUsIGtleSwgbnNPYmplY3QpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHVwZGF0ZXIgVGhlIGZ1bmN0aW9uIHRvIHByb2R1Y2UgdGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7fTtcbiAgICAgKlxuICAgICAqIF8udXBkYXRlV2l0aChvYmplY3QsICdbMF1bMV0nLCBfLmNvbnN0YW50KCdhJyksIE9iamVjdCk7XG4gICAgICogLy8gPT4geyAnMCc6IHsgJzEnOiAnYScgfSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXBkYXRlV2l0aChvYmplY3QsIHBhdGgsIHVwZGF0ZXIsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IG9iamVjdCA6IGJhc2VVcGRhdGUob2JqZWN0LCBwYXRoLCBjYXN0RnVuY3Rpb24odXBkYXRlciksIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0eSB2YWx1ZXMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLnZhbHVlcyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbMSwgMl0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKlxuICAgICAqIF8udmFsdWVzKCdoaScpO1xuICAgICAqIC8vID0+IFsnaCcsICdpJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB2YWx1ZXMob2JqZWN0KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBbXSA6IGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnR5XG4gICAgICogdmFsdWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy52YWx1ZXNJbihuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB2YWx1ZXNJbihvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IFtdIDogYmFzZVZhbHVlcyhvYmplY3QsIGtleXNJbihvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDbGFtcHMgYG51bWJlcmAgd2l0aGluIHRoZSBpbmNsdXNpdmUgYGxvd2VyYCBhbmQgYHVwcGVyYCBib3VuZHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIGNsYW1wLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbG93ZXJdIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXBwZXIgVGhlIHVwcGVyIGJvdW5kLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNsYW1wZWQgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNsYW1wKC0xMCwgLTUsIDUpO1xuICAgICAqIC8vID0+IC01XG4gICAgICpcbiAgICAgKiBfLmNsYW1wKDEwLCAtNSwgNSk7XG4gICAgICogLy8gPT4gNVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsYW1wKG51bWJlciwgbG93ZXIsIHVwcGVyKSB7XG4gICAgICBpZiAodXBwZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB1cHBlciA9IGxvd2VyO1xuICAgICAgICBsb3dlciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmICh1cHBlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHVwcGVyID0gdG9OdW1iZXIodXBwZXIpO1xuICAgICAgICB1cHBlciA9IHVwcGVyID09PSB1cHBlciA/IHVwcGVyIDogMDtcbiAgICAgIH1cbiAgICAgIGlmIChsb3dlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxvd2VyID0gdG9OdW1iZXIobG93ZXIpO1xuICAgICAgICBsb3dlciA9IGxvd2VyID09PSBsb3dlciA/IGxvd2VyIDogMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlQ2xhbXAodG9OdW1iZXIobnVtYmVyKSwgbG93ZXIsIHVwcGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYG5gIGlzIGJldHdlZW4gYHN0YXJ0YCBhbmQgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCBgZW5kYC4gSWZcbiAgICAgKiBgZW5kYCBpcyBub3Qgc3BlY2lmaWVkLCBpdCdzIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuXG4gICAgICogSWYgYHN0YXJ0YCBpcyBncmVhdGVyIHRoYW4gYGVuZGAgdGhlIHBhcmFtcyBhcmUgc3dhcHBlZCB0byBzdXBwb3J0XG4gICAgICogbmVnYXRpdmUgcmFuZ2VzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMy4wXG4gICAgICogQGNhdGVnb3J5IE51bWJlclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG51bWJlcmAgaXMgaW4gdGhlIHJhbmdlLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLnJhbmdlLCBfLnJhbmdlUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDMsIDIsIDQpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSg0LCA4KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoNCwgMik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSgyLCAyKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDEuMiwgMik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDUuMiwgNCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSgtMywgLTIsIC02KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5SYW5nZShudW1iZXIsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHN0YXJ0ID0gdG9GaW5pdGUoc3RhcnQpO1xuICAgICAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVuZCA9IHN0YXJ0O1xuICAgICAgICBzdGFydCA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbmQgPSB0b0Zpbml0ZShlbmQpO1xuICAgICAgfVxuICAgICAgbnVtYmVyID0gdG9OdW1iZXIobnVtYmVyKTtcbiAgICAgIHJldHVybiBiYXNlSW5SYW5nZShudW1iZXIsIHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb2R1Y2VzIGEgcmFuZG9tIG51bWJlciBiZXR3ZWVuIHRoZSBpbmNsdXNpdmUgYGxvd2VyYCBhbmQgYHVwcGVyYCBib3VuZHMuXG4gICAgICogSWYgb25seSBvbmUgYXJndW1lbnQgaXMgcHJvdmlkZWQgYSBudW1iZXIgYmV0d2VlbiBgMGAgYW5kIHRoZSBnaXZlbiBudW1iZXJcbiAgICAgKiBpcyByZXR1cm5lZC4gSWYgYGZsb2F0aW5nYCBpcyBgdHJ1ZWAsIG9yIGVpdGhlciBgbG93ZXJgIG9yIGB1cHBlcmAgYXJlXG4gICAgICogZmxvYXRzLCBhIGZsb2F0aW5nLXBvaW50IG51bWJlciBpcyByZXR1cm5lZCBpbnN0ZWFkIG9mIGFuIGludGVnZXIuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSmF2YVNjcmlwdCBmb2xsb3dzIHRoZSBJRUVFLTc1NCBzdGFuZGFyZCBmb3IgcmVzb2x2aW5nXG4gICAgICogZmxvYXRpbmctcG9pbnQgdmFsdWVzIHdoaWNoIGNhbiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjcuMFxuICAgICAqIEBjYXRlZ29yeSBOdW1iZXJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xvd2VyPTBdIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3VwcGVyPTFdIFRoZSB1cHBlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmbG9hdGluZ10gU3BlY2lmeSByZXR1cm5pbmcgYSBmbG9hdGluZy1wb2ludCBudW1iZXIuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcmFuZG9tIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yYW5kb20oMCwgNSk7XG4gICAgICogLy8gPT4gYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDUpO1xuICAgICAqIC8vID0+IGFsc28gYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDUsIHRydWUpO1xuICAgICAqIC8vID0+IGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyIGJldHdlZW4gMCBhbmQgNVxuICAgICAqXG4gICAgICogXy5yYW5kb20oMS4yLCA1LjIpO1xuICAgICAqIC8vID0+IGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyIGJldHdlZW4gMS4yIGFuZCA1LjJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByYW5kb20obG93ZXIsIHVwcGVyLCBmbG9hdGluZykge1xuICAgICAgaWYgKGZsb2F0aW5nICYmIHR5cGVvZiBmbG9hdGluZyAhPSAnYm9vbGVhbicgJiYgaXNJdGVyYXRlZUNhbGwobG93ZXIsIHVwcGVyLCBmbG9hdGluZykpIHtcbiAgICAgICAgdXBwZXIgPSBmbG9hdGluZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmIChmbG9hdGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdXBwZXIgPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgZmxvYXRpbmcgPSB1cHBlcjtcbiAgICAgICAgICB1cHBlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgbG93ZXIgPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgZmxvYXRpbmcgPSBsb3dlcjtcbiAgICAgICAgICBsb3dlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxvd2VyID09PSB1bmRlZmluZWQgJiYgdXBwZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsb3dlciA9IDA7XG4gICAgICAgIHVwcGVyID0gMTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBsb3dlciA9IHRvRmluaXRlKGxvd2VyKTtcbiAgICAgICAgaWYgKHVwcGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB1cHBlciA9IGxvd2VyO1xuICAgICAgICAgIGxvd2VyID0gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB1cHBlciA9IHRvRmluaXRlKHVwcGVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxvd2VyID4gdXBwZXIpIHtcbiAgICAgICAgdmFyIHRlbXAgPSBsb3dlcjtcbiAgICAgICAgbG93ZXIgPSB1cHBlcjtcbiAgICAgICAgdXBwZXIgPSB0ZW1wO1xuICAgICAgfVxuICAgICAgaWYgKGZsb2F0aW5nIHx8IGxvd2VyICUgMSB8fCB1cHBlciAlIDEpIHtcbiAgICAgICAgdmFyIHJhbmQgPSBuYXRpdmVSYW5kb20oKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZU1pbihsb3dlciArIChyYW5kICogKHVwcGVyIC0gbG93ZXIgKyBmcmVlUGFyc2VGbG9hdCgnMWUtJyArICgocmFuZCArICcnKS5sZW5ndGggLSAxKSkpKSwgdXBwZXIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VSYW5kb20obG93ZXIsIHVwcGVyKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBbY2FtZWwgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ2FtZWxDYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNhbWVsIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYW1lbENhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vQmFyJ1xuICAgICAqXG4gICAgICogXy5jYW1lbENhc2UoJy0tZm9vLWJhci0tJyk7XG4gICAgICogLy8gPT4gJ2Zvb0JhcidcbiAgICAgKlxuICAgICAqIF8uY2FtZWxDYXNlKCdfX0ZPT19CQVJfXycpO1xuICAgICAqIC8vID0+ICdmb29CYXInXG4gICAgICovXG4gICAgdmFyIGNhbWVsQ2FzZSA9IGNyZWF0ZUNvbXBvdW5kZXIoZnVuY3Rpb24ocmVzdWx0LCB3b3JkLCBpbmRleCkge1xuICAgICAgd29yZCA9IHdvcmQudG9Mb3dlckNhc2UoKTtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyBjYXBpdGFsaXplKHdvcmQpIDogd29yZCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIGBzdHJpbmdgIHRvIHVwcGVyIGNhc2UgYW5kIHRoZSByZW1haW5pbmdcbiAgICAgKiB0byBsb3dlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY2FwaXRhbGl6ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNhcGl0YWxpemUoJ0ZSRUQnKTtcbiAgICAgKiAvLyA9PiAnRnJlZCdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgICAgcmV0dXJuIHVwcGVyRmlyc3QodG9TdHJpbmcoc3RyaW5nKS50b0xvd2VyQ2FzZSgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWJ1cnJzIGBzdHJpbmdgIGJ5IGNvbnZlcnRpbmdcbiAgICAgKiBbTGF0aW4tMSBTdXBwbGVtZW50XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYXRpbi0xX1N1cHBsZW1lbnRfKFVuaWNvZGVfYmxvY2spI0NoYXJhY3Rlcl90YWJsZSlcbiAgICAgKiBhbmQgW0xhdGluIEV4dGVuZGVkLUFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xhdGluX0V4dGVuZGVkLUEpXG4gICAgICogbGV0dGVycyB0byBiYXNpYyBMYXRpbiBsZXR0ZXJzIGFuZCByZW1vdmluZ1xuICAgICAqIFtjb21iaW5pbmcgZGlhY3JpdGljYWwgbWFya3NdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrcykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gZGVidXJyLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGRlYnVycmVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWJ1cnIoJ2TDqWrDoCB2dScpO1xuICAgICAqIC8vID0+ICdkZWphIHZ1J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRlYnVycihzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICByZXR1cm4gc3RyaW5nICYmIHN0cmluZy5yZXBsYWNlKHJlTGF0aW4sIGRlYnVyckxldHRlcikucmVwbGFjZShyZUNvbWJvTWFyaywgJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgc3RyaW5nYCBlbmRzIHdpdGggdGhlIGdpdmVuIHRhcmdldCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3RhcmdldF0gVGhlIHN0cmluZyB0byBzZWFyY2ggZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcG9zaXRpb249c3RyaW5nLmxlbmd0aF0gVGhlIHBvc2l0aW9uIHRvIHNlYXJjaCB1cCB0by5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHN0cmluZ2AgZW5kcyB3aXRoIGB0YXJnZXRgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZW5kc1dpdGgoJ2FiYycsICdjJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5lbmRzV2l0aCgnYWJjJywgJ2InKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5lbmRzV2l0aCgnYWJjJywgJ2InLCAyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZW5kc1dpdGgoc3RyaW5nLCB0YXJnZXQsIHBvc2l0aW9uKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgdGFyZ2V0ID0gYmFzZVRvU3RyaW5nKHRhcmdldCk7XG5cbiAgICAgIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbiA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gbGVuZ3RoXG4gICAgICAgIDogYmFzZUNsYW1wKHRvSW50ZWdlcihwb3NpdGlvbiksIDAsIGxlbmd0aCk7XG5cbiAgICAgIHZhciBlbmQgPSBwb3NpdGlvbjtcbiAgICAgIHBvc2l0aW9uIC09IHRhcmdldC5sZW5ndGg7XG4gICAgICByZXR1cm4gcG9zaXRpb24gPj0gMCAmJiBzdHJpbmcuc2xpY2UocG9zaXRpb24sIGVuZCkgPT0gdGFyZ2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoZSBjaGFyYWN0ZXJzIFwiJlwiLCBcIjxcIiwgXCI+XCIsICdcIicsIGFuZCBcIidcIiBpbiBgc3RyaW5nYCB0byB0aGVpclxuICAgICAqIGNvcnJlc3BvbmRpbmcgSFRNTCBlbnRpdGllcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBObyBvdGhlciBjaGFyYWN0ZXJzIGFyZSBlc2NhcGVkLiBUbyBlc2NhcGUgYWRkaXRpb25hbFxuICAgICAqIGNoYXJhY3RlcnMgdXNlIGEgdGhpcmQtcGFydHkgbGlicmFyeSBsaWtlIFtfaGVfXShodHRwczovL210aHMuYmUvaGUpLlxuICAgICAqXG4gICAgICogVGhvdWdoIHRoZSBcIj5cIiBjaGFyYWN0ZXIgaXMgZXNjYXBlZCBmb3Igc3ltbWV0cnksIGNoYXJhY3RlcnMgbGlrZVxuICAgICAqIFwiPlwiIGFuZCBcIi9cIiBkb24ndCBuZWVkIGVzY2FwaW5nIGluIEhUTUwgYW5kIGhhdmUgbm8gc3BlY2lhbCBtZWFuaW5nXG4gICAgICogdW5sZXNzIHRoZXkncmUgcGFydCBvZiBhIHRhZyBvciB1bnF1b3RlZCBhdHRyaWJ1dGUgdmFsdWUuIFNlZVxuICAgICAqIFtNYXRoaWFzIEJ5bmVucydzIGFydGljbGVdKGh0dHBzOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9hbWJpZ3VvdXMtYW1wZXJzYW5kcylcbiAgICAgKiAodW5kZXIgXCJzZW1pLXJlbGF0ZWQgZnVuIGZhY3RcIikgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIFdoZW4gd29ya2luZyB3aXRoIEhUTUwgeW91IHNob3VsZCBhbHdheXNcbiAgICAgKiBbcXVvdGUgYXR0cmlidXRlIHZhbHVlc10oaHR0cDovL3dvbmtvLmNvbS9wb3N0L2h0bWwtZXNjYXBpbmcpIHRvIHJlZHVjZVxuICAgICAqIFhTUyB2ZWN0b3JzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGVzY2FwZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5lc2NhcGUoJ2ZyZWQsIGJhcm5leSwgJiBwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlc2NhcGUoc3RyaW5nKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgcmV0dXJuIChzdHJpbmcgJiYgcmVIYXNVbmVzY2FwZWRIdG1sLnRlc3Qoc3RyaW5nKSlcbiAgICAgICAgPyBzdHJpbmcucmVwbGFjZShyZVVuZXNjYXBlZEh0bWwsIGVzY2FwZUh0bWxDaGFyKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFc2NhcGVzIHRoZSBgUmVnRXhwYCBzcGVjaWFsIGNoYXJhY3RlcnMgXCJeXCIsIFwiJFwiLCBcIlxcXCIsIFwiLlwiLCBcIipcIiwgXCIrXCIsXG4gICAgICogXCI/XCIsIFwiKFwiLCBcIilcIiwgXCJbXCIsIFwiXVwiLCBcIntcIiwgXCJ9XCIsIGFuZCBcInxcIiBpbiBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBlc2NhcGUuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZXNjYXBlUmVnRXhwKCdbbG9kYXNoXShodHRwczovL2xvZGFzaC5jb20vKScpO1xuICAgICAqIC8vID0+ICdcXFtsb2Rhc2hcXF1cXChodHRwczovL2xvZGFzaFxcLmNvbS9cXCknXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHN0cmluZykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHJldHVybiAoc3RyaW5nICYmIHJlSGFzUmVnRXhwQ2hhci50ZXN0KHN0cmluZykpXG4gICAgICAgID8gc3RyaW5nLnJlcGxhY2UocmVSZWdFeHBDaGFyLCAnXFxcXCQmJylcbiAgICAgICAgOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG9cbiAgICAgKiBba2ViYWIgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV0dGVyX2Nhc2UjU3BlY2lhbF9jYXNlX3N0eWxlcykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBrZWJhYiBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ua2ViYWJDYXNlKCdGb28gQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvby1iYXInXG4gICAgICpcbiAgICAgKiBfLmtlYmFiQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvby1iYXInXG4gICAgICpcbiAgICAgKiBfLmtlYmFiQ2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnZm9vLWJhcidcbiAgICAgKi9cbiAgICB2YXIga2ViYWJDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJy0nIDogJycpICsgd29yZC50b0xvd2VyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AsIGFzIHNwYWNlIHNlcGFyYXRlZCB3b3JkcywgdG8gbG93ZXIgY2FzZS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGxvd2VyIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sb3dlckNhc2UoJy0tRm9vLUJhci0tJyk7XG4gICAgICogLy8gPT4gJ2ZvbyBiYXInXG4gICAgICpcbiAgICAgKiBfLmxvd2VyQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ2ZvbyBiYXInXG4gICAgICpcbiAgICAgKiBfLmxvd2VyQ2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnZm9vIGJhcidcbiAgICAgKi9cbiAgICB2YXIgbG93ZXJDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJyAnIDogJycpICsgd29yZC50b0xvd2VyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBgc3RyaW5nYCB0byBsb3dlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sb3dlckZpcnN0KCdGcmVkJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQnXG4gICAgICpcbiAgICAgKiBfLmxvd2VyRmlyc3QoJ0ZSRUQnKTtcbiAgICAgKiAvLyA9PiAnZlJFRCdcbiAgICAgKi9cbiAgICB2YXIgbG93ZXJGaXJzdCA9IGNyZWF0ZUNhc2VGaXJzdCgndG9Mb3dlckNhc2UnKTtcblxuICAgIC8qKlxuICAgICAqIFBhZHMgYHN0cmluZ2Agb24gdGhlIGxlZnQgYW5kIHJpZ2h0IHNpZGVzIGlmIGl0J3Mgc2hvcnRlciB0aGFuIGBsZW5ndGhgLlxuICAgICAqIFBhZGRpbmcgY2hhcmFjdGVycyBhcmUgdHJ1bmNhdGVkIGlmIHRoZXkgY2FuJ3QgYmUgZXZlbmx5IGRpdmlkZWQgYnkgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcGFkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPTBdIFRoZSBwYWRkaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPScgJ10gVGhlIHN0cmluZyB1c2VkIGFzIHBhZGRpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcGFkZGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYWQoJ2FiYycsIDgpO1xuICAgICAqIC8vID0+ICcgIGFiYyAgICdcbiAgICAgKlxuICAgICAqIF8ucGFkKCdhYmMnLCA4LCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnXy1hYmNfLV8nXG4gICAgICpcbiAgICAgKiBfLnBhZCgnYWJjJywgMyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYWQoc3RyaW5nLCBsZW5ndGgsIGNoYXJzKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgbGVuZ3RoID0gdG9JbnRlZ2VyKGxlbmd0aCk7XG5cbiAgICAgIHZhciBzdHJMZW5ndGggPSBsZW5ndGggPyBzdHJpbmdTaXplKHN0cmluZykgOiAwO1xuICAgICAgaWYgKCFsZW5ndGggfHwgc3RyTGVuZ3RoID49IGxlbmd0aCkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIG1pZCA9IChsZW5ndGggLSBzdHJMZW5ndGgpIC8gMjtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIGNyZWF0ZVBhZGRpbmcobmF0aXZlRmxvb3IobWlkKSwgY2hhcnMpICtcbiAgICAgICAgc3RyaW5nICtcbiAgICAgICAgY3JlYXRlUGFkZGluZyhuYXRpdmVDZWlsKG1pZCksIGNoYXJzKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSByaWdodCBzaWRlIGlmIGl0J3Mgc2hvcnRlciB0aGFuIGBsZW5ndGhgLiBQYWRkaW5nXG4gICAgICogY2hhcmFjdGVycyBhcmUgdHJ1bmNhdGVkIGlmIHRoZXkgZXhjZWVkIGBsZW5ndGhgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHBhZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD0wXSBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucGFkRW5kKCdhYmMnLCA2KTtcbiAgICAgKiAvLyA9PiAnYWJjICAgJ1xuICAgICAqXG4gICAgICogXy5wYWRFbmQoJ2FiYycsIDYsICdfLScpO1xuICAgICAqIC8vID0+ICdhYmNfLV8nXG4gICAgICpcbiAgICAgKiBfLnBhZEVuZCgnYWJjJywgMyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYWRFbmQoc3RyaW5nLCBsZW5ndGgsIGNoYXJzKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgbGVuZ3RoID0gdG9JbnRlZ2VyKGxlbmd0aCk7XG5cbiAgICAgIHZhciBzdHJMZW5ndGggPSBsZW5ndGggPyBzdHJpbmdTaXplKHN0cmluZykgOiAwO1xuICAgICAgcmV0dXJuIChsZW5ndGggJiYgc3RyTGVuZ3RoIDwgbGVuZ3RoKVxuICAgICAgICA/IChzdHJpbmcgKyBjcmVhdGVQYWRkaW5nKGxlbmd0aCAtIHN0ckxlbmd0aCwgY2hhcnMpKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSBsZWZ0IHNpZGUgaWYgaXQncyBzaG9ydGVyIHRoYW4gYGxlbmd0aGAuIFBhZGRpbmdcbiAgICAgKiBjaGFyYWN0ZXJzIGFyZSB0cnVuY2F0ZWQgaWYgdGhleSBleGNlZWQgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcGFkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPTBdIFRoZSBwYWRkaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPScgJ10gVGhlIHN0cmluZyB1c2VkIGFzIHBhZGRpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcGFkZGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYWRTdGFydCgnYWJjJywgNik7XG4gICAgICogLy8gPT4gJyAgIGFiYydcbiAgICAgKlxuICAgICAqIF8ucGFkU3RhcnQoJ2FiYycsIDYsICdfLScpO1xuICAgICAqIC8vID0+ICdfLV9hYmMnXG4gICAgICpcbiAgICAgKiBfLnBhZFN0YXJ0KCdhYmMnLCAzKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBhZFN0YXJ0KHN0cmluZywgbGVuZ3RoLCBjaGFycykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGxlbmd0aCA9IHRvSW50ZWdlcihsZW5ndGgpO1xuXG4gICAgICB2YXIgc3RyTGVuZ3RoID0gbGVuZ3RoID8gc3RyaW5nU2l6ZShzdHJpbmcpIDogMDtcbiAgICAgIHJldHVybiAobGVuZ3RoICYmIHN0ckxlbmd0aCA8IGxlbmd0aClcbiAgICAgICAgPyAoY3JlYXRlUGFkZGluZyhsZW5ndGggLSBzdHJMZW5ndGgsIGNoYXJzKSArIHN0cmluZylcbiAgICAgICAgOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG8gYW4gaW50ZWdlciBvZiB0aGUgc3BlY2lmaWVkIHJhZGl4LiBJZiBgcmFkaXhgIGlzXG4gICAgICogYHVuZGVmaW5lZGAgb3IgYDBgLCBhIGByYWRpeGAgb2YgYDEwYCBpcyB1c2VkIHVubGVzcyBgdmFsdWVgIGlzIGFcbiAgICAgKiBoZXhhZGVjaW1hbCwgaW4gd2hpY2ggY2FzZSBhIGByYWRpeGAgb2YgYDE2YCBpcyB1c2VkLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGFsaWducyB3aXRoIHRoZVxuICAgICAqIFtFUzUgaW1wbGVtZW50YXRpb25dKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEuMi4yKSBvZiBgcGFyc2VJbnRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMS4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcmFkaXg9MTBdIFRoZSByYWRpeCB0byBpbnRlcnByZXQgYHZhbHVlYCBieS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBpbnRlZ2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnBhcnNlSW50KCcwOCcpO1xuICAgICAqIC8vID0+IDhcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnNicsICcwOCcsICcxMCddLCBfLnBhcnNlSW50KTtcbiAgICAgKiAvLyA9PiBbNiwgOCwgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGFyc2VJbnQoc3RyaW5nLCByYWRpeCwgZ3VhcmQpIHtcbiAgICAgIGlmIChndWFyZCB8fCByYWRpeCA9PSBudWxsKSB7XG4gICAgICAgIHJhZGl4ID0gMDtcbiAgICAgIH0gZWxzZSBpZiAocmFkaXgpIHtcbiAgICAgICAgcmFkaXggPSArcmFkaXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmF0aXZlUGFyc2VJbnQodG9TdHJpbmcoc3RyaW5nKS5yZXBsYWNlKHJlVHJpbVN0YXJ0LCAnJyksIHJhZGl4IHx8IDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcGVhdHMgdGhlIGdpdmVuIHN0cmluZyBgbmAgdGltZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcmVwZWF0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdCB0aGUgc3RyaW5nLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcmVwZWF0ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJlcGVhdCgnKicsIDMpO1xuICAgICAqIC8vID0+ICcqKionXG4gICAgICpcbiAgICAgKiBfLnJlcGVhdCgnYWJjJywgMik7XG4gICAgICogLy8gPT4gJ2FiY2FiYydcbiAgICAgKlxuICAgICAqIF8ucmVwZWF0KCdhYmMnLCAwKTtcbiAgICAgKiAvLyA9PiAnJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlcGVhdChzdHJpbmcsIG4sIGd1YXJkKSB7XG4gICAgICBpZiAoKGd1YXJkID8gaXNJdGVyYXRlZUNhbGwoc3RyaW5nLCBuLCBndWFyZCkgOiBuID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIG4gPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlUmVwZWF0KHRvU3RyaW5nKHN0cmluZyksIG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcGxhY2VzIG1hdGNoZXMgZm9yIGBwYXR0ZXJuYCBpbiBgc3RyaW5nYCB3aXRoIGByZXBsYWNlbWVudGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYFN0cmluZyNyZXBsYWNlYF0oaHR0cHM6Ly9tZG4uaW8vU3RyaW5nL3JlcGxhY2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cHxzdHJpbmd9IHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gcmVwbGFjZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gcmVwbGFjZW1lbnQgVGhlIG1hdGNoIHJlcGxhY2VtZW50LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIG1vZGlmaWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yZXBsYWNlKCdIaSBGcmVkJywgJ0ZyZWQnLCAnQmFybmV5Jyk7XG4gICAgICogLy8gPT4gJ0hpIEJhcm5leSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXBsYWNlKCkge1xuICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgc3RyaW5nID0gdG9TdHJpbmcoYXJnc1swXSk7XG5cbiAgICAgIHJldHVybiBhcmdzLmxlbmd0aCA8IDMgPyBzdHJpbmcgOiBzdHJpbmcucmVwbGFjZShhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0b1xuICAgICAqIFtzbmFrZSBjYXNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TbmFrZV9jYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHNuYWtlIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zbmFrZUNhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKlxuICAgICAqIF8uc25ha2VDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKlxuICAgICAqIF8uc25ha2VDYXNlKCctLUZPTy1CQVItLScpO1xuICAgICAqIC8vID0+ICdmb29fYmFyJ1xuICAgICAqL1xuICAgIHZhciBzbmFrZUNhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnXycgOiAnJykgKyB3b3JkLnRvTG93ZXJDYXNlKCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBTcGxpdHMgYHN0cmluZ2AgYnkgYHNlcGFyYXRvcmAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYFN0cmluZyNzcGxpdGBdKGh0dHBzOi8vbWRuLmlvL1N0cmluZy9zcGxpdCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gc3BsaXQuXG4gICAgICogQHBhcmFtIHtSZWdFeHB8c3RyaW5nfSBzZXBhcmF0b3IgVGhlIHNlcGFyYXRvciBwYXR0ZXJuIHRvIHNwbGl0IGJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGltaXRdIFRoZSBsZW5ndGggdG8gdHJ1bmNhdGUgcmVzdWx0cyB0by5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHN0cmluZyBzZWdtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zcGxpdCgnYS1iLWMnLCAnLScsIDIpO1xuICAgICAqIC8vID0+IFsnYScsICdiJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcsIHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIGlmIChsaW1pdCAmJiB0eXBlb2YgbGltaXQgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoc3RyaW5nLCBzZXBhcmF0b3IsIGxpbWl0KSkge1xuICAgICAgICBzZXBhcmF0b3IgPSBsaW1pdCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGxpbWl0ID0gbGltaXQgPT09IHVuZGVmaW5lZCA/IE1BWF9BUlJBWV9MRU5HVEggOiBsaW1pdCA+Pj4gMDtcbiAgICAgIGlmICghbGltaXQpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGlmIChzdHJpbmcgJiYgKFxuICAgICAgICAgICAgdHlwZW9mIHNlcGFyYXRvciA9PSAnc3RyaW5nJyB8fFxuICAgICAgICAgICAgKHNlcGFyYXRvciAhPSBudWxsICYmICFpc1JlZ0V4cChzZXBhcmF0b3IpKVxuICAgICAgICAgICkpIHtcbiAgICAgICAgc2VwYXJhdG9yID0gYmFzZVRvU3RyaW5nKHNlcGFyYXRvcik7XG4gICAgICAgIGlmICghc2VwYXJhdG9yICYmIGhhc1VuaWNvZGUoc3RyaW5nKSkge1xuICAgICAgICAgIHJldHVybiBjYXN0U2xpY2Uoc3RyaW5nVG9BcnJheShzdHJpbmcpLCAwLCBsaW1pdCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBzdHJpbmcuc3BsaXQoc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG9cbiAgICAgKiBbc3RhcnQgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV0dGVyX2Nhc2UjU3R5bGlzdGljX29yX3NwZWNpYWxpc2VkX3VzYWdlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0YXJ0IGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zdGFydENhc2UoJy0tZm9vLWJhci0tJyk7XG4gICAgICogLy8gPT4gJ0ZvbyBCYXInXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0Q2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ0ZvbyBCYXInXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0Q2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKi9cbiAgICB2YXIgc3RhcnRDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJyAnIDogJycpICsgdXBwZXJGaXJzdCh3b3JkKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgc3RyaW5nYCBzdGFydHMgd2l0aCB0aGUgZ2l2ZW4gdGFyZ2V0IHN0cmluZy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdGFyZ2V0XSBUaGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtwb3NpdGlvbj0wXSBUaGUgcG9zaXRpb24gdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBzdHJpbmdgIHN0YXJ0cyB3aXRoIGB0YXJnZXRgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3RhcnRzV2l0aCgnYWJjJywgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0c1dpdGgoJ2FiYycsICdiJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uc3RhcnRzV2l0aCgnYWJjJywgJ2InLCAxKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhcnRzV2l0aChzdHJpbmcsIHRhcmdldCwgcG9zaXRpb24pIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uID09IG51bGxcbiAgICAgICAgPyAwXG4gICAgICAgIDogYmFzZUNsYW1wKHRvSW50ZWdlcihwb3NpdGlvbiksIDAsIHN0cmluZy5sZW5ndGgpO1xuXG4gICAgICB0YXJnZXQgPSBiYXNlVG9TdHJpbmcodGFyZ2V0KTtcbiAgICAgIHJldHVybiBzdHJpbmcuc2xpY2UocG9zaXRpb24sIHBvc2l0aW9uICsgdGFyZ2V0Lmxlbmd0aCkgPT0gdGFyZ2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjb21waWxlZCB0ZW1wbGF0ZSBmdW5jdGlvbiB0aGF0IGNhbiBpbnRlcnBvbGF0ZSBkYXRhIHByb3BlcnRpZXNcbiAgICAgKiBpbiBcImludGVycG9sYXRlXCIgZGVsaW1pdGVycywgSFRNTC1lc2NhcGUgaW50ZXJwb2xhdGVkIGRhdGEgcHJvcGVydGllcyBpblxuICAgICAqIFwiZXNjYXBlXCIgZGVsaW1pdGVycywgYW5kIGV4ZWN1dGUgSmF2YVNjcmlwdCBpbiBcImV2YWx1YXRlXCIgZGVsaW1pdGVycy4gRGF0YVxuICAgICAqIHByb3BlcnRpZXMgbWF5IGJlIGFjY2Vzc2VkIGFzIGZyZWUgdmFyaWFibGVzIGluIHRoZSB0ZW1wbGF0ZS4gSWYgYSBzZXR0aW5nXG4gICAgICogb2JqZWN0IGlzIGdpdmVuLCBpdCB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgYF8udGVtcGxhdGVTZXR0aW5nc2AgdmFsdWVzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIEluIHRoZSBkZXZlbG9wbWVudCBidWlsZCBgXy50ZW1wbGF0ZWAgdXRpbGl6ZXNcbiAgICAgKiBbc291cmNlVVJMc10oaHR0cDovL3d3dy5odG1sNXJvY2tzLmNvbS9lbi90dXRvcmlhbHMvZGV2ZWxvcGVydG9vbHMvc291cmNlbWFwcy8jdG9jLXNvdXJjZXVybClcbiAgICAgKiBmb3IgZWFzaWVyIGRlYnVnZ2luZy5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHByZWNvbXBpbGluZyB0ZW1wbGF0ZXMgc2VlXG4gICAgICogW2xvZGFzaCdzIGN1c3RvbSBidWlsZHMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9sb2Rhc2guY29tL2N1c3RvbS1idWlsZHMpLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gQ2hyb21lIGV4dGVuc2lvbiBzYW5kYm94ZXMgc2VlXG4gICAgICogW0Nocm9tZSdzIGV4dGVuc2lvbnMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9kZXZlbG9wZXIuY2hyb21lLmNvbS9leHRlbnNpb25zL3NhbmRib3hpbmdFdmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHRlbXBsYXRlIHN0cmluZy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cH0gW29wdGlvbnMuZXNjYXBlPV8udGVtcGxhdGVTZXR0aW5ncy5lc2NhcGVdXG4gICAgICogIFRoZSBIVE1MIFwiZXNjYXBlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBbb3B0aW9ucy5ldmFsdWF0ZT1fLnRlbXBsYXRlU2V0dGluZ3MuZXZhbHVhdGVdXG4gICAgICogIFRoZSBcImV2YWx1YXRlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5pbXBvcnRzPV8udGVtcGxhdGVTZXR0aW5ncy5pbXBvcnRzXVxuICAgICAqICBBbiBvYmplY3QgdG8gaW1wb3J0IGludG8gdGhlIHRlbXBsYXRlIGFzIGZyZWUgdmFyaWFibGVzLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBbb3B0aW9ucy5pbnRlcnBvbGF0ZT1fLnRlbXBsYXRlU2V0dGluZ3MuaW50ZXJwb2xhdGVdXG4gICAgICogIFRoZSBcImludGVycG9sYXRlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5zb3VyY2VVUkw9J2xvZGFzaC50ZW1wbGF0ZVNvdXJjZXNbbl0nXVxuICAgICAqICBUaGUgc291cmNlVVJMIG9mIHRoZSBjb21waWxlZCB0ZW1wbGF0ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMudmFyaWFibGU9J29iaiddXG4gICAgICogIFRoZSBkYXRhIG9iamVjdCB2YXJpYWJsZSBuYW1lLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjb21waWxlZCB0ZW1wbGF0ZSBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBcImludGVycG9sYXRlXCIgZGVsaW1pdGVyIHRvIGNyZWF0ZSBhIGNvbXBpbGVkIHRlbXBsYXRlLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hlbGxvIDwlPSB1c2VyICU+IScpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXInOiAnZnJlZCcgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGZyZWQhJ1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBIVE1MIFwiZXNjYXBlXCIgZGVsaW1pdGVyIHRvIGVzY2FwZSBkYXRhIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCc8Yj48JS0gdmFsdWUgJT48L2I+Jyk7XG4gICAgICogY29tcGlsZWQoeyAndmFsdWUnOiAnPHNjcmlwdD4nIH0pO1xuICAgICAqIC8vID0+ICc8Yj4mbHQ7c2NyaXB0Jmd0OzwvYj4nXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIFwiZXZhbHVhdGVcIiBkZWxpbWl0ZXIgdG8gZXhlY3V0ZSBKYXZhU2NyaXB0IGFuZCBnZW5lcmF0ZSBIVE1MLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlIF8uZm9yRWFjaCh1c2VycywgZnVuY3Rpb24odXNlcikgeyAlPjxsaT48JS0gdXNlciAlPjwvbGk+PCUgfSk7ICU+Jyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcnMnOiBbJ2ZyZWQnLCAnYmFybmV5J10gfSk7XG4gICAgICogLy8gPT4gJzxsaT5mcmVkPC9saT48bGk+YmFybmV5PC9saT4nXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGludGVybmFsIGBwcmludGAgZnVuY3Rpb24gaW4gXCJldmFsdWF0ZVwiIGRlbGltaXRlcnMuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnPCUgcHJpbnQoXCJoZWxsbyBcIiArIHVzZXIpOyAlPiEnKTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2VyJzogJ2Jhcm5leScgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGJhcm5leSEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIEVTIHRlbXBsYXRlIGxpdGVyYWwgZGVsaW1pdGVyIGFzIGFuIFwiaW50ZXJwb2xhdGVcIiBkZWxpbWl0ZXIuXG4gICAgICogLy8gRGlzYWJsZSBzdXBwb3J0IGJ5IHJlcGxhY2luZyB0aGUgXCJpbnRlcnBvbGF0ZVwiIGRlbGltaXRlci5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyAkeyB1c2VyIH0hJyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcic6ICdwZWJibGVzJyB9KTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gcGViYmxlcyEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgYmFja3NsYXNoZXMgdG8gdHJlYXQgZGVsaW1pdGVycyBhcyBwbGFpbiB0ZXh0LlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlPSBcIlxcXFw8JS0gdmFsdWUgJVxcXFw+XCIgJT4nKTtcbiAgICAgKiBjb21waWxlZCh7ICd2YWx1ZSc6ICdpZ25vcmVkJyB9KTtcbiAgICAgKiAvLyA9PiAnPCUtIHZhbHVlICU+J1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBgaW1wb3J0c2Agb3B0aW9uIHRvIGltcG9ydCBgalF1ZXJ5YCBhcyBganFgLlxuICAgICAqIHZhciB0ZXh0ID0gJzwlIGpxLmVhY2godXNlcnMsIGZ1bmN0aW9uKHVzZXIpIHsgJT48bGk+PCUtIHVzZXIgJT48L2xpPjwlIH0pOyAlPic7XG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSh0ZXh0LCB7ICdpbXBvcnRzJzogeyAnanEnOiBqUXVlcnkgfSB9KTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2Vycyc6IFsnZnJlZCcsICdiYXJuZXknXSB9KTtcbiAgICAgKiAvLyA9PiAnPGxpPmZyZWQ8L2xpPjxsaT5iYXJuZXk8L2xpPidcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgYHNvdXJjZVVSTGAgb3B0aW9uIHRvIHNwZWNpZnkgYSBjdXN0b20gc291cmNlVVJMIGZvciB0aGUgdGVtcGxhdGUuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnaGVsbG8gPCU9IHVzZXIgJT4hJywgeyAnc291cmNlVVJMJzogJy9iYXNpYy9ncmVldGluZy5qc3QnIH0pO1xuICAgICAqIGNvbXBpbGVkKGRhdGEpO1xuICAgICAqIC8vID0+IEZpbmQgdGhlIHNvdXJjZSBvZiBcImdyZWV0aW5nLmpzdFwiIHVuZGVyIHRoZSBTb3VyY2VzIHRhYiBvciBSZXNvdXJjZXMgcGFuZWwgb2YgdGhlIHdlYiBpbnNwZWN0b3IuXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGB2YXJpYWJsZWAgb3B0aW9uIHRvIGVuc3VyZSBhIHdpdGgtc3RhdGVtZW50IGlzbid0IHVzZWQgaW4gdGhlIGNvbXBpbGVkIHRlbXBsYXRlLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hpIDwlPSBkYXRhLnVzZXIgJT4hJywgeyAndmFyaWFibGUnOiAnZGF0YScgfSk7XG4gICAgICogY29tcGlsZWQuc291cmNlO1xuICAgICAqIC8vID0+IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgKiAvLyAgIHZhciBfX3QsIF9fcCA9ICcnO1xuICAgICAqIC8vICAgX19wICs9ICdoaSAnICsgKChfX3QgPSAoIGRhdGEudXNlciApKSA9PSBudWxsID8gJycgOiBfX3QpICsgJyEnO1xuICAgICAqIC8vICAgcmV0dXJuIF9fcDtcbiAgICAgKiAvLyB9XG4gICAgICpcbiAgICAgKiAvLyBVc2UgY3VzdG9tIHRlbXBsYXRlIGRlbGltaXRlcnMuXG4gICAgICogXy50ZW1wbGF0ZVNldHRpbmdzLmludGVycG9sYXRlID0gL3t7KFtcXHNcXFNdKz8pfX0vZztcbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyB7eyB1c2VyIH19IScpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXInOiAnbXVzdGFjaGUnIH0pO1xuICAgICAqIC8vID0+ICdoZWxsbyBtdXN0YWNoZSEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGBzb3VyY2VgIHByb3BlcnR5IHRvIGlubGluZSBjb21waWxlZCB0ZW1wbGF0ZXMgZm9yIG1lYW5pbmdmdWxcbiAgICAgKiAvLyBsaW5lIG51bWJlcnMgaW4gZXJyb3IgbWVzc2FnZXMgYW5kIHN0YWNrIHRyYWNlcy5cbiAgICAgKiBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnanN0LmpzJyksICdcXFxuICAgICAqICAgdmFyIEpTVCA9IHtcXFxuICAgICAqICAgICBcIm1haW5cIjogJyArIF8udGVtcGxhdGUobWFpblRleHQpLnNvdXJjZSArICdcXFxuICAgICAqICAgfTtcXFxuICAgICAqICcpO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRlbXBsYXRlKHN0cmluZywgb3B0aW9ucywgZ3VhcmQpIHtcbiAgICAgIC8vIEJhc2VkIG9uIEpvaG4gUmVzaWcncyBgdG1wbGAgaW1wbGVtZW50YXRpb25cbiAgICAgIC8vIChodHRwOi8vZWpvaG4ub3JnL2Jsb2cvamF2YXNjcmlwdC1taWNyby10ZW1wbGF0aW5nLylcbiAgICAgIC8vIGFuZCBMYXVyYSBEb2t0b3JvdmEncyBkb1QuanMgKGh0dHBzOi8vZ2l0aHViLmNvbS9vbGFkby9kb1QpLlxuICAgICAgdmFyIHNldHRpbmdzID0gbG9kYXNoLnRlbXBsYXRlU2V0dGluZ3M7XG5cbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzdHJpbmcsIG9wdGlvbnMsIGd1YXJkKSkge1xuICAgICAgICBvcHRpb25zID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIG9wdGlvbnMgPSBhc3NpZ25JbldpdGgoe30sIG9wdGlvbnMsIHNldHRpbmdzLCBjdXN0b21EZWZhdWx0c0Fzc2lnbkluKTtcblxuICAgICAgdmFyIGltcG9ydHMgPSBhc3NpZ25JbldpdGgoe30sIG9wdGlvbnMuaW1wb3J0cywgc2V0dGluZ3MuaW1wb3J0cywgY3VzdG9tRGVmYXVsdHNBc3NpZ25JbiksXG4gICAgICAgICAgaW1wb3J0c0tleXMgPSBrZXlzKGltcG9ydHMpLFxuICAgICAgICAgIGltcG9ydHNWYWx1ZXMgPSBiYXNlVmFsdWVzKGltcG9ydHMsIGltcG9ydHNLZXlzKTtcblxuICAgICAgdmFyIGlzRXNjYXBpbmcsXG4gICAgICAgICAgaXNFdmFsdWF0aW5nLFxuICAgICAgICAgIGluZGV4ID0gMCxcbiAgICAgICAgICBpbnRlcnBvbGF0ZSA9IG9wdGlvbnMuaW50ZXJwb2xhdGUgfHwgcmVOb01hdGNoLFxuICAgICAgICAgIHNvdXJjZSA9IFwiX19wICs9ICdcIjtcblxuICAgICAgLy8gQ29tcGlsZSB0aGUgcmVnZXhwIHRvIG1hdGNoIGVhY2ggZGVsaW1pdGVyLlxuICAgICAgdmFyIHJlRGVsaW1pdGVycyA9IFJlZ0V4cChcbiAgICAgICAgKG9wdGlvbnMuZXNjYXBlIHx8IHJlTm9NYXRjaCkuc291cmNlICsgJ3wnICtcbiAgICAgICAgaW50ZXJwb2xhdGUuc291cmNlICsgJ3wnICtcbiAgICAgICAgKGludGVycG9sYXRlID09PSByZUludGVycG9sYXRlID8gcmVFc1RlbXBsYXRlIDogcmVOb01hdGNoKS5zb3VyY2UgKyAnfCcgK1xuICAgICAgICAob3B0aW9ucy5ldmFsdWF0ZSB8fCByZU5vTWF0Y2gpLnNvdXJjZSArICd8JCdcbiAgICAgICwgJ2cnKTtcblxuICAgICAgLy8gVXNlIGEgc291cmNlVVJMIGZvciBlYXNpZXIgZGVidWdnaW5nLlxuICAgICAgLy8gVGhlIHNvdXJjZVVSTCBnZXRzIGluamVjdGVkIGludG8gdGhlIHNvdXJjZSB0aGF0J3MgZXZhbC1lZCwgc28gYmUgY2FyZWZ1bFxuICAgICAgLy8gdG8gbm9ybWFsaXplIGFsbCBraW5kcyBvZiB3aGl0ZXNwYWNlLCBzbyBlLmcuIG5ld2xpbmVzIChhbmQgdW5pY29kZSB2ZXJzaW9ucyBvZiBpdCkgY2FuJ3Qgc25lYWsgaW5cbiAgICAgIC8vIGFuZCBlc2NhcGUgdGhlIGNvbW1lbnQsIHRodXMgaW5qZWN0aW5nIGNvZGUgdGhhdCBnZXRzIGV2YWxlZC5cbiAgICAgIHZhciBzb3VyY2VVUkwgPSAnLy8jIHNvdXJjZVVSTD0nICtcbiAgICAgICAgKGhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywgJ3NvdXJjZVVSTCcpXG4gICAgICAgICAgPyAob3B0aW9ucy5zb3VyY2VVUkwgKyAnJykucmVwbGFjZSgvXFxzL2csICcgJylcbiAgICAgICAgICA6ICgnbG9kYXNoLnRlbXBsYXRlU291cmNlc1snICsgKCsrdGVtcGxhdGVDb3VudGVyKSArICddJylcbiAgICAgICAgKSArICdcXG4nO1xuXG4gICAgICBzdHJpbmcucmVwbGFjZShyZURlbGltaXRlcnMsIGZ1bmN0aW9uKG1hdGNoLCBlc2NhcGVWYWx1ZSwgaW50ZXJwb2xhdGVWYWx1ZSwgZXNUZW1wbGF0ZVZhbHVlLCBldmFsdWF0ZVZhbHVlLCBvZmZzZXQpIHtcbiAgICAgICAgaW50ZXJwb2xhdGVWYWx1ZSB8fCAoaW50ZXJwb2xhdGVWYWx1ZSA9IGVzVGVtcGxhdGVWYWx1ZSk7XG5cbiAgICAgICAgLy8gRXNjYXBlIGNoYXJhY3RlcnMgdGhhdCBjYW4ndCBiZSBpbmNsdWRlZCBpbiBzdHJpbmcgbGl0ZXJhbHMuXG4gICAgICAgIHNvdXJjZSArPSBzdHJpbmcuc2xpY2UoaW5kZXgsIG9mZnNldCkucmVwbGFjZShyZVVuZXNjYXBlZFN0cmluZywgZXNjYXBlU3RyaW5nQ2hhcik7XG5cbiAgICAgICAgLy8gUmVwbGFjZSBkZWxpbWl0ZXJzIHdpdGggc25pcHBldHMuXG4gICAgICAgIGlmIChlc2NhcGVWYWx1ZSkge1xuICAgICAgICAgIGlzRXNjYXBpbmcgPSB0cnVlO1xuICAgICAgICAgIHNvdXJjZSArPSBcIicgK1xcbl9fZShcIiArIGVzY2FwZVZhbHVlICsgXCIpICtcXG4nXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2YWx1YXRlVmFsdWUpIHtcbiAgICAgICAgICBpc0V2YWx1YXRpbmcgPSB0cnVlO1xuICAgICAgICAgIHNvdXJjZSArPSBcIic7XFxuXCIgKyBldmFsdWF0ZVZhbHVlICsgXCI7XFxuX19wICs9ICdcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW50ZXJwb2xhdGVWYWx1ZSkge1xuICAgICAgICAgIHNvdXJjZSArPSBcIicgK1xcbigoX190ID0gKFwiICsgaW50ZXJwb2xhdGVWYWx1ZSArIFwiKSkgPT0gbnVsbCA/ICcnIDogX190KSArXFxuJ1wiO1xuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gb2Zmc2V0ICsgbWF0Y2gubGVuZ3RoO1xuXG4gICAgICAgIC8vIFRoZSBKUyBlbmdpbmUgZW1iZWRkZWQgaW4gQWRvYmUgcHJvZHVjdHMgbmVlZHMgYG1hdGNoYCByZXR1cm5lZCBpblxuICAgICAgICAvLyBvcmRlciB0byBwcm9kdWNlIHRoZSBjb3JyZWN0IGBvZmZzZXRgIHZhbHVlLlxuICAgICAgICByZXR1cm4gbWF0Y2g7XG4gICAgICB9KTtcblxuICAgICAgc291cmNlICs9IFwiJztcXG5cIjtcblxuICAgICAgLy8gSWYgYHZhcmlhYmxlYCBpcyBub3Qgc3BlY2lmaWVkIHdyYXAgYSB3aXRoLXN0YXRlbWVudCBhcm91bmQgdGhlIGdlbmVyYXRlZFxuICAgICAgLy8gY29kZSB0byBhZGQgdGhlIGRhdGEgb2JqZWN0IHRvIHRoZSB0b3Agb2YgdGhlIHNjb3BlIGNoYWluLlxuICAgICAgdmFyIHZhcmlhYmxlID0gaGFzT3duUHJvcGVydHkuY2FsbChvcHRpb25zLCAndmFyaWFibGUnKSAmJiBvcHRpb25zLnZhcmlhYmxlO1xuICAgICAgaWYgKCF2YXJpYWJsZSkge1xuICAgICAgICBzb3VyY2UgPSAnd2l0aCAob2JqKSB7XFxuJyArIHNvdXJjZSArICdcXG59XFxuJztcbiAgICAgIH1cbiAgICAgIC8vIFRocm93IGFuIGVycm9yIGlmIGEgZm9yYmlkZGVuIGNoYXJhY3RlciB3YXMgZm91bmQgaW4gYHZhcmlhYmxlYCwgdG8gcHJldmVudFxuICAgICAgLy8gcG90ZW50aWFsIGNvbW1hbmQgaW5qZWN0aW9uIGF0dGFja3MuXG4gICAgICBlbHNlIGlmIChyZUZvcmJpZGRlbklkZW50aWZpZXJDaGFycy50ZXN0KHZhcmlhYmxlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoSU5WQUxJRF9URU1QTF9WQVJfRVJST1JfVEVYVCk7XG4gICAgICB9XG5cbiAgICAgIC8vIENsZWFudXAgY29kZSBieSBzdHJpcHBpbmcgZW1wdHkgc3RyaW5ncy5cbiAgICAgIHNvdXJjZSA9IChpc0V2YWx1YXRpbmcgPyBzb3VyY2UucmVwbGFjZShyZUVtcHR5U3RyaW5nTGVhZGluZywgJycpIDogc291cmNlKVxuICAgICAgICAucmVwbGFjZShyZUVtcHR5U3RyaW5nTWlkZGxlLCAnJDEnKVxuICAgICAgICAucmVwbGFjZShyZUVtcHR5U3RyaW5nVHJhaWxpbmcsICckMTsnKTtcblxuICAgICAgLy8gRnJhbWUgY29kZSBhcyB0aGUgZnVuY3Rpb24gYm9keS5cbiAgICAgIHNvdXJjZSA9ICdmdW5jdGlvbignICsgKHZhcmlhYmxlIHx8ICdvYmonKSArICcpIHtcXG4nICtcbiAgICAgICAgKHZhcmlhYmxlXG4gICAgICAgICAgPyAnJ1xuICAgICAgICAgIDogJ29iaiB8fCAob2JqID0ge30pO1xcbidcbiAgICAgICAgKSArXG4gICAgICAgIFwidmFyIF9fdCwgX19wID0gJydcIiArXG4gICAgICAgIChpc0VzY2FwaW5nXG4gICAgICAgICAgID8gJywgX19lID0gXy5lc2NhcGUnXG4gICAgICAgICAgIDogJydcbiAgICAgICAgKSArXG4gICAgICAgIChpc0V2YWx1YXRpbmdcbiAgICAgICAgICA/ICcsIF9faiA9IEFycmF5LnByb3RvdHlwZS5qb2luO1xcbicgK1xuICAgICAgICAgICAgXCJmdW5jdGlvbiBwcmludCgpIHsgX19wICs9IF9fai5jYWxsKGFyZ3VtZW50cywgJycpIH1cXG5cIlxuICAgICAgICAgIDogJztcXG4nXG4gICAgICAgICkgK1xuICAgICAgICBzb3VyY2UgK1xuICAgICAgICAncmV0dXJuIF9fcFxcbn0nO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gYXR0ZW1wdChmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uKGltcG9ydHNLZXlzLCBzb3VyY2VVUkwgKyAncmV0dXJuICcgKyBzb3VyY2UpXG4gICAgICAgICAgLmFwcGx5KHVuZGVmaW5lZCwgaW1wb3J0c1ZhbHVlcyk7XG4gICAgICB9KTtcblxuICAgICAgLy8gUHJvdmlkZSB0aGUgY29tcGlsZWQgZnVuY3Rpb24ncyBzb3VyY2UgYnkgaXRzIGB0b1N0cmluZ2AgbWV0aG9kIG9yXG4gICAgICAvLyB0aGUgYHNvdXJjZWAgcHJvcGVydHkgYXMgYSBjb252ZW5pZW5jZSBmb3IgaW5saW5pbmcgY29tcGlsZWQgdGVtcGxhdGVzLlxuICAgICAgcmVzdWx0LnNvdXJjZSA9IHNvdXJjZTtcbiAgICAgIGlmIChpc0Vycm9yKHJlc3VsdCkpIHtcbiAgICAgICAgdGhyb3cgcmVzdWx0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCwgYXMgYSB3aG9sZSwgdG8gbG93ZXIgY2FzZSBqdXN0IGxpa2VcbiAgICAgKiBbU3RyaW5nI3RvTG93ZXJDYXNlXShodHRwczovL21kbi5pby90b0xvd2VyQ2FzZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBsb3dlciBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9Mb3dlcignLS1Gb28tQmFyLS0nKTtcbiAgICAgKiAvLyA9PiAnLS1mb28tYmFyLS0nXG4gICAgICpcbiAgICAgKiBfLnRvTG93ZXIoJ2Zvb0JhcicpO1xuICAgICAqIC8vID0+ICdmb29iYXInXG4gICAgICpcbiAgICAgKiBfLnRvTG93ZXIoJ19fRk9PX0JBUl9fJyk7XG4gICAgICogLy8gPT4gJ19fZm9vX2Jhcl9fJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvTG93ZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0b1N0cmluZyh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCwgYXMgYSB3aG9sZSwgdG8gdXBwZXIgY2FzZSBqdXN0IGxpa2VcbiAgICAgKiBbU3RyaW5nI3RvVXBwZXJDYXNlXShodHRwczovL21kbi5pby90b1VwcGVyQ2FzZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1cHBlciBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9VcHBlcignLS1mb28tYmFyLS0nKTtcbiAgICAgKiAvLyA9PiAnLS1GT08tQkFSLS0nXG4gICAgICpcbiAgICAgKiBfLnRvVXBwZXIoJ2Zvb0JhcicpO1xuICAgICAqIC8vID0+ICdGT09CQVInXG4gICAgICpcbiAgICAgKiBfLnRvVXBwZXIoJ19fZm9vX2Jhcl9fJyk7XG4gICAgICogLy8gPT4gJ19fRk9PX0JBUl9fJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvVXBwZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0b1N0cmluZyh2YWx1ZSkudG9VcHBlckNhc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2Ugb3Igc3BlY2lmaWVkIGNoYXJhY3RlcnMgZnJvbSBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byB0cmltLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9d2hpdGVzcGFjZV0gVGhlIGNoYXJhY3RlcnMgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRyaW0oJyAgYWJjICAnKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqXG4gICAgICogXy50cmltKCctXy1hYmMtXy0nLCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqXG4gICAgICogXy5tYXAoWycgIGZvbyAgJywgJyAgYmFyICAnXSwgXy50cmltKTtcbiAgICAgKiAvLyA9PiBbJ2ZvbycsICdiYXInXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRyaW0oc3RyaW5nLCBjaGFycywgZ3VhcmQpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAoc3RyaW5nICYmIChndWFyZCB8fCBjaGFycyA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICByZXR1cm4gYmFzZVRyaW0oc3RyaW5nKTtcbiAgICAgIH1cbiAgICAgIGlmICghc3RyaW5nIHx8ICEoY2hhcnMgPSBiYXNlVG9TdHJpbmcoY2hhcnMpKSkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIHN0clN5bWJvbHMgPSBzdHJpbmdUb0FycmF5KHN0cmluZyksXG4gICAgICAgICAgY2hyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoY2hhcnMpLFxuICAgICAgICAgIHN0YXJ0ID0gY2hhcnNTdGFydEluZGV4KHN0clN5bWJvbHMsIGNoclN5bWJvbHMpLFxuICAgICAgICAgIGVuZCA9IGNoYXJzRW5kSW5kZXgoc3RyU3ltYm9scywgY2hyU3ltYm9scykgKyAxO1xuXG4gICAgICByZXR1cm4gY2FzdFNsaWNlKHN0clN5bWJvbHMsIHN0YXJ0LCBlbmQpLmpvaW4oJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgdHJhaWxpbmcgd2hpdGVzcGFjZSBvciBzcGVjaWZpZWQgY2hhcmFjdGVycyBmcm9tIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz13aGl0ZXNwYWNlXSBUaGUgY2hhcmFjdGVycyB0byB0cmltLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJpbUVuZCgnICBhYmMgICcpO1xuICAgICAqIC8vID0+ICcgIGFiYydcbiAgICAgKlxuICAgICAqIF8udHJpbUVuZCgnLV8tYWJjLV8tJywgJ18tJyk7XG4gICAgICogLy8gPT4gJy1fLWFiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmltRW5kKHN0cmluZywgY2hhcnMsIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgaWYgKHN0cmluZyAmJiAoZ3VhcmQgfHwgY2hhcnMgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5zbGljZSgwLCB0cmltbWVkRW5kSW5kZXgoc3RyaW5nKSArIDEpO1xuICAgICAgfVxuICAgICAgaWYgKCFzdHJpbmcgfHwgIShjaGFycyA9IGJhc2VUb1N0cmluZyhjaGFycykpKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICB9XG4gICAgICB2YXIgc3RyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoc3RyaW5nKSxcbiAgICAgICAgICBlbmQgPSBjaGFyc0VuZEluZGV4KHN0clN5bWJvbHMsIHN0cmluZ1RvQXJyYXkoY2hhcnMpKSArIDE7XG5cbiAgICAgIHJldHVybiBjYXN0U2xpY2Uoc3RyU3ltYm9scywgMCwgZW5kKS5qb2luKCcnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxlYWRpbmcgd2hpdGVzcGFjZSBvciBzcGVjaWZpZWQgY2hhcmFjdGVycyBmcm9tIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz13aGl0ZXNwYWNlXSBUaGUgY2hhcmFjdGVycyB0byB0cmltLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJpbVN0YXJ0KCcgIGFiYyAgJyk7XG4gICAgICogLy8gPT4gJ2FiYyAgJ1xuICAgICAqXG4gICAgICogXy50cmltU3RhcnQoJy1fLWFiYy1fLScsICdfLScpO1xuICAgICAqIC8vID0+ICdhYmMtXy0nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJpbVN0YXJ0KHN0cmluZywgY2hhcnMsIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgaWYgKHN0cmluZyAmJiAoZ3VhcmQgfHwgY2hhcnMgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKHJlVHJpbVN0YXJ0LCAnJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXN0cmluZyB8fCAhKGNoYXJzID0gYmFzZVRvU3RyaW5nKGNoYXJzKSkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBzdHJTeW1ib2xzID0gc3RyaW5nVG9BcnJheShzdHJpbmcpLFxuICAgICAgICAgIHN0YXJ0ID0gY2hhcnNTdGFydEluZGV4KHN0clN5bWJvbHMsIHN0cmluZ1RvQXJyYXkoY2hhcnMpKTtcblxuICAgICAgcmV0dXJuIGNhc3RTbGljZShzdHJTeW1ib2xzLCBzdGFydCkuam9pbignJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJ1bmNhdGVzIGBzdHJpbmdgIGlmIGl0J3MgbG9uZ2VyIHRoYW4gdGhlIGdpdmVuIG1heGltdW0gc3RyaW5nIGxlbmd0aC5cbiAgICAgKiBUaGUgbGFzdCBjaGFyYWN0ZXJzIG9mIHRoZSB0cnVuY2F0ZWQgc3RyaW5nIGFyZSByZXBsYWNlZCB3aXRoIHRoZSBvbWlzc2lvblxuICAgICAqIHN0cmluZyB3aGljaCBkZWZhdWx0cyB0byBcIi4uLlwiLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRydW5jYXRlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5sZW5ndGg9MzBdIFRoZSBtYXhpbXVtIHN0cmluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLm9taXNzaW9uPScuLi4nXSBUaGUgc3RyaW5nIHRvIGluZGljYXRlIHRleHQgaXMgb21pdHRlZC5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cHxzdHJpbmd9IFtvcHRpb25zLnNlcGFyYXRvcl0gVGhlIHNlcGFyYXRvciBwYXR0ZXJuIHRvIHRydW5jYXRlIHRvLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHRydW5jYXRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJ1bmNhdGUoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nKTtcbiAgICAgKiAvLyA9PiAnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvLi4uJ1xuICAgICAqXG4gICAgICogXy50cnVuY2F0ZSgnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvcmlubycsIHtcbiAgICAgKiAgICdsZW5ndGgnOiAyNCxcbiAgICAgKiAgICdzZXBhcmF0b3InOiAnICdcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAnaGktZGlkZGx5LWhvIHRoZXJlLC4uLidcbiAgICAgKlxuICAgICAqIF8udHJ1bmNhdGUoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nLCB7XG4gICAgICogICAnbGVuZ3RoJzogMjQsXG4gICAgICogICAnc2VwYXJhdG9yJzogLyw/ICsvXG4gICAgICogfSk7XG4gICAgICogLy8gPT4gJ2hpLWRpZGRseS1obyB0aGVyZS4uLidcbiAgICAgKlxuICAgICAqIF8udHJ1bmNhdGUoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nLCB7XG4gICAgICogICAnb21pc3Npb24nOiAnIFsuLi5dJ1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+ICdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWcgWy4uLl0nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJ1bmNhdGUoc3RyaW5nLCBvcHRpb25zKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gREVGQVVMVF9UUlVOQ19MRU5HVEgsXG4gICAgICAgICAgb21pc3Npb24gPSBERUZBVUxUX1RSVU5DX09NSVNTSU9OO1xuXG4gICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgdmFyIHNlcGFyYXRvciA9ICdzZXBhcmF0b3InIGluIG9wdGlvbnMgPyBvcHRpb25zLnNlcGFyYXRvciA6IHNlcGFyYXRvcjtcbiAgICAgICAgbGVuZ3RoID0gJ2xlbmd0aCcgaW4gb3B0aW9ucyA/IHRvSW50ZWdlcihvcHRpb25zLmxlbmd0aCkgOiBsZW5ndGg7XG4gICAgICAgIG9taXNzaW9uID0gJ29taXNzaW9uJyBpbiBvcHRpb25zID8gYmFzZVRvU3RyaW5nKG9wdGlvbnMub21pc3Npb24pIDogb21pc3Npb247XG4gICAgICB9XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuXG4gICAgICB2YXIgc3RyTGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgIGlmIChoYXNVbmljb2RlKHN0cmluZykpIHtcbiAgICAgICAgdmFyIHN0clN5bWJvbHMgPSBzdHJpbmdUb0FycmF5KHN0cmluZyk7XG4gICAgICAgIHN0ckxlbmd0aCA9IHN0clN5bWJvbHMubGVuZ3RoO1xuICAgICAgfVxuICAgICAgaWYgKGxlbmd0aCA+PSBzdHJMZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBlbmQgPSBsZW5ndGggLSBzdHJpbmdTaXplKG9taXNzaW9uKTtcbiAgICAgIGlmIChlbmQgPCAxKSB7XG4gICAgICAgIHJldHVybiBvbWlzc2lvbjtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBzdHJTeW1ib2xzXG4gICAgICAgID8gY2FzdFNsaWNlKHN0clN5bWJvbHMsIDAsIGVuZCkuam9pbignJylcbiAgICAgICAgOiBzdHJpbmcuc2xpY2UoMCwgZW5kKTtcblxuICAgICAgaWYgKHNlcGFyYXRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgKyBvbWlzc2lvbjtcbiAgICAgIH1cbiAgICAgIGlmIChzdHJTeW1ib2xzKSB7XG4gICAgICAgIGVuZCArPSAocmVzdWx0Lmxlbmd0aCAtIGVuZCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNSZWdFeHAoc2VwYXJhdG9yKSkge1xuICAgICAgICBpZiAoc3RyaW5nLnNsaWNlKGVuZCkuc2VhcmNoKHNlcGFyYXRvcikpIHtcbiAgICAgICAgICB2YXIgbWF0Y2gsXG4gICAgICAgICAgICAgIHN1YnN0cmluZyA9IHJlc3VsdDtcblxuICAgICAgICAgIGlmICghc2VwYXJhdG9yLmdsb2JhbCkge1xuICAgICAgICAgICAgc2VwYXJhdG9yID0gUmVnRXhwKHNlcGFyYXRvci5zb3VyY2UsIHRvU3RyaW5nKHJlRmxhZ3MuZXhlYyhzZXBhcmF0b3IpKSArICdnJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNlcGFyYXRvci5sYXN0SW5kZXggPSAwO1xuICAgICAgICAgIHdoaWxlICgobWF0Y2ggPSBzZXBhcmF0b3IuZXhlYyhzdWJzdHJpbmcpKSkge1xuICAgICAgICAgICAgdmFyIG5ld0VuZCA9IG1hdGNoLmluZGV4O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoMCwgbmV3RW5kID09PSB1bmRlZmluZWQgPyBlbmQgOiBuZXdFbmQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHN0cmluZy5pbmRleE9mKGJhc2VUb1N0cmluZyhzZXBhcmF0b3IpLCBlbmQpICE9IGVuZCkge1xuICAgICAgICB2YXIgaW5kZXggPSByZXN1bHQubGFzdEluZGV4T2Yoc2VwYXJhdG9yKTtcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0ICsgb21pc3Npb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGludmVyc2Ugb2YgYF8uZXNjYXBlYDsgdGhpcyBtZXRob2QgY29udmVydHMgdGhlIEhUTUwgZW50aXRpZXNcbiAgICAgKiBgJmFtcDtgLCBgJmx0O2AsIGAmZ3Q7YCwgYCZxdW90O2AsIGFuZCBgJiMzOTtgIGluIGBzdHJpbmdgIHRvXG4gICAgICogdGhlaXIgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXJzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vIG90aGVyIEhUTUwgZW50aXRpZXMgYXJlIHVuZXNjYXBlZC4gVG8gdW5lc2NhcGUgYWRkaXRpb25hbFxuICAgICAqIEhUTUwgZW50aXRpZXMgdXNlIGEgdGhpcmQtcGFydHkgbGlicmFyeSBsaWtlIFtfaGVfXShodHRwczovL210aHMuYmUvaGUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNi4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHVuZXNjYXBlLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHVuZXNjYXBlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udW5lc2NhcGUoJ2ZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICdmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmVzY2FwZShzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICByZXR1cm4gKHN0cmluZyAmJiByZUhhc0VzY2FwZWRIdG1sLnRlc3Qoc3RyaW5nKSlcbiAgICAgICAgPyBzdHJpbmcucmVwbGFjZShyZUVzY2FwZWRIdG1sLCB1bmVzY2FwZUh0bWxDaGFyKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCwgYXMgc3BhY2Ugc2VwYXJhdGVkIHdvcmRzLCB0byB1cHBlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdXBwZXIgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVwcGVyQ2FzZSgnLS1mb28tYmFyJyk7XG4gICAgICogLy8gPT4gJ0ZPTyBCQVInXG4gICAgICpcbiAgICAgKiBfLnVwcGVyQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ0ZPTyBCQVInXG4gICAgICpcbiAgICAgKiBfLnVwcGVyQ2FzZSgnX19mb29fYmFyX18nKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKi9cbiAgICB2YXIgdXBwZXJDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJyAnIDogJycpICsgd29yZC50b1VwcGVyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBgc3RyaW5nYCB0byB1cHBlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51cHBlckZpcnN0KCdmcmVkJyk7XG4gICAgICogLy8gPT4gJ0ZyZWQnXG4gICAgICpcbiAgICAgKiBfLnVwcGVyRmlyc3QoJ0ZSRUQnKTtcbiAgICAgKiAvLyA9PiAnRlJFRCdcbiAgICAgKi9cbiAgICB2YXIgdXBwZXJGaXJzdCA9IGNyZWF0ZUNhc2VGaXJzdCgndG9VcHBlckNhc2UnKTtcblxuICAgIC8qKlxuICAgICAqIFNwbGl0cyBgc3RyaW5nYCBpbnRvIGFuIGFycmF5IG9mIGl0cyB3b3Jkcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfHN0cmluZ30gW3BhdHRlcm5dIFRoZSBwYXR0ZXJuIHRvIG1hdGNoIHdvcmRzLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3b3JkcyBvZiBgc3RyaW5nYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy53b3JkcygnZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnKTtcbiAgICAgKiAvLyA9PiBbJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogXy53b3JkcygnZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnLCAvW14sIF0rL2cpO1xuICAgICAqIC8vID0+IFsnZnJlZCcsICdiYXJuZXknLCAnJicsICdwZWJibGVzJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3b3JkcyhzdHJpbmcsIHBhdHRlcm4sIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgcGF0dGVybiA9IGd1YXJkID8gdW5kZWZpbmVkIDogcGF0dGVybjtcblxuICAgICAgaWYgKHBhdHRlcm4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gaGFzVW5pY29kZVdvcmQoc3RyaW5nKSA/IHVuaWNvZGVXb3JkcyhzdHJpbmcpIDogYXNjaWlXb3JkcyhzdHJpbmcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHN0cmluZy5tYXRjaChwYXR0ZXJuKSB8fCBbXTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBBdHRlbXB0cyB0byBpbnZva2UgYGZ1bmNgLCByZXR1cm5pbmcgZWl0aGVyIHRoZSByZXN1bHQgb3IgdGhlIGNhdWdodCBlcnJvclxuICAgICAqIG9iamVjdC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byBgZnVuY2Agd2hlbiBpdCdzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGF0dGVtcHQuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgYGZ1bmNgIHdpdGguXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGBmdW5jYCByZXN1bHQgb3IgZXJyb3Igb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAvLyBBdm9pZCB0aHJvd2luZyBlcnJvcnMgZm9yIGludmFsaWQgc2VsZWN0b3JzLlxuICAgICAqIHZhciBlbGVtZW50cyA9IF8uYXR0ZW1wdChmdW5jdGlvbihzZWxlY3Rvcikge1xuICAgICAqICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuICAgICAqIH0sICc+Xz4nKTtcbiAgICAgKlxuICAgICAqIGlmIChfLmlzRXJyb3IoZWxlbWVudHMpKSB7XG4gICAgICogICBlbGVtZW50cyA9IFtdO1xuICAgICAqIH1cbiAgICAgKi9cbiAgICB2YXIgYXR0ZW1wdCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIGFyZ3MpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhcHBseShmdW5jLCB1bmRlZmluZWQsIGFyZ3MpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gaXNFcnJvcihlKSA/IGUgOiBuZXcgRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBCaW5kcyBtZXRob2RzIG9mIGFuIG9iamVjdCB0byB0aGUgb2JqZWN0IGl0c2VsZiwgb3ZlcndyaXRpbmcgdGhlIGV4aXN0aW5nXG4gICAgICogbWV0aG9kLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIGJvdW5kIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGJpbmQgYW5kIGFzc2lnbiB0aGUgYm91bmQgbWV0aG9kcyB0by5cbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBtZXRob2ROYW1lcyBUaGUgb2JqZWN0IG1ldGhvZCBuYW1lcyB0byBiaW5kLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB2aWV3ID0ge1xuICAgICAqICAgJ2xhYmVsJzogJ2RvY3MnLFxuICAgICAqICAgJ2NsaWNrJzogZnVuY3Rpb24oKSB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdjbGlja2VkICcgKyB0aGlzLmxhYmVsKTtcbiAgICAgKiAgIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5iaW5kQWxsKHZpZXcsIFsnY2xpY2snXSk7XG4gICAgICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIHZpZXcuY2xpY2spO1xuICAgICAqIC8vID0+IExvZ3MgJ2NsaWNrZWQgZG9jcycgd2hlbiBjbGlja2VkLlxuICAgICAqL1xuICAgIHZhciBiaW5kQWxsID0gZmxhdFJlc3QoZnVuY3Rpb24ob2JqZWN0LCBtZXRob2ROYW1lcykge1xuICAgICAgYXJyYXlFYWNoKG1ldGhvZE5hbWVzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgICAga2V5ID0gdG9LZXkoa2V5KTtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBiaW5kKG9iamVjdFtrZXldLCBvYmplY3QpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGl0ZXJhdGVzIG92ZXIgYHBhaXJzYCBhbmQgaW52b2tlcyB0aGUgY29ycmVzcG9uZGluZ1xuICAgICAqIGZ1bmN0aW9uIG9mIHRoZSBmaXJzdCBwcmVkaWNhdGUgdG8gcmV0dXJuIHRydXRoeS4gVGhlIHByZWRpY2F0ZS1mdW5jdGlvblxuICAgICAqIHBhaXJzIGFyZSBpbnZva2VkIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIGFuZCBhcmd1bWVudHMgb2YgdGhlIGNyZWF0ZWRcbiAgICAgKiBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFpcnMgVGhlIHByZWRpY2F0ZS1mdW5jdGlvbiBwYWlycy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3NpdGUgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBmdW5jID0gXy5jb25kKFtcbiAgICAgKiAgIFtfLm1hdGNoZXMoeyAnYSc6IDEgfSksICAgICAgICAgICBfLmNvbnN0YW50KCdtYXRjaGVzIEEnKV0sXG4gICAgICogICBbXy5jb25mb3Jtcyh7ICdiJzogXy5pc051bWJlciB9KSwgXy5jb25zdGFudCgnbWF0Y2hlcyBCJyldLFxuICAgICAqICAgW18uc3R1YlRydWUsICAgICAgICAgICAgICAgICAgICAgIF8uY29uc3RhbnQoJ25vIG1hdGNoJyldXG4gICAgICogXSk7XG4gICAgICpcbiAgICAgKiBmdW5jKHsgJ2EnOiAxLCAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gJ21hdGNoZXMgQSdcbiAgICAgKlxuICAgICAqIGZ1bmMoeyAnYSc6IDAsICdiJzogMSB9KTtcbiAgICAgKiAvLyA9PiAnbWF0Y2hlcyBCJ1xuICAgICAqXG4gICAgICogZnVuYyh7ICdhJzogJzEnLCAnYic6ICcyJyB9KTtcbiAgICAgKiAvLyA9PiAnbm8gbWF0Y2gnXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uZChwYWlycykge1xuICAgICAgdmFyIGxlbmd0aCA9IHBhaXJzID09IG51bGwgPyAwIDogcGFpcnMubGVuZ3RoLFxuICAgICAgICAgIHRvSXRlcmF0ZWUgPSBnZXRJdGVyYXRlZSgpO1xuXG4gICAgICBwYWlycyA9ICFsZW5ndGggPyBbXSA6IGFycmF5TWFwKHBhaXJzLCBmdW5jdGlvbihwYWlyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFpclsxXSAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbdG9JdGVyYXRlZShwYWlyWzBdKSwgcGFpclsxXV07XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTE7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIHBhaXIgPSBwYWlyc1tpbmRleF07XG4gICAgICAgICAgaWYgKGFwcGx5KHBhaXJbMF0sIHRoaXMsIGFyZ3MpKSB7XG4gICAgICAgICAgICByZXR1cm4gYXBwbHkocGFpclsxXSwgdGhpcywgYXJncyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIHRoZSBwcmVkaWNhdGUgcHJvcGVydGllcyBvZiBgc291cmNlYCB3aXRoXG4gICAgICogdGhlIGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgdmFsdWVzIG9mIGEgZ2l2ZW4gb2JqZWN0LCByZXR1cm5pbmcgYHRydWVgIGlmXG4gICAgICogYWxsIHByZWRpY2F0ZXMgcmV0dXJuIHRydXRoeSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjcmVhdGVkIGZ1bmN0aW9uIGlzIGVxdWl2YWxlbnQgdG8gYF8uY29uZm9ybXNUb2Agd2l0aFxuICAgICAqIGBzb3VyY2VgIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgcHJlZGljYXRlcyB0byBjb25mb3JtIHRvLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IDIsICdiJzogMSB9LFxuICAgICAqICAgeyAnYSc6IDEsICdiJzogMiB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKG9iamVjdHMsIF8uY29uZm9ybXMoeyAnYic6IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gPiAxOyB9IH0pKTtcbiAgICAgKiAvLyA9PiBbeyAnYSc6IDEsICdiJzogMiB9XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbmZvcm1zKHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGJhc2VDb25mb3JtcyhiYXNlQ2xvbmUoc291cmNlLCBDTE9ORV9ERUVQX0ZMQUcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHJldHVybiBmcm9tIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29uc3RhbnQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gXy50aW1lcygyLCBfLmNvbnN0YW50KHsgJ2EnOiAxIH0pKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdHMpO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSB9LCB7ICdhJzogMSB9XVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0c1swXSA9PT0gb2JqZWN0c1sxXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbnN0YW50KHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGB2YWx1ZWAgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBkZWZhdWx0IHZhbHVlIHNob3VsZCBiZSByZXR1cm5lZCBpblxuICAgICAqIGl0cyBwbGFjZS4gVGhlIGBkZWZhdWx0VmFsdWVgIGlzIHJldHVybmVkIGlmIGB2YWx1ZWAgaXMgYE5hTmAsIGBudWxsYCxcbiAgICAgKiBvciBgdW5kZWZpbmVkYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjE0LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7Kn0gZGVmYXVsdFZhbHVlIFRoZSBkZWZhdWx0IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZhdWx0VG8oMSwgMTApO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIF8uZGVmYXVsdFRvKHVuZGVmaW5lZCwgMTApO1xuICAgICAqIC8vID0+IDEwXG4gICAgICovXG4gICAgZnVuY3Rpb24gZGVmYXVsdFRvKHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHJldHVybiAodmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUpID8gZGVmYXVsdFZhbHVlIDogdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgcmVzdWx0IG9mIGludm9raW5nIHRoZSBnaXZlbiBmdW5jdGlvbnNcbiAgICAgKiB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbiwgd2hlcmUgZWFjaCBzdWNjZXNzaXZlXG4gICAgICogaW52b2NhdGlvbiBpcyBzdXBwbGllZCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwcmV2aW91cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFtmdW5jc10gVGhlIGZ1bmN0aW9ucyB0byBpbnZva2UuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29tcG9zaXRlIGZ1bmN0aW9uLlxuICAgICAqIEBzZWUgXy5mbG93UmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgYWRkU3F1YXJlID0gXy5mbG93KFtfLmFkZCwgc3F1YXJlXSk7XG4gICAgICogYWRkU3F1YXJlKDEsIDIpO1xuICAgICAqIC8vID0+IDlcbiAgICAgKi9cbiAgICB2YXIgZmxvdyA9IGNyZWF0ZUZsb3coKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmxvd2AgZXhjZXB0IHRoYXQgaXQgY3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXRcbiAgICAgKiBpbnZva2VzIHRoZSBnaXZlbiBmdW5jdGlvbnMgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW2Z1bmNzXSBUaGUgZnVuY3Rpb25zIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3NpdGUgZnVuY3Rpb24uXG4gICAgICogQHNlZSBfLmZsb3dcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgYWRkU3F1YXJlID0gXy5mbG93UmlnaHQoW3NxdWFyZSwgXy5hZGRdKTtcbiAgICAgKiBhZGRTcXVhcmUoMSwgMik7XG4gICAgICogLy8gPT4gOVxuICAgICAqL1xuICAgIHZhciBmbG93UmlnaHQgPSBjcmVhdGVGbG93KHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgQW55IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3QpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpZGVudGl0eSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZFxuICAgICAqIGZ1bmN0aW9uLiBJZiBgZnVuY2AgaXMgYSBwcm9wZXJ0eSBuYW1lLCB0aGUgY3JlYXRlZCBmdW5jdGlvbiByZXR1cm5zIHRoZVxuICAgICAqIHByb3BlcnR5IHZhbHVlIGZvciBhIGdpdmVuIGVsZW1lbnQuIElmIGBmdW5jYCBpcyBhbiBhcnJheSBvciBvYmplY3QsIHRoZVxuICAgICAqIGNyZWF0ZWQgZnVuY3Rpb24gcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgY29udGFpbiB0aGUgZXF1aXZhbGVudFxuICAgICAqIHNvdXJjZSBwcm9wZXJ0aWVzLCBvdGhlcndpc2UgaXQgcmV0dXJucyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0geyp9IFtmdW5jPV8uaWRlbnRpdHldIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGEgY2FsbGJhY2suXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbHRlcih1c2VycywgXy5pdGVyYXRlZSh7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0pKTtcbiAgICAgKiAvLyA9PiBbeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH1dXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maWx0ZXIodXNlcnMsIF8uaXRlcmF0ZWUoWyd1c2VyJywgJ2ZyZWQnXSkpO1xuICAgICAqIC8vID0+IFt7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWFwKHVzZXJzLCBfLml0ZXJhdGVlKCd1c2VyJykpO1xuICAgICAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gQ3JlYXRlIGN1c3RvbSBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqIF8uaXRlcmF0ZWUgPSBfLndyYXAoXy5pdGVyYXRlZSwgZnVuY3Rpb24oaXRlcmF0ZWUsIGZ1bmMpIHtcbiAgICAgKiAgIHJldHVybiAhXy5pc1JlZ0V4cChmdW5jKSA/IGl0ZXJhdGVlKGZ1bmMpIDogZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICogICAgIHJldHVybiBmdW5jLnRlc3Qoc3RyaW5nKTtcbiAgICAgKiAgIH07XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBfLmZpbHRlcihbJ2FiYycsICdkZWYnXSwgL2VmLyk7XG4gICAgICogLy8gPT4gWydkZWYnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGl0ZXJhdGVlKGZ1bmMpIHtcbiAgICAgIHJldHVybiBiYXNlSXRlcmF0ZWUodHlwZW9mIGZ1bmMgPT0gJ2Z1bmN0aW9uJyA/IGZ1bmMgOiBiYXNlQ2xvbmUoZnVuYywgQ0xPTkVfREVFUF9GTEFHKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgYSBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbiBiZXR3ZWVuIGEgZ2l2ZW5cbiAgICAgKiBvYmplY3QgYW5kIGBzb3VyY2VgLCByZXR1cm5pbmcgYHRydWVgIGlmIHRoZSBnaXZlbiBvYmplY3QgaGFzIGVxdWl2YWxlbnRcbiAgICAgKiBwcm9wZXJ0eSB2YWx1ZXMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGUgY3JlYXRlZCBmdW5jdGlvbiBpcyBlcXVpdmFsZW50IHRvIGBfLmlzTWF0Y2hgIHdpdGggYHNvdXJjZWBcbiAgICAgKiBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIFBhcnRpYWwgY29tcGFyaXNvbnMgd2lsbCBtYXRjaCBlbXB0eSBhcnJheSBhbmQgZW1wdHkgb2JqZWN0IGBzb3VyY2VgXG4gICAgICogdmFsdWVzIGFnYWluc3QgYW55IGFycmF5IG9yIG9iamVjdCB2YWx1ZSwgcmVzcGVjdGl2ZWx5LiBTZWUgYF8uaXNFcXVhbGBcbiAgICAgKiBmb3IgYSBsaXN0IG9mIHN1cHBvcnRlZCB2YWx1ZSBjb21wYXJpc29ucy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBNdWx0aXBsZSB2YWx1ZXMgY2FuIGJlIGNoZWNrZWQgYnkgY29tYmluaW5nIHNldmVyYWwgbWF0Y2hlcnNcbiAgICAgKiB1c2luZyBgXy5vdmVyU29tZWBcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9LFxuICAgICAqICAgeyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maWx0ZXIob2JqZWN0cywgXy5tYXRjaGVzKHsgJ2EnOiA0LCAnYyc6IDYgfSkpO1xuICAgICAqIC8vID0+IFt7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfV1cbiAgICAgKlxuICAgICAqIC8vIENoZWNraW5nIGZvciBzZXZlcmFsIHBvc3NpYmxlIHZhbHVlc1xuICAgICAqIF8uZmlsdGVyKG9iamVjdHMsIF8ub3ZlclNvbWUoW18ubWF0Y2hlcyh7ICdhJzogMSB9KSwgXy5tYXRjaGVzKHsgJ2EnOiA0IH0pXSkpO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDMgfSwgeyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWF0Y2hlcyhzb3VyY2UpIHtcbiAgICAgIHJldHVybiBiYXNlTWF0Y2hlcyhiYXNlQ2xvbmUoc291cmNlLCBDTE9ORV9ERUVQX0ZMQUcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIHBhcnRpYWwgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gdGhlXG4gICAgICogdmFsdWUgYXQgYHBhdGhgIG9mIGEgZ2l2ZW4gb2JqZWN0IHRvIGBzcmNWYWx1ZWAsIHJldHVybmluZyBgdHJ1ZWAgaWYgdGhlXG4gICAgICogb2JqZWN0IHZhbHVlIGlzIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBQYXJ0aWFsIGNvbXBhcmlzb25zIHdpbGwgbWF0Y2ggZW1wdHkgYXJyYXkgYW5kIGVtcHR5IG9iamVjdFxuICAgICAqIGBzcmNWYWx1ZWAgdmFsdWVzIGFnYWluc3QgYW55IGFycmF5IG9yIG9iamVjdCB2YWx1ZSwgcmVzcGVjdGl2ZWx5LiBTZWVcbiAgICAgKiBgXy5pc0VxdWFsYCBmb3IgYSBsaXN0IG9mIHN1cHBvcnRlZCB2YWx1ZSBjb21wYXJpc29ucy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBNdWx0aXBsZSB2YWx1ZXMgY2FuIGJlIGNoZWNrZWQgYnkgY29tYmluaW5nIHNldmVyYWwgbWF0Y2hlcnNcbiAgICAgKiB1c2luZyBgXy5vdmVyU29tZWBcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjIuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9LFxuICAgICAqICAgeyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maW5kKG9iamVjdHMsIF8ubWF0Y2hlc1Byb3BlcnR5KCdhJywgNCkpO1xuICAgICAqIC8vID0+IHsgJ2EnOiA0LCAnYic6IDUsICdjJzogNiB9XG4gICAgICpcbiAgICAgKiAvLyBDaGVja2luZyBmb3Igc2V2ZXJhbCBwb3NzaWJsZSB2YWx1ZXNcbiAgICAgKiBfLmZpbHRlcihvYmplY3RzLCBfLm92ZXJTb21lKFtfLm1hdGNoZXNQcm9wZXJ0eSgnYScsIDEpLCBfLm1hdGNoZXNQcm9wZXJ0eSgnYScsIDQpXSkpO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDMgfSwgeyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWF0Y2hlc1Byb3BlcnR5KHBhdGgsIHNyY1ZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBiYXNlQ2xvbmUoc3JjVmFsdWUsIENMT05FX0RFRVBfRkxBRykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgdGhlIG1ldGhvZCBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QuXG4gICAgICogQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byB0aGUgaW52b2tlZCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy43LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIHRoZSBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBpbnZva2VyIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiB7ICdiJzogXy5jb25zdGFudCgyKSB9IH0sXG4gICAgICogICB7ICdhJzogeyAnYic6IF8uY29uc3RhbnQoMSkgfSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ubWFwKG9iamVjdHMsIF8ubWV0aG9kKCdhLmInKSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICpcbiAgICAgKiBfLm1hcChvYmplY3RzLCBfLm1ldGhvZChbJ2EnLCAnYiddKSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICovXG4gICAgdmFyIG1ldGhvZCA9IGJhc2VSZXN0KGZ1bmN0aW9uKHBhdGgsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VJbnZva2Uob2JqZWN0LCBwYXRoLCBhcmdzKTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ubWV0aG9kYDsgdGhpcyBtZXRob2QgY3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlc1xuICAgICAqIHRoZSBtZXRob2QgYXQgYSBnaXZlbiBwYXRoIG9mIGBvYmplY3RgLiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlXG4gICAgICogcHJvdmlkZWQgdG8gdGhlIGludm9rZWQgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuNy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGludm9rZXIgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IF8udGltZXMoMywgXy5jb25zdGFudCksXG4gICAgICogICAgIG9iamVjdCA9IHsgJ2EnOiBhcnJheSwgJ2InOiBhcnJheSwgJ2MnOiBhcnJheSB9O1xuICAgICAqXG4gICAgICogXy5tYXAoWydhWzJdJywgJ2NbMF0nXSwgXy5tZXRob2RPZihvYmplY3QpKTtcbiAgICAgKiAvLyA9PiBbMiwgMF1cbiAgICAgKlxuICAgICAqIF8ubWFwKFtbJ2EnLCAnMiddLCBbJ2MnLCAnMCddXSwgXy5tZXRob2RPZihvYmplY3QpKTtcbiAgICAgKiAvLyA9PiBbMiwgMF1cbiAgICAgKi9cbiAgICB2YXIgbWV0aG9kT2YgPSBiYXNlUmVzdChmdW5jdGlvbihvYmplY3QsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihwYXRoKSB7XG4gICAgICAgIHJldHVybiBiYXNlSW52b2tlKG9iamVjdCwgcGF0aCwgYXJncyk7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBhbGwgb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIGZ1bmN0aW9uIHByb3BlcnRpZXMgb2YgYSBzb3VyY2VcbiAgICAgKiBvYmplY3QgdG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdC4gSWYgYG9iamVjdGAgaXMgYSBmdW5jdGlvbiwgdGhlbiBtZXRob2RzXG4gICAgICogYXJlIGFkZGVkIHRvIGl0cyBwcm90b3R5cGUgYXMgd2VsbC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVc2UgYF8ucnVuSW5Db250ZXh0YCB0byBjcmVhdGUgYSBwcmlzdGluZSBgbG9kYXNoYCBmdW5jdGlvbiB0b1xuICAgICAqIGF2b2lkIGNvbmZsaWN0cyBjYXVzZWQgYnkgbW9kaWZ5aW5nIHRoZSBvcmlnaW5hbC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R9IFtvYmplY3Q9bG9kYXNoXSBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuY2hhaW49dHJ1ZV0gU3BlY2lmeSB3aGV0aGVyIG1peGlucyBhcmUgY2hhaW5hYmxlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbnxPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHZvd2VscyhzdHJpbmcpIHtcbiAgICAgKiAgIHJldHVybiBfLmZpbHRlcihzdHJpbmcsIGZ1bmN0aW9uKHYpIHtcbiAgICAgKiAgICAgcmV0dXJuIC9bYWVpb3VdL2kudGVzdCh2KTtcbiAgICAgKiAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8ubWl4aW4oeyAndm93ZWxzJzogdm93ZWxzIH0pO1xuICAgICAqIF8udm93ZWxzKCdmcmVkJyk7XG4gICAgICogLy8gPT4gWydlJ11cbiAgICAgKlxuICAgICAqIF8oJ2ZyZWQnKS52b3dlbHMoKS52YWx1ZSgpO1xuICAgICAqIC8vID0+IFsnZSddXG4gICAgICpcbiAgICAgKiBfLm1peGluKHsgJ3Zvd2Vscyc6IHZvd2VscyB9LCB7ICdjaGFpbic6IGZhbHNlIH0pO1xuICAgICAqIF8oJ2ZyZWQnKS52b3dlbHMoKTtcbiAgICAgKiAvLyA9PiBbJ2UnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1peGluKG9iamVjdCwgc291cmNlLCBvcHRpb25zKSB7XG4gICAgICB2YXIgcHJvcHMgPSBrZXlzKHNvdXJjZSksXG4gICAgICAgICAgbWV0aG9kTmFtZXMgPSBiYXNlRnVuY3Rpb25zKHNvdXJjZSwgcHJvcHMpO1xuXG4gICAgICBpZiAob3B0aW9ucyA9PSBudWxsICYmXG4gICAgICAgICAgIShpc09iamVjdChzb3VyY2UpICYmIChtZXRob2ROYW1lcy5sZW5ndGggfHwgIXByb3BzLmxlbmd0aCkpKSB7XG4gICAgICAgIG9wdGlvbnMgPSBzb3VyY2U7XG4gICAgICAgIHNvdXJjZSA9IG9iamVjdDtcbiAgICAgICAgb2JqZWN0ID0gdGhpcztcbiAgICAgICAgbWV0aG9kTmFtZXMgPSBiYXNlRnVuY3Rpb25zKHNvdXJjZSwga2V5cyhzb3VyY2UpKTtcbiAgICAgIH1cbiAgICAgIHZhciBjaGFpbiA9ICEoaXNPYmplY3Qob3B0aW9ucykgJiYgJ2NoYWluJyBpbiBvcHRpb25zKSB8fCAhIW9wdGlvbnMuY2hhaW4sXG4gICAgICAgICAgaXNGdW5jID0gaXNGdW5jdGlvbihvYmplY3QpO1xuXG4gICAgICBhcnJheUVhY2gobWV0aG9kTmFtZXMsIGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICAgICAgdmFyIGZ1bmMgPSBzb3VyY2VbbWV0aG9kTmFtZV07XG4gICAgICAgIG9iamVjdFttZXRob2ROYW1lXSA9IGZ1bmM7XG4gICAgICAgIGlmIChpc0Z1bmMpIHtcbiAgICAgICAgICBvYmplY3QucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgY2hhaW5BbGwgPSB0aGlzLl9fY2hhaW5fXztcbiAgICAgICAgICAgIGlmIChjaGFpbiB8fCBjaGFpbkFsbCkge1xuICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gb2JqZWN0KHRoaXMuX193cmFwcGVkX18pLFxuICAgICAgICAgICAgICAgICAgYWN0aW9ucyA9IHJlc3VsdC5fX2FjdGlvbnNfXyA9IGNvcHlBcnJheSh0aGlzLl9fYWN0aW9uc19fKTtcblxuICAgICAgICAgICAgICBhY3Rpb25zLnB1c2goeyAnZnVuYyc6IGZ1bmMsICdhcmdzJzogYXJndW1lbnRzLCAndGhpc0FyZyc6IG9iamVjdCB9KTtcbiAgICAgICAgICAgICAgcmVzdWx0Ll9fY2hhaW5fXyA9IGNoYWluQWxsO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkob2JqZWN0LCBhcnJheVB1c2goW3RoaXMudmFsdWUoKV0sIGFyZ3VtZW50cykpO1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGBfYCB2YXJpYWJsZSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG9cbiAgICAgKiB0aGUgYGxvZGFzaGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgYGxvZGFzaGAgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBsb2Rhc2ggPSBfLm5vQ29uZmxpY3QoKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgaWYgKHJvb3QuXyA9PT0gdGhpcykge1xuICAgICAgICByb290Ll8gPSBvbGREYXNoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBgdW5kZWZpbmVkYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGltZXMoMiwgXy5ub29wKTtcbiAgICAgKiAvLyA9PiBbdW5kZWZpbmVkLCB1bmRlZmluZWRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gbm9vcCgpIHtcbiAgICAgIC8vIE5vIG9wZXJhdGlvbiBwZXJmb3JtZWQuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgZ2V0cyB0aGUgYXJndW1lbnQgYXQgaW5kZXggYG5gLiBJZiBgbmAgaXMgbmVnYXRpdmUsXG4gICAgICogdGhlIG50aCBhcmd1bWVudCBmcm9tIHRoZSBlbmQgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0wXSBUaGUgaW5kZXggb2YgdGhlIGFyZ3VtZW50IHRvIHJldHVybi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBwYXNzLXRocnUgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBmdW5jID0gXy5udGhBcmcoMSk7XG4gICAgICogZnVuYygnYScsICdiJywgJ2MnLCAnZCcpO1xuICAgICAqIC8vID0+ICdiJ1xuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm50aEFyZygtMik7XG4gICAgICogZnVuYygnYScsICdiJywgJ2MnLCAnZCcpO1xuICAgICAqIC8vID0+ICdjJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIG50aEFyZyhuKSB7XG4gICAgICBuID0gdG9JbnRlZ2VyKG4pO1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VOdGgoYXJncywgbik7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBpdGVyYXRlZXNgIHdpdGggdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlc1xuICAgICAqIGFuZCByZXR1cm5zIHRoZWlyIHJlc3VsdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Li4uKEZ1bmN0aW9ufEZ1bmN0aW9uW10pfSBbaXRlcmF0ZWVzPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGl0ZXJhdGVlcyB0byBpbnZva2UuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBmdW5jID0gXy5vdmVyKFtNYXRoLm1heCwgTWF0aC5taW5dKTtcbiAgICAgKlxuICAgICAqIGZ1bmMoMSwgMiwgMywgNCk7XG4gICAgICogLy8gPT4gWzQsIDFdXG4gICAgICovXG4gICAgdmFyIG92ZXIgPSBjcmVhdGVPdmVyKGFycmF5TWFwKTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyBpZiAqKmFsbCoqIG9mIHRoZSBgcHJlZGljYXRlc2AgcmV0dXJuXG4gICAgICogdHJ1dGh5IHdoZW4gaW52b2tlZCB3aXRoIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBGb2xsb3dpbmcgc2hvcnRoYW5kcyBhcmUgcG9zc2libGUgZm9yIHByb3ZpZGluZyBwcmVkaWNhdGVzLlxuICAgICAqIFBhc3MgYW4gYE9iamVjdGAgYW5kIGl0IHdpbGwgYmUgdXNlZCBhcyBhbiBwYXJhbWV0ZXIgZm9yIGBfLm1hdGNoZXNgIHRvIGNyZWF0ZSB0aGUgcHJlZGljYXRlLlxuICAgICAqIFBhc3MgYW4gYEFycmF5YCBvZiBwYXJhbWV0ZXJzIGZvciBgXy5tYXRjaGVzUHJvcGVydHlgIGFuZCB0aGUgcHJlZGljYXRlIHdpbGwgYmUgY3JlYXRlZCB1c2luZyB0aGVtLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW3ByZWRpY2F0ZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgcHJlZGljYXRlcyB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJFdmVyeShbQm9vbGVhbiwgaXNGaW5pdGVdKTtcbiAgICAgKlxuICAgICAqIGZ1bmMoJzEnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBmdW5jKG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBmdW5jKE5hTik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgb3ZlckV2ZXJ5ID0gY3JlYXRlT3ZlcihhcnJheUV2ZXJ5KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyBpZiAqKmFueSoqIG9mIHRoZSBgcHJlZGljYXRlc2AgcmV0dXJuXG4gICAgICogdHJ1dGh5IHdoZW4gaW52b2tlZCB3aXRoIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBGb2xsb3dpbmcgc2hvcnRoYW5kcyBhcmUgcG9zc2libGUgZm9yIHByb3ZpZGluZyBwcmVkaWNhdGVzLlxuICAgICAqIFBhc3MgYW4gYE9iamVjdGAgYW5kIGl0IHdpbGwgYmUgdXNlZCBhcyBhbiBwYXJhbWV0ZXIgZm9yIGBfLm1hdGNoZXNgIHRvIGNyZWF0ZSB0aGUgcHJlZGljYXRlLlxuICAgICAqIFBhc3MgYW4gYEFycmF5YCBvZiBwYXJhbWV0ZXJzIGZvciBgXy5tYXRjaGVzUHJvcGVydHlgIGFuZCB0aGUgcHJlZGljYXRlIHdpbGwgYmUgY3JlYXRlZCB1c2luZyB0aGVtLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW3ByZWRpY2F0ZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgcHJlZGljYXRlcyB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJTb21lKFtCb29sZWFuLCBpc0Zpbml0ZV0pO1xuICAgICAqXG4gICAgICogZnVuYygnMScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGZ1bmMobnVsbCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogZnVuYyhOYU4pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiB2YXIgbWF0Y2hlc0Z1bmMgPSBfLm92ZXJTb21lKFt7ICdhJzogMSB9LCB7ICdhJzogMiB9XSlcbiAgICAgKiB2YXIgbWF0Y2hlc1Byb3BlcnR5RnVuYyA9IF8ub3ZlclNvbWUoW1snYScsIDFdLCBbJ2EnLCAyXV0pXG4gICAgICovXG4gICAgdmFyIG92ZXJTb21lID0gY3JlYXRlT3ZlcihhcnJheVNvbWUpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgdmFsdWUgYXQgYHBhdGhgIG9mIGEgZ2l2ZW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuNC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiB7ICdiJzogMiB9IH0sXG4gICAgICogICB7ICdhJzogeyAnYic6IDEgfSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYicpKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKlxuICAgICAqIF8ubWFwKF8uc29ydEJ5KG9iamVjdHMsIF8ucHJvcGVydHkoWydhJywgJ2InXSkpLCAnYS5iJyk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHJvcGVydHkocGF0aCkge1xuICAgICAgcmV0dXJuIGlzS2V5KHBhdGgpID8gYmFzZVByb3BlcnR5KHRvS2V5KHBhdGgpKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLnByb3BlcnR5YDsgdGhpcyBtZXRob2QgY3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJuc1xuICAgICAqIHRoZSB2YWx1ZSBhdCBhIGdpdmVuIHBhdGggb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzAsIDEsIDJdLFxuICAgICAqICAgICBvYmplY3QgPSB7ICdhJzogYXJyYXksICdiJzogYXJyYXksICdjJzogYXJyYXkgfTtcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnYVsyXScsICdjWzBdJ10sIF8ucHJvcGVydHlPZihvYmplY3QpKTtcbiAgICAgKiAvLyA9PiBbMiwgMF1cbiAgICAgKlxuICAgICAqIF8ubWFwKFtbJ2EnLCAnMiddLCBbJ2MnLCAnMCddXSwgXy5wcm9wZXJ0eU9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHByb3BlcnR5T2Yob2JqZWN0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ocGF0aCkge1xuICAgICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgbnVtYmVycyAocG9zaXRpdmUgYW5kL29yIG5lZ2F0aXZlKSBwcm9ncmVzc2luZyBmcm9tXG4gICAgICogYHN0YXJ0YCB1cCB0bywgYnV0IG5vdCBpbmNsdWRpbmcsIGBlbmRgLiBBIHN0ZXAgb2YgYC0xYCBpcyB1c2VkIGlmIGEgbmVnYXRpdmVcbiAgICAgKiBgc3RhcnRgIGlzIHNwZWNpZmllZCB3aXRob3V0IGFuIGBlbmRgIG9yIGBzdGVwYC4gSWYgYGVuZGAgaXMgbm90IHNwZWNpZmllZCxcbiAgICAgKiBpdCdzIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSmF2YVNjcmlwdCBmb2xsb3dzIHRoZSBJRUVFLTc1NCBzdGFuZGFyZCBmb3IgcmVzb2x2aW5nXG4gICAgICogZmxvYXRpbmctcG9pbnQgdmFsdWVzIHdoaWNoIGNhbiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTFdIFRoZSB2YWx1ZSB0byBpbmNyZW1lbnQgb3IgZGVjcmVtZW50IGJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZ2Ugb2YgbnVtYmVycy5cbiAgICAgKiBAc2VlIF8uaW5SYW5nZSwgXy5yYW5nZVJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoNCk7XG4gICAgICogLy8gPT4gWzAsIDEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKC00KTtcbiAgICAgKiAvLyA9PiBbMCwgLTEsIC0yLCAtM11cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoMSwgNSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDMsIDRdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDAsIDIwLCA1KTtcbiAgICAgKiAvLyA9PiBbMCwgNSwgMTAsIDE1XVxuICAgICAqXG4gICAgICogXy5yYW5nZSgwLCAtNCwgLTEpO1xuICAgICAqIC8vID0+IFswLCAtMSwgLTIsIC0zXVxuICAgICAqXG4gICAgICogXy5yYW5nZSgxLCA0LCAwKTtcbiAgICAgKiAvLyA9PiBbMSwgMSwgMV1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoMCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICB2YXIgcmFuZ2UgPSBjcmVhdGVSYW5nZSgpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5yYW5nZWAgZXhjZXB0IHRoYXQgaXQgcG9wdWxhdGVzIHZhbHVlcyBpblxuICAgICAqIGRlc2NlbmRpbmcgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RlcD0xXSBUaGUgdmFsdWUgdG8gaW5jcmVtZW50IG9yIGRlY3JlbWVudCBieS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmdlIG9mIG51bWJlcnMuXG4gICAgICogQHNlZSBfLmluUmFuZ2UsIF8ucmFuZ2VcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDQpO1xuICAgICAqIC8vID0+IFszLCAyLCAxLCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KC00KTtcbiAgICAgKiAvLyA9PiBbLTMsIC0yLCAtMSwgMF1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2VSaWdodCgxLCA1KTtcbiAgICAgKiAvLyA9PiBbNCwgMywgMiwgMV1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2VSaWdodCgwLCAyMCwgNSk7XG4gICAgICogLy8gPT4gWzE1LCAxMCwgNSwgMF1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2VSaWdodCgwLCAtNCwgLTEpO1xuICAgICAqIC8vID0+IFstMywgLTIsIC0xLCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDEsIDQsIDApO1xuICAgICAqIC8vID0+IFsxLCAxLCAxXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDApO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgdmFyIHJhbmdlUmlnaHQgPSBjcmVhdGVSYW5nZSh0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgZW1wdHkgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBlbXB0eSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5cyA9IF8udGltZXMoMiwgXy5zdHViQXJyYXkpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXlzKTtcbiAgICAgKiAvLyA9PiBbW10sIFtdXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXlzWzBdID09PSBhcnJheXNbMV0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3R1YkFycmF5KCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjEzLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGltZXMoMiwgXy5zdHViRmFsc2UpO1xuICAgICAqIC8vID0+IFtmYWxzZSwgZmFsc2VdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3R1YkZhbHNlKCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgZW1wdHkgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGVtcHR5IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBfLnRpbWVzKDIsIF8uc3R1Yk9iamVjdCk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3RzKTtcbiAgICAgKiAvLyA9PiBbe30sIHt9XVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0c1swXSA9PT0gb2JqZWN0c1sxXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViT2JqZWN0KCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYW4gZW1wdHkgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDIsIF8uc3R1YlN0cmluZyk7XG4gICAgICogLy8gPT4gWycnLCAnJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViU3RyaW5nKCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYHRydWVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDIsIF8uc3R1YlRydWUpO1xuICAgICAqIC8vID0+IFt0cnVlLCB0cnVlXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0dWJUcnVlKCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUgaXRlcmF0ZWUgYG5gIHRpbWVzLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgdGhlIHJlc3VsdHMgb2ZcbiAgICAgKiBlYWNoIGludm9jYXRpb24uIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OyAoaW5kZXgpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGludm9rZSBgaXRlcmF0ZWVgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50aW1lcygzLCBTdHJpbmcpO1xuICAgICAqIC8vID0+IFsnMCcsICcxJywgJzInXVxuICAgICAqXG4gICAgICogIF8udGltZXMoNCwgXy5jb25zdGFudCgwKSk7XG4gICAgICogLy8gPT4gWzAsIDAsIDAsIDBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGltZXMobiwgaXRlcmF0ZWUpIHtcbiAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICBpZiAobiA8IDEgfHwgbiA+IE1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gTUFYX0FSUkFZX0xFTkdUSCxcbiAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNaW4obiwgTUFYX0FSUkFZX0xFTkdUSCk7XG5cbiAgICAgIGl0ZXJhdGVlID0gZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUpO1xuICAgICAgbiAtPSBNQVhfQVJSQVlfTEVOR1RIO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZVRpbWVzKGxlbmd0aCwgaXRlcmF0ZWUpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBuKSB7XG4gICAgICAgIGl0ZXJhdGVlKGluZGV4KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b1BhdGgoJ2EuYi5jJyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddXG4gICAgICpcbiAgICAgKiBfLnRvUGF0aCgnYVswXS5iLmMnKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnMCcsICdiJywgJ2MnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvUGF0aCh2YWx1ZSkge1xuICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBhcnJheU1hcCh2YWx1ZSwgdG9LZXkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzU3ltYm9sKHZhbHVlKSA/IFt2YWx1ZV0gOiBjb3B5QXJyYXkoc3RyaW5nVG9QYXRoKHRvU3RyaW5nKHZhbHVlKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlcyBhIHVuaXF1ZSBJRC4gSWYgYHByZWZpeGAgaXMgZ2l2ZW4sIHRoZSBJRCBpcyBhcHBlbmRlZCB0byBpdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtwcmVmaXg9JyddIFRoZSB2YWx1ZSB0byBwcmVmaXggdGhlIElEIHdpdGguXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdW5pcXVlIElELlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaXF1ZUlkKCdjb250YWN0XycpO1xuICAgICAqIC8vID0+ICdjb250YWN0XzEwNCdcbiAgICAgKlxuICAgICAqIF8udW5pcXVlSWQoKTtcbiAgICAgKiAvLyA9PiAnMTA1J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuaXF1ZUlkKHByZWZpeCkge1xuICAgICAgdmFyIGlkID0gKytpZENvdW50ZXI7XG4gICAgICByZXR1cm4gdG9TdHJpbmcocHJlZml4KSArIGlkO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEFkZHMgdHdvIG51bWJlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy40LjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhdWdlbmQgVGhlIGZpcnN0IG51bWJlciBpbiBhbiBhZGRpdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYWRkZW5kIFRoZSBzZWNvbmQgbnVtYmVyIGluIGFuIGFkZGl0aW9uLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRvdGFsLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmFkZCg2LCA0KTtcbiAgICAgKiAvLyA9PiAxMFxuICAgICAqL1xuICAgIHZhciBhZGQgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKGF1Z2VuZCwgYWRkZW5kKSB7XG4gICAgICByZXR1cm4gYXVnZW5kICsgYWRkZW5kO1xuICAgIH0sIDApO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYG51bWJlcmAgcm91bmRlZCB1cCB0byBgcHJlY2lzaW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byByb3VuZCB1cC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ByZWNpc2lvbj0wXSBUaGUgcHJlY2lzaW9uIHRvIHJvdW5kIHVwIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgdXAgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNlaWwoNC4wMDYpO1xuICAgICAqIC8vID0+IDVcbiAgICAgKlxuICAgICAqIF8uY2VpbCg2LjAwNCwgMik7XG4gICAgICogLy8gPT4gNi4wMVxuICAgICAqXG4gICAgICogXy5jZWlsKDYwNDAsIC0yKTtcbiAgICAgKiAvLyA9PiA2MTAwXG4gICAgICovXG4gICAgdmFyIGNlaWwgPSBjcmVhdGVSb3VuZCgnY2VpbCcpO1xuXG4gICAgLyoqXG4gICAgICogRGl2aWRlIHR3byBudW1iZXJzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGl2aWRlbmQgVGhlIGZpcnN0IG51bWJlciBpbiBhIGRpdmlzaW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkaXZpc29yIFRoZSBzZWNvbmQgbnVtYmVyIGluIGEgZGl2aXNpb24uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcXVvdGllbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGl2aWRlKDYsIDQpO1xuICAgICAqIC8vID0+IDEuNVxuICAgICAqL1xuICAgIHZhciBkaXZpZGUgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKGRpdmlkZW5kLCBkaXZpc29yKSB7XG4gICAgICByZXR1cm4gZGl2aWRlbmQgLyBkaXZpc29yO1xuICAgIH0sIDEpO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYG51bWJlcmAgcm91bmRlZCBkb3duIHRvIGBwcmVjaXNpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIHJvdW5kIGRvd24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtwcmVjaXNpb249MF0gVGhlIHByZWNpc2lvbiB0byByb3VuZCBkb3duIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgZG93biBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoNC4wMDYpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoMC4wNDYsIDIpO1xuICAgICAqIC8vID0+IDAuMDRcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoNDA2MCwgLTIpO1xuICAgICAqIC8vID0+IDQwMDBcbiAgICAgKi9cbiAgICB2YXIgZmxvb3IgPSBjcmVhdGVSb3VuZCgnZmxvb3InKTtcblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgZW1wdHkgb3IgZmFsc2V5LFxuICAgICAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1heChbNCwgMiwgOCwgNl0pO1xuICAgICAqIC8vID0+IDhcbiAgICAgKlxuICAgICAqIF8ubWF4KFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXgoYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHksIGJhc2VHdClcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5tYXhgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2hcbiAgICAgKiB0aGUgdmFsdWUgaXMgcmFua2VkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ24nOiAxIH0sIHsgJ24nOiAyIH1dO1xuICAgICAqXG4gICAgICogXy5tYXhCeShvYmplY3RzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLm47IH0pO1xuICAgICAqIC8vID0+IHsgJ24nOiAyIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWF4Qnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiB7ICduJzogMiB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWF4QnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlRXh0cmVtdW0oYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSwgYmFzZUd0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgbWVhbiBvZiB0aGUgdmFsdWVzIGluIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbWVhbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5tZWFuKFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gNVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1lYW4oYXJyYXkpIHtcbiAgICAgIHJldHVybiBiYXNlTWVhbihhcnJheSwgaWRlbnRpdHkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ubWVhbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IGluIGBhcnJheWAgdG8gZ2VuZXJhdGUgdGhlIHZhbHVlIHRvIGJlIGF2ZXJhZ2VkLlxuICAgICAqIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICduJzogNCB9LCB7ICduJzogMiB9LCB7ICduJzogOCB9LCB7ICduJzogNiB9XTtcbiAgICAgKlxuICAgICAqIF8ubWVhbkJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4gNVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5tZWFuQnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVhbkJ5KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGJhc2VNZWFuKGFycmF5LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBtaW5pbXVtIHZhbHVlIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgZW1wdHkgb3IgZmFsc2V5LFxuICAgICAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtaW5pbXVtIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1pbihbNCwgMiwgOCwgNl0pO1xuICAgICAqIC8vID0+IDJcbiAgICAgKlxuICAgICAqIF8ubWluKFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtaW4oYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHksIGJhc2VMdClcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5taW5gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2hcbiAgICAgKiB0aGUgdmFsdWUgaXMgcmFua2VkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1pbmltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ24nOiAxIH0sIHsgJ24nOiAyIH1dO1xuICAgICAqXG4gICAgICogXy5taW5CeShvYmplY3RzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLm47IH0pO1xuICAgICAqIC8vID0+IHsgJ24nOiAxIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWluQnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiB7ICduJzogMSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWluQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlRXh0cmVtdW0oYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSwgYmFzZUx0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNdWx0aXBseSB0d28gbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjcuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG11bHRpcGxpZXIgVGhlIGZpcnN0IG51bWJlciBpbiBhIG11bHRpcGxpY2F0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtdWx0aXBsaWNhbmQgVGhlIHNlY29uZCBudW1iZXIgaW4gYSBtdWx0aXBsaWNhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBwcm9kdWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm11bHRpcGx5KDYsIDQpO1xuICAgICAqIC8vID0+IDI0XG4gICAgICovXG4gICAgdmFyIG11bHRpcGx5ID0gY3JlYXRlTWF0aE9wZXJhdGlvbihmdW5jdGlvbihtdWx0aXBsaWVyLCBtdWx0aXBsaWNhbmQpIHtcbiAgICAgIHJldHVybiBtdWx0aXBsaWVyICogbXVsdGlwbGljYW5kO1xuICAgIH0sIDEpO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYG51bWJlcmAgcm91bmRlZCB0byBgcHJlY2lzaW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byByb3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ByZWNpc2lvbj0wXSBUaGUgcHJlY2lzaW9uIHRvIHJvdW5kIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJvdW5kKDQuMDA2KTtcbiAgICAgKiAvLyA9PiA0XG4gICAgICpcbiAgICAgKiBfLnJvdW5kKDQuMDA2LCAyKTtcbiAgICAgKiAvLyA9PiA0LjAxXG4gICAgICpcbiAgICAgKiBfLnJvdW5kKDQwNjAsIC0yKTtcbiAgICAgKiAvLyA9PiA0MTAwXG4gICAgICovXG4gICAgdmFyIHJvdW5kID0gY3JlYXRlUm91bmQoJ3JvdW5kJyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0cmFjdCB0d28gbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1pbnVlbmQgVGhlIGZpcnN0IG51bWJlciBpbiBhIHN1YnRyYWN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdWJ0cmFoZW5kIFRoZSBzZWNvbmQgbnVtYmVyIGluIGEgc3VidHJhY3Rpb24uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgZGlmZmVyZW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zdWJ0cmFjdCg2LCA0KTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICovXG4gICAgdmFyIHN1YnRyYWN0ID0gY3JlYXRlTWF0aE9wZXJhdGlvbihmdW5jdGlvbihtaW51ZW5kLCBzdWJ0cmFoZW5kKSB7XG4gICAgICByZXR1cm4gbWludWVuZCAtIHN1YnRyYWhlbmQ7XG4gICAgfSwgMCk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgc3VtIG9mIHRoZSB2YWx1ZXMgaW4gYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjQuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdW0uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3VtKFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdW0oYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VTdW0oYXJyYXksIGlkZW50aXR5KVxuICAgICAgICA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zdW1gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSB2YWx1ZSB0byBiZSBzdW1tZWQuXG4gICAgICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAnbic6IDQgfSwgeyAnbic6IDIgfSwgeyAnbic6IDggfSwgeyAnbic6IDYgfV07XG4gICAgICpcbiAgICAgKiBfLnN1bUJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc3VtQnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiAyMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN1bUJ5KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVN1bShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IDA7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQWRkIG1ldGhvZHMgdGhhdCByZXR1cm4gd3JhcHBlZCB2YWx1ZXMgaW4gY2hhaW4gc2VxdWVuY2VzLlxuICAgIGxvZGFzaC5hZnRlciA9IGFmdGVyO1xuICAgIGxvZGFzaC5hcnkgPSBhcnk7XG4gICAgbG9kYXNoLmFzc2lnbiA9IGFzc2lnbjtcbiAgICBsb2Rhc2guYXNzaWduSW4gPSBhc3NpZ25JbjtcbiAgICBsb2Rhc2guYXNzaWduSW5XaXRoID0gYXNzaWduSW5XaXRoO1xuICAgIGxvZGFzaC5hc3NpZ25XaXRoID0gYXNzaWduV2l0aDtcbiAgICBsb2Rhc2guYXQgPSBhdDtcbiAgICBsb2Rhc2guYmVmb3JlID0gYmVmb3JlO1xuICAgIGxvZGFzaC5iaW5kID0gYmluZDtcbiAgICBsb2Rhc2guYmluZEFsbCA9IGJpbmRBbGw7XG4gICAgbG9kYXNoLmJpbmRLZXkgPSBiaW5kS2V5O1xuICAgIGxvZGFzaC5jYXN0QXJyYXkgPSBjYXN0QXJyYXk7XG4gICAgbG9kYXNoLmNoYWluID0gY2hhaW47XG4gICAgbG9kYXNoLmNodW5rID0gY2h1bms7XG4gICAgbG9kYXNoLmNvbXBhY3QgPSBjb21wYWN0O1xuICAgIGxvZGFzaC5jb25jYXQgPSBjb25jYXQ7XG4gICAgbG9kYXNoLmNvbmQgPSBjb25kO1xuICAgIGxvZGFzaC5jb25mb3JtcyA9IGNvbmZvcm1zO1xuICAgIGxvZGFzaC5jb25zdGFudCA9IGNvbnN0YW50O1xuICAgIGxvZGFzaC5jb3VudEJ5ID0gY291bnRCeTtcbiAgICBsb2Rhc2guY3JlYXRlID0gY3JlYXRlO1xuICAgIGxvZGFzaC5jdXJyeSA9IGN1cnJ5O1xuICAgIGxvZGFzaC5jdXJyeVJpZ2h0ID0gY3VycnlSaWdodDtcbiAgICBsb2Rhc2guZGVib3VuY2UgPSBkZWJvdW5jZTtcbiAgICBsb2Rhc2guZGVmYXVsdHMgPSBkZWZhdWx0cztcbiAgICBsb2Rhc2guZGVmYXVsdHNEZWVwID0gZGVmYXVsdHNEZWVwO1xuICAgIGxvZGFzaC5kZWZlciA9IGRlZmVyO1xuICAgIGxvZGFzaC5kZWxheSA9IGRlbGF5O1xuICAgIGxvZGFzaC5kaWZmZXJlbmNlID0gZGlmZmVyZW5jZTtcbiAgICBsb2Rhc2guZGlmZmVyZW5jZUJ5ID0gZGlmZmVyZW5jZUJ5O1xuICAgIGxvZGFzaC5kaWZmZXJlbmNlV2l0aCA9IGRpZmZlcmVuY2VXaXRoO1xuICAgIGxvZGFzaC5kcm9wID0gZHJvcDtcbiAgICBsb2Rhc2guZHJvcFJpZ2h0ID0gZHJvcFJpZ2h0O1xuICAgIGxvZGFzaC5kcm9wUmlnaHRXaGlsZSA9IGRyb3BSaWdodFdoaWxlO1xuICAgIGxvZGFzaC5kcm9wV2hpbGUgPSBkcm9wV2hpbGU7XG4gICAgbG9kYXNoLmZpbGwgPSBmaWxsO1xuICAgIGxvZGFzaC5maWx0ZXIgPSBmaWx0ZXI7XG4gICAgbG9kYXNoLmZsYXRNYXAgPSBmbGF0TWFwO1xuICAgIGxvZGFzaC5mbGF0TWFwRGVlcCA9IGZsYXRNYXBEZWVwO1xuICAgIGxvZGFzaC5mbGF0TWFwRGVwdGggPSBmbGF0TWFwRGVwdGg7XG4gICAgbG9kYXNoLmZsYXR0ZW4gPSBmbGF0dGVuO1xuICAgIGxvZGFzaC5mbGF0dGVuRGVlcCA9IGZsYXR0ZW5EZWVwO1xuICAgIGxvZGFzaC5mbGF0dGVuRGVwdGggPSBmbGF0dGVuRGVwdGg7XG4gICAgbG9kYXNoLmZsaXAgPSBmbGlwO1xuICAgIGxvZGFzaC5mbG93ID0gZmxvdztcbiAgICBsb2Rhc2guZmxvd1JpZ2h0ID0gZmxvd1JpZ2h0O1xuICAgIGxvZGFzaC5mcm9tUGFpcnMgPSBmcm9tUGFpcnM7XG4gICAgbG9kYXNoLmZ1bmN0aW9ucyA9IGZ1bmN0aW9ucztcbiAgICBsb2Rhc2guZnVuY3Rpb25zSW4gPSBmdW5jdGlvbnNJbjtcbiAgICBsb2Rhc2guZ3JvdXBCeSA9IGdyb3VwQnk7XG4gICAgbG9kYXNoLmluaXRpYWwgPSBpbml0aWFsO1xuICAgIGxvZGFzaC5pbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3Rpb247XG4gICAgbG9kYXNoLmludGVyc2VjdGlvbkJ5ID0gaW50ZXJzZWN0aW9uQnk7XG4gICAgbG9kYXNoLmludGVyc2VjdGlvbldpdGggPSBpbnRlcnNlY3Rpb25XaXRoO1xuICAgIGxvZGFzaC5pbnZlcnQgPSBpbnZlcnQ7XG4gICAgbG9kYXNoLmludmVydEJ5ID0gaW52ZXJ0Qnk7XG4gICAgbG9kYXNoLmludm9rZU1hcCA9IGludm9rZU1hcDtcbiAgICBsb2Rhc2guaXRlcmF0ZWUgPSBpdGVyYXRlZTtcbiAgICBsb2Rhc2gua2V5QnkgPSBrZXlCeTtcbiAgICBsb2Rhc2gua2V5cyA9IGtleXM7XG4gICAgbG9kYXNoLmtleXNJbiA9IGtleXNJbjtcbiAgICBsb2Rhc2gubWFwID0gbWFwO1xuICAgIGxvZGFzaC5tYXBLZXlzID0gbWFwS2V5cztcbiAgICBsb2Rhc2gubWFwVmFsdWVzID0gbWFwVmFsdWVzO1xuICAgIGxvZGFzaC5tYXRjaGVzID0gbWF0Y2hlcztcbiAgICBsb2Rhc2gubWF0Y2hlc1Byb3BlcnR5ID0gbWF0Y2hlc1Byb3BlcnR5O1xuICAgIGxvZGFzaC5tZW1vaXplID0gbWVtb2l6ZTtcbiAgICBsb2Rhc2gubWVyZ2UgPSBtZXJnZTtcbiAgICBsb2Rhc2gubWVyZ2VXaXRoID0gbWVyZ2VXaXRoO1xuICAgIGxvZGFzaC5tZXRob2QgPSBtZXRob2Q7XG4gICAgbG9kYXNoLm1ldGhvZE9mID0gbWV0aG9kT2Y7XG4gICAgbG9kYXNoLm1peGluID0gbWl4aW47XG4gICAgbG9kYXNoLm5lZ2F0ZSA9IG5lZ2F0ZTtcbiAgICBsb2Rhc2gubnRoQXJnID0gbnRoQXJnO1xuICAgIGxvZGFzaC5vbWl0ID0gb21pdDtcbiAgICBsb2Rhc2gub21pdEJ5ID0gb21pdEJ5O1xuICAgIGxvZGFzaC5vbmNlID0gb25jZTtcbiAgICBsb2Rhc2gub3JkZXJCeSA9IG9yZGVyQnk7XG4gICAgbG9kYXNoLm92ZXIgPSBvdmVyO1xuICAgIGxvZGFzaC5vdmVyQXJncyA9IG92ZXJBcmdzO1xuICAgIGxvZGFzaC5vdmVyRXZlcnkgPSBvdmVyRXZlcnk7XG4gICAgbG9kYXNoLm92ZXJTb21lID0gb3ZlclNvbWU7XG4gICAgbG9kYXNoLnBhcnRpYWwgPSBwYXJ0aWFsO1xuICAgIGxvZGFzaC5wYXJ0aWFsUmlnaHQgPSBwYXJ0aWFsUmlnaHQ7XG4gICAgbG9kYXNoLnBhcnRpdGlvbiA9IHBhcnRpdGlvbjtcbiAgICBsb2Rhc2gucGljayA9IHBpY2s7XG4gICAgbG9kYXNoLnBpY2tCeSA9IHBpY2tCeTtcbiAgICBsb2Rhc2gucHJvcGVydHkgPSBwcm9wZXJ0eTtcbiAgICBsb2Rhc2gucHJvcGVydHlPZiA9IHByb3BlcnR5T2Y7XG4gICAgbG9kYXNoLnB1bGwgPSBwdWxsO1xuICAgIGxvZGFzaC5wdWxsQWxsID0gcHVsbEFsbDtcbiAgICBsb2Rhc2gucHVsbEFsbEJ5ID0gcHVsbEFsbEJ5O1xuICAgIGxvZGFzaC5wdWxsQWxsV2l0aCA9IHB1bGxBbGxXaXRoO1xuICAgIGxvZGFzaC5wdWxsQXQgPSBwdWxsQXQ7XG4gICAgbG9kYXNoLnJhbmdlID0gcmFuZ2U7XG4gICAgbG9kYXNoLnJhbmdlUmlnaHQgPSByYW5nZVJpZ2h0O1xuICAgIGxvZGFzaC5yZWFyZyA9IHJlYXJnO1xuICAgIGxvZGFzaC5yZWplY3QgPSByZWplY3Q7XG4gICAgbG9kYXNoLnJlbW92ZSA9IHJlbW92ZTtcbiAgICBsb2Rhc2gucmVzdCA9IHJlc3Q7XG4gICAgbG9kYXNoLnJldmVyc2UgPSByZXZlcnNlO1xuICAgIGxvZGFzaC5zYW1wbGVTaXplID0gc2FtcGxlU2l6ZTtcbiAgICBsb2Rhc2guc2V0ID0gc2V0O1xuICAgIGxvZGFzaC5zZXRXaXRoID0gc2V0V2l0aDtcbiAgICBsb2Rhc2guc2h1ZmZsZSA9IHNodWZmbGU7XG4gICAgbG9kYXNoLnNsaWNlID0gc2xpY2U7XG4gICAgbG9kYXNoLnNvcnRCeSA9IHNvcnRCeTtcbiAgICBsb2Rhc2guc29ydGVkVW5pcSA9IHNvcnRlZFVuaXE7XG4gICAgbG9kYXNoLnNvcnRlZFVuaXFCeSA9IHNvcnRlZFVuaXFCeTtcbiAgICBsb2Rhc2guc3BsaXQgPSBzcGxpdDtcbiAgICBsb2Rhc2guc3ByZWFkID0gc3ByZWFkO1xuICAgIGxvZGFzaC50YWlsID0gdGFpbDtcbiAgICBsb2Rhc2gudGFrZSA9IHRha2U7XG4gICAgbG9kYXNoLnRha2VSaWdodCA9IHRha2VSaWdodDtcbiAgICBsb2Rhc2gudGFrZVJpZ2h0V2hpbGUgPSB0YWtlUmlnaHRXaGlsZTtcbiAgICBsb2Rhc2gudGFrZVdoaWxlID0gdGFrZVdoaWxlO1xuICAgIGxvZGFzaC50YXAgPSB0YXA7XG4gICAgbG9kYXNoLnRocm90dGxlID0gdGhyb3R0bGU7XG4gICAgbG9kYXNoLnRocnUgPSB0aHJ1O1xuICAgIGxvZGFzaC50b0FycmF5ID0gdG9BcnJheTtcbiAgICBsb2Rhc2gudG9QYWlycyA9IHRvUGFpcnM7XG4gICAgbG9kYXNoLnRvUGFpcnNJbiA9IHRvUGFpcnNJbjtcbiAgICBsb2Rhc2gudG9QYXRoID0gdG9QYXRoO1xuICAgIGxvZGFzaC50b1BsYWluT2JqZWN0ID0gdG9QbGFpbk9iamVjdDtcbiAgICBsb2Rhc2gudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgIGxvZGFzaC51bmFyeSA9IHVuYXJ5O1xuICAgIGxvZGFzaC51bmlvbiA9IHVuaW9uO1xuICAgIGxvZGFzaC51bmlvbkJ5ID0gdW5pb25CeTtcbiAgICBsb2Rhc2gudW5pb25XaXRoID0gdW5pb25XaXRoO1xuICAgIGxvZGFzaC51bmlxID0gdW5pcTtcbiAgICBsb2Rhc2gudW5pcUJ5ID0gdW5pcUJ5O1xuICAgIGxvZGFzaC51bmlxV2l0aCA9IHVuaXFXaXRoO1xuICAgIGxvZGFzaC51bnNldCA9IHVuc2V0O1xuICAgIGxvZGFzaC51bnppcCA9IHVuemlwO1xuICAgIGxvZGFzaC51bnppcFdpdGggPSB1bnppcFdpdGg7XG4gICAgbG9kYXNoLnVwZGF0ZSA9IHVwZGF0ZTtcbiAgICBsb2Rhc2gudXBkYXRlV2l0aCA9IHVwZGF0ZVdpdGg7XG4gICAgbG9kYXNoLnZhbHVlcyA9IHZhbHVlcztcbiAgICBsb2Rhc2gudmFsdWVzSW4gPSB2YWx1ZXNJbjtcbiAgICBsb2Rhc2gud2l0aG91dCA9IHdpdGhvdXQ7XG4gICAgbG9kYXNoLndvcmRzID0gd29yZHM7XG4gICAgbG9kYXNoLndyYXAgPSB3cmFwO1xuICAgIGxvZGFzaC54b3IgPSB4b3I7XG4gICAgbG9kYXNoLnhvckJ5ID0geG9yQnk7XG4gICAgbG9kYXNoLnhvcldpdGggPSB4b3JXaXRoO1xuICAgIGxvZGFzaC56aXAgPSB6aXA7XG4gICAgbG9kYXNoLnppcE9iamVjdCA9IHppcE9iamVjdDtcbiAgICBsb2Rhc2guemlwT2JqZWN0RGVlcCA9IHppcE9iamVjdERlZXA7XG4gICAgbG9kYXNoLnppcFdpdGggPSB6aXBXaXRoO1xuXG4gICAgLy8gQWRkIGFsaWFzZXMuXG4gICAgbG9kYXNoLmVudHJpZXMgPSB0b1BhaXJzO1xuICAgIGxvZGFzaC5lbnRyaWVzSW4gPSB0b1BhaXJzSW47XG4gICAgbG9kYXNoLmV4dGVuZCA9IGFzc2lnbkluO1xuICAgIGxvZGFzaC5leHRlbmRXaXRoID0gYXNzaWduSW5XaXRoO1xuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYGxvZGFzaC5wcm90b3R5cGVgLlxuICAgIG1peGluKGxvZGFzaCwgbG9kYXNoKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8vIEFkZCBtZXRob2RzIHRoYXQgcmV0dXJuIHVud3JhcHBlZCB2YWx1ZXMgaW4gY2hhaW4gc2VxdWVuY2VzLlxuICAgIGxvZGFzaC5hZGQgPSBhZGQ7XG4gICAgbG9kYXNoLmF0dGVtcHQgPSBhdHRlbXB0O1xuICAgIGxvZGFzaC5jYW1lbENhc2UgPSBjYW1lbENhc2U7XG4gICAgbG9kYXNoLmNhcGl0YWxpemUgPSBjYXBpdGFsaXplO1xuICAgIGxvZGFzaC5jZWlsID0gY2VpbDtcbiAgICBsb2Rhc2guY2xhbXAgPSBjbGFtcDtcbiAgICBsb2Rhc2guY2xvbmUgPSBjbG9uZTtcbiAgICBsb2Rhc2guY2xvbmVEZWVwID0gY2xvbmVEZWVwO1xuICAgIGxvZGFzaC5jbG9uZURlZXBXaXRoID0gY2xvbmVEZWVwV2l0aDtcbiAgICBsb2Rhc2guY2xvbmVXaXRoID0gY2xvbmVXaXRoO1xuICAgIGxvZGFzaC5jb25mb3Jtc1RvID0gY29uZm9ybXNUbztcbiAgICBsb2Rhc2guZGVidXJyID0gZGVidXJyO1xuICAgIGxvZGFzaC5kZWZhdWx0VG8gPSBkZWZhdWx0VG87XG4gICAgbG9kYXNoLmRpdmlkZSA9IGRpdmlkZTtcbiAgICBsb2Rhc2guZW5kc1dpdGggPSBlbmRzV2l0aDtcbiAgICBsb2Rhc2guZXEgPSBlcTtcbiAgICBsb2Rhc2guZXNjYXBlID0gZXNjYXBlO1xuICAgIGxvZGFzaC5lc2NhcGVSZWdFeHAgPSBlc2NhcGVSZWdFeHA7XG4gICAgbG9kYXNoLmV2ZXJ5ID0gZXZlcnk7XG4gICAgbG9kYXNoLmZpbmQgPSBmaW5kO1xuICAgIGxvZGFzaC5maW5kSW5kZXggPSBmaW5kSW5kZXg7XG4gICAgbG9kYXNoLmZpbmRLZXkgPSBmaW5kS2V5O1xuICAgIGxvZGFzaC5maW5kTGFzdCA9IGZpbmRMYXN0O1xuICAgIGxvZGFzaC5maW5kTGFzdEluZGV4ID0gZmluZExhc3RJbmRleDtcbiAgICBsb2Rhc2guZmluZExhc3RLZXkgPSBmaW5kTGFzdEtleTtcbiAgICBsb2Rhc2guZmxvb3IgPSBmbG9vcjtcbiAgICBsb2Rhc2guZm9yRWFjaCA9IGZvckVhY2g7XG4gICAgbG9kYXNoLmZvckVhY2hSaWdodCA9IGZvckVhY2hSaWdodDtcbiAgICBsb2Rhc2guZm9ySW4gPSBmb3JJbjtcbiAgICBsb2Rhc2guZm9ySW5SaWdodCA9IGZvckluUmlnaHQ7XG4gICAgbG9kYXNoLmZvck93biA9IGZvck93bjtcbiAgICBsb2Rhc2guZm9yT3duUmlnaHQgPSBmb3JPd25SaWdodDtcbiAgICBsb2Rhc2guZ2V0ID0gZ2V0O1xuICAgIGxvZGFzaC5ndCA9IGd0O1xuICAgIGxvZGFzaC5ndGUgPSBndGU7XG4gICAgbG9kYXNoLmhhcyA9IGhhcztcbiAgICBsb2Rhc2guaGFzSW4gPSBoYXNJbjtcbiAgICBsb2Rhc2guaGVhZCA9IGhlYWQ7XG4gICAgbG9kYXNoLmlkZW50aXR5ID0gaWRlbnRpdHk7XG4gICAgbG9kYXNoLmluY2x1ZGVzID0gaW5jbHVkZXM7XG4gICAgbG9kYXNoLmluZGV4T2YgPSBpbmRleE9mO1xuICAgIGxvZGFzaC5pblJhbmdlID0gaW5SYW5nZTtcbiAgICBsb2Rhc2guaW52b2tlID0gaW52b2tlO1xuICAgIGxvZGFzaC5pc0FyZ3VtZW50cyA9IGlzQXJndW1lbnRzO1xuICAgIGxvZGFzaC5pc0FycmF5ID0gaXNBcnJheTtcbiAgICBsb2Rhc2guaXNBcnJheUJ1ZmZlciA9IGlzQXJyYXlCdWZmZXI7XG4gICAgbG9kYXNoLmlzQXJyYXlMaWtlID0gaXNBcnJheUxpa2U7XG4gICAgbG9kYXNoLmlzQXJyYXlMaWtlT2JqZWN0ID0gaXNBcnJheUxpa2VPYmplY3Q7XG4gICAgbG9kYXNoLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcbiAgICBsb2Rhc2guaXNCdWZmZXIgPSBpc0J1ZmZlcjtcbiAgICBsb2Rhc2guaXNEYXRlID0gaXNEYXRlO1xuICAgIGxvZGFzaC5pc0VsZW1lbnQgPSBpc0VsZW1lbnQ7XG4gICAgbG9kYXNoLmlzRW1wdHkgPSBpc0VtcHR5O1xuICAgIGxvZGFzaC5pc0VxdWFsID0gaXNFcXVhbDtcbiAgICBsb2Rhc2guaXNFcXVhbFdpdGggPSBpc0VxdWFsV2l0aDtcbiAgICBsb2Rhc2guaXNFcnJvciA9IGlzRXJyb3I7XG4gICAgbG9kYXNoLmlzRmluaXRlID0gaXNGaW5pdGU7XG4gICAgbG9kYXNoLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuICAgIGxvZGFzaC5pc0ludGVnZXIgPSBpc0ludGVnZXI7XG4gICAgbG9kYXNoLmlzTGVuZ3RoID0gaXNMZW5ndGg7XG4gICAgbG9kYXNoLmlzTWFwID0gaXNNYXA7XG4gICAgbG9kYXNoLmlzTWF0Y2ggPSBpc01hdGNoO1xuICAgIGxvZGFzaC5pc01hdGNoV2l0aCA9IGlzTWF0Y2hXaXRoO1xuICAgIGxvZGFzaC5pc05hTiA9IGlzTmFOO1xuICAgIGxvZGFzaC5pc05hdGl2ZSA9IGlzTmF0aXZlO1xuICAgIGxvZGFzaC5pc05pbCA9IGlzTmlsO1xuICAgIGxvZGFzaC5pc051bGwgPSBpc051bGw7XG4gICAgbG9kYXNoLmlzTnVtYmVyID0gaXNOdW1iZXI7XG4gICAgbG9kYXNoLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG4gICAgbG9kYXNoLmlzT2JqZWN0TGlrZSA9IGlzT2JqZWN0TGlrZTtcbiAgICBsb2Rhc2guaXNQbGFpbk9iamVjdCA9IGlzUGxhaW5PYmplY3Q7XG4gICAgbG9kYXNoLmlzUmVnRXhwID0gaXNSZWdFeHA7XG4gICAgbG9kYXNoLmlzU2FmZUludGVnZXIgPSBpc1NhZmVJbnRlZ2VyO1xuICAgIGxvZGFzaC5pc1NldCA9IGlzU2V0O1xuICAgIGxvZGFzaC5pc1N0cmluZyA9IGlzU3RyaW5nO1xuICAgIGxvZGFzaC5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuICAgIGxvZGFzaC5pc1R5cGVkQXJyYXkgPSBpc1R5cGVkQXJyYXk7XG4gICAgbG9kYXNoLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG4gICAgbG9kYXNoLmlzV2Vha01hcCA9IGlzV2Vha01hcDtcbiAgICBsb2Rhc2guaXNXZWFrU2V0ID0gaXNXZWFrU2V0O1xuICAgIGxvZGFzaC5qb2luID0gam9pbjtcbiAgICBsb2Rhc2gua2ViYWJDYXNlID0ga2ViYWJDYXNlO1xuICAgIGxvZGFzaC5sYXN0ID0gbGFzdDtcbiAgICBsb2Rhc2gubGFzdEluZGV4T2YgPSBsYXN0SW5kZXhPZjtcbiAgICBsb2Rhc2gubG93ZXJDYXNlID0gbG93ZXJDYXNlO1xuICAgIGxvZGFzaC5sb3dlckZpcnN0ID0gbG93ZXJGaXJzdDtcbiAgICBsb2Rhc2gubHQgPSBsdDtcbiAgICBsb2Rhc2gubHRlID0gbHRlO1xuICAgIGxvZGFzaC5tYXggPSBtYXg7XG4gICAgbG9kYXNoLm1heEJ5ID0gbWF4Qnk7XG4gICAgbG9kYXNoLm1lYW4gPSBtZWFuO1xuICAgIGxvZGFzaC5tZWFuQnkgPSBtZWFuQnk7XG4gICAgbG9kYXNoLm1pbiA9IG1pbjtcbiAgICBsb2Rhc2gubWluQnkgPSBtaW5CeTtcbiAgICBsb2Rhc2guc3R1YkFycmF5ID0gc3R1YkFycmF5O1xuICAgIGxvZGFzaC5zdHViRmFsc2UgPSBzdHViRmFsc2U7XG4gICAgbG9kYXNoLnN0dWJPYmplY3QgPSBzdHViT2JqZWN0O1xuICAgIGxvZGFzaC5zdHViU3RyaW5nID0gc3R1YlN0cmluZztcbiAgICBsb2Rhc2guc3R1YlRydWUgPSBzdHViVHJ1ZTtcbiAgICBsb2Rhc2gubXVsdGlwbHkgPSBtdWx0aXBseTtcbiAgICBsb2Rhc2gubnRoID0gbnRoO1xuICAgIGxvZGFzaC5ub0NvbmZsaWN0ID0gbm9Db25mbGljdDtcbiAgICBsb2Rhc2gubm9vcCA9IG5vb3A7XG4gICAgbG9kYXNoLm5vdyA9IG5vdztcbiAgICBsb2Rhc2gucGFkID0gcGFkO1xuICAgIGxvZGFzaC5wYWRFbmQgPSBwYWRFbmQ7XG4gICAgbG9kYXNoLnBhZFN0YXJ0ID0gcGFkU3RhcnQ7XG4gICAgbG9kYXNoLnBhcnNlSW50ID0gcGFyc2VJbnQ7XG4gICAgbG9kYXNoLnJhbmRvbSA9IHJhbmRvbTtcbiAgICBsb2Rhc2gucmVkdWNlID0gcmVkdWNlO1xuICAgIGxvZGFzaC5yZWR1Y2VSaWdodCA9IHJlZHVjZVJpZ2h0O1xuICAgIGxvZGFzaC5yZXBlYXQgPSByZXBlYXQ7XG4gICAgbG9kYXNoLnJlcGxhY2UgPSByZXBsYWNlO1xuICAgIGxvZGFzaC5yZXN1bHQgPSByZXN1bHQ7XG4gICAgbG9kYXNoLnJvdW5kID0gcm91bmQ7XG4gICAgbG9kYXNoLnJ1bkluQ29udGV4dCA9IHJ1bkluQ29udGV4dDtcbiAgICBsb2Rhc2guc2FtcGxlID0gc2FtcGxlO1xuICAgIGxvZGFzaC5zaXplID0gc2l6ZTtcbiAgICBsb2Rhc2guc25ha2VDYXNlID0gc25ha2VDYXNlO1xuICAgIGxvZGFzaC5zb21lID0gc29tZTtcbiAgICBsb2Rhc2guc29ydGVkSW5kZXggPSBzb3J0ZWRJbmRleDtcbiAgICBsb2Rhc2guc29ydGVkSW5kZXhCeSA9IHNvcnRlZEluZGV4Qnk7XG4gICAgbG9kYXNoLnNvcnRlZEluZGV4T2YgPSBzb3J0ZWRJbmRleE9mO1xuICAgIGxvZGFzaC5zb3J0ZWRMYXN0SW5kZXggPSBzb3J0ZWRMYXN0SW5kZXg7XG4gICAgbG9kYXNoLnNvcnRlZExhc3RJbmRleEJ5ID0gc29ydGVkTGFzdEluZGV4Qnk7XG4gICAgbG9kYXNoLnNvcnRlZExhc3RJbmRleE9mID0gc29ydGVkTGFzdEluZGV4T2Y7XG4gICAgbG9kYXNoLnN0YXJ0Q2FzZSA9IHN0YXJ0Q2FzZTtcbiAgICBsb2Rhc2guc3RhcnRzV2l0aCA9IHN0YXJ0c1dpdGg7XG4gICAgbG9kYXNoLnN1YnRyYWN0ID0gc3VidHJhY3Q7XG4gICAgbG9kYXNoLnN1bSA9IHN1bTtcbiAgICBsb2Rhc2guc3VtQnkgPSBzdW1CeTtcbiAgICBsb2Rhc2gudGVtcGxhdGUgPSB0ZW1wbGF0ZTtcbiAgICBsb2Rhc2gudGltZXMgPSB0aW1lcztcbiAgICBsb2Rhc2gudG9GaW5pdGUgPSB0b0Zpbml0ZTtcbiAgICBsb2Rhc2gudG9JbnRlZ2VyID0gdG9JbnRlZ2VyO1xuICAgIGxvZGFzaC50b0xlbmd0aCA9IHRvTGVuZ3RoO1xuICAgIGxvZGFzaC50b0xvd2VyID0gdG9Mb3dlcjtcbiAgICBsb2Rhc2gudG9OdW1iZXIgPSB0b051bWJlcjtcbiAgICBsb2Rhc2gudG9TYWZlSW50ZWdlciA9IHRvU2FmZUludGVnZXI7XG4gICAgbG9kYXNoLnRvU3RyaW5nID0gdG9TdHJpbmc7XG4gICAgbG9kYXNoLnRvVXBwZXIgPSB0b1VwcGVyO1xuICAgIGxvZGFzaC50cmltID0gdHJpbTtcbiAgICBsb2Rhc2gudHJpbUVuZCA9IHRyaW1FbmQ7XG4gICAgbG9kYXNoLnRyaW1TdGFydCA9IHRyaW1TdGFydDtcbiAgICBsb2Rhc2gudHJ1bmNhdGUgPSB0cnVuY2F0ZTtcbiAgICBsb2Rhc2gudW5lc2NhcGUgPSB1bmVzY2FwZTtcbiAgICBsb2Rhc2gudW5pcXVlSWQgPSB1bmlxdWVJZDtcbiAgICBsb2Rhc2gudXBwZXJDYXNlID0gdXBwZXJDYXNlO1xuICAgIGxvZGFzaC51cHBlckZpcnN0ID0gdXBwZXJGaXJzdDtcblxuICAgIC8vIEFkZCBhbGlhc2VzLlxuICAgIGxvZGFzaC5lYWNoID0gZm9yRWFjaDtcbiAgICBsb2Rhc2guZWFjaFJpZ2h0ID0gZm9yRWFjaFJpZ2h0O1xuICAgIGxvZGFzaC5maXJzdCA9IGhlYWQ7XG5cbiAgICBtaXhpbihsb2Rhc2gsIChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBzb3VyY2UgPSB7fTtcbiAgICAgIGJhc2VGb3JPd24obG9kYXNoLCBmdW5jdGlvbihmdW5jLCBtZXRob2ROYW1lKSB7XG4gICAgICAgIGlmICghaGFzT3duUHJvcGVydHkuY2FsbChsb2Rhc2gucHJvdG90eXBlLCBtZXRob2ROYW1lKSkge1xuICAgICAgICAgIHNvdXJjZVttZXRob2ROYW1lXSA9IGZ1bmM7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICB9KCkpLCB7ICdjaGFpbic6IGZhbHNlIH0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNlbWFudGljIHZlcnNpb24gbnVtYmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBsb2Rhc2guVkVSU0lPTiA9IFZFUlNJT047XG5cbiAgICAvLyBBc3NpZ24gZGVmYXVsdCBwbGFjZWhvbGRlcnMuXG4gICAgYXJyYXlFYWNoKFsnYmluZCcsICdiaW5kS2V5JywgJ2N1cnJ5JywgJ2N1cnJ5UmlnaHQnLCAncGFydGlhbCcsICdwYXJ0aWFsUmlnaHQnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgbG9kYXNoW21ldGhvZE5hbWVdLnBsYWNlaG9sZGVyID0gbG9kYXNoO1xuICAgIH0pO1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyBmb3IgYF8uZHJvcGAgYW5kIGBfLnRha2VgIHZhcmlhbnRzLlxuICAgIGFycmF5RWFjaChbJ2Ryb3AnLCAndGFrZSddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24obikge1xuICAgICAgICBuID0gbiA9PT0gdW5kZWZpbmVkID8gMSA6IG5hdGl2ZU1heCh0b0ludGVnZXIobiksIDApO1xuXG4gICAgICAgIHZhciByZXN1bHQgPSAodGhpcy5fX2ZpbHRlcmVkX18gJiYgIWluZGV4KVxuICAgICAgICAgID8gbmV3IExhenlXcmFwcGVyKHRoaXMpXG4gICAgICAgICAgOiB0aGlzLmNsb25lKCk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5fX2ZpbHRlcmVkX18pIHtcbiAgICAgICAgICByZXN1bHQuX190YWtlQ291bnRfXyA9IG5hdGl2ZU1pbihuLCByZXN1bHQuX190YWtlQ291bnRfXyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0Ll9fdmlld3NfXy5wdXNoKHtcbiAgICAgICAgICAgICdzaXplJzogbmF0aXZlTWluKG4sIE1BWF9BUlJBWV9MRU5HVEgpLFxuICAgICAgICAgICAgJ3R5cGUnOiBtZXRob2ROYW1lICsgKHJlc3VsdC5fX2Rpcl9fIDwgMCA/ICdSaWdodCcgOiAnJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcblxuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWUgKyAnUmlnaHQnXSA9IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpW21ldGhvZE5hbWVdKG4pLnJldmVyc2UoKTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIHRoYXQgYWNjZXB0IGFuIGBpdGVyYXRlZWAgdmFsdWUuXG4gICAgYXJyYXlFYWNoKFsnZmlsdGVyJywgJ21hcCcsICd0YWtlV2hpbGUnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSwgaW5kZXgpIHtcbiAgICAgIHZhciB0eXBlID0gaW5kZXggKyAxLFxuICAgICAgICAgIGlzRmlsdGVyID0gdHlwZSA9PSBMQVpZX0ZJTFRFUl9GTEFHIHx8IHR5cGUgPT0gTEFaWV9XSElMRV9GTEFHO1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbihpdGVyYXRlZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICByZXN1bHQuX19pdGVyYXRlZXNfXy5wdXNoKHtcbiAgICAgICAgICAnaXRlcmF0ZWUnOiBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyksXG4gICAgICAgICAgJ3R5cGUnOiB0eXBlXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHQuX19maWx0ZXJlZF9fID0gcmVzdWx0Ll9fZmlsdGVyZWRfXyB8fCBpc0ZpbHRlcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIGZvciBgXy5oZWFkYCBhbmQgYF8ubGFzdGAuXG4gICAgYXJyYXlFYWNoKFsnaGVhZCcsICdsYXN0J10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUsIGluZGV4KSB7XG4gICAgICB2YXIgdGFrZU5hbWUgPSAndGFrZScgKyAoaW5kZXggPyAnUmlnaHQnIDogJycpO1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdGFrZU5hbWVdKDEpLnZhbHVlKClbMF07XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyBmb3IgYF8uaW5pdGlhbGAgYW5kIGBfLnRhaWxgLlxuICAgIGFycmF5RWFjaChbJ2luaXRpYWwnLCAndGFpbCddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgdmFyIGRyb3BOYW1lID0gJ2Ryb3AnICsgKGluZGV4ID8gJycgOiAnUmlnaHQnKTtcblxuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fZmlsdGVyZWRfXyA/IG5ldyBMYXp5V3JhcHBlcih0aGlzKSA6IHRoaXNbZHJvcE5hbWVdKDEpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jb21wYWN0ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWx0ZXIoaWRlbnRpdHkpO1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKHByZWRpY2F0ZSkuaGVhZCgpO1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUuZmluZExhc3QgPSBmdW5jdGlvbihwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJldmVyc2UoKS5maW5kKHByZWRpY2F0ZSk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5pbnZva2VNYXAgPSBiYXNlUmVzdChmdW5jdGlvbihwYXRoLCBhcmdzKSB7XG4gICAgICBpZiAodHlwZW9mIHBhdGggPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBiYXNlSW52b2tlKHZhbHVlLCBwYXRoLCBhcmdzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnJlamVjdCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKG5lZ2F0ZShnZXRJdGVyYXRlZShwcmVkaWNhdGUpKSk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICAgIHN0YXJ0ID0gdG9JbnRlZ2VyKHN0YXJ0KTtcblxuICAgICAgdmFyIHJlc3VsdCA9IHRoaXM7XG4gICAgICBpZiAocmVzdWx0Ll9fZmlsdGVyZWRfXyAmJiAoc3RhcnQgPiAwIHx8IGVuZCA8IDApKSB7XG4gICAgICAgIHJldHVybiBuZXcgTGF6eVdyYXBwZXIocmVzdWx0KTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnRha2VSaWdodCgtc3RhcnQpO1xuICAgICAgfSBlbHNlIGlmIChzdGFydCkge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQuZHJvcChzdGFydCk7XG4gICAgICB9XG4gICAgICBpZiAoZW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZW5kID0gdG9JbnRlZ2VyKGVuZCk7XG4gICAgICAgIHJlc3VsdCA9IGVuZCA8IDAgPyByZXN1bHQuZHJvcFJpZ2h0KC1lbmQpIDogcmVzdWx0LnRha2UoZW5kIC0gc3RhcnQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnRha2VSaWdodFdoaWxlID0gZnVuY3Rpb24ocHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXZlcnNlKCkudGFrZVdoaWxlKHByZWRpY2F0ZSkucmV2ZXJzZSgpO1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUudG9BcnJheSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudGFrZShNQVhfQVJSQVlfTEVOR1RIKTtcbiAgICB9O1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyB0byBgbG9kYXNoLnByb3RvdHlwZWAuXG4gICAgYmFzZUZvck93bihMYXp5V3JhcHBlci5wcm90b3R5cGUsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBjaGVja0l0ZXJhdGVlID0gL14oPzpmaWx0ZXJ8ZmluZHxtYXB8cmVqZWN0KXxXaGlsZSQvLnRlc3QobWV0aG9kTmFtZSksXG4gICAgICAgICAgaXNUYWtlciA9IC9eKD86aGVhZHxsYXN0KSQvLnRlc3QobWV0aG9kTmFtZSksXG4gICAgICAgICAgbG9kYXNoRnVuYyA9IGxvZGFzaFtpc1Rha2VyID8gKCd0YWtlJyArIChtZXRob2ROYW1lID09ICdsYXN0JyA/ICdSaWdodCcgOiAnJykpIDogbWV0aG9kTmFtZV0sXG4gICAgICAgICAgcmV0VW53cmFwcGVkID0gaXNUYWtlciB8fCAvXmZpbmQvLnRlc3QobWV0aG9kTmFtZSk7XG5cbiAgICAgIGlmICghbG9kYXNoRnVuYykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsb2Rhc2gucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuX193cmFwcGVkX18sXG4gICAgICAgICAgICBhcmdzID0gaXNUYWtlciA/IFsxXSA6IGFyZ3VtZW50cyxcbiAgICAgICAgICAgIGlzTGF6eSA9IHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIsXG4gICAgICAgICAgICBpdGVyYXRlZSA9IGFyZ3NbMF0sXG4gICAgICAgICAgICB1c2VMYXp5ID0gaXNMYXp5IHx8IGlzQXJyYXkodmFsdWUpO1xuXG4gICAgICAgIHZhciBpbnRlcmNlcHRvciA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IGxvZGFzaEZ1bmMuYXBwbHkobG9kYXNoLCBhcnJheVB1c2goW3ZhbHVlXSwgYXJncykpO1xuICAgICAgICAgIHJldHVybiAoaXNUYWtlciAmJiBjaGFpbkFsbCkgPyByZXN1bHRbMF0gOiByZXN1bHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHVzZUxhenkgJiYgY2hlY2tJdGVyYXRlZSAmJiB0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiBpdGVyYXRlZS5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIC8vIEF2b2lkIGxhenkgdXNlIGlmIHRoZSBpdGVyYXRlZSBoYXMgYSBcImxlbmd0aFwiIHZhbHVlIG90aGVyIHRoYW4gYDFgLlxuICAgICAgICAgIGlzTGF6eSA9IHVzZUxhenkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY2hhaW5BbGwgPSB0aGlzLl9fY2hhaW5fXyxcbiAgICAgICAgICAgIGlzSHlicmlkID0gISF0aGlzLl9fYWN0aW9uc19fLmxlbmd0aCxcbiAgICAgICAgICAgIGlzVW53cmFwcGVkID0gcmV0VW53cmFwcGVkICYmICFjaGFpbkFsbCxcbiAgICAgICAgICAgIG9ubHlMYXp5ID0gaXNMYXp5ICYmICFpc0h5YnJpZDtcblxuICAgICAgICBpZiAoIXJldFVud3JhcHBlZCAmJiB1c2VMYXp5KSB7XG4gICAgICAgICAgdmFsdWUgPSBvbmx5TGF6eSA/IHZhbHVlIDogbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgICAgIHZhciByZXN1bHQgPSBmdW5jLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICAgICAgICByZXN1bHQuX19hY3Rpb25zX18ucHVzaCh7ICdmdW5jJzogdGhydSwgJ2FyZ3MnOiBbaW50ZXJjZXB0b3JdLCAndGhpc0FyZyc6IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIocmVzdWx0LCBjaGFpbkFsbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzVW53cmFwcGVkICYmIG9ubHlMYXp5KSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0ID0gdGhpcy50aHJ1KGludGVyY2VwdG9yKTtcbiAgICAgICAgcmV0dXJuIGlzVW53cmFwcGVkID8gKGlzVGFrZXIgPyByZXN1bHQudmFsdWUoKVswXSA6IHJlc3VsdC52YWx1ZSgpKSA6IHJlc3VsdDtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYEFycmF5YCBtZXRob2RzIHRvIGBsb2Rhc2gucHJvdG90eXBlYC5cbiAgICBhcnJheUVhY2goWydwb3AnLCAncHVzaCcsICdzaGlmdCcsICdzb3J0JywgJ3NwbGljZScsICd1bnNoaWZ0J10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBmdW5jID0gYXJyYXlQcm90b1ttZXRob2ROYW1lXSxcbiAgICAgICAgICBjaGFpbk5hbWUgPSAvXig/OnB1c2h8c29ydHx1bnNoaWZ0KSQvLnRlc3QobWV0aG9kTmFtZSkgPyAndGFwJyA6ICd0aHJ1JyxcbiAgICAgICAgICByZXRVbndyYXBwZWQgPSAvXig/OnBvcHxzaGlmdCkkLy50ZXN0KG1ldGhvZE5hbWUpO1xuXG4gICAgICBsb2Rhc2gucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBpZiAocmV0VW53cmFwcGVkICYmICF0aGlzLl9fY2hhaW5fXykge1xuICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMudmFsdWUoKTtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW10sIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzW2NoYWluTmFtZV0oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW10sIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBNYXAgbWluaWZpZWQgbWV0aG9kIG5hbWVzIHRvIHRoZWlyIHJlYWwgbmFtZXMuXG4gICAgYmFzZUZvck93bihMYXp5V3JhcHBlci5wcm90b3R5cGUsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBsb2Rhc2hGdW5jID0gbG9kYXNoW21ldGhvZE5hbWVdO1xuICAgICAgaWYgKGxvZGFzaEZ1bmMpIHtcbiAgICAgICAgdmFyIGtleSA9IGxvZGFzaEZ1bmMubmFtZSArICcnO1xuICAgICAgICBpZiAoIWhhc093blByb3BlcnR5LmNhbGwocmVhbE5hbWVzLCBrZXkpKSB7XG4gICAgICAgICAgcmVhbE5hbWVzW2tleV0gPSBbXTtcbiAgICAgICAgfVxuICAgICAgICByZWFsTmFtZXNba2V5XS5wdXNoKHsgJ25hbWUnOiBtZXRob2ROYW1lLCAnZnVuYyc6IGxvZGFzaEZ1bmMgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZWFsTmFtZXNbY3JlYXRlSHlicmlkKHVuZGVmaW5lZCwgV1JBUF9CSU5EX0tFWV9GTEFHKS5uYW1lXSA9IFt7XG4gICAgICAnbmFtZSc6ICd3cmFwcGVyJyxcbiAgICAgICdmdW5jJzogdW5kZWZpbmVkXG4gICAgfV07XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgTGF6eVdyYXBwZXJgLlxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jbG9uZSA9IGxhenlDbG9uZTtcbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUucmV2ZXJzZSA9IGxhenlSZXZlcnNlO1xuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS52YWx1ZSA9IGxhenlWYWx1ZTtcblxuICAgIC8vIEFkZCBjaGFpbiBzZXF1ZW5jZSBtZXRob2RzIHRvIHRoZSBgbG9kYXNoYCB3cmFwcGVyLlxuICAgIGxvZGFzaC5wcm90b3R5cGUuYXQgPSB3cmFwcGVyQXQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5jaGFpbiA9IHdyYXBwZXJDaGFpbjtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmNvbW1pdCA9IHdyYXBwZXJDb21taXQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5uZXh0ID0gd3JhcHBlck5leHQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5wbGFudCA9IHdyYXBwZXJQbGFudDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnJldmVyc2UgPSB3cmFwcGVyUmV2ZXJzZTtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnRvSlNPTiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWVPZiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWUgPSB3cmFwcGVyVmFsdWU7XG5cbiAgICAvLyBBZGQgbGF6eSBhbGlhc2VzLlxuICAgIGxvZGFzaC5wcm90b3R5cGUuZmlyc3QgPSBsb2Rhc2gucHJvdG90eXBlLmhlYWQ7XG5cbiAgICBpZiAoc3ltSXRlcmF0b3IpIHtcbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbc3ltSXRlcmF0b3JdID0gd3JhcHBlclRvSXRlcmF0b3I7XG4gICAgfVxuICAgIHJldHVybiBsb2Rhc2g7XG4gIH0pO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8vIEV4cG9ydCBsb2Rhc2guXG4gIHZhciBfID0gcnVuSW5Db250ZXh0KCk7XG5cbiAgLy8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3IgY29uZGl0aW9uIHBhdHRlcm5zIGxpa2U6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBMb2Rhc2ggb24gdGhlIGdsb2JhbCBvYmplY3QgdG8gcHJldmVudCBlcnJvcnMgd2hlbiBMb2Rhc2ggaXNcbiAgICAvLyBsb2FkZWQgYnkgYSBzY3JpcHQgdGFnIGluIHRoZSBwcmVzZW5jZSBvZiBhbiBBTUQgbG9hZGVyLlxuICAgIC8vIFNlZSBodHRwOi8vcmVxdWlyZWpzLm9yZy9kb2NzL2Vycm9ycy5odG1sI21pc21hdGNoIGZvciBtb3JlIGRldGFpbHMuXG4gICAgLy8gVXNlIGBfLm5vQ29uZmxpY3RgIHRvIHJlbW92ZSBMb2Rhc2ggZnJvbSB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290Ll8gPSBfO1xuXG4gICAgLy8gRGVmaW5lIGFzIGFuIGFub255bW91cyBtb2R1bGUgc28sIHRocm91Z2ggcGF0aCBtYXBwaW5nLCBpdCBjYW4gYmVcbiAgICAvLyByZWZlcmVuY2VkIGFzIHRoZSBcInVuZGVyc2NvcmVcIiBtb2R1bGUuXG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIF87XG4gICAgfSk7XG4gIH1cbiAgLy8gQ2hlY2sgZm9yIGBleHBvcnRzYCBhZnRlciBgZGVmaW5lYCBpbiBjYXNlIGEgYnVpbGQgb3B0aW1pemVyIGFkZHMgaXQuXG4gIGVsc2UgaWYgKGZyZWVNb2R1bGUpIHtcbiAgICAvLyBFeHBvcnQgZm9yIE5vZGUuanMuXG4gICAgKGZyZWVNb2R1bGUuZXhwb3J0cyA9IF8pLl8gPSBfO1xuICAgIC8vIEV4cG9ydCBmb3IgQ29tbW9uSlMgc3VwcG9ydC5cbiAgICBmcmVlRXhwb3J0cy5fID0gXztcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBFeHBvcnQgdG8gdGhlIGdsb2JhbCBvYmplY3QuXG4gICAgcm9vdC5fID0gXztcbiAgfVxufS5jYWxsKHRoaXMpKTtcbiIsImltcG9ydCB7IE91dGxpbmUsIFJhd091dGxpbmUgfSBmcm9tICcuL291dGxpbmUnO1xuaW1wb3J0IHsgQ3Vyc29yIH0gZnJvbSAnLi9jdXJzb3InO1xuaW1wb3J0IGtleWJvYXJkSlMgZnJvbSAna2V5Ym9hcmRqcyc7XG5pbXBvcnQgKiBhcyByYXdPdXRsaW5lIGZyb20gJy4vdGVzdC1kYXRhLmpzb24nO1xuaW1wb3J0IHtzaG93SGVscH0gZnJvbSAnaGVscCc7XG5pbXBvcnQgeyBTZWFyY2ggfSBmcm9tICcuL3NlYXJjaCc7XG5cbmxldCBvdXRsaW5lRGF0YSA9IHJhd091dGxpbmU7XG5pZihsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYWN0aXZlT3V0bGluZScpKSB7XG4gIGNvbnN0IG91dGxpbmVJZCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdhY3RpdmVPdXRsaW5lJyk7XG4gIG91dGxpbmVEYXRhID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbShvdXRsaW5lSWQpKTtcbn1cblxuY29uc3Qgc3RhdGUgPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xuY29uc3Qgb3V0bGluZSA9IG5ldyBPdXRsaW5lKG91dGxpbmVEYXRhIGFzIHVua25vd24gYXMgUmF3T3V0bGluZSk7XG5vdXRsaW5lcigpLmlubmVySFRNTCA9IG91dGxpbmUucmVuZGVyKCk7XG5cbmNvbnN0IGN1cnNvciA9IG5ldyBDdXJzb3IoKTtcbi8vIHBsYWNlIHRoZSBjdXJzb3IgYXQgdGhlIHRvcCFcbmN1cnNvci5zZXQoJy5ub2RlJyk7XG5cbmNvbnN0IHNlYXJjaCA9IG5ldyBTZWFyY2goKTtcblxuZnVuY3Rpb24gb3V0bGluZXIoKSB7XG4gIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjb3V0bGluZXInKTtcbn1cblxuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Rpc3BsYXktaGVscCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZSA9PiB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbiAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICBzaG93SGVscCgpO1xufSk7XG5cbi8vIG1vdmUgZG93blxua2V5Ym9hcmRKUy53aXRoQ29udGV4dCgnbmF2aWdhdGlvbicsICgpID0+IHtcbiAga2V5Ym9hcmRKUy5iaW5kKCdqJywgZSA9PiB7XG4gICAgLy8gbW92ZSBjdXJzb3IgZG93blxuICAgIC8vIGlmIHNoaWZ0IGtleSBpcyBoZWxkLCBzd2FwIHRoZSBub2RlIHdpdGggaXRzIG5leHQgc2libGluZ1xuICAgIGNvbnN0IHNpYmxpbmcgPSBjdXJzb3IuZ2V0KCkubmV4dEVsZW1lbnRTaWJsaW5nO1xuXG4gICAgaWYoc2libGluZykge1xuICAgICAgaWYoZS5zaGlmdEtleSkge1xuICAgICAgICAvLyBzd2FwIHRoaXMgbm9kZSB3aXRoIGl0cyBwcmV2aW91cyBzaWJsaW5nXG4gICAgICAgIGNvbnN0IHJlcyA9IG91dGxpbmUuc3dhcE5vZGVXaXRoTmV4dFNpYmxpbmcoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgICAgICBjb25zdCBodG1sID0gb3V0bGluZS5yZW5kZXJOb2RlKHJlcy5wYXJlbnROb2RlKTtcblxuICAgICAgICBpZihyZXMucGFyZW50Tm9kZS5pZCA9PT0gJzAwMDAwMCcpIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50Lm91dGVySFRNTCA9IGh0bWw7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMudGFyZ2V0Tm9kZS5pZH1gKTtcbiAgICAgICAgc2F2ZSgpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3NpYmxpbmcuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyl9YCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuXG4gIGtleWJvYXJkSlMuYmluZCgnc2hpZnQgKyAvJywgZSA9PiB7XG4gICAgc2hvd0hlbHAoKTtcbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdrJywgZSA9PiB7XG4gICAgLy8gbW92ZSBjdXJzb3IgdXBcbiAgICAvLyBpZiBzaGlmdCBrZXkgaXMgaGVsZCwgc3dhcCB0aGUgbm9kZSB3aXRoIGl0cyBwcmV2aW91cyBzaWJsaW5nXG4gICAgY29uc3Qgc2libGluZyA9IGN1cnNvci5nZXQoKS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuXG4gICAgaWYoc2libGluZyAmJiAhc2libGluZy5jbGFzc0xpc3QuY29udGFpbnMoJ25vZGVDb250ZW50JykpIHtcbiAgICAgIGlmKGUuc2hpZnRLZXkpIHtcbiAgICAgICAgLy8gc3dhcCB0aGlzIG5vZGUgd2l0aCBpdHMgcHJldmlvdXMgc2libGluZ1xuICAgICAgICBjb25zdCByZXMgPSBvdXRsaW5lLnN3YXBOb2RlV2l0aFByZXZpb3VzU2libGluZyhjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgICAgIC8vIHJlLXJlbmRlciB0aGUgcGFyZW50IG5vZGUgYW5kIGRpc3BsYXkgdGhhdCFcbiAgICAgICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMucGFyZW50Tm9kZSk7XG5cbiAgICAgICAgaWYocmVzLnBhcmVudE5vZGUuaWQgPT09ICcwMDAwMDAnKSB7XG4gICAgICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5vdXRlckhUTUwgPSBodG1sO1xuICAgICAgICB9XG5cbiAgICAgICAgY3Vyc29yLnNldChgI2lkLSR7cmVzLnRhcmdldE5vZGUuaWR9YCk7XG4gICAgICAgIHNhdmUoKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtzaWJsaW5nLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpfWApO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdsJywgZSA9PiB7XG4gICAgLy8gaWYgdGhlIG5vZGUgaXMgY29sbGFwc2VkLCB3ZSBjYW4ndCBnbyBpbnRvIGl0cyBjaGlsZHJlblxuICAgIGlmKGN1cnNvci5pc05vZGVDb2xsYXBzZWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZihlLnNoaWZ0S2V5KSB7XG4gICAgICBjb25zdCByZXMgPSBvdXRsaW5lLmxvd2VyTm9kZVRvQ2hpbGQoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMub2xkUGFyZW50Tm9kZSk7XG5cbiAgICAgIGlmKHJlcy5vbGRQYXJlbnROb2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50Lm91dGVySFRNTCA9IGh0bWw7XG4gICAgICB9XG4gICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMudGFyZ2V0Tm9kZS5pZH1gKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IGN1cnNvci5nZXQoKS5xdWVyeVNlbGVjdG9yKCcubm9kZScpO1xuICAgICAgaWYoY2hpbGRyZW4pIHtcbiAgICAgICAgY3Vyc29yLnNldChgI2lkLSR7Y2hpbGRyZW4uZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyl9YCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ2gnLCBlID0+IHtcbiAgICBjb25zdCBwYXJlbnQgPSBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudDtcbiAgICBpZihwYXJlbnQgJiYgcGFyZW50LmNsYXNzTGlzdC5jb250YWlucygnbm9kZScpKSB7XG4gICAgICBpZihlLnNoaWZ0S2V5KSB7XG4gICAgICAgIGlmKG91dGxpbmUuZGF0YS50cmVlLmNoaWxkcmVuLm1hcChuID0+IG4uaWQpLmluY2x1ZGVzKGN1cnNvci5nZXRJZE9mTm9kZSgpKSkge1xuICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSB0b3AgbGV2ZWwgaXRlbSwgd2UgY2FuJ3QgZWxldmF0ZSBhbnkgZnVydGhlclxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXMgPSBvdXRsaW5lLmxpZnROb2RlVG9QYXJlbnQoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuXG4gICAgICAgIGNvbnN0IGh0bWwgPSBvdXRsaW5lLnJlbmRlck5vZGUocmVzLnBhcmVudE5vZGUpO1xuXG4gICAgICAgIGlmKHJlcy5wYXJlbnROb2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50Lm91dGVySFRNTCA9IGh0bWw7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMudGFyZ2V0Tm9kZS5pZH1gKTtcbiAgICAgICAgc2F2ZSgpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3BhcmVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGtleWJvYXJkSlMuYmluZCgneicsIGUgPT4ge1xuICAgIC8vIHRvZ2dsZSBjb2xsYXBzZVxuICAgIGlmKGN1cnNvci5pc05vZGVFeHBhbmRlZCgpKSB7XG4gICAgICBjdXJzb3IuY29sbGFwc2UoKTtcbiAgICAgIG91dGxpbmUuZm9sZChjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgfVxuICAgIGVsc2UgaWYoY3Vyc29yLmlzTm9kZUNvbGxhcHNlZCgpKSB7XG4gICAgICBjdXJzb3IuZXhwYW5kKCk7XG4gICAgICBvdXRsaW5lLnVuZm9sZChjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgfVxuICAgIHNhdmUoKTtcbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdzaGlmdCArIDQnLCBlID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgLy8gc3dpdGNoIHRvIGVkaXRpbmcgbW9kZVxuICAgIGN1cnNvci5nZXQoKS5jbGFzc0xpc3QuYWRkKCdoaWRkZW4tY3Vyc29yJyk7XG4gICAgY29uc3QgY29udGVudE5vZGUgPSBjdXJzb3IuZ2V0KCkucXVlcnlTZWxlY3RvcignLm5vZGVDb250ZW50JykgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAvLyBzd2FwIHRoZSBjb250ZW50IHRvIHRoZSBkZWZhdWx0IVxuICAgIGNvbnRlbnROb2RlLmlubmVySFRNTCA9IG91dGxpbmUuZGF0YS5jb250ZW50Tm9kZXNbY3Vyc29yLmdldElkT2ZOb2RlKCldLmNvbnRlbnQ7XG4gICAgY29udGVudE5vZGUuY29udGVudEVkaXRhYmxlID0gXCJ0cnVlXCI7XG5cbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKGNvbnRlbnROb2RlKTtcbiAgICByYW5nZS5jb2xsYXBzZShmYWxzZSk7XG5cbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIHNlbGVjdGlvbi5hZGRSYW5nZShyYW5nZSk7XG5cbiAgICBjb250ZW50Tm9kZS5mb2N1cygpO1xuICAgIGtleWJvYXJkSlMuc2V0Q29udGV4dCgnZWRpdGluZycpO1xuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ2knLCBlID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgLy8gc3dpdGNoIHRvIGVkaXRpbmcgbW9kZVxuICAgIGN1cnNvci5nZXQoKS5jbGFzc0xpc3QuYWRkKCdoaWRkZW4tY3Vyc29yJyk7XG4gICAgY29uc3QgY29udGVudE5vZGUgPSBjdXJzb3IuZ2V0KCkucXVlcnlTZWxlY3RvcignLm5vZGVDb250ZW50JykgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAvLyBzd2FwIHRoZSBjb250ZW50IHRvIHRoZSBkZWZhdWx0IVxuICAgIGNvbnRlbnROb2RlLmlubmVySFRNTCA9IG91dGxpbmUuZGF0YS5jb250ZW50Tm9kZXNbY3Vyc29yLmdldElkT2ZOb2RlKCldLmNvbnRlbnQ7XG4gICAgY29udGVudE5vZGUuY29udGVudEVkaXRhYmxlID0gXCJ0cnVlXCI7XG4gICAgY29udGVudE5vZGUuZm9jdXMoKTtcbiAgICBrZXlib2FyZEpTLnNldENvbnRleHQoJ2VkaXRpbmcnKTtcbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdzaGlmdCArIHgnLCBlID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgLy8gdG9nZ2xlIFwic3RyaWtldGhyb3VnaFwiIG9mIG5vZGVcbiAgICBjdXJzb3IuZ2V0KCkuY2xhc3NMaXN0LnRvZ2dsZSgnc3RyaWtldGhyb3VnaCcpO1xuICAgIG91dGxpbmUuZGF0YS5jb250ZW50Tm9kZXNbY3Vyc29yLmdldElkT2ZOb2RlKCldLnN0cmlrZXRocm91Z2ggPSBjdXJzb3IuZ2V0KCkuY2xhc3NMaXN0LmNvbnRhaW5zKCdzdHJpa2V0aHJvdWdoJyk7XG4gICAgc2F2ZSgpO1xuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ3RhYicsIGUgPT4ge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgIGNvbnN0IHJlcyA9IG91dGxpbmUuY3JlYXRlQ2hpbGROb2RlKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICBjb25zdCBodG1sID0gb3V0bGluZS5yZW5kZXJOb2RlKHJlcy5wYXJlbnROb2RlKTtcblxuICAgIGN1cnNvci5nZXQoKS5vdXRlckhUTUwgPSBodG1sO1xuXG4gICAgY3Vyc29yLnNldChgI2lkLSR7cmVzLm5vZGUuaWR9YCk7XG4gICAgc2F2ZSgpO1xuICB9KTtcbiAgXG4gIGtleWJvYXJkSlMuYmluZCgnZW50ZXInLCBlID0+IHtcbiAgICAvLyBjcmVhdGUgYSBuZXcgbm9kZSBhcyBhIHNpYmxpbmcgb2YgdGhlIHNlbGVjdGVkIG5vZGVcbiAgICBpZihlLnNoaWZ0S2V5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnByZXZlbnRSZXBlYXQoKTtcblxuICAgIGNvbnN0IHJlcyA9IG91dGxpbmUuY3JlYXRlU2libGluZ05vZGUoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuXG4gICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMucGFyZW50Tm9kZSk7XG4gICAgaWYocmVzLnBhcmVudE5vZGUuaWQgPT09ICcwMDAwMDAnKSB7XG4gICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50Lm91dGVySFRNTCA9IGh0bWw7XG4gICAgfVxuXG4gICAgY3Vyc29yLnNldChgI2lkLSR7cmVzLm5vZGUuaWR9YCk7XG4gICAgc2F2ZSgpO1xuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ2QnLCBlID0+IHtcbiAgICAvLyBkZWxldGluZyBhIG5vZGUgcmVxdWlyZXMgZCArIHNoaWZ0XG4gICAgaWYoIWUuc2hpZnRLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXMgPSBvdXRsaW5lLnJlbW92ZU5vZGUoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgIGNvbnN0IGh0bWwgPSBvdXRsaW5lLnJlbmRlck5vZGUocmVzLnBhcmVudE5vZGUpO1xuICAgIC8vIHRoZSBwcmV2aW91cyBzaWJsaW5nIVxuICAgIGNvbnN0IHByZXZTaWJsaW5nID0gY3Vyc29yLmdldCgpLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG4gICAgY29uc3QgbmV4dFNpYmxpbmcgPSBjdXJzb3IuZ2V0KCkubmV4dEVsZW1lbnRTaWJsaW5nO1xuICAgIGlmKHJlcy5wYXJlbnROb2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5vdXRlckhUTUwgPSBodG1sO1xuICAgIH1cblxuICAgIGlmKHByZXZTaWJsaW5nLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpKSB7XG4gICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtwcmV2U2libGluZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKX1gKTtcbiAgICB9XG4gICAgZWxzZSBpZihuZXh0U2libGluZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSkge1xuICAgICAgY3Vyc29yLnNldChgI2lkLSR7bmV4dFNpYmxpbmcuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyl9YCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY29uc29sZS5sb2cocmVzLnBhcmVudE5vZGUuaWQpO1xuICAgICAgY3Vyc29yLnNldChgI2lkLSR7cmVzLnBhcmVudE5vZGUuaWR9YCk7XG4gICAgfVxuXG4gICAgc2F2ZSgpO1xuICB9KTtcbn0pO1xuXG5rZXlib2FyZEpTLndpdGhDb250ZXh0KCdlZGl0aW5nJywgKCkgPT4ge1xuICBrZXlib2FyZEpTLmJpbmQoWydlc2MnLCAnZW50ZXInXSwgZSA9PiB7XG4gICAgY3Vyc29yLmdldCgpLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbi1jdXJzb3InKTtcblxuICAgIGNvbnN0IGNvbnRlbnROb2RlID0gY3Vyc29yLmdldCgpLnF1ZXJ5U2VsZWN0b3IoJy5ub2RlQ29udGVudCcpIGFzIEhUTUxFbGVtZW50O1xuXG4gICAgY29udGVudE5vZGUuY29udGVudEVkaXRhYmxlID0gXCJmYWxzZVwiO1xuICAgIGNvbnRlbnROb2RlLmJsdXIoKTtcbiAgICBrZXlib2FyZEpTLnNldENvbnRleHQoJ25hdmlnYXRpb24nKTtcblxuICAgIG91dGxpbmUudXBkYXRlQ29udGVudChjdXJzb3IuZ2V0SWRPZk5vZGUoKSwgY29udGVudE5vZGUuaW5uZXJIVE1MLnRyaW0oKSk7XG4gICAgLy8gcmUtcmVuZGVyIHRoaXMgbm9kZSFcbiAgICBjb250ZW50Tm9kZS5pbm5lckhUTUwgPSBvdXRsaW5lLnJlbmRlckNvbnRlbnQoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgIHNhdmUoKTtcbiAgfSk7XG59KTtcblxua2V5Ym9hcmRKUy5zZXRDb250ZXh0KCduYXZpZ2F0aW9uJyk7XG5cbnNlYXJjaC5jcmVhdGVJbmRleCh7XG4gIGlkOiBcInN0cmluZ1wiLFxuICBjcmVhdGVkOiBcIm51bWJlclwiLFxuICB0eXBlOiBcInN0cmluZ1wiLFxuICBjb250ZW50OiBcInN0cmluZ1wiLFxuICBzdHJpa2V0aHJvdWdoOiBcImJvb2xlYW5cIlxufSkudGhlbihhc3luYyAoKSA9PiB7XG4gIGF3YWl0IHNlYXJjaC5pbmRleEJhdGNoKG91dGxpbmUuZGF0YS5jb250ZW50Tm9kZXMpO1xuICBzZWFyY2guYmluZEV2ZW50cygpO1xufSk7XG5cbmZ1bmN0aW9uIHJlY3Vyc2l2ZWx5RXhwYW5kKHN0YXJ0OiBIVE1MRWxlbWVudCkge1xuICBpZihzdGFydC5jbGFzc0xpc3QuY29udGFpbnMoJ25vZGUnKSkge1xuICAgIGlmKHN0YXJ0LmNsYXNzTGlzdC5jb250YWlucygnY29sbGFwc2VkJykpIHtcbiAgICAgIHN0YXJ0LmNsYXNzTGlzdC5yZW1vdmUoJ2NvbGxhcHNlZCcpO1xuICAgICAgc3RhcnQuY2xhc3NMaXN0LmFkZCgnZXhwYW5kZWQnKTtcbiAgICAgIG91dGxpbmUudW5mb2xkKHN0YXJ0LmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpKTtcbiAgICB9XG5cbiAgICBpZihzdGFydC5wYXJlbnRFbGVtZW50KSB7XG4gICAgICByZWN1cnNpdmVseUV4cGFuZChzdGFydC5wYXJlbnRFbGVtZW50KVxuICAgIH1cbiAgfVxufVxuXG5zZWFyY2gub25UZXJtU2VsZWN0aW9uID0gKGRvY0lkOiBzdHJpbmcpID0+IHtcbiAgLy8gaWYgYW55IHBhcmVudCBlbGVtZW50IGluIHRoZSBjaGFpbiB0byB0aGlzIG5vZGVcbiAgLy8gYXJlIGNvbGxhcHNlZCwgd2Ugd2FudCB0byBtYWtlIHN1cmUgd2UgZXhwYW5kIHRoZW1cblxuICByZWN1cnNpdmVseUV4cGFuZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgaWQtJHtkb2NJZH1gKS5wYXJlbnRFbGVtZW50KTtcbiAgY3Vyc29yLnNldChgI2lkLSR7ZG9jSWR9YCk7XG5cbiAgc2F2ZSgpO1xufTtcblxuZnVuY3Rpb24gc2F2ZUltbWVkaWF0ZSgpIHtcbiAgbG9jYWxTdG9yYWdlLnNldEl0ZW0ob3V0bGluZS5kYXRhLmlkLCBKU09OLnN0cmluZ2lmeShvdXRsaW5lLmRhdGEpKTtcbiAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2FjdGl2ZU91dGxpbmUnLCBvdXRsaW5lLmRhdGEuaWQpO1xuICBjb25zb2xlLmxvZygnc2F2ZWQuLi4nLCBvdXRsaW5lLmRhdGEpO1xuICBzdGF0ZS5kZWxldGUoJ3NhdmVUaW1lb3V0Jyk7XG59XG5cbmZ1bmN0aW9uIHNhdmUoKSB7XG4gIGlmKCFzdGF0ZS5oYXMoJ3NhdmVUaW1lb3V0JykpIHtcbiAgICBzdGF0ZS5zZXQoJ3NhdmVUaW1lb3V0Jywgc2V0VGltZW91dChzYXZlSW1tZWRpYXRlLCAyMDAwKSk7XG4gIH1cbn1cblxuXG5zYXZlKCk7XG4iLCJpbXBvcnQge2lzVmlzaWJsZX0gZnJvbSBcImRvbVwiO1xuXG5leHBvcnQgY2xhc3MgQ3Vyc29yIHtcbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgfVxuXG4gIGdldCgpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmN1cnNvcicpO1xuICB9XG5cbiAgZ2V0SWRPZk5vZGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKTtcbiAgfVxuXG4gIHVuc2V0KCkge1xuICAgIGNvbnN0IGVsID0gdGhpcy5nZXQoKTtcbiAgICBpZihlbCkge1xuICAgICAgZWwuY2xhc3NMaXN0LnJlbW92ZSgnY3Vyc29yJyk7XG4gICAgfVxuICB9XG5cbiAgc2V0KGVsZW1lbnRJZDogc3RyaW5nKSB7XG4gICAgdGhpcy51bnNldCgpO1xuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50SWQpIGFzIEhUTUxFbGVtZW50O1xuXG4gICAgaWYoZWwpIHtcbiAgICAgIGVsLmNsYXNzTGlzdC5hZGQoJ2N1cnNvcicpO1xuICAgICAgaWYoIWlzVmlzaWJsZShlbCkpIHtcbiAgICAgICAgZWwuc2Nyb2xsSW50b1ZpZXcodHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29sbGFwc2UoKSB7XG4gICAgdGhpcy5nZXQoKS5jbGFzc0xpc3QucmVtb3ZlKCdleHBhbmRlZCcpO1xuICAgIHRoaXMuZ2V0KCkuY2xhc3NMaXN0LmFkZCgnY29sbGFwc2VkJyk7XG4gIH1cblxuICBleHBhbmQoKSB7XG4gICAgdGhpcy5nZXQoKS5jbGFzc0xpc3QucmVtb3ZlKCdjb2xsYXBzZWQnKTtcbiAgICB0aGlzLmdldCgpLmNsYXNzTGlzdC5hZGQoJ2V4cGFuZGVkJyk7XG4gIH1cblxuICBpc05vZGVDb2xsYXBzZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuY2xhc3NMaXN0LmNvbnRhaW5zKCdjb2xsYXBzZWQnKTtcbiAgfVxuICBcbiAgaXNOb2RlRXhwYW5kZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuY2xhc3NMaXN0LmNvbnRhaW5zKCdleHBhbmRlZCcpO1xuICB9XG59XG4iLCJleHBvcnQgZnVuY3Rpb24gaXNWaXNpYmxlKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgY29uc3QgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIChcbiAgICAgICAgcmVjdC50b3AgPj0gMCAmJlxuICAgICAgICByZWN0LmxlZnQgPj0gMCAmJlxuICAgICAgICByZWN0LnRvcCA8PSAod2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpICYmICAgICBcbiAgICAgICAgcmVjdC5yaWdodCA8PSAod2luZG93LmlubmVyV2lkdGggfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoKVxuICAgICk7XG59XG4iLCJpbXBvcnQga2V5Ym9hcmRKUyBmcm9tICdrZXlib2FyZGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ2xvZGFzaCc7XG5cbmNvbnN0IGtleWJvYXJkQ29tbWFuZHMgPSB7XG4gICdoJzogJ01vdmUgdGhlIGN1cnNvciB0byB0aGUgUGFyZW50IEVsZW1lbnQgb2YgdGhlIGN1cnJlbnQgbm9kZScsXG4gICdsJzogJ01vdmUgdGhlIGN1cnNvciB0byB0aGUgZmlyc3QgQ2hpbGQgRWxlbWVudCBvZiB0aGUgY3VycmVudCBub2RlJyxcbiAgJ2onOiAnTW92ZSB0aGUgY3Vyc29yIHRvIHRoZSBuZXh0IHNpYmxpbmcgb2YgdGhlIGN1cnJlbnQgbm9kZScsXG4gICdrJzogJ01vdmUgdGhlIGN1cnNvciB0byB0aGUgcHJldmlvdXMgc2libGluZyBvZiB0aGUgY3VycmVudCBub2RlJyxcbiAgJ2VudGVyJzogJ0FkZCBhIG5ldyBub2RlIGFzIGEgc2libGluZyB0byB0aGUgY3VycmVudCBub2RlJyxcbiAgJ3RhYic6ICdBZGQgYSBuZXcgbm9kZSBhcyB0aGUgY2hpbGQgb2YgdGhlIGN1cnJlbnQgbm9kZScsXG4gICdzaGlmdCArIGonOiAnU3dhcCB0aGUgY3VycmVudCBub2RlIHdpdGggbmV4dCBzaWJsaW5nIG5vZGUnLFxuICAnc2hpZnQgKyBrJzogJ1N3YXAgdGhlIGN1cnJlbnQgbm9kZSB3aXRoIHRoZSBwcmV2aW91cyBzaWJsaW5nIG5vZGUnLFxuICAnc2hpZnQgKyBoJzogJ0xpZnQgdGhlIGN1cnJlbnQgbm9kZSB0byBiZSBhIHNpYmxpbmcgb2YgdGhlIHBhcmVudCBub2RlJyxcbiAgJ3NoaWZ0ICsgbCc6ICdMb3dlciB0aGUgY3VycmVudCBub2RlIHRvIGJlIGEgY2hpbGQgb2YgdGhlIHByZXZpb3VzIHNpYmxpbmcgbm9kZScsXG4gICdzaGlmdCArIGQnOiAnRGVsZXRlIHRoZSBjdXJyZW50IG5vZGUnLFxuICAnc2hpZnQgKyBmJzogJ09wZW4gdGhlIHNlYXJjaCBtb2RhbCcsXG4gICdpJzogJ0VudGVyIFwiZWRpdFwiIG1vZGUsIGFuZCBwbGFjZSB0aGUgY3Vyc29yIGF0IHRoZSBzdGFydCBvZiB0aGUgZWRpdGFibGUgY29udGVudCcsXG4gICckJzogJ0VudGVyIFwiZWRpdFwiIG1vZGUsIGFuZCBwbGFjZSB0aGUgY3Vyc29yIGF0IHRoZSBlbmQgb2YgdGhlIGVkaXRhYmxlIGNvbnRlbnQnLFxuICAnZXNjYXBlJzogJ0V4aXQgdGhlIGN1cnJlbnQgbW9kZSBhbmQgcmV0dXJuIHRvIFwibmF2aWdhdGlvblwiIG1vZGUnLFxuICAnPyc6ICdEaXNwbGF5IHRoaXMgaGVscCBkaWFsb2d1ZSdcbn07XG5cbmNvbnN0IG1vZGFsSFRNTCA9IGBcbiAgPGRpdiBjbGFzcz1cIm1vZGFsXCI+XG4gIDxkaXYgY2xhc3M9XCJtb2RhbC1jb250ZW50XCI+XG4gICAgPGgxPkhlbHA8L2gxPlxuICAgIDx0YWJsZT5cbiAgICA8dGhlYWQ+XG4gICAgPHRyPlxuICAgIDx0aD5LZXk8L3RoPlxuICAgIDx0aD5BY3Rpb248L3RoPlxuICAgIDwvdHI+XG4gICAgPC90aGVhZD5cbiAgICA8dGJvZHk+XG4gICAgJHttYXAoa2V5Ym9hcmRDb21tYW5kcywgKHRleHQsIGtleSkgPT4ge1xuICAgICAgcmV0dXJuIGBcbiAgICAgIDx0cj5cbiAgICAgICAgPHRkPlxuICAgICAgICAgIDxrYmQ+JHtrZXl9PC9rYmQ+XG4gICAgICAgIDwvdGQ+XG4gICAgICAgIDx0ZD5cbiAgICAgICAgICAke3RleHR9XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L3RyPlxuICAgICAgYFxuICAgIH0pLmpvaW4oXCJcXG5cIil9XG4gICAgPC90Ym9keT5cbiAgICA8L3RhYmxlPlxuICA8L2Rpdj5cbiAgPC9kaXY+XG5gXG5cbmV4cG9ydCBmdW5jdGlvbiBzaG93SGVscCgpIHtcbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpLmlubmVySFRNTCArPSBtb2RhbEhUTUw7XG4gIGtleWJvYXJkSlMuc2V0Q29udGV4dCgnaGVscCcpO1xufVxuXG5rZXlib2FyZEpTLndpdGhDb250ZXh0KCdoZWxwJywgKCkgPT4ge1xuICBrZXlib2FyZEpTLmJpbmQoJ2VzY2FwZScsIGUgPT4ge1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb2RhbCcpLnJlbW92ZSgpO1xuICAgIGtleWJvYXJkSlMuc2V0Q29udGV4dCgnbmF2aWdhdGlvbicpO1xuICB9KTtcbn0pO1xuIiwiaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgdjQgYXMgdXVpZCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHsgbWFya2VkIH0gZnJvbSAnbWFya2VkJztcblxuZXhwb3J0IGludGVyZmFjZSBSYXdPdXRsaW5lIHtcbiAgaWQ6IHN0cmluZztcbiAgY3JlYXRlZDogbnVtYmVyO1xuICBuYW1lOiBzdHJpbmc7XG4gIHRyZWU6IE91dGxpbmVUcmVlO1xuICBjb250ZW50Tm9kZXM6IFJlY29yZDxzdHJpbmcsIE91dGxpbmVOb2RlPlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE91dGxpbmVUcmVlIHtcbiAgaWQ6IHN0cmluZztcbiAgY2hpbGRyZW46IE91dGxpbmVUcmVlW11cbiAgY29sbGFwc2VkOiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE91dGxpbmVOb2RlIHtcbiAgaWQ6IHN0cmluZztcbiAgY3JlYXRlZDogbnVtYmVyO1xuICB0eXBlOiAndGV4dCcsXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgc3RyaWtldGhyb3VnaDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBjbGFzcyBPdXRsaW5lIHtcbiAgZGF0YTogUmF3T3V0bGluZTtcblxuICBjb25zdHJ1Y3RvcihvdXRsaW5lRGF0YTogUmF3T3V0bGluZSkge1xuICAgIHRoaXMuZGF0YSA9IG91dGxpbmVEYXRhO1xuICB9XG5cbiAgZmluZE5vZGVJblRyZWUocm9vdDogT3V0bGluZVRyZWUsIGlkOiBzdHJpbmcsIGFjdGlvbjogKGl0ZW06IE91dGxpbmVUcmVlLCBwYXJlbnQ6IE91dGxpbmVUcmVlKSA9PiB2b2lkLCBydW5TdGF0ZTogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgbGV0IHJ1biA9IHJ1blN0YXRlO1xuICAgIGlmKHJ1bikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBfLmVhY2gocm9vdC5jaGlsZHJlbiwgKGNoaWxkTm9kZSwgaWR4KSA9PiB7XG4gICAgICBpZihjaGlsZE5vZGUuaWQgPT09IGlkKSB7XG4gICAgICAgIGFjdGlvbihjaGlsZE5vZGUsIHJvb3QpO1xuICAgICAgICBydW4gPSB0cnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGNoaWxkTm9kZS5jaGlsZHJlbikge1xuICAgICAgICB0aGlzLmZpbmROb2RlSW5UcmVlKGNoaWxkTm9kZSwgaWQsIGFjdGlvbiwgcnVuKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZvbGQobm9kZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmZpbmROb2RlSW5UcmVlKHRoaXMuZGF0YS50cmVlLCBub2RlSWQsIGl0ZW0gPT4ge1xuICAgICAgaXRlbS5jb2xsYXBzZWQgPSB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgdW5mb2xkKG5vZGVJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgbm9kZUlkLCBpdGVtID0+IHtcbiAgICAgIGl0ZW0uY29sbGFwc2VkID0gZmFsc2U7XG4gICAgfSk7XG4gIH1cblxuICBmbGF0dGVuT3V0bGluZVRyZWVDaGlsZHJlbih0cmVlOiBPdXRsaW5lVHJlZSk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdHJlZS5jaGlsZHJlbi5tYXAobm9kZSA9PiBub2RlLmlkKTtcbiAgfVxuXG4gIGxpZnROb2RlVG9QYXJlbnQobm9kZUlkOiBzdHJpbmcpIHtcbiAgICBsZXQgcnVuID0gZmFsc2U7XG4gICAgbGV0IHRhcmdldE5vZGU6IE91dGxpbmVUcmVlLCBwYXJlbnROb2RlOiBPdXRsaW5lVHJlZTtcbiAgICB0aGlzLmZpbmROb2RlSW5UcmVlKHRoaXMuZGF0YS50cmVlLCBub2RlSWQsICh0Tm9kZSwgcE5vZGUpID0+IHtcbiAgICAgIHRhcmdldE5vZGUgPSB0Tm9kZTtcbiAgICAgIHRoaXMuZmluZE5vZGVJblRyZWUodGhpcy5kYXRhLnRyZWUsIHBOb2RlLmlkLCAob3JpZ2luYWxQYXJlbnROb2RlLCBuZXdQYXJlbnROb2RlKSA9PiB7O1xuICAgICAgICAgIGlmKHJ1bikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwYXJlbnROb2RlID0gbmV3UGFyZW50Tm9kZTtcbiAgICAgICAgICBydW4gPSB0cnVlO1xuXG4gICAgICAgICAgY29uc3QgZmxhdElkID0gbmV3UGFyZW50Tm9kZS5jaGlsZHJlbi5tYXAobiA9PiBuLmlkKTtcblxuICAgICAgICAgIGNvbnN0IG9yaWdpbmFsTm9kZVBvc2l0aW9uID0gb3JpZ2luYWxQYXJlbnROb2RlLmNoaWxkcmVuLm1hcChuID0+IG4uaWQpLmluZGV4T2YodGFyZ2V0Tm9kZS5pZCk7XG4gICAgICAgICAgY29uc3QgbmV3Tm9kZVBvc2l0aW9uID0gZmxhdElkLmluZGV4T2Yob3JpZ2luYWxQYXJlbnROb2RlLmlkKTtcblxuICAgICAgICAgIG9yaWdpbmFsUGFyZW50Tm9kZS5jaGlsZHJlbi5zcGxpY2Uob3JpZ2luYWxOb2RlUG9zaXRpb24sIDEpO1xuXG4gICAgICAgICAgbmV3UGFyZW50Tm9kZS5jaGlsZHJlbi5zcGxpY2UobmV3Tm9kZVBvc2l0aW9uICsgMSwgMCwgdGFyZ2V0Tm9kZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICB0YXJnZXROb2RlLFxuICAgICAgcGFyZW50Tm9kZVxuICAgIH1cbiAgfVxuICBcbiAgbG93ZXJOb2RlVG9DaGlsZChub2RlSWQ6IHN0cmluZykge1xuICAgIGxldCBydW4gPSBmYWxzZTtcbiAgICAvLyBmaW5kIHRoZSBwcmV2aW91cyBzaWJsaW5nXG4gICAgLy8gbWFrZSB0aGlzIG5vZGUgYSBjaGlsZCBvZiB0aGUgc2libGluZyBub2RlXG4gICAgbGV0IHRhcmdldE5vZGU6IE91dGxpbmVUcmVlLCBuZXdQYXJlbnROb2RlOiBPdXRsaW5lVHJlZSwgb2xkUGFyZW50Tm9kZTogT3V0bGluZVRyZWU7XG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgbm9kZUlkLCAodE5vZGUsIHBOb2RlKSA9PiB7XG4gICAgICBpZihydW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcnVuICA9IHRydWU7XG4gICAgICB0YXJnZXROb2RlID0gdE5vZGU7XG4gICAgICBcbiAgICAgIGxldCBpZExpc3QgPSBwTm9kZS5jaGlsZHJlbi5tYXAobiA9PiBuLmlkKTtcbiAgICAgIC8vIHRoZXJlIGFyZSBubyBvdGhlciBzaWJsaW5ncyBzbyB3ZSBjYW4ndCBkbyBhbnl0aGluZ1xuICAgICAgaWYoaWRMaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gaWRMaXN0LmluZGV4T2YodGFyZ2V0Tm9kZS5pZCk7XG4gICAgICBjb25zdCBwcmV2U2libGluZ1Bvc2l0aW9uID0gcG9zaXRpb24gLSAxO1xuXG4gICAgICBwTm9kZS5jaGlsZHJlbltwcmV2U2libGluZ1Bvc2l0aW9uXS5jaGlsZHJlbi5zcGxpY2UoMCwgMCwgdGFyZ2V0Tm9kZSk7XG4gICAgICBwTm9kZS5jaGlsZHJlbi5zcGxpY2UocG9zaXRpb24sIDEpO1xuXG4gICAgICBuZXdQYXJlbnROb2RlID0gcE5vZGUuY2hpbGRyZW5bcHJldlNpYmxpbmdQb3NpdGlvbl07XG4gICAgICBvbGRQYXJlbnROb2RlID0gcE5vZGU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRhcmdldE5vZGUsXG4gICAgICBuZXdQYXJlbnROb2RlLFxuICAgICAgb2xkUGFyZW50Tm9kZVxuICAgIH1cbiAgfVxuXG4gIHN3YXBOb2RlV2l0aE5leHRTaWJsaW5nKG5vZGVJZDogc3RyaW5nKSB7XG4gICAgbGV0IHRhcmdldE5vZGU6IE91dGxpbmVUcmVlLCBwYXJlbnROb2RlOiBPdXRsaW5lVHJlZTtcbiAgICB0aGlzLmZpbmROb2RlSW5UcmVlKHRoaXMuZGF0YS50cmVlLCBub2RlSWQsICh0Tm9kZSwgcE5vZGUpID0+IHtcbiAgICAgICAgdGFyZ2V0Tm9kZSA9IHROb2RlO1xuICAgICAgICBwYXJlbnROb2RlID0gcE5vZGU7XG4gICAgICAgIGNvbnN0IGZsYXRJZCA9IHBhcmVudE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCk7XG4gICAgICAgIGNvbnN0IG5vZGVQb3NpdGlvbiA9IGZsYXRJZC5pbmRleE9mKHRhcmdldE5vZGUuaWQpO1xuXG4gICAgICAgIGlmKG5vZGVQb3NpdGlvbiA9PT0gKGZsYXRJZC5sZW5ndGggLSAxKSkge1xuICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIGxhc3Qgbm9kZSBpbiB0aGUgbGlzdCwgdGhlcmUncyBub3RoaW5nIHRvIHN3YXBcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgdGhlIG5vZGUgZnJvbSB0aGlzIHBvaW50LCBhbmQgcHVzaCBpdCBvbmUgbGF0ZXJcbiAgICAgICAgcGFyZW50Tm9kZS5jaGlsZHJlbi5zcGxpY2Uobm9kZVBvc2l0aW9uLCAxKTtcbiAgICAgICAgcGFyZW50Tm9kZS5jaGlsZHJlbi5zcGxpY2Uobm9kZVBvc2l0aW9uICsgMSwgMCwgdGFyZ2V0Tm9kZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdGFyZ2V0Tm9kZSxcbiAgICAgIHBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICBzd2FwTm9kZVdpdGhQcmV2aW91c1NpYmxpbmcobm9kZUlkOiBzdHJpbmcpIHtcbiAgICBsZXQgdGFyZ2V0Tm9kZTogT3V0bGluZVRyZWUsIHBhcmVudE5vZGU6IE91dGxpbmVUcmVlO1xuICAgIHRoaXMuZmluZE5vZGVJblRyZWUodGhpcy5kYXRhLnRyZWUsIG5vZGVJZCwgKHROb2RlLCBwTm9kZSkgPT4ge1xuICAgICAgICB0YXJnZXROb2RlID0gdE5vZGU7XG4gICAgICAgIHBhcmVudE5vZGUgPSBwTm9kZTtcbiAgICAgICAgY29uc3QgZmxhdElkID0gcGFyZW50Tm9kZS5jaGlsZHJlbi5tYXAobiA9PiBuLmlkKTtcbiAgICAgICAgY29uc3Qgbm9kZVBvc2l0aW9uID0gZmxhdElkLmluZGV4T2YodGFyZ2V0Tm9kZS5pZCk7XG5cbiAgICAgICAgaWYobm9kZVBvc2l0aW9uID09PSAwKSB7XG4gICAgICAgICAgLy8gdGhpcyBpcyB0aGUgZmlyc3Qgbm9kZSBpbiB0aGUgbGlzdCwgdGhlcmUncyBub3RoaW5nIHRvIHN3YXBcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyByZW1vdmUgdGhlIG5vZGUgZnJvbSB0aGlzIHBvaW50LCBhbmQgcHVzaCBpdCBvbmUgbGF0ZXJcbiAgICAgICAgcGFyZW50Tm9kZS5jaGlsZHJlbi5zcGxpY2Uobm9kZVBvc2l0aW9uLCAxKTtcbiAgICAgICAgcGFyZW50Tm9kZS5jaGlsZHJlbi5zcGxpY2Uobm9kZVBvc2l0aW9uIC0gMSwgMCwgdGFyZ2V0Tm9kZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdGFyZ2V0Tm9kZSxcbiAgICAgIHBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICBjcmVhdGVTaWJsaW5nTm9kZSh0YXJnZXROb2RlOiBzdHJpbmcsIG5vZGVEYXRhPzogT3V0bGluZU5vZGUpIHtcbiAgICBjb25zdCBvdXRsaW5lTm9kZTogT3V0bGluZU5vZGUgPSBub2RlRGF0YSB8fCB7XG4gICAgICBpZDogdXVpZCgpLFxuICAgICAgY3JlYXRlZDogRGF0ZS5ub3coKSxcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIGNvbnRlbnQ6ICctLS0nLFxuICAgICAgc3RyaWtldGhyb3VnaDogZmFsc2VcbiAgICB9O1xuXG4gICAgdGhpcy5kYXRhLmNvbnRlbnROb2Rlc1tvdXRsaW5lTm9kZS5pZF0gPSBvdXRsaW5lTm9kZTtcblxuICAgIGxldCBwYXJlbnROb2RlOiBPdXRsaW5lVHJlZTtcblxuICAgIHRoaXMuZmluZE5vZGVJblRyZWUodGhpcy5kYXRhLnRyZWUsIHRhcmdldE5vZGUsIChub2RlLCBwYXJlbnQpID0+IHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gcGFyZW50LmNoaWxkcmVuLm1hcChuID0+IG4uaWQpLmluZGV4T2YodGFyZ2V0Tm9kZSk7XG4gICAgICBwYXJlbnQuY2hpbGRyZW4uc3BsaWNlKHBvc2l0aW9uICsgMSwgMCwge1xuICAgICAgICBpZDogb3V0bGluZU5vZGUuaWQsXG4gICAgICAgIGNvbGxhcHNlZDogZmFsc2UsXG4gICAgICAgIGNoaWxkcmVuOiBbXVxuICAgICAgfSk7XG5cbiAgICAgIHBhcmVudE5vZGUgPSBwYXJlbnQ7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbm9kZTogb3V0bGluZU5vZGUsXG4gICAgICBwYXJlbnROb2RlXG4gICAgfVxuICB9XG5cbiAgY3JlYXRlQ2hpbGROb2RlKGN1cnJlbnROb2RlOiBzdHJpbmcsIG5vZGVJZD86IHN0cmluZykge1xuICAgIGNvbnN0IG5vZGU6IE91dGxpbmVOb2RlID0gbm9kZUlkID8gdGhpcy5kYXRhLmNvbnRlbnROb2Rlc1tub2RlSWRdIDpcbiAgICB7XG4gICAgICBpZDogdXVpZCgpLFxuICAgICAgY3JlYXRlZDogRGF0ZS5ub3coKSxcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIGNvbnRlbnQ6ICctLS0nLFxuICAgICAgc3RyaWtldGhyb3VnaDogZmFsc2VcbiAgICB9O1xuXG4gICAgaWYoIW5vZGVJZCkge1xuICAgICAgdGhpcy5kYXRhLmNvbnRlbnROb2Rlc1tub2RlLmlkXSA9IG5vZGU7XG4gICAgfVxuXG4gICAgbGV0IHBhcmVudE5vZGU6IE91dGxpbmVUcmVlO1xuXG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgY3VycmVudE5vZGUsIChmb3VuZE5vZGUsIHBhcmVudCkgPT4ge1xuICAgICAgZm91bmROb2RlLmNoaWxkcmVuLnVuc2hpZnQoe1xuICAgICAgICBpZDogbm9kZS5pZCxcbiAgICAgICAgY2hpbGRyZW46IFtdLFxuICAgICAgICBjb2xsYXBzZWQ6IGZhbHNlXG4gICAgICB9KTtcblxuICAgICAgcGFyZW50Tm9kZSA9IGZvdW5kTm9kZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBub2RlLFxuICAgICAgcGFyZW50Tm9kZVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZU5vZGUobm9kZUlkOiBzdHJpbmcpIHtcbiAgICBsZXQgcnVuID0gZmFsc2U7XG4gICAgbGV0IHJlbW92ZWROb2RlOiBPdXRsaW5lVHJlZSwgcGFyZW50Tm9kZTogT3V0bGluZVRyZWU7XG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgbm9kZUlkLCAodE5vZGUsIHBOb2RlKSA9PiB7XG4gICAgICBpZihydW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcnVuID0gdHJ1ZTtcbiAgICAgIHJlbW92ZWROb2RlID0gdE5vZGU7XG4gICAgICBwYXJlbnROb2RlID0gcE5vZGU7XG5cbiAgICAgIGxldCBwb3NpdGlvbiA9IHBhcmVudE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCkuaW5kZXhPZih0Tm9kZS5pZCk7XG5cbiAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICByZW1vdmVkTm9kZSxcbiAgICAgIHBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICB1cGRhdGVDb250ZW50KGlkOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZykge1xuICAgIGlmKCF0aGlzLmRhdGEuY29udGVudE5vZGVzW2lkXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG5vZGUnKTtcbiAgICB9XG5cbiAgICB0aGlzLmRhdGEuY29udGVudE5vZGVzW2lkXS5jb250ZW50ID0gY29udGVudDtcbiAgfVxuXG4gIHJlbmRlckNvbnRlbnQobm9kZUlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCBub2RlID0gdGhpcy5kYXRhLmNvbnRlbnROb2Rlc1tub2RlSWRdO1xuICAgIGxldCBjb250ZW50OiBzdHJpbmc7XG4gICAgc3dpdGNoKG5vZGUudHlwZSkge1xuICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgIGNvbnRlbnQgPSBtYXJrZWQucGFyc2Uobm9kZS5jb250ZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OiBcbiAgICAgICAgY29udGVudCA9IG5vZGUuY29udGVudDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRlbnQ7XG4gIH1cblxuICByZW5kZXJOb2RlKG5vZGU6IE91dGxpbmVUcmVlKTogc3RyaW5nIHtcbiAgICBpZihub2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgcmV0dXJuIHRoaXMucmVuZGVyKCk7XG4gICAgfVxuICAgIGNvbnN0IGNvbGxhcHNlID0gbm9kZS5jb2xsYXBzZWQgPyAnY29sbGFwc2VkJzogJ2V4cGFuZGVkJztcbiAgICBjb25zdCBjb250ZW50OiBPdXRsaW5lTm9kZSA9IHRoaXMuZGF0YS5jb250ZW50Tm9kZXNbbm9kZS5pZF0gfHwge1xuICAgICAgaWQ6IG5vZGUuaWQsXG4gICAgICBjcmVhdGVkOiBEYXRlLm5vdygpLFxuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgY29udGVudDogJycsXG4gICAgICBzdHJpa2V0aHJvdWdoOiBmYWxzZVxuICAgIH07XG5cbiAgICBjb25zdCBzdHJpa2V0aHJvdWdoID0gY29udGVudC5zdHJpa2V0aHJvdWdoID8gJ3N0cmlrZXRocm91Z2gnIDogJyc7XG5cbiAgICBsZXQgaHRtbCA9IGA8ZGl2IGNsYXNzPVwibm9kZSAke2NvbGxhcHNlfSAke3N0cmlrZXRocm91Z2h9XCIgZGF0YS1pZD1cIiR7bm9kZS5pZH1cIiBpZD1cImlkLSR7bm9kZS5pZH1cIj5cbiAgICA8ZGl2IGNsYXNzPVwibm9kZUNvbnRlbnRcIiBkYXRhLXR5cGU9XCIke2NvbnRlbnQudHlwZX1cIj5cbiAgICAgICR7dGhpcy5yZW5kZXJDb250ZW50KG5vZGUuaWQpfVxuICAgIDwvZGl2PlxuICAgICR7bm9kZS5jaGlsZHJlbi5sZW5ndGggPyBfLm1hcChub2RlLmNoaWxkcmVuLCB0aGlzLnJlbmRlck5vZGUuYmluZCh0aGlzKSkuam9pbihcIlxcblwiKSA6ICcnfVxuICAgIDwvZGl2PmBcblxuICAgIHJldHVybiBodG1sO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIC8qXG4gICAgICogcmVuZGVyIHN0YXJ0cyBhdCB0aGUgcm9vdCBub2RlIGFuZCBvbmx5IHJlbmRlcnMgaXRzIGNoaWxkcmVuLiBUaGUgcm9vdCBcbiAgICAgKiBub2RlIG9ubHkgZXhpc3RzIGFzIGEgY29udGFpbmVyIGFyb3VuZCB0aGUgcmVzdCB0byBlbnN1cmUgYSBzdGFuZGFyZCBmb3JtYXRcbiAgICAgKiBmb3IgdGhlIHRyZWVcbiAgICAgKi9cbiAgICByZXR1cm4gXy5tYXAodGhpcy5kYXRhLnRyZWUuY2hpbGRyZW4sIHRoaXMucmVuZGVyTm9kZS5iaW5kKHRoaXMpKS5qb2luKFwiXFxuXCIpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBjcmVhdGUsIGluc2VydCwgaW5zZXJ0QmF0Y2gsIHNlYXJjaCB9IGZyb20gJ0BseXJhc2VhcmNoL2x5cmEnO1xuaW1wb3J0IHsgbWFwIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IE91dGxpbmVOb2RlIH0gZnJvbSAnb3V0bGluZSc7XG5pbXBvcnQga2V5Ym9hcmRKUyBmcm9tICdrZXlib2FyZGpzJztcbmltcG9ydCB7aXNWaXNpYmxlfSBmcm9tICdkb20nO1xuXG5jb25zdCBzZWFyY2hNb2RhbCA9IGBcbjxkaXYgY2xhc3M9XCJtb2RhbFwiPlxuPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRlbnRcIiBpZD1cInNlYXJjaFwiPlxuPGlucHV0IHR5cGU9XCJ0ZXh0XCIgaWQ9XCJzZWFyY2gtcXVlcnlcIiBwbGFjZWhvbGRlcj1cImVudGVyIGZ1enp5IHNlYXJjaCB0ZXJtc1wiPlxuPHVsIGlkPVwic2VhcmNoLXJlc3VsdHNcIj5cbjwvdWw+XG48L2Rpdj5cbjwvZGl2PlxuYDtcblxuZXhwb3J0IGNsYXNzIFNlYXJjaCB7XG4gIGRiOiBhbnk7XG4gIGRlYm91bmNlOiBhbnk7XG4gIHN0YXRlOiAncmVhZHknIHwgJ25vdHJlYWR5J1xuXG4gIG9uVGVybVNlbGVjdGlvbjogYW55O1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLnN0YXRlID0gJ25vdHJlYWR5JztcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUluZGV4KHNjaGVtYTogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICAgIHRoaXMuZGIgPSBhd2FpdCBjcmVhdGUoe1xuICAgICAgc2NoZW1hXG4gICAgfSk7XG4gICAgdGhpcy5zdGF0ZSA9ICdyZWFkeSc7XG4gIH1cblxuICBiaW5kRXZlbnRzKCkge1xuICAgIGtleWJvYXJkSlMud2l0aENvbnRleHQoJ3NlYXJjaCcsICgpID0+IHtcbiAgICAgIGtleWJvYXJkSlMuYmluZCgnZXNjYXBlJywgZSA9PiB7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb2RhbCcpLnJlbW92ZSgpO1xuICAgICAgICBrZXlib2FyZEpTLnNldENvbnRleHQoJ25hdmlnYXRpb24nKTtcbiAgICAgIH0pO1xuXG4gICAgICBrZXlib2FyZEpTLmJpbmQoJ2Rvd24nLCBlID0+IHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VhcmNoLXF1ZXJ5JykuYmx1cigpO1xuICAgICAgICBjb25zdCBlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZWFyY2gtcmVzdWx0LnNlbGVjdGVkJyk7XG4gICAgICAgIGlmKGVsLm5leHRFbGVtZW50U2libGluZykge1xuICAgICAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoJ3NlbGVjdGVkJyk7XG4gICAgICAgICAgZWwubmV4dEVsZW1lbnRTaWJsaW5nLmNsYXNzTGlzdC5hZGQoJ3NlbGVjdGVkJyk7XG4gICAgICAgICAgaWYoIWlzVmlzaWJsZShlbC5uZXh0RWxlbWVudFNpYmxpbmcgYXMgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgICAgICBlbC5uZXh0RWxlbWVudFNpYmxpbmcuc2Nyb2xsSW50b1ZpZXcoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBrZXlib2FyZEpTLmJpbmQoJ3VwJywgZSA9PiB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2VhcmNoLXJlc3VsdC5zZWxlY3RlZCcpO1xuICAgICAgICBpZihlbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nKSB7XG4gICAgICAgICAgZWwuY2xhc3NMaXN0LnJlbW92ZSgnc2VsZWN0ZWQnKTtcbiAgICAgICAgICBlbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nLmNsYXNzTGlzdC5hZGQoJ3NlbGVjdGVkJyk7XG4gICAgICAgICAgaWYoIWlzVmlzaWJsZShlbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nIGFzIEhUTUxFbGVtZW50KSkge1xuICAgICAgICAgICAgZWwucHJldmlvdXNFbGVtZW50U2libGluZy5zY3JvbGxJbnRvVmlldygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAga2V5Ym9hcmRKUy5iaW5kKCdlbnRlcicsIGUgPT4ge1xuICAgICAgICBjb25zdCBlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZWFyY2gtcmVzdWx0LnNlbGVjdGVkJyk7XG4gICAgICAgIGNvbnN0IGRvY0lkID0gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyk7XG5cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vZGFsJykucmVtb3ZlKCk7XG4gICAgICAgIGtleWJvYXJkSlMuc2V0Q29udGV4dCgnbmF2aWdhdGlvbicpO1xuXG4gICAgICAgIGlmKHRoaXMub25UZXJtU2VsZWN0aW9uKSB7XG4gICAgICAgICAgdGhpcy5vblRlcm1TZWxlY3Rpb24oZG9jSWQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGtleWJvYXJkSlMud2l0aENvbnRleHQoJ25hdmlnYXRpb24nLCAoKSA9PiB7XG4gICAgICBrZXlib2FyZEpTLmJpbmQoJ3NoaWZ0ICsgZicsIGUgPT4ge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7IFxuXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5pbm5lckhUTUwgKz0gc2VhcmNoTW9kYWw7XG4gICAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlYXJjaC1xdWVyeScpO1xuICAgICAgICBlbC5mb2N1cygpO1xuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCdrZXl1cCcsIHRoaXMuZGVib3VuY2VTZWFyY2guYmluZCh0aGlzKSk7XG4gICAgICAgIGtleWJvYXJkSlMuc2V0Q29udGV4dCgnc2VhcmNoJyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGRlYm91bmNlU2VhcmNoKGU6IEtleWJvYXJkRXZlbnQpIHtcbiAgICBpZih0aGlzLmRlYm91bmNlKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMuZGVib3VuY2UpO1xuICAgIH1cblxuICAgIGNvbnN0IGVsID0gZS50YXJnZXQgYXMgSFRNTFRleHRBcmVhRWxlbWVudDtcbiAgICBjb25zdCBxdWVyeSA9IGVsLnZhbHVlLnRvU3RyaW5nKCkudHJpbSgpO1xuXG4gICAgaWYocXVlcnkubGVuZ3RoKSB7XG4gICAgICB0aGlzLmRlYm91bmNlID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGlzcGxheVNlYXJjaChxdWVyeSwgZSk7XG4gICAgICB9LCAxMDApO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGRpc3BsYXlTZWFyY2godGVybXM6IHN0cmluZywgZTogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmKCF0aGlzLnN0YXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuc2VhcmNoKHRlcm1zKTtcblxuICAgIGNvbnN0IHJlc3VsdENvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWFyY2gtcmVzdWx0cycpO1xuXG4gICAgaWYocmVzLmhpdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXN1bHRDb250YWluZXIuaW5uZXJIVE1MID0gJzxsaT48ZW0+Tm8gUmVzdWx0czwvZW0+PC9saT4nO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGh0bWwgPSByZXMuaGl0cy5tYXAoKGRvYywgaWR4KSA9PiB7XG4gICAgICBjb25zdCBjb250ZW50ID0gZG9jLmRvY3VtZW50LmNvbnRlbnQudG9TdHJpbmcoKTtcbiAgICAgIGNvbnN0IGRpc3BsYXkgPSBjb250ZW50LnN1YnN0cmluZygwLCAxMDApO1xuXG4gICAgICByZXR1cm4gYFxuICAgICAgPGxpIGNsYXNzPVwic2VhcmNoLXJlc3VsdCAke2lkeCA9PT0gMCA/ICdzZWxlY3RlZCcgOiAnJ31cIiBkYXRhLWlkPVwiJHtkb2MuaWR9XCI+JHtkaXNwbGF5fSR7Y29udGVudC5sZW5ndGggPiBkaXNwbGF5Lmxlbmd0aCA/ICcuLi4nOiAnJ308L2xpPlxuICAgICAgYDtcbiAgICB9KTtcblxuICAgIHJlc3VsdENvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sLmpvaW4oXCJcXG5cIik7XG4gIH1cblxuICBpbmRleERvYyhkb2M6IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgICByZXR1cm4gaW5zZXJ0KHRoaXMuZGIsIGRvYylcbiAgfVxuXG4gIGluZGV4QmF0Y2goZG9jczogUmVjb3JkPHN0cmluZywgT3V0bGluZU5vZGU+KSB7XG4gICAgcmV0dXJuIGluc2VydEJhdGNoKHRoaXMuZGIsIG1hcChkb2NzLCBkb2MgPT4gZG9jIGFzIGFueSkpO1xuICB9XG5cbiAgc2VhcmNoKHRlcm06IHN0cmluZykge1xuICAgIHJldHVybiBzZWFyY2godGhpcy5kYiwge1xuICAgICAgdGVybTogdGVybS50cmltKCksXG4gICAgICBwcm9wZXJ0aWVzOiBbXCJjb250ZW50XCJdXG4gICAgfSk7XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTklMXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIF9uaWwuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJwYXJzZVwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiBfcGFyc2UuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJzdHJpbmdpZnlcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3N0cmluZ2lmeS5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInYxXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIF92LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjNcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3YyLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjRcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3YzLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjVcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3Y0LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidmFsaWRhdGVcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3ZhbGlkYXRlLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidmVyc2lvblwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiBfdmVyc2lvbi5kZWZhdWx0O1xuICB9XG59KTtcblxudmFyIF92ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92MS5qc1wiKSk7XG5cbnZhciBfdjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3YzLmpzXCIpKTtcblxudmFyIF92MyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjQuanNcIikpO1xuXG52YXIgX3Y0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92NS5qc1wiKSk7XG5cbnZhciBfbmlsID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9uaWwuanNcIikpO1xuXG52YXIgX3ZlcnNpb24gPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZlcnNpb24uanNcIikpO1xuXG52YXIgX3ZhbGlkYXRlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92YWxpZGF0ZS5qc1wiKSk7XG5cbnZhciBfc3RyaW5naWZ5ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9zdHJpbmdpZnkuanNcIikpO1xuXG52YXIgX3BhcnNlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9wYXJzZS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbi8qXG4gKiBCcm93c2VyLWNvbXBhdGlibGUgSmF2YVNjcmlwdCBNRDVcbiAqXG4gKiBNb2RpZmljYXRpb24gb2YgSmF2YVNjcmlwdCBNRDVcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ibHVlaW1wL0phdmFTY3JpcHQtTUQ1XG4gKlxuICogQ29weXJpZ2h0IDIwMTEsIFNlYmFzdGlhbiBUc2NoYW5cbiAqIGh0dHBzOi8vYmx1ZWltcC5uZXRcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2U6XG4gKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVFxuICpcbiAqIEJhc2VkIG9uXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFJTQSBEYXRhIFNlY3VyaXR5LCBJbmMuIE1ENSBNZXNzYWdlXG4gKiBEaWdlc3QgQWxnb3JpdGhtLCBhcyBkZWZpbmVkIGluIFJGQyAxMzIxLlxuICogVmVyc2lvbiAyLjIgQ29weXJpZ2h0IChDKSBQYXVsIEpvaG5zdG9uIDE5OTkgLSAyMDA5XG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBtb3JlIGluZm8uXG4gKi9cbmZ1bmN0aW9uIG1kNShieXRlcykge1xuICBpZiAodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IG1zZyA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChieXRlcykpOyAvLyBVVEY4IGVzY2FwZVxuXG4gICAgYnl0ZXMgPSBuZXcgVWludDhBcnJheShtc2cubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgKytpKSB7XG4gICAgICBieXRlc1tpXSA9IG1zZy5jaGFyQ29kZUF0KGkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtZDVUb0hleEVuY29kZWRBcnJheSh3b3Jkc1RvTWQ1KGJ5dGVzVG9Xb3JkcyhieXRlcyksIGJ5dGVzLmxlbmd0aCAqIDgpKTtcbn1cbi8qXG4gKiBDb252ZXJ0IGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMgdG8gYW4gYXJyYXkgb2YgYnl0ZXNcbiAqL1xuXG5cbmZ1bmN0aW9uIG1kNVRvSGV4RW5jb2RlZEFycmF5KGlucHV0KSB7XG4gIGNvbnN0IG91dHB1dCA9IFtdO1xuICBjb25zdCBsZW5ndGgzMiA9IGlucHV0Lmxlbmd0aCAqIDMyO1xuICBjb25zdCBoZXhUYWIgPSAnMDEyMzQ1Njc4OWFiY2RlZic7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGgzMjsgaSArPSA4KSB7XG4gICAgY29uc3QgeCA9IGlucHV0W2kgPj4gNV0gPj4+IGkgJSAzMiAmIDB4ZmY7XG4gICAgY29uc3QgaGV4ID0gcGFyc2VJbnQoaGV4VGFiLmNoYXJBdCh4ID4+PiA0ICYgMHgwZikgKyBoZXhUYWIuY2hhckF0KHggJiAweDBmKSwgMTYpO1xuICAgIG91dHB1dC5wdXNoKGhleCk7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGUgb3V0cHV0IGxlbmd0aCB3aXRoIHBhZGRpbmcgYW5kIGJpdCBsZW5ndGhcbiAqL1xuXG5cbmZ1bmN0aW9uIGdldE91dHB1dExlbmd0aChpbnB1dExlbmd0aDgpIHtcbiAgcmV0dXJuIChpbnB1dExlbmd0aDggKyA2NCA+Pj4gOSA8PCA0KSArIDE0ICsgMTtcbn1cbi8qXG4gKiBDYWxjdWxhdGUgdGhlIE1ENSBvZiBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzLCBhbmQgYSBiaXQgbGVuZ3RoLlxuICovXG5cblxuZnVuY3Rpb24gd29yZHNUb01kNSh4LCBsZW4pIHtcbiAgLyogYXBwZW5kIHBhZGRpbmcgKi9cbiAgeFtsZW4gPj4gNV0gfD0gMHg4MCA8PCBsZW4gJSAzMjtcbiAgeFtnZXRPdXRwdXRMZW5ndGgobGVuKSAtIDFdID0gbGVuO1xuICBsZXQgYSA9IDE3MzI1ODQxOTM7XG4gIGxldCBiID0gLTI3MTczMzg3OTtcbiAgbGV0IGMgPSAtMTczMjU4NDE5NDtcbiAgbGV0IGQgPSAyNzE3MzM4Nzg7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSArPSAxNikge1xuICAgIGNvbnN0IG9sZGEgPSBhO1xuICAgIGNvbnN0IG9sZGIgPSBiO1xuICAgIGNvbnN0IG9sZGMgPSBjO1xuICAgIGNvbnN0IG9sZGQgPSBkO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2ldLCA3LCAtNjgwODc2OTM2KTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgMV0sIDEyLCAtMzg5NTY0NTg2KTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgMl0sIDE3LCA2MDYxMDU4MTkpO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyAzXSwgMjIsIC0xMDQ0NTI1MzMwKTtcbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpICsgNF0sIDcsIC0xNzY0MTg4OTcpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyA1XSwgMTIsIDEyMDAwODA0MjYpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyA2XSwgMTcsIC0xNDczMjMxMzQxKTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgN10sIDIyLCAtNDU3MDU5ODMpO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2kgKyA4XSwgNywgMTc3MDAzNTQxNik7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDldLCAxMiwgLTE5NTg0MTQ0MTcpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyAxMF0sIDE3LCAtNDIwNjMpO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyAxMV0sIDIyLCAtMTk5MDQwNDE2Mik7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaSArIDEyXSwgNywgMTgwNDYwMzY4Mik7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDEzXSwgMTIsIC00MDM0MTEwMSk7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgMTVdLCAyMiwgMTIzNjUzNTMyOSk7XG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDFdLCA1LCAtMTY1Nzk2NTEwKTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgNl0sIDksIC0xMDY5NTAxNjMyKTtcbiAgICBjID0gbWQ1Z2coYywgZCwgYSwgYiwgeFtpICsgMTFdLCAxNCwgNjQzNzE3NzEzKTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpXSwgMjAsIC0zNzM4OTczMDIpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyA1XSwgNSwgLTcwMTU1ODY5MSk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDEwXSwgOSwgMzgwMTYwODMpO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAxNV0sIDE0LCAtNjYwNDc4MzM1KTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpICsgNF0sIDIwLCAtNDA1NTM3ODQ4KTtcbiAgICBhID0gbWQ1Z2coYSwgYiwgYywgZCwgeFtpICsgOV0sIDUsIDU2ODQ0NjQzOCk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDE0XSwgOSwgLTEwMTk4MDM2OTApO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAzXSwgMTQsIC0xODczNjM5NjEpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2kgKyA4XSwgMjAsIDExNjM1MzE1MDEpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyAxM10sIDUsIC0xNDQ0NjgxNDY3KTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMl0sIDksIC01MTQwMzc4NCk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDddLCAxNCwgMTczNTMyODQ3Myk7XG4gICAgYiA9IG1kNWdnKGIsIGMsIGQsIGEsIHhbaSArIDEyXSwgMjAsIC0xOTI2NjA3NzM0KTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgNV0sIDQsIC0zNzg1NTgpO1xuICAgIGQgPSBtZDVoaChkLCBhLCBiLCBjLCB4W2kgKyA4XSwgMTEsIC0yMDIyNTc0NDYzKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgMTFdLCAxNiwgMTgzOTAzMDU2Mik7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDE0XSwgMjMsIC0zNTMwOTU1Nik7XG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDFdLCA0LCAtMTUzMDk5MjA2MCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaSArIDRdLCAxMSwgMTI3Mjg5MzM1Myk7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDddLCAxNiwgLTE1NTQ5NzYzMik7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDEwXSwgMjMsIC0xMDk0NzMwNjQwKTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgMTNdLCA0LCA2ODEyNzkxNzQpO1xuICAgIGQgPSBtZDVoaChkLCBhLCBiLCBjLCB4W2ldLCAxMSwgLTM1ODUzNzIyMik7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDNdLCAxNiwgLTcyMjUyMTk3OSk7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDZdLCAyMywgNzYwMjkxODkpO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyA5XSwgNCwgLTY0MDM2NDQ4Nyk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaSArIDEyXSwgMTEsIC00MjE4MTU4MzUpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyAxNV0sIDE2LCA1MzA3NDI1MjApO1xuICAgIGIgPSBtZDVoaChiLCBjLCBkLCBhLCB4W2kgKyAyXSwgMjMsIC05OTUzMzg2NTEpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2ldLCA2LCAtMTk4NjMwODQ0KTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgN10sIDEwLCAxMTI2ODkxNDE1KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgMTRdLCAxNSwgLTE0MTYzNTQ5MDUpO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyA1XSwgMjEsIC01NzQzNDA1NSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaSArIDEyXSwgNiwgMTcwMDQ4NTU3MSk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDNdLCAxMCwgLTE4OTQ5ODY2MDYpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyAxMF0sIDE1LCAtMTA1MTUyMyk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDFdLCAyMSwgLTIwNTQ5MjI3OTkpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2kgKyA4XSwgNiwgMTg3MzMxMzM1OSk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDE1XSwgMTAsIC0zMDYxMTc0NCk7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDZdLCAxNSwgLTE1NjAxOTgzODApO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyAxM10sIDIxLCAxMzA5MTUxNjQ5KTtcbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpICsgNF0sIDYsIC0xNDU1MjMwNzApO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyAxMV0sIDEwLCAtMTEyMDIxMDM3OSk7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDJdLCAxNSwgNzE4Nzg3MjU5KTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgOV0sIDIxLCAtMzQzNDg1NTUxKTtcbiAgICBhID0gc2FmZUFkZChhLCBvbGRhKTtcbiAgICBiID0gc2FmZUFkZChiLCBvbGRiKTtcbiAgICBjID0gc2FmZUFkZChjLCBvbGRjKTtcbiAgICBkID0gc2FmZUFkZChkLCBvbGRkKTtcbiAgfVxuXG4gIHJldHVybiBbYSwgYiwgYywgZF07XG59XG4vKlxuICogQ29udmVydCBhbiBhcnJheSBieXRlcyB0byBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzXG4gKiBDaGFyYWN0ZXJzID4yNTUgaGF2ZSB0aGVpciBoaWdoLWJ5dGUgc2lsZW50bHkgaWdub3JlZC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGJ5dGVzVG9Xb3JkcyhpbnB1dCkge1xuICBpZiAoaW5wdXQubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgbGVuZ3RoOCA9IGlucHV0Lmxlbmd0aCAqIDg7XG4gIGNvbnN0IG91dHB1dCA9IG5ldyBVaW50MzJBcnJheShnZXRPdXRwdXRMZW5ndGgobGVuZ3RoOCkpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoODsgaSArPSA4KSB7XG4gICAgb3V0cHV0W2kgPj4gNV0gfD0gKGlucHV0W2kgLyA4XSAmIDB4ZmYpIDw8IGkgJSAzMjtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59XG4vKlxuICogQWRkIGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnMgaW50ZXJuYWxseVxuICogdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAqL1xuXG5cbmZ1bmN0aW9uIHNhZmVBZGQoeCwgeSkge1xuICBjb25zdCBsc3cgPSAoeCAmIDB4ZmZmZikgKyAoeSAmIDB4ZmZmZik7XG4gIGNvbnN0IG1zdyA9ICh4ID4+IDE2KSArICh5ID4+IDE2KSArIChsc3cgPj4gMTYpO1xuICByZXR1cm4gbXN3IDw8IDE2IHwgbHN3ICYgMHhmZmZmO1xufVxuLypcbiAqIEJpdHdpc2Ugcm90YXRlIGEgMzItYml0IG51bWJlciB0byB0aGUgbGVmdC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGJpdFJvdGF0ZUxlZnQobnVtLCBjbnQpIHtcbiAgcmV0dXJuIG51bSA8PCBjbnQgfCBudW0gPj4+IDMyIC0gY250O1xufVxuLypcbiAqIFRoZXNlIGZ1bmN0aW9ucyBpbXBsZW1lbnQgdGhlIGZvdXIgYmFzaWMgb3BlcmF0aW9ucyB0aGUgYWxnb3JpdGhtIHVzZXMuXG4gKi9cblxuXG5mdW5jdGlvbiBtZDVjbW4ocSwgYSwgYiwgeCwgcywgdCkge1xuICByZXR1cm4gc2FmZUFkZChiaXRSb3RhdGVMZWZ0KHNhZmVBZGQoc2FmZUFkZChhLCBxKSwgc2FmZUFkZCh4LCB0KSksIHMpLCBiKTtcbn1cblxuZnVuY3Rpb24gbWQ1ZmYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGIgJiBjIHwgfmIgJiBkLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gbWQ1Z2coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGIgJiBkIHwgYyAmIH5kLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gbWQ1aGgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIG1kNWlpKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIG1kNWNtbihjIF4gKGIgfCB+ZCksIGEsIGIsIHgsIHMsIHQpO1xufVxuXG52YXIgX2RlZmF1bHQgPSBtZDU7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcbmNvbnN0IHJhbmRvbVVVSUQgPSB0eXBlb2YgY3J5cHRvICE9PSAndW5kZWZpbmVkJyAmJiBjcnlwdG8ucmFuZG9tVVVJRCAmJiBjcnlwdG8ucmFuZG9tVVVJRC5iaW5kKGNyeXB0byk7XG52YXIgX2RlZmF1bHQgPSB7XG4gIHJhbmRvbVVVSURcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcbnZhciBfZGVmYXVsdCA9ICcwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAnO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gcGFyc2UodXVpZCkge1xuICBpZiAoISgwLCBfdmFsaWRhdGUuZGVmYXVsdCkodXVpZCkpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ0ludmFsaWQgVVVJRCcpO1xuICB9XG5cbiAgbGV0IHY7XG4gIGNvbnN0IGFyciA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gUGFyc2UgIyMjIyMjIyMtLi4uLi0uLi4uLS4uLi4tLi4uLi4uLi4uLi4uXG5cbiAgYXJyWzBdID0gKHYgPSBwYXJzZUludCh1dWlkLnNsaWNlKDAsIDgpLCAxNikpID4+PiAyNDtcbiAgYXJyWzFdID0gdiA+Pj4gMTYgJiAweGZmO1xuICBhcnJbMl0gPSB2ID4+PiA4ICYgMHhmZjtcbiAgYXJyWzNdID0gdiAmIDB4ZmY7IC8vIFBhcnNlIC4uLi4uLi4uLSMjIyMtLi4uLi0uLi4uLS4uLi4uLi4uLi4uLlxuXG4gIGFycls0XSA9ICh2ID0gcGFyc2VJbnQodXVpZC5zbGljZSg5LCAxMyksIDE2KSkgPj4+IDg7XG4gIGFycls1XSA9IHYgJiAweGZmOyAvLyBQYXJzZSAuLi4uLi4uLi0uLi4uLSMjIyMtLi4uLi0uLi4uLi4uLi4uLi5cblxuICBhcnJbNl0gPSAodiA9IHBhcnNlSW50KHV1aWQuc2xpY2UoMTQsIDE4KSwgMTYpKSA+Pj4gODtcbiAgYXJyWzddID0gdiAmIDB4ZmY7IC8vIFBhcnNlIC4uLi4uLi4uLS4uLi4tLi4uLi0jIyMjLS4uLi4uLi4uLi4uLlxuXG4gIGFycls4XSA9ICh2ID0gcGFyc2VJbnQodXVpZC5zbGljZSgxOSwgMjMpLCAxNikpID4+PiA4O1xuICBhcnJbOV0gPSB2ICYgMHhmZjsgLy8gUGFyc2UgLi4uLi4uLi4tLi4uLi0uLi4uLS4uLi4tIyMjIyMjIyMjIyMjXG4gIC8vIChVc2UgXCIvXCIgdG8gYXZvaWQgMzItYml0IHRydW5jYXRpb24gd2hlbiBiaXQtc2hpZnRpbmcgaGlnaC1vcmRlciBieXRlcylcblxuICBhcnJbMTBdID0gKHYgPSBwYXJzZUludCh1dWlkLnNsaWNlKDI0LCAzNiksIDE2KSkgLyAweDEwMDAwMDAwMDAwICYgMHhmZjtcbiAgYXJyWzExXSA9IHYgLyAweDEwMDAwMDAwMCAmIDB4ZmY7XG4gIGFyclsxMl0gPSB2ID4+PiAyNCAmIDB4ZmY7XG4gIGFyclsxM10gPSB2ID4+PiAxNiAmIDB4ZmY7XG4gIGFyclsxNF0gPSB2ID4+PiA4ICYgMHhmZjtcbiAgYXJyWzE1XSA9IHYgJiAweGZmO1xuICByZXR1cm4gYXJyO1xufVxuXG52YXIgX2RlZmF1bHQgPSBwYXJzZTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xudmFyIF9kZWZhdWx0ID0gL14oPzpbMC05YS1mXXs4fS1bMC05YS1mXXs0fS1bMS01XVswLTlhLWZdezN9LVs4OWFiXVswLTlhLWZdezN9LVswLTlhLWZdezEyfXwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDApJC9pO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBybmc7XG4vLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiBJbiB0aGUgYnJvd3NlciB3ZSB0aGVyZWZvcmVcbi8vIHJlcXVpcmUgdGhlIGNyeXB0byBBUEkgYW5kIGRvIG5vdCBzdXBwb3J0IGJ1aWx0LWluIGZhbGxiYWNrIHRvIGxvd2VyIHF1YWxpdHkgcmFuZG9tIG51bWJlclxuLy8gZ2VuZXJhdG9ycyAobGlrZSBNYXRoLnJhbmRvbSgpKS5cbmxldCBnZXRSYW5kb21WYWx1ZXM7XG5jb25zdCBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTtcblxuZnVuY3Rpb24gcm5nKCkge1xuICAvLyBsYXp5IGxvYWQgc28gdGhhdCBlbnZpcm9ubWVudHMgdGhhdCBuZWVkIHRvIHBvbHlmaWxsIGhhdmUgYSBjaGFuY2UgdG8gZG8gc29cbiAgaWYgKCFnZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAvLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG8gaW1wbGVtZW50YXRpb24uXG4gICAgZ2V0UmFuZG9tVmFsdWVzID0gdHlwZW9mIGNyeXB0byAhPT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKTtcblxuICAgIGlmICghZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoKSBub3Qgc3VwcG9ydGVkLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3V1aWRqcy91dWlkI2dldHJhbmRvbXZhbHVlcy1ub3Qtc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG59IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbi8vIEFkYXB0ZWQgZnJvbSBDaHJpcyBWZW5lc3MnIFNIQTEgY29kZSBhdFxuLy8gaHR0cDovL3d3dy5tb3ZhYmxlLXR5cGUuY28udWsvc2NyaXB0cy9zaGExLmh0bWxcbmZ1bmN0aW9uIGYocywgeCwgeSwgeikge1xuICBzd2l0Y2ggKHMpIHtcbiAgICBjYXNlIDA6XG4gICAgICByZXR1cm4geCAmIHkgXiB+eCAmIHo7XG5cbiAgICBjYXNlIDE6XG4gICAgICByZXR1cm4geCBeIHkgXiB6O1xuXG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuIHggJiB5IF4geCAmIHogXiB5ICYgejtcblxuICAgIGNhc2UgMzpcbiAgICAgIHJldHVybiB4IF4geSBeIHo7XG4gIH1cbn1cblxuZnVuY3Rpb24gUk9UTCh4LCBuKSB7XG4gIHJldHVybiB4IDw8IG4gfCB4ID4+PiAzMiAtIG47XG59XG5cbmZ1bmN0aW9uIHNoYTEoYnl0ZXMpIHtcbiAgY29uc3QgSyA9IFsweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjLCAweGNhNjJjMWQ2XTtcbiAgY29uc3QgSCA9IFsweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLCAweDEwMzI1NDc2LCAweGMzZDJlMWYwXTtcblxuICBpZiAodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IG1zZyA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChieXRlcykpOyAvLyBVVEY4IGVzY2FwZVxuXG4gICAgYnl0ZXMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgKytpKSB7XG4gICAgICBieXRlcy5wdXNoKG1zZy5jaGFyQ29kZUF0KGkpKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoYnl0ZXMpKSB7XG4gICAgLy8gQ29udmVydCBBcnJheS1saWtlIHRvIEFycmF5XG4gICAgYnl0ZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChieXRlcyk7XG4gIH1cblxuICBieXRlcy5wdXNoKDB4ODApO1xuICBjb25zdCBsID0gYnl0ZXMubGVuZ3RoIC8gNCArIDI7XG4gIGNvbnN0IE4gPSBNYXRoLmNlaWwobCAvIDE2KTtcbiAgY29uc3QgTSA9IG5ldyBBcnJheShOKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IE47ICsraSkge1xuICAgIGNvbnN0IGFyciA9IG5ldyBVaW50MzJBcnJheSgxNik7XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IDE2OyArK2opIHtcbiAgICAgIGFycltqXSA9IGJ5dGVzW2kgKiA2NCArIGogKiA0XSA8PCAyNCB8IGJ5dGVzW2kgKiA2NCArIGogKiA0ICsgMV0gPDwgMTYgfCBieXRlc1tpICogNjQgKyBqICogNCArIDJdIDw8IDggfCBieXRlc1tpICogNjQgKyBqICogNCArIDNdO1xuICAgIH1cblxuICAgIE1baV0gPSBhcnI7XG4gIH1cblxuICBNW04gLSAxXVsxNF0gPSAoYnl0ZXMubGVuZ3RoIC0gMSkgKiA4IC8gTWF0aC5wb3coMiwgMzIpO1xuICBNW04gLSAxXVsxNF0gPSBNYXRoLmZsb29yKE1bTiAtIDFdWzE0XSk7XG4gIE1bTiAtIDFdWzE1XSA9IChieXRlcy5sZW5ndGggLSAxKSAqIDggJiAweGZmZmZmZmZmO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgKytpKSB7XG4gICAgY29uc3QgVyA9IG5ldyBVaW50MzJBcnJheSg4MCk7XG5cbiAgICBmb3IgKGxldCB0ID0gMDsgdCA8IDE2OyArK3QpIHtcbiAgICAgIFdbdF0gPSBNW2ldW3RdO1xuICAgIH1cblxuICAgIGZvciAobGV0IHQgPSAxNjsgdCA8IDgwOyArK3QpIHtcbiAgICAgIFdbdF0gPSBST1RMKFdbdCAtIDNdIF4gV1t0IC0gOF0gXiBXW3QgLSAxNF0gXiBXW3QgLSAxNl0sIDEpO1xuICAgIH1cblxuICAgIGxldCBhID0gSFswXTtcbiAgICBsZXQgYiA9IEhbMV07XG4gICAgbGV0IGMgPSBIWzJdO1xuICAgIGxldCBkID0gSFszXTtcbiAgICBsZXQgZSA9IEhbNF07XG5cbiAgICBmb3IgKGxldCB0ID0gMDsgdCA8IDgwOyArK3QpIHtcbiAgICAgIGNvbnN0IHMgPSBNYXRoLmZsb29yKHQgLyAyMCk7XG4gICAgICBjb25zdCBUID0gUk9UTChhLCA1KSArIGYocywgYiwgYywgZCkgKyBlICsgS1tzXSArIFdbdF0gPj4+IDA7XG4gICAgICBlID0gZDtcbiAgICAgIGQgPSBjO1xuICAgICAgYyA9IFJPVEwoYiwgMzApID4+PiAwO1xuICAgICAgYiA9IGE7XG4gICAgICBhID0gVDtcbiAgICB9XG5cbiAgICBIWzBdID0gSFswXSArIGEgPj4+IDA7XG4gICAgSFsxXSA9IEhbMV0gKyBiID4+PiAwO1xuICAgIEhbMl0gPSBIWzJdICsgYyA+Pj4gMDtcbiAgICBIWzNdID0gSFszXSArIGQgPj4+IDA7XG4gICAgSFs0XSA9IEhbNF0gKyBlID4+PiAwO1xuICB9XG5cbiAgcmV0dXJuIFtIWzBdID4+IDI0ICYgMHhmZiwgSFswXSA+PiAxNiAmIDB4ZmYsIEhbMF0gPj4gOCAmIDB4ZmYsIEhbMF0gJiAweGZmLCBIWzFdID4+IDI0ICYgMHhmZiwgSFsxXSA+PiAxNiAmIDB4ZmYsIEhbMV0gPj4gOCAmIDB4ZmYsIEhbMV0gJiAweGZmLCBIWzJdID4+IDI0ICYgMHhmZiwgSFsyXSA+PiAxNiAmIDB4ZmYsIEhbMl0gPj4gOCAmIDB4ZmYsIEhbMl0gJiAweGZmLCBIWzNdID4+IDI0ICYgMHhmZiwgSFszXSA+PiAxNiAmIDB4ZmYsIEhbM10gPj4gOCAmIDB4ZmYsIEhbM10gJiAweGZmLCBIWzRdID4+IDI0ICYgMHhmZiwgSFs0XSA+PiAxNiAmIDB4ZmYsIEhbNF0gPj4gOCAmIDB4ZmYsIEhbNF0gJiAweGZmXTtcbn1cblxudmFyIF9kZWZhdWx0ID0gc2hhMTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuZXhwb3J0cy51bnNhZmVTdHJpbmdpZnkgPSB1bnNhZmVTdHJpbmdpZnk7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuLyoqXG4gKiBDb252ZXJ0IGFycmF5IG9mIDE2IGJ5dGUgdmFsdWVzIHRvIFVVSUQgc3RyaW5nIGZvcm1hdCBvZiB0aGUgZm9ybTpcbiAqIFhYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWFxuICovXG5jb25zdCBieXRlVG9IZXggPSBbXTtcblxuZm9yIChsZXQgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXgucHVzaCgoaSArIDB4MTAwKS50b1N0cmluZygxNikuc2xpY2UoMSkpO1xufVxuXG5mdW5jdGlvbiB1bnNhZmVTdHJpbmdpZnkoYXJyLCBvZmZzZXQgPSAwKSB7XG4gIC8vIE5vdGU6IEJlIGNhcmVmdWwgZWRpdGluZyB0aGlzIGNvZGUhICBJdCdzIGJlZW4gdHVuZWQgZm9yIHBlcmZvcm1hbmNlXG4gIC8vIGFuZCB3b3JrcyBpbiB3YXlzIHlvdSBtYXkgbm90IGV4cGVjdC4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS91dWlkanMvdXVpZC9wdWxsLzQzNFxuICByZXR1cm4gKGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMF1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDJdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgM11dICsgJy0nICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA0XV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDVdXSArICctJyArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgNl1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA3XV0gKyAnLScgKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDhdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgOV1dICsgJy0nICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxMF1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxMV1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxMl1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxM11dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxNF1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxNV1dKS50b0xvd2VyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdpZnkoYXJyLCBvZmZzZXQgPSAwKSB7XG4gIGNvbnN0IHV1aWQgPSB1bnNhZmVTdHJpbmdpZnkoYXJyLCBvZmZzZXQpOyAvLyBDb25zaXN0ZW5jeSBjaGVjayBmb3IgdmFsaWQgVVVJRC4gIElmIHRoaXMgdGhyb3dzLCBpdCdzIGxpa2VseSBkdWUgdG8gb25lXG4gIC8vIG9mIHRoZSBmb2xsb3dpbmc6XG4gIC8vIC0gT25lIG9yIG1vcmUgaW5wdXQgYXJyYXkgdmFsdWVzIGRvbid0IG1hcCB0byBhIGhleCBvY3RldCAobGVhZGluZyB0b1xuICAvLyBcInVuZGVmaW5lZFwiIGluIHRoZSB1dWlkKVxuICAvLyAtIEludmFsaWQgaW5wdXQgdmFsdWVzIGZvciB0aGUgUkZDIGB2ZXJzaW9uYCBvciBgdmFyaWFudGAgZmllbGRzXG5cbiAgaWYgKCEoMCwgX3ZhbGlkYXRlLmRlZmF1bHQpKHV1aWQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKCdTdHJpbmdpZmllZCBVVUlEIGlzIGludmFsaWQnKTtcbiAgfVxuXG4gIHJldHVybiB1dWlkO1xufVxuXG52YXIgX2RlZmF1bHQgPSBzdHJpbmdpZnk7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9ybmcgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3JuZy5qc1wiKSk7XG5cbnZhciBfc3RyaW5naWZ5ID0gcmVxdWlyZShcIi4vc3RyaW5naWZ5LmpzXCIpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG4vLyAqKmB2MSgpYCAtIEdlbmVyYXRlIHRpbWUtYmFzZWQgVVVJRCoqXG4vL1xuLy8gSW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL0xpb3NLL1VVSUQuanNcbi8vIGFuZCBodHRwOi8vZG9jcy5weXRob24ub3JnL2xpYnJhcnkvdXVpZC5odG1sXG5sZXQgX25vZGVJZDtcblxubGV0IF9jbG9ja3NlcTsgLy8gUHJldmlvdXMgdXVpZCBjcmVhdGlvbiB0aW1lXG5cblxubGV0IF9sYXN0TVNlY3MgPSAwO1xubGV0IF9sYXN0TlNlY3MgPSAwOyAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3V1aWRqcy91dWlkIGZvciBBUEkgZGV0YWlsc1xuXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICBsZXQgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgY29uc3QgYiA9IGJ1ZiB8fCBuZXcgQXJyYXkoMTYpO1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgbGV0IG5vZGUgPSBvcHRpb25zLm5vZGUgfHwgX25vZGVJZDtcbiAgbGV0IGNsb2Nrc2VxID0gb3B0aW9ucy5jbG9ja3NlcSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jbG9ja3NlcSA6IF9jbG9ja3NlcTsgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG5cbiAgaWYgKG5vZGUgPT0gbnVsbCB8fCBjbG9ja3NlcSA9PSBudWxsKSB7XG4gICAgY29uc3Qgc2VlZEJ5dGVzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IF9ybmcuZGVmYXVsdCkoKTtcblxuICAgIGlmIChub2RlID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjUsIGNyZWF0ZSBhbmQgNDgtYml0IG5vZGUgaWQsICg0NyByYW5kb20gYml0cyArIG11bHRpY2FzdCBiaXQgPSAxKVxuICAgICAgbm9kZSA9IF9ub2RlSWQgPSBbc2VlZEJ5dGVzWzBdIHwgMHgwMSwgc2VlZEJ5dGVzWzFdLCBzZWVkQnl0ZXNbMl0sIHNlZWRCeXRlc1szXSwgc2VlZEJ5dGVzWzRdLCBzZWVkQnl0ZXNbNV1dO1xuICAgIH1cblxuICAgIGlmIChjbG9ja3NlcSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC4yLjIsIHJhbmRvbWl6ZSAoMTQgYml0KSBjbG9ja3NlcVxuICAgICAgY2xvY2tzZXEgPSBfY2xvY2tzZXEgPSAoc2VlZEJ5dGVzWzZdIDw8IDggfCBzZWVkQnl0ZXNbN10pICYgMHgzZmZmO1xuICAgIH1cbiAgfSAvLyBVVUlEIHRpbWVzdGFtcHMgYXJlIDEwMCBuYW5vLXNlY29uZCB1bml0cyBzaW5jZSB0aGUgR3JlZ29yaWFuIGVwb2NoLFxuICAvLyAoMTU4Mi0xMC0xNSAwMDowMCkuICBKU051bWJlcnMgYXJlbid0IHByZWNpc2UgZW5vdWdoIGZvciB0aGlzLCBzb1xuICAvLyB0aW1lIGlzIGhhbmRsZWQgaW50ZXJuYWxseSBhcyAnbXNlY3MnIChpbnRlZ2VyIG1pbGxpc2Vjb25kcykgYW5kICduc2VjcydcbiAgLy8gKDEwMC1uYW5vc2Vjb25kcyBvZmZzZXQgZnJvbSBtc2Vjcykgc2luY2UgdW5peCBlcG9jaCwgMTk3MC0wMS0wMSAwMDowMC5cblxuXG4gIGxldCBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBEYXRlLm5vdygpOyAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG5cbiAgbGV0IG5zZWNzID0gb3B0aW9ucy5uc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5uc2VjcyA6IF9sYXN0TlNlY3MgKyAxOyAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG5cbiAgY29uc3QgZHQgPSBtc2VjcyAtIF9sYXN0TVNlY3MgKyAobnNlY3MgLSBfbGFzdE5TZWNzKSAvIDEwMDAwOyAvLyBQZXIgNC4yLjEuMiwgQnVtcCBjbG9ja3NlcSBvbiBjbG9jayByZWdyZXNzaW9uXG5cbiAgaWYgKGR0IDwgMCAmJiBvcHRpb25zLmNsb2Nrc2VxID09PSB1bmRlZmluZWQpIHtcbiAgICBjbG9ja3NlcSA9IGNsb2Nrc2VxICsgMSAmIDB4M2ZmZjtcbiAgfSAvLyBSZXNldCBuc2VjcyBpZiBjbG9jayByZWdyZXNzZXMgKG5ldyBjbG9ja3NlcSkgb3Igd2UndmUgbW92ZWQgb250byBhIG5ld1xuICAvLyB0aW1lIGludGVydmFsXG5cblxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfSAvLyBQZXIgNC4yLjEuMiBUaHJvdyBlcnJvciBpZiB0b28gbWFueSB1dWlkcyBhcmUgcmVxdWVzdGVkXG5cblxuICBpZiAobnNlY3MgPj0gMTAwMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1dWlkLnYxKCk6IENhbid0IGNyZWF0ZSBtb3JlIHRoYW4gMTBNIHV1aWRzL3NlY1wiKTtcbiAgfVxuXG4gIF9sYXN0TVNlY3MgPSBtc2VjcztcbiAgX2xhc3ROU2VjcyA9IG5zZWNzO1xuICBfY2xvY2tzZXEgPSBjbG9ja3NlcTsgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG5cbiAgbXNlY3MgKz0gMTIyMTkyOTI4MDAwMDA7IC8vIGB0aW1lX2xvd2BcblxuICBjb25zdCB0bCA9ICgobXNlY3MgJiAweGZmZmZmZmYpICogMTAwMDAgKyBuc2VjcykgJSAweDEwMDAwMDAwMDtcbiAgYltpKytdID0gdGwgPj4+IDI0ICYgMHhmZjtcbiAgYltpKytdID0gdGwgPj4+IDE2ICYgMHhmZjtcbiAgYltpKytdID0gdGwgPj4+IDggJiAweGZmO1xuICBiW2krK10gPSB0bCAmIDB4ZmY7IC8vIGB0aW1lX21pZGBcblxuICBjb25zdCB0bWggPSBtc2VjcyAvIDB4MTAwMDAwMDAwICogMTAwMDAgJiAweGZmZmZmZmY7XG4gIGJbaSsrXSA9IHRtaCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRtaCAmIDB4ZmY7IC8vIGB0aW1lX2hpZ2hfYW5kX3ZlcnNpb25gXG5cbiAgYltpKytdID0gdG1oID4+PiAyNCAmIDB4ZiB8IDB4MTA7IC8vIGluY2x1ZGUgdmVyc2lvblxuXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmOyAvLyBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGAgKFBlciA0LjIuMiAtIGluY2x1ZGUgdmFyaWFudClcblxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7IC8vIGBjbG9ja19zZXFfbG93YFxuXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjsgLy8gYG5vZGVgXG5cbiAgZm9yIChsZXQgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmIHx8ICgwLCBfc3RyaW5naWZ5LnVuc2FmZVN0cmluZ2lmeSkoYik7XG59XG5cbnZhciBfZGVmYXVsdCA9IHYxO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjM1LmpzXCIpKTtcblxudmFyIF9tZCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vbWQ1LmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuY29uc3QgdjMgPSAoMCwgX3YuZGVmYXVsdCkoJ3YzJywgMHgzMCwgX21kLmRlZmF1bHQpO1xudmFyIF9kZWZhdWx0ID0gdjM7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuVVJMID0gZXhwb3J0cy5ETlMgPSB2b2lkIDA7XG5leHBvcnRzLmRlZmF1bHQgPSB2MzU7XG5cbnZhciBfc3RyaW5naWZ5ID0gcmVxdWlyZShcIi4vc3RyaW5naWZ5LmpzXCIpO1xuXG52YXIgX3BhcnNlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9wYXJzZS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIHN0cmluZ1RvQnl0ZXMoc3RyKSB7XG4gIHN0ciA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzdHIpKTsgLy8gVVRGOCBlc2NhcGVcblxuICBjb25zdCBieXRlcyA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgYnl0ZXMucHVzaChzdHIuY2hhckNvZGVBdChpKSk7XG4gIH1cblxuICByZXR1cm4gYnl0ZXM7XG59XG5cbmNvbnN0IEROUyA9ICc2YmE3YjgxMC05ZGFkLTExZDEtODBiNC0wMGMwNGZkNDMwYzgnO1xuZXhwb3J0cy5ETlMgPSBETlM7XG5jb25zdCBVUkwgPSAnNmJhN2I4MTEtOWRhZC0xMWQxLTgwYjQtMDBjMDRmZDQzMGM4JztcbmV4cG9ydHMuVVJMID0gVVJMO1xuXG5mdW5jdGlvbiB2MzUobmFtZSwgdmVyc2lvbiwgaGFzaGZ1bmMpIHtcbiAgZnVuY3Rpb24gZ2VuZXJhdGVVVUlEKHZhbHVlLCBuYW1lc3BhY2UsIGJ1Ziwgb2Zmc2V0KSB7XG4gICAgdmFyIF9uYW1lc3BhY2U7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgdmFsdWUgPSBzdHJpbmdUb0J5dGVzKHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG5hbWVzcGFjZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG5hbWVzcGFjZSA9ICgwLCBfcGFyc2UuZGVmYXVsdCkobmFtZXNwYWNlKTtcbiAgICB9XG5cbiAgICBpZiAoKChfbmFtZXNwYWNlID0gbmFtZXNwYWNlKSA9PT0gbnVsbCB8fCBfbmFtZXNwYWNlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfbmFtZXNwYWNlLmxlbmd0aCkgIT09IDE2KSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ05hbWVzcGFjZSBtdXN0IGJlIGFycmF5LWxpa2UgKDE2IGl0ZXJhYmxlIGludGVnZXIgdmFsdWVzLCAwLTI1NSknKTtcbiAgICB9IC8vIENvbXB1dGUgaGFzaCBvZiBuYW1lc3BhY2UgYW5kIHZhbHVlLCBQZXIgNC4zXG4gICAgLy8gRnV0dXJlOiBVc2Ugc3ByZWFkIHN5bnRheCB3aGVuIHN1cHBvcnRlZCBvbiBhbGwgcGxhdGZvcm1zLCBlLmcuIGBieXRlcyA9XG4gICAgLy8gaGFzaGZ1bmMoWy4uLm5hbWVzcGFjZSwgLi4uIHZhbHVlXSlgXG5cblxuICAgIGxldCBieXRlcyA9IG5ldyBVaW50OEFycmF5KDE2ICsgdmFsdWUubGVuZ3RoKTtcbiAgICBieXRlcy5zZXQobmFtZXNwYWNlKTtcbiAgICBieXRlcy5zZXQodmFsdWUsIG5hbWVzcGFjZS5sZW5ndGgpO1xuICAgIGJ5dGVzID0gaGFzaGZ1bmMoYnl0ZXMpO1xuICAgIGJ5dGVzWzZdID0gYnl0ZXNbNl0gJiAweDBmIHwgdmVyc2lvbjtcbiAgICBieXRlc1s4XSA9IGJ5dGVzWzhdICYgMHgzZiB8IDB4ODA7XG5cbiAgICBpZiAoYnVmKSB7XG4gICAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxNjsgKytpKSB7XG4gICAgICAgIGJ1ZltvZmZzZXQgKyBpXSA9IGJ5dGVzW2ldO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnVmO1xuICAgIH1cblxuICAgIHJldHVybiAoMCwgX3N0cmluZ2lmeS51bnNhZmVTdHJpbmdpZnkpKGJ5dGVzKTtcbiAgfSAvLyBGdW5jdGlvbiNuYW1lIGlzIG5vdCBzZXR0YWJsZSBvbiBzb21lIHBsYXRmb3JtcyAoIzI3MClcblxuXG4gIHRyeSB7XG4gICAgZ2VuZXJhdGVVVUlELm5hbWUgPSBuYW1lOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHlcbiAgfSBjYXRjaCAoZXJyKSB7fSAvLyBGb3IgQ29tbW9uSlMgZGVmYXVsdCBleHBvcnQgc3VwcG9ydFxuXG5cbiAgZ2VuZXJhdGVVVUlELkROUyA9IEROUztcbiAgZ2VuZXJhdGVVVUlELlVSTCA9IFVSTDtcbiAgcmV0dXJuIGdlbmVyYXRlVVVJRDtcbn0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9uYXRpdmUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL25hdGl2ZS5qc1wiKSk7XG5cbnZhciBfcm5nID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9ybmcuanNcIikpO1xuXG52YXIgX3N0cmluZ2lmeSA9IHJlcXVpcmUoXCIuL3N0cmluZ2lmeS5qc1wiKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdjQob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgaWYgKF9uYXRpdmUuZGVmYXVsdC5yYW5kb21VVUlEICYmICFidWYgJiYgIW9wdGlvbnMpIHtcbiAgICByZXR1cm4gX25hdGl2ZS5kZWZhdWx0LnJhbmRvbVVVSUQoKTtcbiAgfVxuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIGNvbnN0IHJuZHMgPSBvcHRpb25zLnJhbmRvbSB8fCAob3B0aW9ucy5ybmcgfHwgX3JuZy5kZWZhdWx0KSgpOyAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG5cblxuICBybmRzWzZdID0gcm5kc1s2XSAmIDB4MGYgfCAweDQwO1xuICBybmRzWzhdID0gcm5kc1s4XSAmIDB4M2YgfCAweDgwOyAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcblxuICBpZiAoYnVmKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDE2OyArK2kpIHtcbiAgICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHJuZHNbaV07XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZjtcbiAgfVxuXG4gIHJldHVybiAoMCwgX3N0cmluZ2lmeS51bnNhZmVTdHJpbmdpZnkpKHJuZHMpO1xufVxuXG52YXIgX2RlZmF1bHQgPSB2NDtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3YgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3YzNS5qc1wiKSk7XG5cbnZhciBfc2hhID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9zaGExLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuY29uc3QgdjUgPSAoMCwgX3YuZGVmYXVsdCkoJ3Y1JywgMHg1MCwgX3NoYS5kZWZhdWx0KTtcbnZhciBfZGVmYXVsdCA9IHY1O1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfcmVnZXggPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3JlZ2V4LmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdmFsaWRhdGUodXVpZCkge1xuICByZXR1cm4gdHlwZW9mIHV1aWQgPT09ICdzdHJpbmcnICYmIF9yZWdleC5kZWZhdWx0LnRlc3QodXVpZCk7XG59XG5cbnZhciBfZGVmYXVsdCA9IHZhbGlkYXRlO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdmVyc2lvbih1dWlkKSB7XG4gIGlmICghKDAsIF92YWxpZGF0ZS5kZWZhdWx0KSh1dWlkKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignSW52YWxpZCBVVUlEJyk7XG4gIH1cblxuICByZXR1cm4gcGFyc2VJbnQodXVpZC5zbGljZSgxNCwgMTUpLCAxNik7XG59XG5cbnZhciBfZGVmYXVsdCA9IHZlcnNpb247XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICAgIHZhbHVlOiB0cnVlXG59KTtcbmZ1bmN0aW9uIF9leHBvcnQodGFyZ2V0LCBhbGwpIHtcbiAgICBmb3IodmFyIG5hbWUgaW4gYWxsKU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIG5hbWUsIHtcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgZ2V0OiBhbGxbbmFtZV1cbiAgICB9KTtcbn1cbl9leHBvcnQoZXhwb3J0cywge1xuICAgIGNyZWF0ZTogKCk9PmNyZWF0ZSxcbiAgICBpbnNlcnQ6ICgpPT5pbnNlcnQsXG4gICAgaW5zZXJ0V2l0aEhvb2tzOiAoKT0+aW5zZXJ0V2l0aEhvb2tzLFxuICAgIGluc2VydEJhdGNoOiAoKT0+aW5zZXJ0QmF0Y2gsXG4gICAgcmVtb3ZlOiAoKT0+cmVtb3ZlLFxuICAgIHNlYXJjaDogKCk9PnNlYXJjaCxcbiAgICBzYXZlOiAoKT0+c2F2ZSxcbiAgICBsb2FkOiAoKT0+bG9hZCxcbiAgICByZXF1aXJlTHlyYTogKCk9PnJlcXVpcmVMeXJhXG59KTtcbmxldCBfZXNtQ3JlYXRlO1xubGV0IF9lc21JbnNlcnQ7XG5sZXQgX2VzbUluc2VydFdpdGhIb29rcztcbmxldCBfZXNtSW5zZXJ0QmF0Y2g7XG5sZXQgX2VzbVJlbW92ZTtcbmxldCBfZXNtU2VhcmNoO1xubGV0IF9lc21TYXZlO1xubGV0IF9lc21Mb2FkO1xuYXN5bmMgZnVuY3Rpb24gY3JlYXRlKC4uLmFyZ3MpIHtcbiAgICBpZiAoIV9lc21DcmVhdGUpIHtcbiAgICAgICAgY29uc3QgaW1wb3J0ZWQgPSBhd2FpdCBpbXBvcnQoXCIuLi9tZXRob2RzL2NyZWF0ZS5qc1wiKTtcbiAgICAgICAgX2VzbUNyZWF0ZSA9IGltcG9ydGVkLmNyZWF0ZTtcbiAgICB9XG4gICAgcmV0dXJuIF9lc21DcmVhdGUoLi4uYXJncyk7XG59XG5hc3luYyBmdW5jdGlvbiBpbnNlcnQoLi4uYXJncykge1xuICAgIGlmICghX2VzbUluc2VydCkge1xuICAgICAgICBjb25zdCBpbXBvcnRlZCA9IGF3YWl0IGltcG9ydChcIi4uL21ldGhvZHMvaW5zZXJ0LmpzXCIpO1xuICAgICAgICBfZXNtSW5zZXJ0ID0gaW1wb3J0ZWQuaW5zZXJ0O1xuICAgIH1cbiAgICByZXR1cm4gX2VzbUluc2VydCguLi5hcmdzKTtcbn1cbmFzeW5jIGZ1bmN0aW9uIGluc2VydFdpdGhIb29rcyguLi5hcmdzKSB7XG4gICAgaWYgKCFfZXNtSW5zZXJ0V2l0aEhvb2tzKSB7XG4gICAgICAgIGNvbnN0IGltcG9ydGVkID0gYXdhaXQgaW1wb3J0KFwiLi4vbWV0aG9kcy9pbnNlcnQuanNcIik7XG4gICAgICAgIF9lc21JbnNlcnRXaXRoSG9va3MgPSBpbXBvcnRlZC5pbnNlcnRXaXRoSG9va3M7XG4gICAgfVxuICAgIHJldHVybiBfZXNtSW5zZXJ0V2l0aEhvb2tzKC4uLmFyZ3MpO1xufVxuYXN5bmMgZnVuY3Rpb24gaW5zZXJ0QmF0Y2goLi4uYXJncykge1xuICAgIGlmICghX2VzbUluc2VydEJhdGNoKSB7XG4gICAgICAgIGNvbnN0IGltcG9ydGVkID0gYXdhaXQgaW1wb3J0KFwiLi4vbWV0aG9kcy9pbnNlcnQuanNcIik7XG4gICAgICAgIF9lc21JbnNlcnRCYXRjaCA9IGltcG9ydGVkLmluc2VydEJhdGNoO1xuICAgIH1cbiAgICByZXR1cm4gX2VzbUluc2VydEJhdGNoKC4uLmFyZ3MpO1xufVxuYXN5bmMgZnVuY3Rpb24gcmVtb3ZlKC4uLmFyZ3MpIHtcbiAgICBpZiAoIV9lc21SZW1vdmUpIHtcbiAgICAgICAgY29uc3QgaW1wb3J0ZWQgPSBhd2FpdCBpbXBvcnQoXCIuLi9tZXRob2RzL3JlbW92ZS5qc1wiKTtcbiAgICAgICAgX2VzbVJlbW92ZSA9IGltcG9ydGVkLnJlbW92ZTtcbiAgICB9XG4gICAgcmV0dXJuIF9lc21SZW1vdmUoLi4uYXJncyk7XG59XG5hc3luYyBmdW5jdGlvbiBzZWFyY2goLi4uYXJncykge1xuICAgIGlmICghX2VzbVNlYXJjaCkge1xuICAgICAgICBjb25zdCBpbXBvcnRlZCA9IGF3YWl0IGltcG9ydChcIi4uL21ldGhvZHMvc2VhcmNoLmpzXCIpO1xuICAgICAgICBfZXNtU2VhcmNoID0gaW1wb3J0ZWQuc2VhcmNoO1xuICAgIH1cbiAgICByZXR1cm4gX2VzbVNlYXJjaCguLi5hcmdzKTtcbn1cbmFzeW5jIGZ1bmN0aW9uIHNhdmUoLi4uYXJncykge1xuICAgIGlmICghX2VzbVNhdmUpIHtcbiAgICAgICAgY29uc3QgaW1wb3J0ZWQgPSBhd2FpdCBpbXBvcnQoXCIuLi9tZXRob2RzL3NhdmUuanNcIik7XG4gICAgICAgIF9lc21TYXZlID0gaW1wb3J0ZWQuc2F2ZTtcbiAgICB9XG4gICAgcmV0dXJuIF9lc21TYXZlKC4uLmFyZ3MpO1xufVxuYXN5bmMgZnVuY3Rpb24gbG9hZCguLi5hcmdzKSB7XG4gICAgaWYgKCFfZXNtTG9hZCkge1xuICAgICAgICBjb25zdCBpbXBvcnRlZCA9IGF3YWl0IGltcG9ydChcIi4uL21ldGhvZHMvbG9hZC5qc1wiKTtcbiAgICAgICAgX2VzbUxvYWQgPSBpbXBvcnRlZC5sb2FkO1xuICAgIH1cbiAgICByZXR1cm4gX2VzbUxvYWQoLi4uYXJncyk7XG59XG5mdW5jdGlvbiByZXF1aXJlTHlyYShjYWxsYmFjaykge1xuICAgIGltcG9ydChcIi4uL2luZGV4LmpzXCIpLnRoZW4oKGxvYWRlZCk9PnNldFRpbWVvdXQoKCk9PmNhbGxiYWNrKHVuZGVmaW5lZCwgbG9hZGVkKSwgMSkpLmNhdGNoKChlcnJvcik9PnNldFRpbWVvdXQoKCk9PmNhbGxiYWNrKGVycm9yKSwgMSkpO1xufVxuXG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCIvKipcbiAqIG1hcmtlZCB2NC4yLjEyIC0gYSBtYXJrZG93biBwYXJzZXJcbiAqIENvcHlyaWdodCAoYykgMjAxMS0yMDIzLCBDaHJpc3RvcGhlciBKZWZmcmV5LiAoTUlUIExpY2Vuc2VkKVxuICogaHR0cHM6Ly9naXRodWIuY29tL21hcmtlZGpzL21hcmtlZFxuICovXG5cbi8qKlxuICogRE8gTk9UIEVESVQgVEhJUyBGSUxFXG4gKiBUaGUgY29kZSBpbiB0aGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGZyb20gZmlsZXMgaW4gLi9zcmMvXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTtcbiAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7XG4gICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBfdG9Qcm9wZXJ0eUtleShkZXNjcmlwdG9yLmtleSksIGRlc2NyaXB0b3IpO1xuICB9XG59XG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb25zdHJ1Y3RvciwgXCJwcm90b3R5cGVcIiwge1xuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KTtcbiAgcmV0dXJuIENvbnN0cnVjdG9yO1xufVxuZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikge1xuICBpZiAoIW8pIHJldHVybjtcbiAgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTtcbiAgdmFyIG4gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobykuc2xpY2UoOCwgLTEpO1xuICBpZiAobiA9PT0gXCJPYmplY3RcIiAmJiBvLmNvbnN0cnVjdG9yKSBuID0gby5jb25zdHJ1Y3Rvci5uYW1lO1xuICBpZiAobiA9PT0gXCJNYXBcIiB8fCBuID09PSBcIlNldFwiKSByZXR1cm4gQXJyYXkuZnJvbShvKTtcbiAgaWYgKG4gPT09IFwiQXJndW1lbnRzXCIgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QobikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xufVxuZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHtcbiAgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+IGFyci5sZW5ndGgpIGxlbiA9IGFyci5sZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgYXJyMltpXSA9IGFycltpXTtcbiAgcmV0dXJuIGFycjI7XG59XG5mdW5jdGlvbiBfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlckxvb3NlKG8sIGFsbG93QXJyYXlMaWtlKSB7XG4gIHZhciBpdCA9IHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdIHx8IG9bXCJAQGl0ZXJhdG9yXCJdO1xuICBpZiAoaXQpIHJldHVybiAoaXQgPSBpdC5jYWxsKG8pKS5uZXh0LmJpbmQoaXQpO1xuICBpZiAoQXJyYXkuaXNBcnJheShvKSB8fCAoaXQgPSBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobykpIHx8IGFsbG93QXJyYXlMaWtlICYmIG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSB7XG4gICAgaWYgKGl0KSBvID0gaXQ7XG4gICAgdmFyIGkgPSAwO1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoaSA+PSBvLmxlbmd0aCkgcmV0dXJuIHtcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRvbmU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogb1tpKytdXG4gICAgICB9O1xuICAgIH07XG4gIH1cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBpdGVyYXRlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xufVxuZnVuY3Rpb24gX3RvUHJpbWl0aXZlKGlucHV0LCBoaW50KSB7XG4gIGlmICh0eXBlb2YgaW5wdXQgIT09IFwib2JqZWN0XCIgfHwgaW5wdXQgPT09IG51bGwpIHJldHVybiBpbnB1dDtcbiAgdmFyIHByaW0gPSBpbnB1dFtTeW1ib2wudG9QcmltaXRpdmVdO1xuICBpZiAocHJpbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIHJlcyA9IHByaW0uY2FsbChpbnB1dCwgaGludCB8fCBcImRlZmF1bHRcIik7XG4gICAgaWYgKHR5cGVvZiByZXMgIT09IFwib2JqZWN0XCIpIHJldHVybiByZXM7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuXCIpO1xuICB9XG4gIHJldHVybiAoaGludCA9PT0gXCJzdHJpbmdcIiA/IFN0cmluZyA6IE51bWJlcikoaW5wdXQpO1xufVxuZnVuY3Rpb24gX3RvUHJvcGVydHlLZXkoYXJnKSB7XG4gIHZhciBrZXkgPSBfdG9QcmltaXRpdmUoYXJnLCBcInN0cmluZ1wiKTtcbiAgcmV0dXJuIHR5cGVvZiBrZXkgPT09IFwic3ltYm9sXCIgPyBrZXkgOiBTdHJpbmcoa2V5KTtcbn1cblxuZnVuY3Rpb24gZ2V0RGVmYXVsdHMoKSB7XG4gIHJldHVybiB7XG4gICAgYXN5bmM6IGZhbHNlLFxuICAgIGJhc2VVcmw6IG51bGwsXG4gICAgYnJlYWtzOiBmYWxzZSxcbiAgICBleHRlbnNpb25zOiBudWxsLFxuICAgIGdmbTogdHJ1ZSxcbiAgICBoZWFkZXJJZHM6IHRydWUsXG4gICAgaGVhZGVyUHJlZml4OiAnJyxcbiAgICBoaWdobGlnaHQ6IG51bGwsXG4gICAgbGFuZ1ByZWZpeDogJ2xhbmd1YWdlLScsXG4gICAgbWFuZ2xlOiB0cnVlLFxuICAgIHBlZGFudGljOiBmYWxzZSxcbiAgICByZW5kZXJlcjogbnVsbCxcbiAgICBzYW5pdGl6ZTogZmFsc2UsXG4gICAgc2FuaXRpemVyOiBudWxsLFxuICAgIHNpbGVudDogZmFsc2UsXG4gICAgc21hcnR5cGFudHM6IGZhbHNlLFxuICAgIHRva2VuaXplcjogbnVsbCxcbiAgICB3YWxrVG9rZW5zOiBudWxsLFxuICAgIHhodG1sOiBmYWxzZVxuICB9O1xufVxuZXhwb3J0cy5kZWZhdWx0cyA9IGdldERlZmF1bHRzKCk7XG5mdW5jdGlvbiBjaGFuZ2VEZWZhdWx0cyhuZXdEZWZhdWx0cykge1xuICBleHBvcnRzLmRlZmF1bHRzID0gbmV3RGVmYXVsdHM7XG59XG5cbi8qKlxuICogSGVscGVyc1xuICovXG52YXIgZXNjYXBlVGVzdCA9IC9bJjw+XCInXS87XG52YXIgZXNjYXBlUmVwbGFjZSA9IG5ldyBSZWdFeHAoZXNjYXBlVGVzdC5zb3VyY2UsICdnJyk7XG52YXIgZXNjYXBlVGVzdE5vRW5jb2RlID0gL1s8PlwiJ118Jig/ISgjXFxkezEsN318I1tYeF1bYS1mQS1GMC05XXsxLDZ9fFxcdyspOykvO1xudmFyIGVzY2FwZVJlcGxhY2VOb0VuY29kZSA9IG5ldyBSZWdFeHAoZXNjYXBlVGVzdE5vRW5jb2RlLnNvdXJjZSwgJ2cnKTtcbnZhciBlc2NhcGVSZXBsYWNlbWVudHMgPSB7XG4gICcmJzogJyZhbXA7JyxcbiAgJzwnOiAnJmx0OycsXG4gICc+JzogJyZndDsnLFxuICAnXCInOiAnJnF1b3Q7JyxcbiAgXCInXCI6ICcmIzM5Oydcbn07XG52YXIgZ2V0RXNjYXBlUmVwbGFjZW1lbnQgPSBmdW5jdGlvbiBnZXRFc2NhcGVSZXBsYWNlbWVudChjaCkge1xuICByZXR1cm4gZXNjYXBlUmVwbGFjZW1lbnRzW2NoXTtcbn07XG5mdW5jdGlvbiBlc2NhcGUoaHRtbCwgZW5jb2RlKSB7XG4gIGlmIChlbmNvZGUpIHtcbiAgICBpZiAoZXNjYXBlVGVzdC50ZXN0KGh0bWwpKSB7XG4gICAgICByZXR1cm4gaHRtbC5yZXBsYWNlKGVzY2FwZVJlcGxhY2UsIGdldEVzY2FwZVJlcGxhY2VtZW50KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGVzY2FwZVRlc3ROb0VuY29kZS50ZXN0KGh0bWwpKSB7XG4gICAgICByZXR1cm4gaHRtbC5yZXBsYWNlKGVzY2FwZVJlcGxhY2VOb0VuY29kZSwgZ2V0RXNjYXBlUmVwbGFjZW1lbnQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaHRtbDtcbn1cbnZhciB1bmVzY2FwZVRlc3QgPSAvJigjKD86XFxkKyl8KD86I3hbMC05QS1GYS1mXSspfCg/OlxcdyspKTs/L2lnO1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sXG4gKi9cbmZ1bmN0aW9uIHVuZXNjYXBlKGh0bWwpIHtcbiAgLy8gZXhwbGljaXRseSBtYXRjaCBkZWNpbWFsLCBoZXgsIGFuZCBuYW1lZCBIVE1MIGVudGl0aWVzXG4gIHJldHVybiBodG1sLnJlcGxhY2UodW5lc2NhcGVUZXN0LCBmdW5jdGlvbiAoXywgbikge1xuICAgIG4gPSBuLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKG4gPT09ICdjb2xvbicpIHJldHVybiAnOic7XG4gICAgaWYgKG4uY2hhckF0KDApID09PSAnIycpIHtcbiAgICAgIHJldHVybiBuLmNoYXJBdCgxKSA9PT0gJ3gnID8gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChuLnN1YnN0cmluZygyKSwgMTYpKSA6IFN0cmluZy5mcm9tQ2hhckNvZGUoK24uc3Vic3RyaW5nKDEpKTtcbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9KTtcbn1cbnZhciBjYXJldCA9IC8oXnxbXlxcW10pXFxeL2c7XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmcgfCBSZWdFeHB9IHJlZ2V4XG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0XG4gKi9cbmZ1bmN0aW9uIGVkaXQocmVnZXgsIG9wdCkge1xuICByZWdleCA9IHR5cGVvZiByZWdleCA9PT0gJ3N0cmluZycgPyByZWdleCA6IHJlZ2V4LnNvdXJjZTtcbiAgb3B0ID0gb3B0IHx8ICcnO1xuICB2YXIgb2JqID0ge1xuICAgIHJlcGxhY2U6IGZ1bmN0aW9uIHJlcGxhY2UobmFtZSwgdmFsKSB7XG4gICAgICB2YWwgPSB2YWwuc291cmNlIHx8IHZhbDtcbiAgICAgIHZhbCA9IHZhbC5yZXBsYWNlKGNhcmV0LCAnJDEnKTtcbiAgICAgIHJlZ2V4ID0gcmVnZXgucmVwbGFjZShuYW1lLCB2YWwpO1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9LFxuICAgIGdldFJlZ2V4OiBmdW5jdGlvbiBnZXRSZWdleCgpIHtcbiAgICAgIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4LCBvcHQpO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIG9iajtcbn1cbnZhciBub25Xb3JkQW5kQ29sb25UZXN0ID0gL1teXFx3Ol0vZztcbnZhciBvcmlnaW5JbmRlcGVuZGVudFVybCA9IC9eJHxeW2Etel1bYS16MC05Ky4tXSo6fF5bPyNdL2k7XG5cbi8qKlxuICogQHBhcmFtIHtib29sZWFufSBzYW5pdGl6ZVxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBocmVmXG4gKi9cbmZ1bmN0aW9uIGNsZWFuVXJsKHNhbml0aXplLCBiYXNlLCBocmVmKSB7XG4gIGlmIChzYW5pdGl6ZSkge1xuICAgIHZhciBwcm90O1xuICAgIHRyeSB7XG4gICAgICBwcm90ID0gZGVjb2RlVVJJQ29tcG9uZW50KHVuZXNjYXBlKGhyZWYpKS5yZXBsYWNlKG5vbldvcmRBbmRDb2xvblRlc3QsICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAocHJvdC5pbmRleE9mKCdqYXZhc2NyaXB0OicpID09PSAwIHx8IHByb3QuaW5kZXhPZigndmJzY3JpcHQ6JykgPT09IDAgfHwgcHJvdC5pbmRleE9mKCdkYXRhOicpID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbiAgaWYgKGJhc2UgJiYgIW9yaWdpbkluZGVwZW5kZW50VXJsLnRlc3QoaHJlZikpIHtcbiAgICBocmVmID0gcmVzb2x2ZVVybChiYXNlLCBocmVmKTtcbiAgfVxuICB0cnkge1xuICAgIGhyZWYgPSBlbmNvZGVVUkkoaHJlZikucmVwbGFjZSgvJTI1L2csICclJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4gaHJlZjtcbn1cbnZhciBiYXNlVXJscyA9IHt9O1xudmFyIGp1c3REb21haW4gPSAvXlteOl0rOlxcLypbXi9dKiQvO1xudmFyIHByb3RvY29sID0gL14oW146XSs6KVtcXHNcXFNdKiQvO1xudmFyIGRvbWFpbiA9IC9eKFteOl0rOlxcLypbXi9dKilbXFxzXFxTXSokLztcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gYmFzZVxuICogQHBhcmFtIHtzdHJpbmd9IGhyZWZcbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVVybChiYXNlLCBocmVmKSB7XG4gIGlmICghYmFzZVVybHNbJyAnICsgYmFzZV0pIHtcbiAgICAvLyB3ZSBjYW4gaWdub3JlIGV2ZXJ5dGhpbmcgaW4gYmFzZSBhZnRlciB0aGUgbGFzdCBzbGFzaCBvZiBpdHMgcGF0aCBjb21wb25lbnQsXG4gICAgLy8gYnV0IHdlIG1pZ2h0IG5lZWQgdG8gYWRkIF90aGF0X1xuICAgIC8vIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzOTg2I3NlY3Rpb24tM1xuICAgIGlmIChqdXN0RG9tYWluLnRlc3QoYmFzZSkpIHtcbiAgICAgIGJhc2VVcmxzWycgJyArIGJhc2VdID0gYmFzZSArICcvJztcbiAgICB9IGVsc2Uge1xuICAgICAgYmFzZVVybHNbJyAnICsgYmFzZV0gPSBydHJpbShiYXNlLCAnLycsIHRydWUpO1xuICAgIH1cbiAgfVxuICBiYXNlID0gYmFzZVVybHNbJyAnICsgYmFzZV07XG4gIHZhciByZWxhdGl2ZUJhc2UgPSBiYXNlLmluZGV4T2YoJzonKSA9PT0gLTE7XG4gIGlmIChocmVmLnN1YnN0cmluZygwLCAyKSA9PT0gJy8vJykge1xuICAgIGlmIChyZWxhdGl2ZUJhc2UpIHtcbiAgICAgIHJldHVybiBocmVmO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZS5yZXBsYWNlKHByb3RvY29sLCAnJDEnKSArIGhyZWY7XG4gIH0gZWxzZSBpZiAoaHJlZi5jaGFyQXQoMCkgPT09ICcvJykge1xuICAgIGlmIChyZWxhdGl2ZUJhc2UpIHtcbiAgICAgIHJldHVybiBocmVmO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZS5yZXBsYWNlKGRvbWFpbiwgJyQxJykgKyBocmVmO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlICsgaHJlZjtcbiAgfVxufVxudmFyIG5vb3BUZXN0ID0ge1xuICBleGVjOiBmdW5jdGlvbiBub29wVGVzdCgpIHt9XG59O1xuZnVuY3Rpb24gbWVyZ2Uob2JqKSB7XG4gIHZhciBpID0gMSxcbiAgICB0YXJnZXQsXG4gICAga2V5O1xuICBmb3IgKDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHRhcmdldCA9IGFyZ3VtZW50c1tpXTtcbiAgICBmb3IgKGtleSBpbiB0YXJnZXQpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGFyZ2V0LCBrZXkpKSB7XG4gICAgICAgIG9ialtrZXldID0gdGFyZ2V0W2tleV07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59XG5mdW5jdGlvbiBzcGxpdENlbGxzKHRhYmxlUm93LCBjb3VudCkge1xuICAvLyBlbnN1cmUgdGhhdCBldmVyeSBjZWxsLWRlbGltaXRpbmcgcGlwZSBoYXMgYSBzcGFjZVxuICAvLyBiZWZvcmUgaXQgdG8gZGlzdGluZ3Vpc2ggaXQgZnJvbSBhbiBlc2NhcGVkIHBpcGVcbiAgdmFyIHJvdyA9IHRhYmxlUm93LnJlcGxhY2UoL1xcfC9nLCBmdW5jdGlvbiAobWF0Y2gsIG9mZnNldCwgc3RyKSB7XG4gICAgICB2YXIgZXNjYXBlZCA9IGZhbHNlLFxuICAgICAgICBjdXJyID0gb2Zmc2V0O1xuICAgICAgd2hpbGUgKC0tY3VyciA+PSAwICYmIHN0cltjdXJyXSA9PT0gJ1xcXFwnKSB7XG4gICAgICAgIGVzY2FwZWQgPSAhZXNjYXBlZDtcbiAgICAgIH1cbiAgICAgIGlmIChlc2NhcGVkKSB7XG4gICAgICAgIC8vIG9kZCBudW1iZXIgb2Ygc2xhc2hlcyBtZWFucyB8IGlzIGVzY2FwZWRcbiAgICAgICAgLy8gc28gd2UgbGVhdmUgaXQgYWxvbmVcbiAgICAgICAgcmV0dXJuICd8JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGFkZCBzcGFjZSBiZWZvcmUgdW5lc2NhcGVkIHxcbiAgICAgICAgcmV0dXJuICcgfCc7XG4gICAgICB9XG4gICAgfSksXG4gICAgY2VsbHMgPSByb3cuc3BsaXQoLyBcXHwvKTtcbiAgdmFyIGkgPSAwO1xuXG4gIC8vIEZpcnN0L2xhc3QgY2VsbCBpbiBhIHJvdyBjYW5ub3QgYmUgZW1wdHkgaWYgaXQgaGFzIG5vIGxlYWRpbmcvdHJhaWxpbmcgcGlwZVxuICBpZiAoIWNlbGxzWzBdLnRyaW0oKSkge1xuICAgIGNlbGxzLnNoaWZ0KCk7XG4gIH1cbiAgaWYgKGNlbGxzLmxlbmd0aCA+IDAgJiYgIWNlbGxzW2NlbGxzLmxlbmd0aCAtIDFdLnRyaW0oKSkge1xuICAgIGNlbGxzLnBvcCgpO1xuICB9XG4gIGlmIChjZWxscy5sZW5ndGggPiBjb3VudCkge1xuICAgIGNlbGxzLnNwbGljZShjb3VudCk7XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKGNlbGxzLmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBjZWxscy5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAgZm9yICg7IGkgPCBjZWxscy5sZW5ndGg7IGkrKykge1xuICAgIC8vIGxlYWRpbmcgb3IgdHJhaWxpbmcgd2hpdGVzcGFjZSBpcyBpZ25vcmVkIHBlciB0aGUgZ2ZtIHNwZWNcbiAgICBjZWxsc1tpXSA9IGNlbGxzW2ldLnRyaW0oKS5yZXBsYWNlKC9cXFxcXFx8L2csICd8Jyk7XG4gIH1cbiAgcmV0dXJuIGNlbGxzO1xufVxuXG4vKipcbiAqIFJlbW92ZSB0cmFpbGluZyAnYydzLiBFcXVpdmFsZW50IHRvIHN0ci5yZXBsYWNlKC9jKiQvLCAnJykuXG4gKiAvYyokLyBpcyB2dWxuZXJhYmxlIHRvIFJFRE9TLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBjXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGludmVydCBSZW1vdmUgc3VmZml4IG9mIG5vbi1jIGNoYXJzIGluc3RlYWQuIERlZmF1bHQgZmFsc2V5LlxuICovXG5mdW5jdGlvbiBydHJpbShzdHIsIGMsIGludmVydCkge1xuICB2YXIgbCA9IHN0ci5sZW5ndGg7XG4gIGlmIChsID09PSAwKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLy8gTGVuZ3RoIG9mIHN1ZmZpeCBtYXRjaGluZyB0aGUgaW52ZXJ0IGNvbmRpdGlvbi5cbiAgdmFyIHN1ZmZMZW4gPSAwO1xuXG4gIC8vIFN0ZXAgbGVmdCB1bnRpbCB3ZSBmYWlsIHRvIG1hdGNoIHRoZSBpbnZlcnQgY29uZGl0aW9uLlxuICB3aGlsZSAoc3VmZkxlbiA8IGwpIHtcbiAgICB2YXIgY3VyckNoYXIgPSBzdHIuY2hhckF0KGwgLSBzdWZmTGVuIC0gMSk7XG4gICAgaWYgKGN1cnJDaGFyID09PSBjICYmICFpbnZlcnQpIHtcbiAgICAgIHN1ZmZMZW4rKztcbiAgICB9IGVsc2UgaWYgKGN1cnJDaGFyICE9PSBjICYmIGludmVydCkge1xuICAgICAgc3VmZkxlbisrO1xuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0ci5zbGljZSgwLCBsIC0gc3VmZkxlbik7XG59XG5mdW5jdGlvbiBmaW5kQ2xvc2luZ0JyYWNrZXQoc3RyLCBiKSB7XG4gIGlmIChzdHIuaW5kZXhPZihiWzFdKSA9PT0gLTEpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgdmFyIGwgPSBzdHIubGVuZ3RoO1xuICB2YXIgbGV2ZWwgPSAwLFxuICAgIGkgPSAwO1xuICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgIGlmIChzdHJbaV0gPT09ICdcXFxcJykge1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSBpZiAoc3RyW2ldID09PSBiWzBdKSB7XG4gICAgICBsZXZlbCsrO1xuICAgIH0gZWxzZSBpZiAoc3RyW2ldID09PSBiWzFdKSB7XG4gICAgICBsZXZlbC0tO1xuICAgICAgaWYgKGxldmVsIDwgMCkge1xuICAgICAgICByZXR1cm4gaTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuZnVuY3Rpb24gY2hlY2tTYW5pdGl6ZURlcHJlY2F0aW9uKG9wdCkge1xuICBpZiAob3B0ICYmIG9wdC5zYW5pdGl6ZSAmJiAhb3B0LnNpbGVudCkge1xuICAgIGNvbnNvbGUud2FybignbWFya2VkKCk6IHNhbml0aXplIGFuZCBzYW5pdGl6ZXIgcGFyYW1ldGVycyBhcmUgZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDAuNy4wLCBzaG91bGQgbm90IGJlIHVzZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgZnV0dXJlLiBSZWFkIG1vcmUgaGVyZTogaHR0cHM6Ly9tYXJrZWQuanMub3JnLyMvVVNJTkdfQURWQU5DRUQubWQjb3B0aW9ucycpO1xuICB9XG59XG5cbi8vIGNvcGllZCBmcm9tIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS81NDUwMTEzLzgwNjc3N1xuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0dGVyblxuICogQHBhcmFtIHtudW1iZXJ9IGNvdW50XG4gKi9cbmZ1bmN0aW9uIHJlcGVhdFN0cmluZyhwYXR0ZXJuLCBjb3VudCkge1xuICBpZiAoY291bnQgPCAxKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIHZhciByZXN1bHQgPSAnJztcbiAgd2hpbGUgKGNvdW50ID4gMSkge1xuICAgIGlmIChjb3VudCAmIDEpIHtcbiAgICAgIHJlc3VsdCArPSBwYXR0ZXJuO1xuICAgIH1cbiAgICBjb3VudCA+Pj0gMTtcbiAgICBwYXR0ZXJuICs9IHBhdHRlcm47XG4gIH1cbiAgcmV0dXJuIHJlc3VsdCArIHBhdHRlcm47XG59XG5cbmZ1bmN0aW9uIG91dHB1dExpbmsoY2FwLCBsaW5rLCByYXcsIGxleGVyKSB7XG4gIHZhciBocmVmID0gbGluay5ocmVmO1xuICB2YXIgdGl0bGUgPSBsaW5rLnRpdGxlID8gZXNjYXBlKGxpbmsudGl0bGUpIDogbnVsbDtcbiAgdmFyIHRleHQgPSBjYXBbMV0ucmVwbGFjZSgvXFxcXChbXFxbXFxdXSkvZywgJyQxJyk7XG4gIGlmIChjYXBbMF0uY2hhckF0KDApICE9PSAnIScpIHtcbiAgICBsZXhlci5zdGF0ZS5pbkxpbmsgPSB0cnVlO1xuICAgIHZhciB0b2tlbiA9IHtcbiAgICAgIHR5cGU6ICdsaW5rJyxcbiAgICAgIHJhdzogcmF3LFxuICAgICAgaHJlZjogaHJlZixcbiAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgIHRleHQ6IHRleHQsXG4gICAgICB0b2tlbnM6IGxleGVyLmlubGluZVRva2Vucyh0ZXh0KVxuICAgIH07XG4gICAgbGV4ZXIuc3RhdGUuaW5MaW5rID0gZmFsc2U7XG4gICAgcmV0dXJuIHRva2VuO1xuICB9XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ2ltYWdlJyxcbiAgICByYXc6IHJhdyxcbiAgICBocmVmOiBocmVmLFxuICAgIHRpdGxlOiB0aXRsZSxcbiAgICB0ZXh0OiBlc2NhcGUodGV4dClcbiAgfTtcbn1cbmZ1bmN0aW9uIGluZGVudENvZGVDb21wZW5zYXRpb24ocmF3LCB0ZXh0KSB7XG4gIHZhciBtYXRjaEluZGVudFRvQ29kZSA9IHJhdy5tYXRjaCgvXihcXHMrKSg/OmBgYCkvKTtcbiAgaWYgKG1hdGNoSW5kZW50VG9Db2RlID09PSBudWxsKSB7XG4gICAgcmV0dXJuIHRleHQ7XG4gIH1cbiAgdmFyIGluZGVudFRvQ29kZSA9IG1hdGNoSW5kZW50VG9Db2RlWzFdO1xuICByZXR1cm4gdGV4dC5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgdmFyIG1hdGNoSW5kZW50SW5Ob2RlID0gbm9kZS5tYXRjaCgvXlxccysvKTtcbiAgICBpZiAobWF0Y2hJbmRlbnRJbk5vZGUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbiAgICB2YXIgaW5kZW50SW5Ob2RlID0gbWF0Y2hJbmRlbnRJbk5vZGVbMF07XG4gICAgaWYgKGluZGVudEluTm9kZS5sZW5ndGggPj0gaW5kZW50VG9Db2RlLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIG5vZGUuc2xpY2UoaW5kZW50VG9Db2RlLmxlbmd0aCk7XG4gICAgfVxuICAgIHJldHVybiBub2RlO1xuICB9KS5qb2luKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBUb2tlbml6ZXJcbiAqL1xudmFyIFRva2VuaXplciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFRva2VuaXplcihvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCBleHBvcnRzLmRlZmF1bHRzO1xuICB9XG4gIHZhciBfcHJvdG8gPSBUb2tlbml6ZXIucHJvdG90eXBlO1xuICBfcHJvdG8uc3BhY2UgPSBmdW5jdGlvbiBzcGFjZShzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5uZXdsaW5lLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwICYmIGNhcFswXS5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnc3BhY2UnLFxuICAgICAgICByYXc6IGNhcFswXVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5jb2RlID0gZnVuY3Rpb24gY29kZShzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5jb2RlLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgdGV4dCA9IGNhcFswXS5yZXBsYWNlKC9eIHsxLDR9L2dtLCAnJyk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnY29kZScsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICBjb2RlQmxvY2tTdHlsZTogJ2luZGVudGVkJyxcbiAgICAgICAgdGV4dDogIXRoaXMub3B0aW9ucy5wZWRhbnRpYyA/IHJ0cmltKHRleHQsICdcXG4nKSA6IHRleHRcbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8uZmVuY2VzID0gZnVuY3Rpb24gZmVuY2VzKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLmZlbmNlcy5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHJhdyA9IGNhcFswXTtcbiAgICAgIHZhciB0ZXh0ID0gaW5kZW50Q29kZUNvbXBlbnNhdGlvbihyYXcsIGNhcFszXSB8fCAnJyk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnY29kZScsXG4gICAgICAgIHJhdzogcmF3LFxuICAgICAgICBsYW5nOiBjYXBbMl0gPyBjYXBbMl0udHJpbSgpLnJlcGxhY2UodGhpcy5ydWxlcy5pbmxpbmUuX2VzY2FwZXMsICckMScpIDogY2FwWzJdLFxuICAgICAgICB0ZXh0OiB0ZXh0XG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmhlYWRpbmcgPSBmdW5jdGlvbiBoZWFkaW5nKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLmhlYWRpbmcuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHZhciB0ZXh0ID0gY2FwWzJdLnRyaW0oKTtcblxuICAgICAgLy8gcmVtb3ZlIHRyYWlsaW5nICNzXG4gICAgICBpZiAoLyMkLy50ZXN0KHRleHQpKSB7XG4gICAgICAgIHZhciB0cmltbWVkID0gcnRyaW0odGV4dCwgJyMnKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgICAgICAgIHRleHQgPSB0cmltbWVkLnRyaW0oKTtcbiAgICAgICAgfSBlbHNlIGlmICghdHJpbW1lZCB8fCAvICQvLnRlc3QodHJpbW1lZCkpIHtcbiAgICAgICAgICAvLyBDb21tb25NYXJrIHJlcXVpcmVzIHNwYWNlIGJlZm9yZSB0cmFpbGluZyAjc1xuICAgICAgICAgIHRleHQgPSB0cmltbWVkLnRyaW0oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2hlYWRpbmcnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgZGVwdGg6IGNhcFsxXS5sZW5ndGgsXG4gICAgICAgIHRleHQ6IHRleHQsXG4gICAgICAgIHRva2VuczogdGhpcy5sZXhlci5pbmxpbmUodGV4dClcbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8uaHIgPSBmdW5jdGlvbiBocihzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5oci5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2hyJyxcbiAgICAgICAgcmF3OiBjYXBbMF1cbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8uYmxvY2txdW90ZSA9IGZ1bmN0aW9uIGJsb2NrcXVvdGUoc3JjKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuYmxvY2suYmxvY2txdW90ZS5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHRleHQgPSBjYXBbMF0ucmVwbGFjZSgvXiAqPlsgXFx0XT8vZ20sICcnKTtcbiAgICAgIHZhciB0b3AgPSB0aGlzLmxleGVyLnN0YXRlLnRvcDtcbiAgICAgIHRoaXMubGV4ZXIuc3RhdGUudG9wID0gdHJ1ZTtcbiAgICAgIHZhciB0b2tlbnMgPSB0aGlzLmxleGVyLmJsb2NrVG9rZW5zKHRleHQpO1xuICAgICAgdGhpcy5sZXhlci5zdGF0ZS50b3AgPSB0b3A7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnYmxvY2txdW90ZScsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0b2tlbnM6IHRva2VucyxcbiAgICAgICAgdGV4dDogdGV4dFxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5saXN0ID0gZnVuY3Rpb24gbGlzdChzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5saXN0LmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgcmF3LCBpc3Rhc2ssIGlzY2hlY2tlZCwgaW5kZW50LCBpLCBibGFua0xpbmUsIGVuZHNXaXRoQmxhbmtMaW5lLCBsaW5lLCBuZXh0TGluZSwgcmF3TGluZSwgaXRlbUNvbnRlbnRzLCBlbmRFYXJseTtcbiAgICAgIHZhciBidWxsID0gY2FwWzFdLnRyaW0oKTtcbiAgICAgIHZhciBpc29yZGVyZWQgPSBidWxsLmxlbmd0aCA+IDE7XG4gICAgICB2YXIgbGlzdCA9IHtcbiAgICAgICAgdHlwZTogJ2xpc3QnLFxuICAgICAgICByYXc6ICcnLFxuICAgICAgICBvcmRlcmVkOiBpc29yZGVyZWQsXG4gICAgICAgIHN0YXJ0OiBpc29yZGVyZWQgPyArYnVsbC5zbGljZSgwLCAtMSkgOiAnJyxcbiAgICAgICAgbG9vc2U6IGZhbHNlLFxuICAgICAgICBpdGVtczogW11cbiAgICAgIH07XG4gICAgICBidWxsID0gaXNvcmRlcmVkID8gXCJcXFxcZHsxLDl9XFxcXFwiICsgYnVsbC5zbGljZSgtMSkgOiBcIlxcXFxcIiArIGJ1bGw7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnBlZGFudGljKSB7XG4gICAgICAgIGJ1bGwgPSBpc29yZGVyZWQgPyBidWxsIDogJ1sqKy1dJztcbiAgICAgIH1cblxuICAgICAgLy8gR2V0IG5leHQgbGlzdCBpdGVtXG4gICAgICB2YXIgaXRlbVJlZ2V4ID0gbmV3IFJlZ0V4cChcIl4oIHswLDN9XCIgKyBidWxsICsgXCIpKCg/OltcXHQgXVteXFxcXG5dKik/KD86XFxcXG58JCkpXCIpO1xuXG4gICAgICAvLyBDaGVjayBpZiBjdXJyZW50IGJ1bGxldCBwb2ludCBjYW4gc3RhcnQgYSBuZXcgTGlzdCBJdGVtXG4gICAgICB3aGlsZSAoc3JjKSB7XG4gICAgICAgIGVuZEVhcmx5ID0gZmFsc2U7XG4gICAgICAgIGlmICghKGNhcCA9IGl0ZW1SZWdleC5leGVjKHNyYykpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucnVsZXMuYmxvY2suaHIudGVzdChzcmMpKSB7XG4gICAgICAgICAgLy8gRW5kIGxpc3QgaWYgYnVsbGV0IHdhcyBhY3R1YWxseSBIUiAocG9zc2libHkgbW92ZSBpbnRvIGl0ZW1SZWdleD8pXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgcmF3ID0gY2FwWzBdO1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHJhdy5sZW5ndGgpO1xuICAgICAgICBsaW5lID0gY2FwWzJdLnNwbGl0KCdcXG4nLCAxKVswXS5yZXBsYWNlKC9eXFx0Ky8sIGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgcmV0dXJuICcgJy5yZXBlYXQoMyAqIHQubGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIG5leHRMaW5lID0gc3JjLnNwbGl0KCdcXG4nLCAxKVswXTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgICAgICAgIGluZGVudCA9IDI7XG4gICAgICAgICAgaXRlbUNvbnRlbnRzID0gbGluZS50cmltTGVmdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGluZGVudCA9IGNhcFsyXS5zZWFyY2goL1teIF0vKTsgLy8gRmluZCBmaXJzdCBub24tc3BhY2UgY2hhclxuICAgICAgICAgIGluZGVudCA9IGluZGVudCA+IDQgPyAxIDogaW5kZW50OyAvLyBUcmVhdCBpbmRlbnRlZCBjb2RlIGJsb2NrcyAoPiA0IHNwYWNlcykgYXMgaGF2aW5nIG9ubHkgMSBpbmRlbnRcbiAgICAgICAgICBpdGVtQ29udGVudHMgPSBsaW5lLnNsaWNlKGluZGVudCk7XG4gICAgICAgICAgaW5kZW50ICs9IGNhcFsxXS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgYmxhbmtMaW5lID0gZmFsc2U7XG4gICAgICAgIGlmICghbGluZSAmJiAvXiAqJC8udGVzdChuZXh0TGluZSkpIHtcbiAgICAgICAgICAvLyBJdGVtcyBiZWdpbiB3aXRoIGF0IG1vc3Qgb25lIGJsYW5rIGxpbmVcbiAgICAgICAgICByYXcgKz0gbmV4dExpbmUgKyAnXFxuJztcbiAgICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKG5leHRMaW5lLmxlbmd0aCArIDEpO1xuICAgICAgICAgIGVuZEVhcmx5ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWVuZEVhcmx5KSB7XG4gICAgICAgICAgdmFyIG5leHRCdWxsZXRSZWdleCA9IG5ldyBSZWdFeHAoXCJeIHswLFwiICsgTWF0aC5taW4oMywgaW5kZW50IC0gMSkgKyBcIn0oPzpbKistXXxcXFxcZHsxLDl9Wy4pXSkoKD86WyBcXHRdW15cXFxcbl0qKT8oPzpcXFxcbnwkKSlcIik7XG4gICAgICAgICAgdmFyIGhyUmVnZXggPSBuZXcgUmVnRXhwKFwiXiB7MCxcIiArIE1hdGgubWluKDMsIGluZGVudCAtIDEpICsgXCJ9KCg/Oi0gKil7Myx9fCg/Ol8gKil7Myx9fCg/OlxcXFwqICopezMsfSkoPzpcXFxcbit8JClcIik7XG4gICAgICAgICAgdmFyIGZlbmNlc0JlZ2luUmVnZXggPSBuZXcgUmVnRXhwKFwiXiB7MCxcIiArIE1hdGgubWluKDMsIGluZGVudCAtIDEpICsgXCJ9KD86YGBgfH5+filcIik7XG4gICAgICAgICAgdmFyIGhlYWRpbmdCZWdpblJlZ2V4ID0gbmV3IFJlZ0V4cChcIl4gezAsXCIgKyBNYXRoLm1pbigzLCBpbmRlbnQgLSAxKSArIFwifSNcIik7XG5cbiAgICAgICAgICAvLyBDaGVjayBpZiBmb2xsb3dpbmcgbGluZXMgc2hvdWxkIGJlIGluY2x1ZGVkIGluIExpc3QgSXRlbVxuICAgICAgICAgIHdoaWxlIChzcmMpIHtcbiAgICAgICAgICAgIHJhd0xpbmUgPSBzcmMuc3BsaXQoJ1xcbicsIDEpWzBdO1xuICAgICAgICAgICAgbmV4dExpbmUgPSByYXdMaW5lO1xuXG4gICAgICAgICAgICAvLyBSZS1hbGlnbiB0byBmb2xsb3cgY29tbW9ubWFyayBuZXN0aW5nIHJ1bGVzXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBlZGFudGljKSB7XG4gICAgICAgICAgICAgIG5leHRMaW5lID0gbmV4dExpbmUucmVwbGFjZSgvXiB7MSw0fSg/PSggezR9KSpbXiBdKS9nLCAnICAnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRW5kIGxpc3QgaXRlbSBpZiBmb3VuZCBjb2RlIGZlbmNlc1xuICAgICAgICAgICAgaWYgKGZlbmNlc0JlZ2luUmVnZXgudGVzdChuZXh0TGluZSkpIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEVuZCBsaXN0IGl0ZW0gaWYgZm91bmQgc3RhcnQgb2YgbmV3IGhlYWRpbmdcbiAgICAgICAgICAgIGlmIChoZWFkaW5nQmVnaW5SZWdleC50ZXN0KG5leHRMaW5lKSkge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRW5kIGxpc3QgaXRlbSBpZiBmb3VuZCBzdGFydCBvZiBuZXcgYnVsbGV0XG4gICAgICAgICAgICBpZiAobmV4dEJ1bGxldFJlZ2V4LnRlc3QobmV4dExpbmUpKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBIb3Jpem9udGFsIHJ1bGUgZm91bmRcbiAgICAgICAgICAgIGlmIChoclJlZ2V4LnRlc3Qoc3JjKSkge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZXh0TGluZS5zZWFyY2goL1teIF0vKSA+PSBpbmRlbnQgfHwgIW5leHRMaW5lLnRyaW0oKSkge1xuICAgICAgICAgICAgICAvLyBEZWRlbnQgaWYgcG9zc2libGVcbiAgICAgICAgICAgICAgaXRlbUNvbnRlbnRzICs9ICdcXG4nICsgbmV4dExpbmUuc2xpY2UoaW5kZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIG5vdCBlbm91Z2ggaW5kZW50YXRpb25cbiAgICAgICAgICAgICAgaWYgKGJsYW5rTGluZSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gcGFyYWdyYXBoIGNvbnRpbnVhdGlvbiB1bmxlc3MgbGFzdCBsaW5lIHdhcyBhIGRpZmZlcmVudCBibG9jayBsZXZlbCBlbGVtZW50XG4gICAgICAgICAgICAgIGlmIChsaW5lLnNlYXJjaCgvW14gXS8pID49IDQpIHtcbiAgICAgICAgICAgICAgICAvLyBpbmRlbnRlZCBjb2RlIGJsb2NrXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGZlbmNlc0JlZ2luUmVnZXgudGVzdChsaW5lKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChoZWFkaW5nQmVnaW5SZWdleC50ZXN0KGxpbmUpKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGhyUmVnZXgudGVzdChsaW5lKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGl0ZW1Db250ZW50cyArPSAnXFxuJyArIG5leHRMaW5lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFibGFua0xpbmUgJiYgIW5leHRMaW5lLnRyaW0oKSkge1xuICAgICAgICAgICAgICAvLyBDaGVjayBpZiBjdXJyZW50IGxpbmUgaXMgYmxhbmtcbiAgICAgICAgICAgICAgYmxhbmtMaW5lID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJhdyArPSByYXdMaW5lICsgJ1xcbic7XG4gICAgICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHJhd0xpbmUubGVuZ3RoICsgMSk7XG4gICAgICAgICAgICBsaW5lID0gbmV4dExpbmUuc2xpY2UoaW5kZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFsaXN0Lmxvb3NlKSB7XG4gICAgICAgICAgLy8gSWYgdGhlIHByZXZpb3VzIGl0ZW0gZW5kZWQgd2l0aCBhIGJsYW5rIGxpbmUsIHRoZSBsaXN0IGlzIGxvb3NlXG4gICAgICAgICAgaWYgKGVuZHNXaXRoQmxhbmtMaW5lKSB7XG4gICAgICAgICAgICBsaXN0Lmxvb3NlID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKC9cXG4gKlxcbiAqJC8udGVzdChyYXcpKSB7XG4gICAgICAgICAgICBlbmRzV2l0aEJsYW5rTGluZSA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIHRhc2sgbGlzdCBpdGVtc1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmdmbSkge1xuICAgICAgICAgIGlzdGFzayA9IC9eXFxbWyB4WF1cXF0gLy5leGVjKGl0ZW1Db250ZW50cyk7XG4gICAgICAgICAgaWYgKGlzdGFzaykge1xuICAgICAgICAgICAgaXNjaGVja2VkID0gaXN0YXNrWzBdICE9PSAnWyBdICc7XG4gICAgICAgICAgICBpdGVtQ29udGVudHMgPSBpdGVtQ29udGVudHMucmVwbGFjZSgvXlxcW1sgeFhdXFxdICsvLCAnJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxpc3QuaXRlbXMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ2xpc3RfaXRlbScsXG4gICAgICAgICAgcmF3OiByYXcsXG4gICAgICAgICAgdGFzazogISFpc3Rhc2ssXG4gICAgICAgICAgY2hlY2tlZDogaXNjaGVja2VkLFxuICAgICAgICAgIGxvb3NlOiBmYWxzZSxcbiAgICAgICAgICB0ZXh0OiBpdGVtQ29udGVudHNcbiAgICAgICAgfSk7XG4gICAgICAgIGxpc3QucmF3ICs9IHJhdztcbiAgICAgIH1cblxuICAgICAgLy8gRG8gbm90IGNvbnN1bWUgbmV3bGluZXMgYXQgZW5kIG9mIGZpbmFsIGl0ZW0uIEFsdGVybmF0aXZlbHksIG1ha2UgaXRlbVJlZ2V4ICpzdGFydCogd2l0aCBhbnkgbmV3bGluZXMgdG8gc2ltcGxpZnkvc3BlZWQgdXAgZW5kc1dpdGhCbGFua0xpbmUgbG9naWNcbiAgICAgIGxpc3QuaXRlbXNbbGlzdC5pdGVtcy5sZW5ndGggLSAxXS5yYXcgPSByYXcudHJpbVJpZ2h0KCk7XG4gICAgICBsaXN0Lml0ZW1zW2xpc3QuaXRlbXMubGVuZ3RoIC0gMV0udGV4dCA9IGl0ZW1Db250ZW50cy50cmltUmlnaHQoKTtcbiAgICAgIGxpc3QucmF3ID0gbGlzdC5yYXcudHJpbVJpZ2h0KCk7XG4gICAgICB2YXIgbCA9IGxpc3QuaXRlbXMubGVuZ3RoO1xuXG4gICAgICAvLyBJdGVtIGNoaWxkIHRva2VucyBoYW5kbGVkIGhlcmUgYXQgZW5kIGJlY2F1c2Ugd2UgbmVlZGVkIHRvIGhhdmUgdGhlIGZpbmFsIGl0ZW0gdG8gdHJpbSBpdCBmaXJzdFxuICAgICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLnRvcCA9IGZhbHNlO1xuICAgICAgICBsaXN0Lml0ZW1zW2ldLnRva2VucyA9IHRoaXMubGV4ZXIuYmxvY2tUb2tlbnMobGlzdC5pdGVtc1tpXS50ZXh0LCBbXSk7XG4gICAgICAgIGlmICghbGlzdC5sb29zZSkge1xuICAgICAgICAgIC8vIENoZWNrIGlmIGxpc3Qgc2hvdWxkIGJlIGxvb3NlXG4gICAgICAgICAgdmFyIHNwYWNlcnMgPSBsaXN0Lml0ZW1zW2ldLnRva2Vucy5maWx0ZXIoZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgIHJldHVybiB0LnR5cGUgPT09ICdzcGFjZSc7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdmFyIGhhc011bHRpcGxlTGluZUJyZWFrcyA9IHNwYWNlcnMubGVuZ3RoID4gMCAmJiBzcGFjZXJzLnNvbWUoZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgIHJldHVybiAvXFxuLipcXG4vLnRlc3QodC5yYXcpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGxpc3QubG9vc2UgPSBoYXNNdWx0aXBsZUxpbmVCcmVha3M7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU2V0IGFsbCBpdGVtcyB0byBsb29zZSBpZiBsaXN0IGlzIGxvb3NlXG4gICAgICBpZiAobGlzdC5sb29zZSkge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgbGlzdC5pdGVtc1tpXS5sb29zZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBsaXN0O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmh0bWwgPSBmdW5jdGlvbiBodG1sKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLmh0bWwuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHZhciB0b2tlbiA9IHtcbiAgICAgICAgdHlwZTogJ2h0bWwnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgcHJlOiAhdGhpcy5vcHRpb25zLnNhbml0aXplciAmJiAoY2FwWzFdID09PSAncHJlJyB8fCBjYXBbMV0gPT09ICdzY3JpcHQnIHx8IGNhcFsxXSA9PT0gJ3N0eWxlJyksXG4gICAgICAgIHRleHQ6IGNhcFswXVxuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2FuaXRpemUpIHtcbiAgICAgICAgdmFyIHRleHQgPSB0aGlzLm9wdGlvbnMuc2FuaXRpemVyID8gdGhpcy5vcHRpb25zLnNhbml0aXplcihjYXBbMF0pIDogZXNjYXBlKGNhcFswXSk7XG4gICAgICAgIHRva2VuLnR5cGUgPSAncGFyYWdyYXBoJztcbiAgICAgICAgdG9rZW4udGV4dCA9IHRleHQ7XG4gICAgICAgIHRva2VuLnRva2VucyA9IHRoaXMubGV4ZXIuaW5saW5lKHRleHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmRlZiA9IGZ1bmN0aW9uIGRlZihzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5kZWYuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHZhciB0YWcgPSBjYXBbMV0udG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9cXHMrL2csICcgJyk7XG4gICAgICB2YXIgaHJlZiA9IGNhcFsyXSA/IGNhcFsyXS5yZXBsYWNlKC9ePCguKik+JC8sICckMScpLnJlcGxhY2UodGhpcy5ydWxlcy5pbmxpbmUuX2VzY2FwZXMsICckMScpIDogJyc7XG4gICAgICB2YXIgdGl0bGUgPSBjYXBbM10gPyBjYXBbM10uc3Vic3RyaW5nKDEsIGNhcFszXS5sZW5ndGggLSAxKS5yZXBsYWNlKHRoaXMucnVsZXMuaW5saW5lLl9lc2NhcGVzLCAnJDEnKSA6IGNhcFszXTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdkZWYnLFxuICAgICAgICB0YWc6IHRhZyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIGhyZWY6IGhyZWYsXG4gICAgICAgIHRpdGxlOiB0aXRsZVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by50YWJsZSA9IGZ1bmN0aW9uIHRhYmxlKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLnRhYmxlLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgaXRlbSA9IHtcbiAgICAgICAgdHlwZTogJ3RhYmxlJyxcbiAgICAgICAgaGVhZGVyOiBzcGxpdENlbGxzKGNhcFsxXSkubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRleHQ6IGNcbiAgICAgICAgICB9O1xuICAgICAgICB9KSxcbiAgICAgICAgYWxpZ246IGNhcFsyXS5yZXBsYWNlKC9eICp8XFx8ICokL2csICcnKS5zcGxpdCgvICpcXHwgKi8pLFxuICAgICAgICByb3dzOiBjYXBbM10gJiYgY2FwWzNdLnRyaW0oKSA/IGNhcFszXS5yZXBsYWNlKC9cXG5bIFxcdF0qJC8sICcnKS5zcGxpdCgnXFxuJykgOiBbXVxuICAgICAgfTtcbiAgICAgIGlmIChpdGVtLmhlYWRlci5sZW5ndGggPT09IGl0ZW0uYWxpZ24ubGVuZ3RoKSB7XG4gICAgICAgIGl0ZW0ucmF3ID0gY2FwWzBdO1xuICAgICAgICB2YXIgbCA9IGl0ZW0uYWxpZ24ubGVuZ3RoO1xuICAgICAgICB2YXIgaSwgaiwgaywgcm93O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgaWYgKC9eICotKzogKiQvLnRlc3QoaXRlbS5hbGlnbltpXSkpIHtcbiAgICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSAncmlnaHQnO1xuICAgICAgICAgIH0gZWxzZSBpZiAoL14gKjotKzogKiQvLnRlc3QoaXRlbS5hbGlnbltpXSkpIHtcbiAgICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSAnY2VudGVyJztcbiAgICAgICAgICB9IGVsc2UgaWYgKC9eICo6LSsgKiQvLnRlc3QoaXRlbS5hbGlnbltpXSkpIHtcbiAgICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSAnbGVmdCc7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsID0gaXRlbS5yb3dzLmxlbmd0aDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgIGl0ZW0ucm93c1tpXSA9IHNwbGl0Q2VsbHMoaXRlbS5yb3dzW2ldLCBpdGVtLmhlYWRlci5sZW5ndGgpLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdGV4dDogY1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHBhcnNlIGNoaWxkIHRva2VucyBpbnNpZGUgaGVhZGVycyBhbmQgY2VsbHNcblxuICAgICAgICAvLyBoZWFkZXIgY2hpbGQgdG9rZW5zXG4gICAgICAgIGwgPSBpdGVtLmhlYWRlci5sZW5ndGg7XG4gICAgICAgIGZvciAoaiA9IDA7IGogPCBsOyBqKyspIHtcbiAgICAgICAgICBpdGVtLmhlYWRlcltqXS50b2tlbnMgPSB0aGlzLmxleGVyLmlubGluZShpdGVtLmhlYWRlcltqXS50ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNlbGwgY2hpbGQgdG9rZW5zXG4gICAgICAgIGwgPSBpdGVtLnJvd3MubGVuZ3RoO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgbDsgaisrKSB7XG4gICAgICAgICAgcm93ID0gaXRlbS5yb3dzW2pdO1xuICAgICAgICAgIGZvciAoayA9IDA7IGsgPCByb3cubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgIHJvd1trXS50b2tlbnMgPSB0aGlzLmxleGVyLmlubGluZShyb3dba10udGV4dCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmxoZWFkaW5nID0gZnVuY3Rpb24gbGhlYWRpbmcoc3JjKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuYmxvY2subGhlYWRpbmcuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdoZWFkaW5nJyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIGRlcHRoOiBjYXBbMl0uY2hhckF0KDApID09PSAnPScgPyAxIDogMixcbiAgICAgICAgdGV4dDogY2FwWzFdLFxuICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lKGNhcFsxXSlcbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8ucGFyYWdyYXBoID0gZnVuY3Rpb24gcGFyYWdyYXBoKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLnBhcmFncmFwaC5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHRleHQgPSBjYXBbMV0uY2hhckF0KGNhcFsxXS5sZW5ndGggLSAxKSA9PT0gJ1xcbicgPyBjYXBbMV0uc2xpY2UoMCwgLTEpIDogY2FwWzFdO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3BhcmFncmFwaCcsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lKHRleHQpXG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLnRleHQgPSBmdW5jdGlvbiB0ZXh0KHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLnRleHQuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIHRleHQ6IGNhcFswXSxcbiAgICAgICAgdG9rZW5zOiB0aGlzLmxleGVyLmlubGluZShjYXBbMF0pXG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmVzY2FwZSA9IGZ1bmN0aW9uIGVzY2FwZSQxKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmlubGluZS5lc2NhcGUuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdlc2NhcGUnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgdGV4dDogZXNjYXBlKGNhcFsxXSlcbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8udGFnID0gZnVuY3Rpb24gdGFnKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmlubGluZS50YWcuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIGlmICghdGhpcy5sZXhlci5zdGF0ZS5pbkxpbmsgJiYgL148YSAvaS50ZXN0KGNhcFswXSkpIHtcbiAgICAgICAgdGhpcy5sZXhlci5zdGF0ZS5pbkxpbmsgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmxleGVyLnN0YXRlLmluTGluayAmJiAvXjxcXC9hPi9pLnRlc3QoY2FwWzBdKSkge1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLmluTGluayA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgJiYgL148KHByZXxjb2RlfGtiZHxzY3JpcHQpKFxcc3w+KS9pLnRlc3QoY2FwWzBdKSkge1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgJiYgL148XFwvKHByZXxjb2RlfGtiZHxzY3JpcHQpKFxcc3w+KS9pLnRlc3QoY2FwWzBdKSkge1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHRoaXMub3B0aW9ucy5zYW5pdGl6ZSA/ICd0ZXh0JyA6ICdodG1sJyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIGluTGluazogdGhpcy5sZXhlci5zdGF0ZS5pbkxpbmssXG4gICAgICAgIGluUmF3QmxvY2s6IHRoaXMubGV4ZXIuc3RhdGUuaW5SYXdCbG9jayxcbiAgICAgICAgdGV4dDogdGhpcy5vcHRpb25zLnNhbml0aXplID8gdGhpcy5vcHRpb25zLnNhbml0aXplciA/IHRoaXMub3B0aW9ucy5zYW5pdGl6ZXIoY2FwWzBdKSA6IGVzY2FwZShjYXBbMF0pIDogY2FwWzBdXG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmxpbmsgPSBmdW5jdGlvbiBsaW5rKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmlubGluZS5saW5rLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgdHJpbW1lZFVybCA9IGNhcFsyXS50cmltKCk7XG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5wZWRhbnRpYyAmJiAvXjwvLnRlc3QodHJpbW1lZFVybCkpIHtcbiAgICAgICAgLy8gY29tbW9ubWFyayByZXF1aXJlcyBtYXRjaGluZyBhbmdsZSBicmFja2V0c1xuICAgICAgICBpZiAoIS8+JC8udGVzdCh0cmltbWVkVXJsKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVuZGluZyBhbmdsZSBicmFja2V0IGNhbm5vdCBiZSBlc2NhcGVkXG4gICAgICAgIHZhciBydHJpbVNsYXNoID0gcnRyaW0odHJpbW1lZFVybC5zbGljZSgwLCAtMSksICdcXFxcJyk7XG4gICAgICAgIGlmICgodHJpbW1lZFVybC5sZW5ndGggLSBydHJpbVNsYXNoLmxlbmd0aCkgJSAyID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBmaW5kIGNsb3NpbmcgcGFyZW50aGVzaXNcbiAgICAgICAgdmFyIGxhc3RQYXJlbkluZGV4ID0gZmluZENsb3NpbmdCcmFja2V0KGNhcFsyXSwgJygpJyk7XG4gICAgICAgIGlmIChsYXN0UGFyZW5JbmRleCA+IC0xKSB7XG4gICAgICAgICAgdmFyIHN0YXJ0ID0gY2FwWzBdLmluZGV4T2YoJyEnKSA9PT0gMCA/IDUgOiA0O1xuICAgICAgICAgIHZhciBsaW5rTGVuID0gc3RhcnQgKyBjYXBbMV0ubGVuZ3RoICsgbGFzdFBhcmVuSW5kZXg7XG4gICAgICAgICAgY2FwWzJdID0gY2FwWzJdLnN1YnN0cmluZygwLCBsYXN0UGFyZW5JbmRleCk7XG4gICAgICAgICAgY2FwWzBdID0gY2FwWzBdLnN1YnN0cmluZygwLCBsaW5rTGVuKS50cmltKCk7XG4gICAgICAgICAgY2FwWzNdID0gJyc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBocmVmID0gY2FwWzJdO1xuICAgICAgdmFyIHRpdGxlID0gJyc7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnBlZGFudGljKSB7XG4gICAgICAgIC8vIHNwbGl0IHBlZGFudGljIGhyZWYgYW5kIHRpdGxlXG4gICAgICAgIHZhciBsaW5rID0gL14oW14nXCJdKlteXFxzXSlcXHMrKFsnXCJdKSguKilcXDIvLmV4ZWMoaHJlZik7XG4gICAgICAgIGlmIChsaW5rKSB7XG4gICAgICAgICAgaHJlZiA9IGxpbmtbMV07XG4gICAgICAgICAgdGl0bGUgPSBsaW5rWzNdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aXRsZSA9IGNhcFszXSA/IGNhcFszXS5zbGljZSgxLCAtMSkgOiAnJztcbiAgICAgIH1cbiAgICAgIGhyZWYgPSBocmVmLnRyaW0oKTtcbiAgICAgIGlmICgvXjwvLnRlc3QoaHJlZikpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYyAmJiAhLz4kLy50ZXN0KHRyaW1tZWRVcmwpKSB7XG4gICAgICAgICAgLy8gcGVkYW50aWMgYWxsb3dzIHN0YXJ0aW5nIGFuZ2xlIGJyYWNrZXQgd2l0aG91dCBlbmRpbmcgYW5nbGUgYnJhY2tldFxuICAgICAgICAgIGhyZWYgPSBocmVmLnNsaWNlKDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhyZWYgPSBocmVmLnNsaWNlKDEsIC0xKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG91dHB1dExpbmsoY2FwLCB7XG4gICAgICAgIGhyZWY6IGhyZWYgPyBocmVmLnJlcGxhY2UodGhpcy5ydWxlcy5pbmxpbmUuX2VzY2FwZXMsICckMScpIDogaHJlZixcbiAgICAgICAgdGl0bGU6IHRpdGxlID8gdGl0bGUucmVwbGFjZSh0aGlzLnJ1bGVzLmlubGluZS5fZXNjYXBlcywgJyQxJykgOiB0aXRsZVxuICAgICAgfSwgY2FwWzBdLCB0aGlzLmxleGVyKTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5yZWZsaW5rID0gZnVuY3Rpb24gcmVmbGluayhzcmMsIGxpbmtzKSB7XG4gICAgdmFyIGNhcDtcbiAgICBpZiAoKGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLnJlZmxpbmsuZXhlYyhzcmMpKSB8fCAoY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUubm9saW5rLmV4ZWMoc3JjKSkpIHtcbiAgICAgIHZhciBsaW5rID0gKGNhcFsyXSB8fCBjYXBbMV0pLnJlcGxhY2UoL1xccysvZywgJyAnKTtcbiAgICAgIGxpbmsgPSBsaW5rc1tsaW5rLnRvTG93ZXJDYXNlKCldO1xuICAgICAgaWYgKCFsaW5rKSB7XG4gICAgICAgIHZhciB0ZXh0ID0gY2FwWzBdLmNoYXJBdCgwKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgcmF3OiB0ZXh0LFxuICAgICAgICAgIHRleHQ6IHRleHRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXRwdXRMaW5rKGNhcCwgbGluaywgY2FwWzBdLCB0aGlzLmxleGVyKTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5lbVN0cm9uZyA9IGZ1bmN0aW9uIGVtU3Ryb25nKHNyYywgbWFza2VkU3JjLCBwcmV2Q2hhcikge1xuICAgIGlmIChwcmV2Q2hhciA9PT0gdm9pZCAwKSB7XG4gICAgICBwcmV2Q2hhciA9ICcnO1xuICAgIH1cbiAgICB2YXIgbWF0Y2ggPSB0aGlzLnJ1bGVzLmlubGluZS5lbVN0cm9uZy5sRGVsaW0uZXhlYyhzcmMpO1xuICAgIGlmICghbWF0Y2gpIHJldHVybjtcblxuICAgIC8vIF8gY2FuJ3QgYmUgYmV0d2VlbiB0d28gYWxwaGFudW1lcmljcy4gXFxwe0x9XFxwe059IGluY2x1ZGVzIG5vbi1lbmdsaXNoIGFscGhhYmV0L251bWJlcnMgYXMgd2VsbFxuICAgIGlmIChtYXRjaFszXSAmJiBwcmV2Q2hhci5tYXRjaCgvKD86WzAtOUEtWmEtelxceEFBXFx4QjJcXHhCM1xceEI1XFx4QjlcXHhCQVxceEJDLVxceEJFXFx4QzAtXFx4RDZcXHhEOC1cXHhGNlxceEY4LVxcdTAyQzFcXHUwMkM2LVxcdTAyRDFcXHUwMkUwLVxcdTAyRTRcXHUwMkVDXFx1MDJFRVxcdTAzNzAtXFx1MDM3NFxcdTAzNzZcXHUwMzc3XFx1MDM3QS1cXHUwMzdEXFx1MDM3RlxcdTAzODZcXHUwMzg4LVxcdTAzOEFcXHUwMzhDXFx1MDM4RS1cXHUwM0ExXFx1MDNBMy1cXHUwM0Y1XFx1MDNGNy1cXHUwNDgxXFx1MDQ4QS1cXHUwNTJGXFx1MDUzMS1cXHUwNTU2XFx1MDU1OVxcdTA1NjAtXFx1MDU4OFxcdTA1RDAtXFx1MDVFQVxcdTA1RUYtXFx1MDVGMlxcdTA2MjAtXFx1MDY0QVxcdTA2NjAtXFx1MDY2OVxcdTA2NkVcXHUwNjZGXFx1MDY3MS1cXHUwNkQzXFx1MDZENVxcdTA2RTVcXHUwNkU2XFx1MDZFRS1cXHUwNkZDXFx1MDZGRlxcdTA3MTBcXHUwNzEyLVxcdTA3MkZcXHUwNzRELVxcdTA3QTVcXHUwN0IxXFx1MDdDMC1cXHUwN0VBXFx1MDdGNFxcdTA3RjVcXHUwN0ZBXFx1MDgwMC1cXHUwODE1XFx1MDgxQVxcdTA4MjRcXHUwODI4XFx1MDg0MC1cXHUwODU4XFx1MDg2MC1cXHUwODZBXFx1MDg3MC1cXHUwODg3XFx1MDg4OS1cXHUwODhFXFx1MDhBMC1cXHUwOEM5XFx1MDkwNC1cXHUwOTM5XFx1MDkzRFxcdTA5NTBcXHUwOTU4LVxcdTA5NjFcXHUwOTY2LVxcdTA5NkZcXHUwOTcxLVxcdTA5ODBcXHUwOTg1LVxcdTA5OENcXHUwOThGXFx1MDk5MFxcdTA5OTMtXFx1MDlBOFxcdTA5QUEtXFx1MDlCMFxcdTA5QjJcXHUwOUI2LVxcdTA5QjlcXHUwOUJEXFx1MDlDRVxcdTA5RENcXHUwOUREXFx1MDlERi1cXHUwOUUxXFx1MDlFNi1cXHUwOUYxXFx1MDlGNC1cXHUwOUY5XFx1MDlGQ1xcdTBBMDUtXFx1MEEwQVxcdTBBMEZcXHUwQTEwXFx1MEExMy1cXHUwQTI4XFx1MEEyQS1cXHUwQTMwXFx1MEEzMlxcdTBBMzNcXHUwQTM1XFx1MEEzNlxcdTBBMzhcXHUwQTM5XFx1MEE1OS1cXHUwQTVDXFx1MEE1RVxcdTBBNjYtXFx1MEE2RlxcdTBBNzItXFx1MEE3NFxcdTBBODUtXFx1MEE4RFxcdTBBOEYtXFx1MEE5MVxcdTBBOTMtXFx1MEFBOFxcdTBBQUEtXFx1MEFCMFxcdTBBQjJcXHUwQUIzXFx1MEFCNS1cXHUwQUI5XFx1MEFCRFxcdTBBRDBcXHUwQUUwXFx1MEFFMVxcdTBBRTYtXFx1MEFFRlxcdTBBRjlcXHUwQjA1LVxcdTBCMENcXHUwQjBGXFx1MEIxMFxcdTBCMTMtXFx1MEIyOFxcdTBCMkEtXFx1MEIzMFxcdTBCMzJcXHUwQjMzXFx1MEIzNS1cXHUwQjM5XFx1MEIzRFxcdTBCNUNcXHUwQjVEXFx1MEI1Ri1cXHUwQjYxXFx1MEI2Ni1cXHUwQjZGXFx1MEI3MS1cXHUwQjc3XFx1MEI4M1xcdTBCODUtXFx1MEI4QVxcdTBCOEUtXFx1MEI5MFxcdTBCOTItXFx1MEI5NVxcdTBCOTlcXHUwQjlBXFx1MEI5Q1xcdTBCOUVcXHUwQjlGXFx1MEJBM1xcdTBCQTRcXHUwQkE4LVxcdTBCQUFcXHUwQkFFLVxcdTBCQjlcXHUwQkQwXFx1MEJFNi1cXHUwQkYyXFx1MEMwNS1cXHUwQzBDXFx1MEMwRS1cXHUwQzEwXFx1MEMxMi1cXHUwQzI4XFx1MEMyQS1cXHUwQzM5XFx1MEMzRFxcdTBDNTgtXFx1MEM1QVxcdTBDNURcXHUwQzYwXFx1MEM2MVxcdTBDNjYtXFx1MEM2RlxcdTBDNzgtXFx1MEM3RVxcdTBDODBcXHUwQzg1LVxcdTBDOENcXHUwQzhFLVxcdTBDOTBcXHUwQzkyLVxcdTBDQThcXHUwQ0FBLVxcdTBDQjNcXHUwQ0I1LVxcdTBDQjlcXHUwQ0JEXFx1MENERFxcdTBDREVcXHUwQ0UwXFx1MENFMVxcdTBDRTYtXFx1MENFRlxcdTBDRjFcXHUwQ0YyXFx1MEQwNC1cXHUwRDBDXFx1MEQwRS1cXHUwRDEwXFx1MEQxMi1cXHUwRDNBXFx1MEQzRFxcdTBENEVcXHUwRDU0LVxcdTBENTZcXHUwRDU4LVxcdTBENjFcXHUwRDY2LVxcdTBENzhcXHUwRDdBLVxcdTBEN0ZcXHUwRDg1LVxcdTBEOTZcXHUwRDlBLVxcdTBEQjFcXHUwREIzLVxcdTBEQkJcXHUwREJEXFx1MERDMC1cXHUwREM2XFx1MERFNi1cXHUwREVGXFx1MEUwMS1cXHUwRTMwXFx1MEUzMlxcdTBFMzNcXHUwRTQwLVxcdTBFNDZcXHUwRTUwLVxcdTBFNTlcXHUwRTgxXFx1MEU4MlxcdTBFODRcXHUwRTg2LVxcdTBFOEFcXHUwRThDLVxcdTBFQTNcXHUwRUE1XFx1MEVBNy1cXHUwRUIwXFx1MEVCMlxcdTBFQjNcXHUwRUJEXFx1MEVDMC1cXHUwRUM0XFx1MEVDNlxcdTBFRDAtXFx1MEVEOVxcdTBFREMtXFx1MEVERlxcdTBGMDBcXHUwRjIwLVxcdTBGMzNcXHUwRjQwLVxcdTBGNDdcXHUwRjQ5LVxcdTBGNkNcXHUwRjg4LVxcdTBGOENcXHUxMDAwLVxcdTEwMkFcXHUxMDNGLVxcdTEwNDlcXHUxMDUwLVxcdTEwNTVcXHUxMDVBLVxcdTEwNURcXHUxMDYxXFx1MTA2NVxcdTEwNjZcXHUxMDZFLVxcdTEwNzBcXHUxMDc1LVxcdTEwODFcXHUxMDhFXFx1MTA5MC1cXHUxMDk5XFx1MTBBMC1cXHUxMEM1XFx1MTBDN1xcdTEwQ0RcXHUxMEQwLVxcdTEwRkFcXHUxMEZDLVxcdTEyNDhcXHUxMjRBLVxcdTEyNERcXHUxMjUwLVxcdTEyNTZcXHUxMjU4XFx1MTI1QS1cXHUxMjVEXFx1MTI2MC1cXHUxMjg4XFx1MTI4QS1cXHUxMjhEXFx1MTI5MC1cXHUxMkIwXFx1MTJCMi1cXHUxMkI1XFx1MTJCOC1cXHUxMkJFXFx1MTJDMFxcdTEyQzItXFx1MTJDNVxcdTEyQzgtXFx1MTJENlxcdTEyRDgtXFx1MTMxMFxcdTEzMTItXFx1MTMxNVxcdTEzMTgtXFx1MTM1QVxcdTEzNjktXFx1MTM3Q1xcdTEzODAtXFx1MTM4RlxcdTEzQTAtXFx1MTNGNVxcdTEzRjgtXFx1MTNGRFxcdTE0MDEtXFx1MTY2Q1xcdTE2NkYtXFx1MTY3RlxcdTE2ODEtXFx1MTY5QVxcdTE2QTAtXFx1MTZFQVxcdTE2RUUtXFx1MTZGOFxcdTE3MDAtXFx1MTcxMVxcdTE3MUYtXFx1MTczMVxcdTE3NDAtXFx1MTc1MVxcdTE3NjAtXFx1MTc2Q1xcdTE3NkUtXFx1MTc3MFxcdTE3ODAtXFx1MTdCM1xcdTE3RDdcXHUxN0RDXFx1MTdFMC1cXHUxN0U5XFx1MTdGMC1cXHUxN0Y5XFx1MTgxMC1cXHUxODE5XFx1MTgyMC1cXHUxODc4XFx1MTg4MC1cXHUxODg0XFx1MTg4Ny1cXHUxOEE4XFx1MThBQVxcdTE4QjAtXFx1MThGNVxcdTE5MDAtXFx1MTkxRVxcdTE5NDYtXFx1MTk2RFxcdTE5NzAtXFx1MTk3NFxcdTE5ODAtXFx1MTlBQlxcdTE5QjAtXFx1MTlDOVxcdTE5RDAtXFx1MTlEQVxcdTFBMDAtXFx1MUExNlxcdTFBMjAtXFx1MUE1NFxcdTFBODAtXFx1MUE4OVxcdTFBOTAtXFx1MUE5OVxcdTFBQTdcXHUxQjA1LVxcdTFCMzNcXHUxQjQ1LVxcdTFCNENcXHUxQjUwLVxcdTFCNTlcXHUxQjgzLVxcdTFCQTBcXHUxQkFFLVxcdTFCRTVcXHUxQzAwLVxcdTFDMjNcXHUxQzQwLVxcdTFDNDlcXHUxQzRELVxcdTFDN0RcXHUxQzgwLVxcdTFDODhcXHUxQzkwLVxcdTFDQkFcXHUxQ0JELVxcdTFDQkZcXHUxQ0U5LVxcdTFDRUNcXHUxQ0VFLVxcdTFDRjNcXHUxQ0Y1XFx1MUNGNlxcdTFDRkFcXHUxRDAwLVxcdTFEQkZcXHUxRTAwLVxcdTFGMTVcXHUxRjE4LVxcdTFGMURcXHUxRjIwLVxcdTFGNDVcXHUxRjQ4LVxcdTFGNERcXHUxRjUwLVxcdTFGNTdcXHUxRjU5XFx1MUY1QlxcdTFGNURcXHUxRjVGLVxcdTFGN0RcXHUxRjgwLVxcdTFGQjRcXHUxRkI2LVxcdTFGQkNcXHUxRkJFXFx1MUZDMi1cXHUxRkM0XFx1MUZDNi1cXHUxRkNDXFx1MUZEMC1cXHUxRkQzXFx1MUZENi1cXHUxRkRCXFx1MUZFMC1cXHUxRkVDXFx1MUZGMi1cXHUxRkY0XFx1MUZGNi1cXHUxRkZDXFx1MjA3MFxcdTIwNzFcXHUyMDc0LVxcdTIwNzlcXHUyMDdGLVxcdTIwODlcXHUyMDkwLVxcdTIwOUNcXHUyMTAyXFx1MjEwN1xcdTIxMEEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMURcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJBLVxcdTIxMkRcXHUyMTJGLVxcdTIxMzlcXHUyMTNDLVxcdTIxM0ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRFXFx1MjE1MC1cXHUyMTg5XFx1MjQ2MC1cXHUyNDlCXFx1MjRFQS1cXHUyNEZGXFx1Mjc3Ni1cXHUyNzkzXFx1MkMwMC1cXHUyQ0U0XFx1MkNFQi1cXHUyQ0VFXFx1MkNGMlxcdTJDRjNcXHUyQ0ZEXFx1MkQwMC1cXHUyRDI1XFx1MkQyN1xcdTJEMkRcXHUyRDMwLVxcdTJENjdcXHUyRDZGXFx1MkQ4MC1cXHUyRDk2XFx1MkRBMC1cXHUyREE2XFx1MkRBOC1cXHUyREFFXFx1MkRCMC1cXHUyREI2XFx1MkRCOC1cXHUyREJFXFx1MkRDMC1cXHUyREM2XFx1MkRDOC1cXHUyRENFXFx1MkREMC1cXHUyREQ2XFx1MkREOC1cXHUyRERFXFx1MkUyRlxcdTMwMDUtXFx1MzAwN1xcdTMwMjEtXFx1MzAyOVxcdTMwMzEtXFx1MzAzNVxcdTMwMzgtXFx1MzAzQ1xcdTMwNDEtXFx1MzA5NlxcdTMwOUQtXFx1MzA5RlxcdTMwQTEtXFx1MzBGQVxcdTMwRkMtXFx1MzBGRlxcdTMxMDUtXFx1MzEyRlxcdTMxMzEtXFx1MzE4RVxcdTMxOTItXFx1MzE5NVxcdTMxQTAtXFx1MzFCRlxcdTMxRjAtXFx1MzFGRlxcdTMyMjAtXFx1MzIyOVxcdTMyNDgtXFx1MzI0RlxcdTMyNTEtXFx1MzI1RlxcdTMyODAtXFx1MzI4OVxcdTMyQjEtXFx1MzJCRlxcdTM0MDAtXFx1NERCRlxcdTRFMDAtXFx1QTQ4Q1xcdUE0RDAtXFx1QTRGRFxcdUE1MDAtXFx1QTYwQ1xcdUE2MTAtXFx1QTYyQlxcdUE2NDAtXFx1QTY2RVxcdUE2N0YtXFx1QTY5RFxcdUE2QTAtXFx1QTZFRlxcdUE3MTctXFx1QTcxRlxcdUE3MjItXFx1QTc4OFxcdUE3OEItXFx1QTdDQVxcdUE3RDBcXHVBN0QxXFx1QTdEM1xcdUE3RDUtXFx1QTdEOVxcdUE3RjItXFx1QTgwMVxcdUE4MDMtXFx1QTgwNVxcdUE4MDctXFx1QTgwQVxcdUE4MEMtXFx1QTgyMlxcdUE4MzAtXFx1QTgzNVxcdUE4NDAtXFx1QTg3M1xcdUE4ODItXFx1QThCM1xcdUE4RDAtXFx1QThEOVxcdUE4RjItXFx1QThGN1xcdUE4RkJcXHVBOEZEXFx1QThGRVxcdUE5MDAtXFx1QTkyNVxcdUE5MzAtXFx1QTk0NlxcdUE5NjAtXFx1QTk3Q1xcdUE5ODQtXFx1QTlCMlxcdUE5Q0YtXFx1QTlEOVxcdUE5RTAtXFx1QTlFNFxcdUE5RTYtXFx1QTlGRVxcdUFBMDAtXFx1QUEyOFxcdUFBNDAtXFx1QUE0MlxcdUFBNDQtXFx1QUE0QlxcdUFBNTAtXFx1QUE1OVxcdUFBNjAtXFx1QUE3NlxcdUFBN0FcXHVBQTdFLVxcdUFBQUZcXHVBQUIxXFx1QUFCNVxcdUFBQjZcXHVBQUI5LVxcdUFBQkRcXHVBQUMwXFx1QUFDMlxcdUFBREItXFx1QUFERFxcdUFBRTAtXFx1QUFFQVxcdUFBRjItXFx1QUFGNFxcdUFCMDEtXFx1QUIwNlxcdUFCMDktXFx1QUIwRVxcdUFCMTEtXFx1QUIxNlxcdUFCMjAtXFx1QUIyNlxcdUFCMjgtXFx1QUIyRVxcdUFCMzAtXFx1QUI1QVxcdUFCNUMtXFx1QUI2OVxcdUFCNzAtXFx1QUJFMlxcdUFCRjAtXFx1QUJGOVxcdUFDMDAtXFx1RDdBM1xcdUQ3QjAtXFx1RDdDNlxcdUQ3Q0ItXFx1RDdGQlxcdUY5MDAtXFx1RkE2RFxcdUZBNzAtXFx1RkFEOVxcdUZCMDAtXFx1RkIwNlxcdUZCMTMtXFx1RkIxN1xcdUZCMURcXHVGQjFGLVxcdUZCMjhcXHVGQjJBLVxcdUZCMzZcXHVGQjM4LVxcdUZCM0NcXHVGQjNFXFx1RkI0MFxcdUZCNDFcXHVGQjQzXFx1RkI0NFxcdUZCNDYtXFx1RkJCMVxcdUZCRDMtXFx1RkQzRFxcdUZENTAtXFx1RkQ4RlxcdUZEOTItXFx1RkRDN1xcdUZERjAtXFx1RkRGQlxcdUZFNzAtXFx1RkU3NFxcdUZFNzYtXFx1RkVGQ1xcdUZGMTAtXFx1RkYxOVxcdUZGMjEtXFx1RkYzQVxcdUZGNDEtXFx1RkY1QVxcdUZGNjYtXFx1RkZCRVxcdUZGQzItXFx1RkZDN1xcdUZGQ0EtXFx1RkZDRlxcdUZGRDItXFx1RkZEN1xcdUZGREEtXFx1RkZEQ118XFx1RDgwMFtcXHVEQzAwLVxcdURDMEJcXHVEQzBELVxcdURDMjZcXHVEQzI4LVxcdURDM0FcXHVEQzNDXFx1REMzRFxcdURDM0YtXFx1REM0RFxcdURDNTAtXFx1REM1RFxcdURDODAtXFx1RENGQVxcdUREMDctXFx1REQzM1xcdURENDAtXFx1REQ3OFxcdUREOEFcXHVERDhCXFx1REU4MC1cXHVERTlDXFx1REVBMC1cXHVERUQwXFx1REVFMS1cXHVERUZCXFx1REYwMC1cXHVERjIzXFx1REYyRC1cXHVERjRBXFx1REY1MC1cXHVERjc1XFx1REY4MC1cXHVERjlEXFx1REZBMC1cXHVERkMzXFx1REZDOC1cXHVERkNGXFx1REZEMS1cXHVERkQ1XXxcXHVEODAxW1xcdURDMDAtXFx1REM5RFxcdURDQTAtXFx1RENBOVxcdURDQjAtXFx1RENEM1xcdURDRDgtXFx1RENGQlxcdUREMDAtXFx1REQyN1xcdUREMzAtXFx1REQ2M1xcdURENzAtXFx1REQ3QVxcdUREN0MtXFx1REQ4QVxcdUREOEMtXFx1REQ5MlxcdUREOTRcXHVERDk1XFx1REQ5Ny1cXHVEREExXFx1RERBMy1cXHVEREIxXFx1RERCMy1cXHVEREI5XFx1RERCQlxcdUREQkNcXHVERTAwLVxcdURGMzZcXHVERjQwLVxcdURGNTVcXHVERjYwLVxcdURGNjdcXHVERjgwLVxcdURGODVcXHVERjg3LVxcdURGQjBcXHVERkIyLVxcdURGQkFdfFxcdUQ4MDJbXFx1REMwMC1cXHVEQzA1XFx1REMwOFxcdURDMEEtXFx1REMzNVxcdURDMzdcXHVEQzM4XFx1REMzQ1xcdURDM0YtXFx1REM1NVxcdURDNTgtXFx1REM3NlxcdURDNzktXFx1REM5RVxcdURDQTctXFx1RENBRlxcdURDRTAtXFx1RENGMlxcdURDRjRcXHVEQ0Y1XFx1RENGQi1cXHVERDFCXFx1REQyMC1cXHVERDM5XFx1REQ4MC1cXHVEREI3XFx1RERCQy1cXHVERENGXFx1REREMi1cXHVERTAwXFx1REUxMC1cXHVERTEzXFx1REUxNS1cXHVERTE3XFx1REUxOS1cXHVERTM1XFx1REU0MC1cXHVERTQ4XFx1REU2MC1cXHVERTdFXFx1REU4MC1cXHVERTlGXFx1REVDMC1cXHVERUM3XFx1REVDOS1cXHVERUU0XFx1REVFQi1cXHVERUVGXFx1REYwMC1cXHVERjM1XFx1REY0MC1cXHVERjU1XFx1REY1OC1cXHVERjcyXFx1REY3OC1cXHVERjkxXFx1REZBOS1cXHVERkFGXXxcXHVEODAzW1xcdURDMDAtXFx1REM0OFxcdURDODAtXFx1RENCMlxcdURDQzAtXFx1RENGMlxcdURDRkEtXFx1REQyM1xcdUREMzAtXFx1REQzOVxcdURFNjAtXFx1REU3RVxcdURFODAtXFx1REVBOVxcdURFQjBcXHVERUIxXFx1REYwMC1cXHVERjI3XFx1REYzMC1cXHVERjQ1XFx1REY1MS1cXHVERjU0XFx1REY3MC1cXHVERjgxXFx1REZCMC1cXHVERkNCXFx1REZFMC1cXHVERkY2XXxcXHVEODA0W1xcdURDMDMtXFx1REMzN1xcdURDNTItXFx1REM2RlxcdURDNzFcXHVEQzcyXFx1REM3NVxcdURDODMtXFx1RENBRlxcdURDRDAtXFx1RENFOFxcdURDRjAtXFx1RENGOVxcdUREMDMtXFx1REQyNlxcdUREMzYtXFx1REQzRlxcdURENDRcXHVERDQ3XFx1REQ1MC1cXHVERDcyXFx1REQ3NlxcdUREODMtXFx1RERCMlxcdUREQzEtXFx1RERDNFxcdURERDAtXFx1REREQVxcdURERENcXHVEREUxLVxcdURERjRcXHVERTAwLVxcdURFMTFcXHVERTEzLVxcdURFMkJcXHVERTgwLVxcdURFODZcXHVERTg4XFx1REU4QS1cXHVERThEXFx1REU4Ri1cXHVERTlEXFx1REU5Ri1cXHVERUE4XFx1REVCMC1cXHVERURFXFx1REVGMC1cXHVERUY5XFx1REYwNS1cXHVERjBDXFx1REYwRlxcdURGMTBcXHVERjEzLVxcdURGMjhcXHVERjJBLVxcdURGMzBcXHVERjMyXFx1REYzM1xcdURGMzUtXFx1REYzOVxcdURGM0RcXHVERjUwXFx1REY1RC1cXHVERjYxXXxcXHVEODA1W1xcdURDMDAtXFx1REMzNFxcdURDNDctXFx1REM0QVxcdURDNTAtXFx1REM1OVxcdURDNUYtXFx1REM2MVxcdURDODAtXFx1RENBRlxcdURDQzRcXHVEQ0M1XFx1RENDN1xcdURDRDAtXFx1RENEOVxcdUREODAtXFx1RERBRVxcdURERDgtXFx1REREQlxcdURFMDAtXFx1REUyRlxcdURFNDRcXHVERTUwLVxcdURFNTlcXHVERTgwLVxcdURFQUFcXHVERUI4XFx1REVDMC1cXHVERUM5XFx1REYwMC1cXHVERjFBXFx1REYzMC1cXHVERjNCXFx1REY0MC1cXHVERjQ2XXxcXHVEODA2W1xcdURDMDAtXFx1REMyQlxcdURDQTAtXFx1RENGMlxcdURDRkYtXFx1REQwNlxcdUREMDlcXHVERDBDLVxcdUREMTNcXHVERDE1XFx1REQxNlxcdUREMTgtXFx1REQyRlxcdUREM0ZcXHVERDQxXFx1REQ1MC1cXHVERDU5XFx1RERBMC1cXHVEREE3XFx1RERBQS1cXHVEREQwXFx1RERFMVxcdURERTNcXHVERTAwXFx1REUwQi1cXHVERTMyXFx1REUzQVxcdURFNTBcXHVERTVDLVxcdURFODlcXHVERTlEXFx1REVCMC1cXHVERUY4XXxcXHVEODA3W1xcdURDMDAtXFx1REMwOFxcdURDMEEtXFx1REMyRVxcdURDNDBcXHVEQzUwLVxcdURDNkNcXHVEQzcyLVxcdURDOEZcXHVERDAwLVxcdUREMDZcXHVERDA4XFx1REQwOVxcdUREMEItXFx1REQzMFxcdURENDZcXHVERDUwLVxcdURENTlcXHVERDYwLVxcdURENjVcXHVERDY3XFx1REQ2OFxcdURENkEtXFx1REQ4OVxcdUREOThcXHVEREEwLVxcdUREQTlcXHVERUUwLVxcdURFRjJcXHVERkIwXFx1REZDMC1cXHVERkQ0XXxcXHVEODA4W1xcdURDMDAtXFx1REY5OV18XFx1RDgwOVtcXHVEQzAwLVxcdURDNkVcXHVEQzgwLVxcdURENDNdfFxcdUQ4MEJbXFx1REY5MC1cXHVERkYwXXxbXFx1RDgwQ1xcdUQ4MUMtXFx1RDgyMFxcdUQ4MjJcXHVEODQwLVxcdUQ4NjhcXHVEODZBLVxcdUQ4NkNcXHVEODZGLVxcdUQ4NzJcXHVEODc0LVxcdUQ4NzlcXHVEODgwLVxcdUQ4ODNdW1xcdURDMDAtXFx1REZGRl18XFx1RDgwRFtcXHVEQzAwLVxcdURDMkVdfFxcdUQ4MTFbXFx1REMwMC1cXHVERTQ2XXxcXHVEODFBW1xcdURDMDAtXFx1REUzOFxcdURFNDAtXFx1REU1RVxcdURFNjAtXFx1REU2OVxcdURFNzAtXFx1REVCRVxcdURFQzAtXFx1REVDOVxcdURFRDAtXFx1REVFRFxcdURGMDAtXFx1REYyRlxcdURGNDAtXFx1REY0M1xcdURGNTAtXFx1REY1OVxcdURGNUItXFx1REY2MVxcdURGNjMtXFx1REY3N1xcdURGN0QtXFx1REY4Rl18XFx1RDgxQltcXHVERTQwLVxcdURFOTZcXHVERjAwLVxcdURGNEFcXHVERjUwXFx1REY5My1cXHVERjlGXFx1REZFMFxcdURGRTFcXHVERkUzXXxcXHVEODIxW1xcdURDMDAtXFx1REZGN118XFx1RDgyM1tcXHVEQzAwLVxcdURDRDVcXHVERDAwLVxcdUREMDhdfFxcdUQ4MkJbXFx1REZGMC1cXHVERkYzXFx1REZGNS1cXHVERkZCXFx1REZGRFxcdURGRkVdfFxcdUQ4MkNbXFx1REMwMC1cXHVERDIyXFx1REQ1MC1cXHVERDUyXFx1REQ2NC1cXHVERDY3XFx1REQ3MC1cXHVERUZCXXxcXHVEODJGW1xcdURDMDAtXFx1REM2QVxcdURDNzAtXFx1REM3Q1xcdURDODAtXFx1REM4OFxcdURDOTAtXFx1REM5OV18XFx1RDgzNFtcXHVERUUwLVxcdURFRjNcXHVERjYwLVxcdURGNzhdfFxcdUQ4MzVbXFx1REMwMC1cXHVEQzU0XFx1REM1Ni1cXHVEQzlDXFx1REM5RVxcdURDOUZcXHVEQ0EyXFx1RENBNVxcdURDQTZcXHVEQ0E5LVxcdURDQUNcXHVEQ0FFLVxcdURDQjlcXHVEQ0JCXFx1RENCRC1cXHVEQ0MzXFx1RENDNS1cXHVERDA1XFx1REQwNy1cXHVERDBBXFx1REQwRC1cXHVERDE0XFx1REQxNi1cXHVERDFDXFx1REQxRS1cXHVERDM5XFx1REQzQi1cXHVERDNFXFx1REQ0MC1cXHVERDQ0XFx1REQ0NlxcdURENEEtXFx1REQ1MFxcdURENTItXFx1REVBNVxcdURFQTgtXFx1REVDMFxcdURFQzItXFx1REVEQVxcdURFREMtXFx1REVGQVxcdURFRkMtXFx1REYxNFxcdURGMTYtXFx1REYzNFxcdURGMzYtXFx1REY0RVxcdURGNTAtXFx1REY2RVxcdURGNzAtXFx1REY4OFxcdURGOEEtXFx1REZBOFxcdURGQUEtXFx1REZDMlxcdURGQzQtXFx1REZDQlxcdURGQ0UtXFx1REZGRl18XFx1RDgzN1tcXHVERjAwLVxcdURGMUVdfFxcdUQ4MzhbXFx1REQwMC1cXHVERDJDXFx1REQzNy1cXHVERDNEXFx1REQ0MC1cXHVERDQ5XFx1REQ0RVxcdURFOTAtXFx1REVBRFxcdURFQzAtXFx1REVFQlxcdURFRjAtXFx1REVGOV18XFx1RDgzOVtcXHVERkUwLVxcdURGRTZcXHVERkU4LVxcdURGRUJcXHVERkVEXFx1REZFRVxcdURGRjAtXFx1REZGRV18XFx1RDgzQVtcXHVEQzAwLVxcdURDQzRcXHVEQ0M3LVxcdURDQ0ZcXHVERDAwLVxcdURENDNcXHVERDRCXFx1REQ1MC1cXHVERDU5XXxcXHVEODNCW1xcdURDNzEtXFx1RENBQlxcdURDQUQtXFx1RENBRlxcdURDQjEtXFx1RENCNFxcdUREMDEtXFx1REQyRFxcdUREMkYtXFx1REQzRFxcdURFMDAtXFx1REUwM1xcdURFMDUtXFx1REUxRlxcdURFMjFcXHVERTIyXFx1REUyNFxcdURFMjdcXHVERTI5LVxcdURFMzJcXHVERTM0LVxcdURFMzdcXHVERTM5XFx1REUzQlxcdURFNDJcXHVERTQ3XFx1REU0OVxcdURFNEJcXHVERTRELVxcdURFNEZcXHVERTUxXFx1REU1MlxcdURFNTRcXHVERTU3XFx1REU1OVxcdURFNUJcXHVERTVEXFx1REU1RlxcdURFNjFcXHVERTYyXFx1REU2NFxcdURFNjctXFx1REU2QVxcdURFNkMtXFx1REU3MlxcdURFNzQtXFx1REU3N1xcdURFNzktXFx1REU3Q1xcdURFN0VcXHVERTgwLVxcdURFODlcXHVERThCLVxcdURFOUJcXHVERUExLVxcdURFQTNcXHVERUE1LVxcdURFQTlcXHVERUFCLVxcdURFQkJdfFxcdUQ4M0NbXFx1REQwMC1cXHVERDBDXXxcXHVEODNFW1xcdURGRjAtXFx1REZGOV18XFx1RDg2OVtcXHVEQzAwLVxcdURFREZcXHVERjAwLVxcdURGRkZdfFxcdUQ4NkRbXFx1REMwMC1cXHVERjM4XFx1REY0MC1cXHVERkZGXXxcXHVEODZFW1xcdURDMDAtXFx1REMxRFxcdURDMjAtXFx1REZGRl18XFx1RDg3M1tcXHVEQzAwLVxcdURFQTFcXHVERUIwLVxcdURGRkZdfFxcdUQ4N0FbXFx1REMwMC1cXHVERkUwXXxcXHVEODdFW1xcdURDMDAtXFx1REUxRF18XFx1RDg4NFtcXHVEQzAwLVxcdURGNEFdKS8pKSByZXR1cm47XG4gICAgdmFyIG5leHRDaGFyID0gbWF0Y2hbMV0gfHwgbWF0Y2hbMl0gfHwgJyc7XG4gICAgaWYgKCFuZXh0Q2hhciB8fCBuZXh0Q2hhciAmJiAocHJldkNoYXIgPT09ICcnIHx8IHRoaXMucnVsZXMuaW5saW5lLnB1bmN0dWF0aW9uLmV4ZWMocHJldkNoYXIpKSkge1xuICAgICAgdmFyIGxMZW5ndGggPSBtYXRjaFswXS5sZW5ndGggLSAxO1xuICAgICAgdmFyIHJEZWxpbSxcbiAgICAgICAgckxlbmd0aCxcbiAgICAgICAgZGVsaW1Ub3RhbCA9IGxMZW5ndGgsXG4gICAgICAgIG1pZERlbGltVG90YWwgPSAwO1xuICAgICAgdmFyIGVuZFJlZyA9IG1hdGNoWzBdWzBdID09PSAnKicgPyB0aGlzLnJ1bGVzLmlubGluZS5lbVN0cm9uZy5yRGVsaW1Bc3QgOiB0aGlzLnJ1bGVzLmlubGluZS5lbVN0cm9uZy5yRGVsaW1VbmQ7XG4gICAgICBlbmRSZWcubGFzdEluZGV4ID0gMDtcblxuICAgICAgLy8gQ2xpcCBtYXNrZWRTcmMgdG8gc2FtZSBzZWN0aW9uIG9mIHN0cmluZyBhcyBzcmMgKG1vdmUgdG8gbGV4ZXI/KVxuICAgICAgbWFza2VkU3JjID0gbWFza2VkU3JjLnNsaWNlKC0xICogc3JjLmxlbmd0aCArIGxMZW5ndGgpO1xuICAgICAgd2hpbGUgKChtYXRjaCA9IGVuZFJlZy5leGVjKG1hc2tlZFNyYykpICE9IG51bGwpIHtcbiAgICAgICAgckRlbGltID0gbWF0Y2hbMV0gfHwgbWF0Y2hbMl0gfHwgbWF0Y2hbM10gfHwgbWF0Y2hbNF0gfHwgbWF0Y2hbNV0gfHwgbWF0Y2hbNl07XG4gICAgICAgIGlmICghckRlbGltKSBjb250aW51ZTsgLy8gc2tpcCBzaW5nbGUgKiBpbiBfX2FiYyphYmNfX1xuXG4gICAgICAgIHJMZW5ndGggPSByRGVsaW0ubGVuZ3RoO1xuICAgICAgICBpZiAobWF0Y2hbM10gfHwgbWF0Y2hbNF0pIHtcbiAgICAgICAgICAvLyBmb3VuZCBhbm90aGVyIExlZnQgRGVsaW1cbiAgICAgICAgICBkZWxpbVRvdGFsICs9IHJMZW5ndGg7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSBpZiAobWF0Y2hbNV0gfHwgbWF0Y2hbNl0pIHtcbiAgICAgICAgICAvLyBlaXRoZXIgTGVmdCBvciBSaWdodCBEZWxpbVxuICAgICAgICAgIGlmIChsTGVuZ3RoICUgMyAmJiAhKChsTGVuZ3RoICsgckxlbmd0aCkgJSAzKSkge1xuICAgICAgICAgICAgbWlkRGVsaW1Ub3RhbCArPSByTGVuZ3RoO1xuICAgICAgICAgICAgY29udGludWU7IC8vIENvbW1vbk1hcmsgRW1waGFzaXMgUnVsZXMgOS0xMFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGltVG90YWwgLT0gckxlbmd0aDtcbiAgICAgICAgaWYgKGRlbGltVG90YWwgPiAwKSBjb250aW51ZTsgLy8gSGF2ZW4ndCBmb3VuZCBlbm91Z2ggY2xvc2luZyBkZWxpbWl0ZXJzXG5cbiAgICAgICAgLy8gUmVtb3ZlIGV4dHJhIGNoYXJhY3RlcnMuICphKioqIC0+ICphKlxuICAgICAgICByTGVuZ3RoID0gTWF0aC5taW4ockxlbmd0aCwgckxlbmd0aCArIGRlbGltVG90YWwgKyBtaWREZWxpbVRvdGFsKTtcbiAgICAgICAgdmFyIHJhdyA9IHNyYy5zbGljZSgwLCBsTGVuZ3RoICsgbWF0Y2guaW5kZXggKyAobWF0Y2hbMF0ubGVuZ3RoIC0gckRlbGltLmxlbmd0aCkgKyByTGVuZ3RoKTtcblxuICAgICAgICAvLyBDcmVhdGUgYGVtYCBpZiBzbWFsbGVzdCBkZWxpbWl0ZXIgaGFzIG9kZCBjaGFyIGNvdW50LiAqYSoqKlxuICAgICAgICBpZiAoTWF0aC5taW4obExlbmd0aCwgckxlbmd0aCkgJSAyKSB7XG4gICAgICAgICAgdmFyIF90ZXh0ID0gcmF3LnNsaWNlKDEsIC0xKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2VtJyxcbiAgICAgICAgICAgIHJhdzogcmF3LFxuICAgICAgICAgICAgdGV4dDogX3RleHQsXG4gICAgICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lVG9rZW5zKF90ZXh0KVxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgJ3N0cm9uZycgaWYgc21hbGxlc3QgZGVsaW1pdGVyIGhhcyBldmVuIGNoYXIgY291bnQuICoqYSoqKlxuICAgICAgICB2YXIgdGV4dCA9IHJhdy5zbGljZSgyLCAtMik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogJ3N0cm9uZycsXG4gICAgICAgICAgcmF3OiByYXcsXG4gICAgICAgICAgdGV4dDogdGV4dCxcbiAgICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lVG9rZW5zKHRleHQpXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9O1xuICBfcHJvdG8uY29kZXNwYW4gPSBmdW5jdGlvbiBjb2Rlc3BhbihzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUuY29kZS5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHRleHQgPSBjYXBbMl0ucmVwbGFjZSgvXFxuL2csICcgJyk7XG4gICAgICB2YXIgaGFzTm9uU3BhY2VDaGFycyA9IC9bXiBdLy50ZXN0KHRleHQpO1xuICAgICAgdmFyIGhhc1NwYWNlQ2hhcnNPbkJvdGhFbmRzID0gL14gLy50ZXN0KHRleHQpICYmIC8gJC8udGVzdCh0ZXh0KTtcbiAgICAgIGlmIChoYXNOb25TcGFjZUNoYXJzICYmIGhhc1NwYWNlQ2hhcnNPbkJvdGhFbmRzKSB7XG4gICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZygxLCB0ZXh0Lmxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgICAgdGV4dCA9IGVzY2FwZSh0ZXh0LCB0cnVlKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdjb2Rlc3BhbicsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0OiB0ZXh0XG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmJyID0gZnVuY3Rpb24gYnIoc3JjKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLmJyLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnYnInLFxuICAgICAgICByYXc6IGNhcFswXVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5kZWwgPSBmdW5jdGlvbiBkZWwoc3JjKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLmRlbC5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2RlbCcsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0OiBjYXBbMl0sXG4gICAgICAgIHRva2VuczogdGhpcy5sZXhlci5pbmxpbmVUb2tlbnMoY2FwWzJdKVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5hdXRvbGluayA9IGZ1bmN0aW9uIGF1dG9saW5rKHNyYywgbWFuZ2xlKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLmF1dG9saW5rLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgdGV4dCwgaHJlZjtcbiAgICAgIGlmIChjYXBbMl0gPT09ICdAJykge1xuICAgICAgICB0ZXh0ID0gZXNjYXBlKHRoaXMub3B0aW9ucy5tYW5nbGUgPyBtYW5nbGUoY2FwWzFdKSA6IGNhcFsxXSk7XG4gICAgICAgIGhyZWYgPSAnbWFpbHRvOicgKyB0ZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGV4dCA9IGVzY2FwZShjYXBbMV0pO1xuICAgICAgICBocmVmID0gdGV4dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdsaW5rJyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIHRleHQ6IHRleHQsXG4gICAgICAgIGhyZWY6IGhyZWYsXG4gICAgICAgIHRva2VuczogW3tcbiAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgcmF3OiB0ZXh0LFxuICAgICAgICAgIHRleHQ6IHRleHRcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8udXJsID0gZnVuY3Rpb24gdXJsKHNyYywgbWFuZ2xlKSB7XG4gICAgdmFyIGNhcDtcbiAgICBpZiAoY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUudXJsLmV4ZWMoc3JjKSkge1xuICAgICAgdmFyIHRleHQsIGhyZWY7XG4gICAgICBpZiAoY2FwWzJdID09PSAnQCcpIHtcbiAgICAgICAgdGV4dCA9IGVzY2FwZSh0aGlzLm9wdGlvbnMubWFuZ2xlID8gbWFuZ2xlKGNhcFswXSkgOiBjYXBbMF0pO1xuICAgICAgICBocmVmID0gJ21haWx0bzonICsgdGV4dDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGRvIGV4dGVuZGVkIGF1dG9saW5rIHBhdGggdmFsaWRhdGlvblxuICAgICAgICB2YXIgcHJldkNhcFplcm87XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBwcmV2Q2FwWmVybyA9IGNhcFswXTtcbiAgICAgICAgICBjYXBbMF0gPSB0aGlzLnJ1bGVzLmlubGluZS5fYmFja3BlZGFsLmV4ZWMoY2FwWzBdKVswXTtcbiAgICAgICAgfSB3aGlsZSAocHJldkNhcFplcm8gIT09IGNhcFswXSk7XG4gICAgICAgIHRleHQgPSBlc2NhcGUoY2FwWzBdKTtcbiAgICAgICAgaWYgKGNhcFsxXSA9PT0gJ3d3dy4nKSB7XG4gICAgICAgICAgaHJlZiA9ICdodHRwOi8vJyArIGNhcFswXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBocmVmID0gY2FwWzBdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnbGluaycsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICBocmVmOiBocmVmLFxuICAgICAgICB0b2tlbnM6IFt7XG4gICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgIHJhdzogdGV4dCxcbiAgICAgICAgICB0ZXh0OiB0ZXh0XG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmlubGluZVRleHQgPSBmdW5jdGlvbiBpbmxpbmVUZXh0KHNyYywgc21hcnR5cGFudHMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUudGV4dC5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHRleHQ7XG4gICAgICBpZiAodGhpcy5sZXhlci5zdGF0ZS5pblJhd0Jsb2NrKSB7XG4gICAgICAgIHRleHQgPSB0aGlzLm9wdGlvbnMuc2FuaXRpemUgPyB0aGlzLm9wdGlvbnMuc2FuaXRpemVyID8gdGhpcy5vcHRpb25zLnNhbml0aXplcihjYXBbMF0pIDogZXNjYXBlKGNhcFswXSkgOiBjYXBbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZXh0ID0gZXNjYXBlKHRoaXMub3B0aW9ucy5zbWFydHlwYW50cyA/IHNtYXJ0eXBhbnRzKGNhcFswXSkgOiBjYXBbMF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgdGV4dDogdGV4dFxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIHJldHVybiBUb2tlbml6ZXI7XG59KCk7XG5cbi8qKlxuICogQmxvY2stTGV2ZWwgR3JhbW1hclxuICovXG52YXIgYmxvY2sgPSB7XG4gIG5ld2xpbmU6IC9eKD86ICooPzpcXG58JCkpKy8sXG4gIGNvZGU6IC9eKCB7NH1bXlxcbl0rKD86XFxuKD86ICooPzpcXG58JCkpKik/KSsvLFxuICBmZW5jZXM6IC9eIHswLDN9KGB7Myx9KD89W15gXFxuXSpcXG4pfH57Myx9KShbXlxcbl0qKVxcbig/OnwoW1xcc1xcU10qPylcXG4pKD86IHswLDN9XFwxW35gXSogKig/PVxcbnwkKXwkKS8sXG4gIGhyOiAvXiB7MCwzfSgoPzotW1xcdCBdKil7Myx9fCg/Ol9bIFxcdF0qKXszLH18KD86XFwqWyBcXHRdKil7Myx9KSg/Olxcbit8JCkvLFxuICBoZWFkaW5nOiAvXiB7MCwzfSgjezEsNn0pKD89XFxzfCQpKC4qKSg/Olxcbit8JCkvLFxuICBibG9ja3F1b3RlOiAvXiggezAsM30+ID8ocGFyYWdyYXBofFteXFxuXSopKD86XFxufCQpKSsvLFxuICBsaXN0OiAvXiggezAsM31idWxsKShbIFxcdF1bXlxcbl0rPyk/KD86XFxufCQpLyxcbiAgaHRtbDogJ14gezAsM30oPzonIC8vIG9wdGlvbmFsIGluZGVudGF0aW9uXG4gICsgJzwoc2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYSlbXFxcXHM+XVtcXFxcc1xcXFxTXSo/KD86PC9cXFxcMT5bXlxcXFxuXSpcXFxcbit8JCknIC8vICgxKVxuICArICd8Y29tbWVudFteXFxcXG5dKihcXFxcbit8JCknIC8vICgyKVxuICArICd8PFxcXFw/W1xcXFxzXFxcXFNdKj8oPzpcXFxcPz5cXFxcbip8JCknIC8vICgzKVxuICArICd8PCFbQS1aXVtcXFxcc1xcXFxTXSo/KD86PlxcXFxuKnwkKScgLy8gKDQpXG4gICsgJ3w8IVxcXFxbQ0RBVEFcXFxcW1tcXFxcc1xcXFxTXSo/KD86XFxcXF1cXFxcXT5cXFxcbip8JCknIC8vICg1KVxuICArICd8PC8/KHRhZykoPzogK3xcXFxcbnwvPz4pW1xcXFxzXFxcXFNdKj8oPzooPzpcXFxcbiAqKStcXFxcbnwkKScgLy8gKDYpXG4gICsgJ3w8KD8hc2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYSkoW2Etel1bXFxcXHctXSopKD86YXR0cmlidXRlKSo/ICovPz4oPz1bIFxcXFx0XSooPzpcXFxcbnwkKSlbXFxcXHNcXFxcU10qPyg/Oig/OlxcXFxuICopK1xcXFxufCQpJyAvLyAoNykgb3BlbiB0YWdcbiAgKyAnfDwvKD8hc2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYSlbYS16XVtcXFxcdy1dKlxcXFxzKj4oPz1bIFxcXFx0XSooPzpcXFxcbnwkKSlbXFxcXHNcXFxcU10qPyg/Oig/OlxcXFxuICopK1xcXFxufCQpJyAvLyAoNykgY2xvc2luZyB0YWdcbiAgKyAnKScsXG4gIGRlZjogL14gezAsM31cXFsobGFiZWwpXFxdOiAqKD86XFxuICopPyhbXjxcXHNdW15cXHNdKnw8Lio/PikoPzooPzogKyg/OlxcbiAqKT98ICpcXG4gKikodGl0bGUpKT8gKig/Olxcbit8JCkvLFxuICB0YWJsZTogbm9vcFRlc3QsXG4gIGxoZWFkaW5nOiAvXigoPzoufFxcbig/IVxcbikpKz8pXFxuIHswLDN9KD0rfC0rKSAqKD86XFxuK3wkKS8sXG4gIC8vIHJlZ2V4IHRlbXBsYXRlLCBwbGFjZWhvbGRlcnMgd2lsbCBiZSByZXBsYWNlZCBhY2NvcmRpbmcgdG8gZGlmZmVyZW50IHBhcmFncmFwaFxuICAvLyBpbnRlcnJ1cHRpb24gcnVsZXMgb2YgY29tbW9ubWFyayBhbmQgdGhlIG9yaWdpbmFsIG1hcmtkb3duIHNwZWM6XG4gIF9wYXJhZ3JhcGg6IC9eKFteXFxuXSsoPzpcXG4oPyFocnxoZWFkaW5nfGxoZWFkaW5nfGJsb2NrcXVvdGV8ZmVuY2VzfGxpc3R8aHRtbHx0YWJsZXwgK1xcbilbXlxcbl0rKSopLyxcbiAgdGV4dDogL15bXlxcbl0rL1xufTtcbmJsb2NrLl9sYWJlbCA9IC8oPyFcXHMqXFxdKSg/OlxcXFwufFteXFxbXFxdXFxcXF0pKy87XG5ibG9jay5fdGl0bGUgPSAvKD86XCIoPzpcXFxcXCI/fFteXCJcXFxcXSkqXCJ8J1teJ1xcbl0qKD86XFxuW14nXFxuXSspKlxcbj8nfFxcKFteKCldKlxcKSkvO1xuYmxvY2suZGVmID0gZWRpdChibG9jay5kZWYpLnJlcGxhY2UoJ2xhYmVsJywgYmxvY2suX2xhYmVsKS5yZXBsYWNlKCd0aXRsZScsIGJsb2NrLl90aXRsZSkuZ2V0UmVnZXgoKTtcbmJsb2NrLmJ1bGxldCA9IC8oPzpbKistXXxcXGR7MSw5fVsuKV0pLztcbmJsb2NrLmxpc3RJdGVtU3RhcnQgPSBlZGl0KC9eKCAqKShidWxsKSAqLykucmVwbGFjZSgnYnVsbCcsIGJsb2NrLmJ1bGxldCkuZ2V0UmVnZXgoKTtcbmJsb2NrLmxpc3QgPSBlZGl0KGJsb2NrLmxpc3QpLnJlcGxhY2UoL2J1bGwvZywgYmxvY2suYnVsbGV0KS5yZXBsYWNlKCdocicsICdcXFxcbisoPz1cXFxcMT8oPzooPzotICopezMsfXwoPzpfICopezMsfXwoPzpcXFxcKiAqKXszLH0pKD86XFxcXG4rfCQpKScpLnJlcGxhY2UoJ2RlZicsICdcXFxcbisoPz0nICsgYmxvY2suZGVmLnNvdXJjZSArICcpJykuZ2V0UmVnZXgoKTtcbmJsb2NrLl90YWcgPSAnYWRkcmVzc3xhcnRpY2xlfGFzaWRlfGJhc2V8YmFzZWZvbnR8YmxvY2txdW90ZXxib2R5fGNhcHRpb24nICsgJ3xjZW50ZXJ8Y29sfGNvbGdyb3VwfGRkfGRldGFpbHN8ZGlhbG9nfGRpcnxkaXZ8ZGx8ZHR8ZmllbGRzZXR8ZmlnY2FwdGlvbicgKyAnfGZpZ3VyZXxmb290ZXJ8Zm9ybXxmcmFtZXxmcmFtZXNldHxoWzEtNl18aGVhZHxoZWFkZXJ8aHJ8aHRtbHxpZnJhbWUnICsgJ3xsZWdlbmR8bGl8bGlua3xtYWlufG1lbnV8bWVudWl0ZW18bWV0YXxuYXZ8bm9mcmFtZXN8b2x8b3B0Z3JvdXB8b3B0aW9uJyArICd8cHxwYXJhbXxzZWN0aW9ufHNvdXJjZXxzdW1tYXJ5fHRhYmxlfHRib2R5fHRkfHRmb290fHRofHRoZWFkfHRpdGxlfHRyJyArICd8dHJhY2t8dWwnO1xuYmxvY2suX2NvbW1lbnQgPSAvPCEtLSg/IS0/PilbXFxzXFxTXSo/KD86LS0+fCQpLztcbmJsb2NrLmh0bWwgPSBlZGl0KGJsb2NrLmh0bWwsICdpJykucmVwbGFjZSgnY29tbWVudCcsIGJsb2NrLl9jb21tZW50KS5yZXBsYWNlKCd0YWcnLCBibG9jay5fdGFnKS5yZXBsYWNlKCdhdHRyaWJ1dGUnLCAvICtbYS16QS1aOl9dW1xcdy46LV0qKD86ICo9ICpcIlteXCJcXG5dKlwifCAqPSAqJ1teJ1xcbl0qJ3wgKj0gKlteXFxzXCInPTw+YF0rKT8vKS5nZXRSZWdleCgpO1xuYmxvY2sucGFyYWdyYXBoID0gZWRpdChibG9jay5fcGFyYWdyYXBoKS5yZXBsYWNlKCdocicsIGJsb2NrLmhyKS5yZXBsYWNlKCdoZWFkaW5nJywgJyB7MCwzfSN7MSw2fSAnKS5yZXBsYWNlKCd8bGhlYWRpbmcnLCAnJykgLy8gc2V0ZXggaGVhZGluZ3MgZG9uJ3QgaW50ZXJydXB0IGNvbW1vbm1hcmsgcGFyYWdyYXBoc1xuLnJlcGxhY2UoJ3x0YWJsZScsICcnKS5yZXBsYWNlKCdibG9ja3F1b3RlJywgJyB7MCwzfT4nKS5yZXBsYWNlKCdmZW5jZXMnLCAnIHswLDN9KD86YHszLH0oPz1bXmBcXFxcbl0qXFxcXG4pfH57Myx9KVteXFxcXG5dKlxcXFxuJykucmVwbGFjZSgnbGlzdCcsICcgezAsM30oPzpbKistXXwxWy4pXSkgJykgLy8gb25seSBsaXN0cyBzdGFydGluZyBmcm9tIDEgY2FuIGludGVycnVwdFxuLnJlcGxhY2UoJ2h0bWwnLCAnPC8/KD86dGFnKSg/OiArfFxcXFxufC8/Pil8PCg/OnNjcmlwdHxwcmV8c3R5bGV8dGV4dGFyZWF8IS0tKScpLnJlcGxhY2UoJ3RhZycsIGJsb2NrLl90YWcpIC8vIHBhcnMgY2FuIGJlIGludGVycnVwdGVkIGJ5IHR5cGUgKDYpIGh0bWwgYmxvY2tzXG4uZ2V0UmVnZXgoKTtcbmJsb2NrLmJsb2NrcXVvdGUgPSBlZGl0KGJsb2NrLmJsb2NrcXVvdGUpLnJlcGxhY2UoJ3BhcmFncmFwaCcsIGJsb2NrLnBhcmFncmFwaCkuZ2V0UmVnZXgoKTtcblxuLyoqXG4gKiBOb3JtYWwgQmxvY2sgR3JhbW1hclxuICovXG5cbmJsb2NrLm5vcm1hbCA9IG1lcmdlKHt9LCBibG9jayk7XG5cbi8qKlxuICogR0ZNIEJsb2NrIEdyYW1tYXJcbiAqL1xuXG5ibG9jay5nZm0gPSBtZXJnZSh7fSwgYmxvY2subm9ybWFsLCB7XG4gIHRhYmxlOiAnXiAqKFteXFxcXG4gXS4qXFxcXHwuKilcXFxcbicgLy8gSGVhZGVyXG4gICsgJyB7MCwzfSg/OlxcXFx8ICopPyg6Py0rOj8gKig/OlxcXFx8ICo6Py0rOj8gKikqKSg/OlxcXFx8ICopPycgLy8gQWxpZ25cbiAgKyAnKD86XFxcXG4oKD86KD8hICpcXFxcbnxocnxoZWFkaW5nfGJsb2NrcXVvdGV8Y29kZXxmZW5jZXN8bGlzdHxodG1sKS4qKD86XFxcXG58JCkpKilcXFxcbip8JCknIC8vIENlbGxzXG59KTtcblxuYmxvY2suZ2ZtLnRhYmxlID0gZWRpdChibG9jay5nZm0udGFibGUpLnJlcGxhY2UoJ2hyJywgYmxvY2suaHIpLnJlcGxhY2UoJ2hlYWRpbmcnLCAnIHswLDN9I3sxLDZ9ICcpLnJlcGxhY2UoJ2Jsb2NrcXVvdGUnLCAnIHswLDN9PicpLnJlcGxhY2UoJ2NvZGUnLCAnIHs0fVteXFxcXG5dJykucmVwbGFjZSgnZmVuY2VzJywgJyB7MCwzfSg/OmB7Myx9KD89W15gXFxcXG5dKlxcXFxuKXx+ezMsfSlbXlxcXFxuXSpcXFxcbicpLnJlcGxhY2UoJ2xpc3QnLCAnIHswLDN9KD86WyorLV18MVsuKV0pICcpIC8vIG9ubHkgbGlzdHMgc3RhcnRpbmcgZnJvbSAxIGNhbiBpbnRlcnJ1cHRcbi5yZXBsYWNlKCdodG1sJywgJzwvPyg/OnRhZykoPzogK3xcXFxcbnwvPz4pfDwoPzpzY3JpcHR8cHJlfHN0eWxlfHRleHRhcmVhfCEtLSknKS5yZXBsYWNlKCd0YWcnLCBibG9jay5fdGFnKSAvLyB0YWJsZXMgY2FuIGJlIGludGVycnVwdGVkIGJ5IHR5cGUgKDYpIGh0bWwgYmxvY2tzXG4uZ2V0UmVnZXgoKTtcbmJsb2NrLmdmbS5wYXJhZ3JhcGggPSBlZGl0KGJsb2NrLl9wYXJhZ3JhcGgpLnJlcGxhY2UoJ2hyJywgYmxvY2suaHIpLnJlcGxhY2UoJ2hlYWRpbmcnLCAnIHswLDN9I3sxLDZ9ICcpLnJlcGxhY2UoJ3xsaGVhZGluZycsICcnKSAvLyBzZXRleCBoZWFkaW5ncyBkb24ndCBpbnRlcnJ1cHQgY29tbW9ubWFyayBwYXJhZ3JhcGhzXG4ucmVwbGFjZSgndGFibGUnLCBibG9jay5nZm0udGFibGUpIC8vIGludGVycnVwdCBwYXJhZ3JhcGhzIHdpdGggdGFibGVcbi5yZXBsYWNlKCdibG9ja3F1b3RlJywgJyB7MCwzfT4nKS5yZXBsYWNlKCdmZW5jZXMnLCAnIHswLDN9KD86YHszLH0oPz1bXmBcXFxcbl0qXFxcXG4pfH57Myx9KVteXFxcXG5dKlxcXFxuJykucmVwbGFjZSgnbGlzdCcsICcgezAsM30oPzpbKistXXwxWy4pXSkgJykgLy8gb25seSBsaXN0cyBzdGFydGluZyBmcm9tIDEgY2FuIGludGVycnVwdFxuLnJlcGxhY2UoJ2h0bWwnLCAnPC8/KD86dGFnKSg/OiArfFxcXFxufC8/Pil8PCg/OnNjcmlwdHxwcmV8c3R5bGV8dGV4dGFyZWF8IS0tKScpLnJlcGxhY2UoJ3RhZycsIGJsb2NrLl90YWcpIC8vIHBhcnMgY2FuIGJlIGludGVycnVwdGVkIGJ5IHR5cGUgKDYpIGh0bWwgYmxvY2tzXG4uZ2V0UmVnZXgoKTtcbi8qKlxuICogUGVkYW50aWMgZ3JhbW1hciAob3JpZ2luYWwgSm9obiBHcnViZXIncyBsb29zZSBtYXJrZG93biBzcGVjaWZpY2F0aW9uKVxuICovXG5cbmJsb2NrLnBlZGFudGljID0gbWVyZ2Uoe30sIGJsb2NrLm5vcm1hbCwge1xuICBodG1sOiBlZGl0KCdeICooPzpjb21tZW50ICooPzpcXFxcbnxcXFxccyokKScgKyAnfDwodGFnKVtcXFxcc1xcXFxTXSs/PC9cXFxcMT4gKig/OlxcXFxuezIsfXxcXFxccyokKScgLy8gY2xvc2VkIHRhZ1xuICArICd8PHRhZyg/OlwiW15cIl0qXCJ8XFwnW15cXCddKlxcJ3xcXFxcc1teXFwnXCIvPlxcXFxzXSopKj8vPz4gKig/OlxcXFxuezIsfXxcXFxccyokKSknKS5yZXBsYWNlKCdjb21tZW50JywgYmxvY2suX2NvbW1lbnQpLnJlcGxhY2UoL3RhZy9nLCAnKD8hKD86JyArICdhfGVtfHN0cm9uZ3xzbWFsbHxzfGNpdGV8cXxkZm58YWJicnxkYXRhfHRpbWV8Y29kZXx2YXJ8c2FtcHxrYmR8c3ViJyArICd8c3VwfGl8Ynx1fG1hcmt8cnVieXxydHxycHxiZGl8YmRvfHNwYW58YnJ8d2JyfGluc3xkZWx8aW1nKScgKyAnXFxcXGIpXFxcXHcrKD8hOnxbXlxcXFx3XFxcXHNAXSpAKVxcXFxiJykuZ2V0UmVnZXgoKSxcbiAgZGVmOiAvXiAqXFxbKFteXFxdXSspXFxdOiAqPD8oW15cXHM+XSspPj8oPzogKyhbXCIoXVteXFxuXStbXCIpXSkpPyAqKD86XFxuK3wkKS8sXG4gIGhlYWRpbmc6IC9eKCN7MSw2fSkoLiopKD86XFxuK3wkKS8sXG4gIGZlbmNlczogbm9vcFRlc3QsXG4gIC8vIGZlbmNlcyBub3Qgc3VwcG9ydGVkXG4gIGxoZWFkaW5nOiAvXiguKz8pXFxuIHswLDN9KD0rfC0rKSAqKD86XFxuK3wkKS8sXG4gIHBhcmFncmFwaDogZWRpdChibG9jay5ub3JtYWwuX3BhcmFncmFwaCkucmVwbGFjZSgnaHInLCBibG9jay5ocikucmVwbGFjZSgnaGVhZGluZycsICcgKiN7MSw2fSAqW15cXG5dJykucmVwbGFjZSgnbGhlYWRpbmcnLCBibG9jay5saGVhZGluZykucmVwbGFjZSgnYmxvY2txdW90ZScsICcgezAsM30+JykucmVwbGFjZSgnfGZlbmNlcycsICcnKS5yZXBsYWNlKCd8bGlzdCcsICcnKS5yZXBsYWNlKCd8aHRtbCcsICcnKS5nZXRSZWdleCgpXG59KTtcblxuLyoqXG4gKiBJbmxpbmUtTGV2ZWwgR3JhbW1hclxuICovXG52YXIgaW5saW5lID0ge1xuICBlc2NhcGU6IC9eXFxcXChbIVwiIyQlJicoKSorLFxcLS4vOjs8PT4/QFxcW1xcXVxcXFxeX2B7fH1+XSkvLFxuICBhdXRvbGluazogL148KHNjaGVtZTpbXlxcc1xceDAwLVxceDFmPD5dKnxlbWFpbCk+LyxcbiAgdXJsOiBub29wVGVzdCxcbiAgdGFnOiAnXmNvbW1lbnQnICsgJ3xePC9bYS16QS1aXVtcXFxcdzotXSpcXFxccyo+JyAvLyBzZWxmLWNsb3NpbmcgdGFnXG4gICsgJ3xePFthLXpBLVpdW1xcXFx3LV0qKD86YXR0cmlidXRlKSo/XFxcXHMqLz8+JyAvLyBvcGVuIHRhZ1xuICArICd8XjxcXFxcP1tcXFxcc1xcXFxTXSo/XFxcXD8+JyAvLyBwcm9jZXNzaW5nIGluc3RydWN0aW9uLCBlLmcuIDw/cGhwID8+XG4gICsgJ3xePCFbYS16QS1aXStcXFxcc1tcXFxcc1xcXFxTXSo/PicgLy8gZGVjbGFyYXRpb24sIGUuZy4gPCFET0NUWVBFIGh0bWw+XG4gICsgJ3xePCFcXFxcW0NEQVRBXFxcXFtbXFxcXHNcXFxcU10qP1xcXFxdXFxcXF0+JyxcbiAgLy8gQ0RBVEEgc2VjdGlvblxuICBsaW5rOiAvXiE/XFxbKGxhYmVsKVxcXVxcKFxccyooaHJlZikoPzpcXHMrKHRpdGxlKSk/XFxzKlxcKS8sXG4gIHJlZmxpbms6IC9eIT9cXFsobGFiZWwpXFxdXFxbKHJlZilcXF0vLFxuICBub2xpbms6IC9eIT9cXFsocmVmKVxcXSg/OlxcW1xcXSk/LyxcbiAgcmVmbGlua1NlYXJjaDogJ3JlZmxpbmt8bm9saW5rKD8hXFxcXCgpJyxcbiAgZW1TdHJvbmc6IHtcbiAgICBsRGVsaW06IC9eKD86XFwqKyg/OihbcHVuY3RfXSl8W15cXHMqXSkpfF5fKyg/OihbcHVuY3QqXSl8KFteXFxzX10pKS8sXG4gICAgLy8gICAgICAgICgxKSBhbmQgKDIpIGNhbiBvbmx5IGJlIGEgUmlnaHQgRGVsaW1pdGVyLiAoMykgYW5kICg0KSBjYW4gb25seSBiZSBMZWZ0LiAgKDUpIGFuZCAoNikgY2FuIGJlIGVpdGhlciBMZWZ0IG9yIFJpZ2h0LlxuICAgIC8vICAgICAgICAgICgpIFNraXAgb3JwaGFuIGluc2lkZSBzdHJvbmcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgpIENvbnN1bWUgdG8gZGVsaW0gICAgICgxKSAjKioqICAgICAgICAgICAgICAgICgyKSBhKioqIywgYSoqKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDMpICMqKiphLCAqKiphICAgICAgICAgICAgICAgICAoNCkgKioqIyAgICAgICAgICAgICAgKDUpICMqKiojICAgICAgICAgICAgICAgICAoNikgYSoqKmFcbiAgICByRGVsaW1Bc3Q6IC9eKD86W15fKlxcXFxdfFxcXFwuKSo/XFxfXFxfKD86W15fKlxcXFxdfFxcXFwuKSo/XFwqKD86W15fKlxcXFxdfFxcXFwuKSo/KD89XFxfXFxfKXwoPzpbXipcXFxcXXxcXFxcLikrKD89W14qXSl8W3B1bmN0X10oXFwqKykoPz1bXFxzXXwkKXwoPzpbXnB1bmN0Kl9cXHNcXFxcXXxcXFxcLikoXFwqKykoPz1bcHVuY3RfXFxzXXwkKXxbcHVuY3RfXFxzXShcXCorKSg/PVtecHVuY3QqX1xcc10pfFtcXHNdKFxcKispKD89W3B1bmN0X10pfFtwdW5jdF9dKFxcKispKD89W3B1bmN0X10pfCg/OltecHVuY3QqX1xcc1xcXFxdfFxcXFwuKShcXCorKSg/PVtecHVuY3QqX1xcc10pLyxcbiAgICByRGVsaW1VbmQ6IC9eKD86W15fKlxcXFxdfFxcXFwuKSo/XFwqXFwqKD86W15fKlxcXFxdfFxcXFwuKSo/XFxfKD86W15fKlxcXFxdfFxcXFwuKSo/KD89XFwqXFwqKXwoPzpbXl9cXFxcXXxcXFxcLikrKD89W15fXSl8W3B1bmN0Kl0oXFxfKykoPz1bXFxzXXwkKXwoPzpbXnB1bmN0Kl9cXHNcXFxcXXxcXFxcLikoXFxfKykoPz1bcHVuY3QqXFxzXXwkKXxbcHVuY3QqXFxzXShcXF8rKSg/PVtecHVuY3QqX1xcc10pfFtcXHNdKFxcXyspKD89W3B1bmN0Kl0pfFtwdW5jdCpdKFxcXyspKD89W3B1bmN0Kl0pLyAvLyBeLSBOb3QgYWxsb3dlZCBmb3IgX1xuICB9LFxuXG4gIGNvZGU6IC9eKGArKShbXmBdfFteYF1bXFxzXFxTXSo/W15gXSlcXDEoPyFgKS8sXG4gIGJyOiAvXiggezIsfXxcXFxcKVxcbig/IVxccyokKS8sXG4gIGRlbDogbm9vcFRlc3QsXG4gIHRleHQ6IC9eKGArfFteYF0pKD86KD89IHsyLH1cXG4pfFtcXHNcXFNdKj8oPzooPz1bXFxcXDwhXFxbYCpfXXxcXGJffCQpfFteIF0oPz0gezIsfVxcbikpKS8sXG4gIHB1bmN0dWF0aW9uOiAvXihbXFxzcHVuY3R1YXRpb25dKS9cbn07XG5cbi8vIGxpc3Qgb2YgcHVuY3R1YXRpb24gbWFya3MgZnJvbSBDb21tb25NYXJrIHNwZWNcbi8vIHdpdGhvdXQgKiBhbmQgXyB0byBoYW5kbGUgdGhlIGRpZmZlcmVudCBlbXBoYXNpcyBtYXJrZXJzICogYW5kIF9cbmlubGluZS5fcHVuY3R1YXRpb24gPSAnIVwiIyQlJlxcJygpK1xcXFwtLiwvOjs8PT4/QFxcXFxbXFxcXF1gXnt8fX4nO1xuaW5saW5lLnB1bmN0dWF0aW9uID0gZWRpdChpbmxpbmUucHVuY3R1YXRpb24pLnJlcGxhY2UoL3B1bmN0dWF0aW9uL2csIGlubGluZS5fcHVuY3R1YXRpb24pLmdldFJlZ2V4KCk7XG5cbi8vIHNlcXVlbmNlcyBlbSBzaG91bGQgc2tpcCBvdmVyIFt0aXRsZV0obGluayksIGBjb2RlYCwgPGh0bWw+XG5pbmxpbmUuYmxvY2tTa2lwID0gL1xcW1teXFxdXSo/XFxdXFwoW15cXCldKj9cXCl8YFteYF0qP2B8PFtePl0qPz4vZztcbi8vIGxvb2tiZWhpbmQgaXMgbm90IGF2YWlsYWJsZSBvbiBTYWZhcmkgYXMgb2YgdmVyc2lvbiAxNlxuLy8gaW5saW5lLmVzY2FwZWRFbVN0ID0gLyg/PD0oPzpefFteXFxcXCkoPzpcXFxcW15dKSopXFxcXFsqX10vZztcbmlubGluZS5lc2NhcGVkRW1TdCA9IC8oPzpefFteXFxcXF0pKD86XFxcXFxcXFwpKlxcXFxbKl9dL2c7XG5pbmxpbmUuX2NvbW1lbnQgPSBlZGl0KGJsb2NrLl9jb21tZW50KS5yZXBsYWNlKCcoPzotLT58JCknLCAnLS0+JykuZ2V0UmVnZXgoKTtcbmlubGluZS5lbVN0cm9uZy5sRGVsaW0gPSBlZGl0KGlubGluZS5lbVN0cm9uZy5sRGVsaW0pLnJlcGxhY2UoL3B1bmN0L2csIGlubGluZS5fcHVuY3R1YXRpb24pLmdldFJlZ2V4KCk7XG5pbmxpbmUuZW1TdHJvbmcuckRlbGltQXN0ID0gZWRpdChpbmxpbmUuZW1TdHJvbmcuckRlbGltQXN0LCAnZycpLnJlcGxhY2UoL3B1bmN0L2csIGlubGluZS5fcHVuY3R1YXRpb24pLmdldFJlZ2V4KCk7XG5pbmxpbmUuZW1TdHJvbmcuckRlbGltVW5kID0gZWRpdChpbmxpbmUuZW1TdHJvbmcuckRlbGltVW5kLCAnZycpLnJlcGxhY2UoL3B1bmN0L2csIGlubGluZS5fcHVuY3R1YXRpb24pLmdldFJlZ2V4KCk7XG5pbmxpbmUuX2VzY2FwZXMgPSAvXFxcXChbIVwiIyQlJicoKSorLFxcLS4vOjs8PT4/QFxcW1xcXVxcXFxeX2B7fH1+XSkvZztcbmlubGluZS5fc2NoZW1lID0gL1thLXpBLVpdW2EtekEtWjAtOSsuLV17MSwzMX0vO1xuaW5saW5lLl9lbWFpbCA9IC9bYS16QS1aMC05LiEjJCUmJyorLz0/Xl9ge3x9fi1dKyhAKVthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPyg/OlxcLlthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPykrKD8hWy1fXSkvO1xuaW5saW5lLmF1dG9saW5rID0gZWRpdChpbmxpbmUuYXV0b2xpbmspLnJlcGxhY2UoJ3NjaGVtZScsIGlubGluZS5fc2NoZW1lKS5yZXBsYWNlKCdlbWFpbCcsIGlubGluZS5fZW1haWwpLmdldFJlZ2V4KCk7XG5pbmxpbmUuX2F0dHJpYnV0ZSA9IC9cXHMrW2EtekEtWjpfXVtcXHcuOi1dKig/Olxccyo9XFxzKlwiW15cIl0qXCJ8XFxzKj1cXHMqJ1teJ10qJ3xcXHMqPVxccypbXlxcc1wiJz08PmBdKyk/LztcbmlubGluZS50YWcgPSBlZGl0KGlubGluZS50YWcpLnJlcGxhY2UoJ2NvbW1lbnQnLCBpbmxpbmUuX2NvbW1lbnQpLnJlcGxhY2UoJ2F0dHJpYnV0ZScsIGlubGluZS5fYXR0cmlidXRlKS5nZXRSZWdleCgpO1xuaW5saW5lLl9sYWJlbCA9IC8oPzpcXFsoPzpcXFxcLnxbXlxcW1xcXVxcXFxdKSpcXF18XFxcXC58YFteYF0qYHxbXlxcW1xcXVxcXFxgXSkqPy87XG5pbmxpbmUuX2hyZWYgPSAvPCg/OlxcXFwufFteXFxuPD5cXFxcXSkrPnxbXlxcc1xceDAwLVxceDFmXSovO1xuaW5saW5lLl90aXRsZSA9IC9cIig/OlxcXFxcIj98W15cIlxcXFxdKSpcInwnKD86XFxcXCc/fFteJ1xcXFxdKSonfFxcKCg/OlxcXFxcXCk/fFteKVxcXFxdKSpcXCkvO1xuaW5saW5lLmxpbmsgPSBlZGl0KGlubGluZS5saW5rKS5yZXBsYWNlKCdsYWJlbCcsIGlubGluZS5fbGFiZWwpLnJlcGxhY2UoJ2hyZWYnLCBpbmxpbmUuX2hyZWYpLnJlcGxhY2UoJ3RpdGxlJywgaW5saW5lLl90aXRsZSkuZ2V0UmVnZXgoKTtcbmlubGluZS5yZWZsaW5rID0gZWRpdChpbmxpbmUucmVmbGluaykucmVwbGFjZSgnbGFiZWwnLCBpbmxpbmUuX2xhYmVsKS5yZXBsYWNlKCdyZWYnLCBibG9jay5fbGFiZWwpLmdldFJlZ2V4KCk7XG5pbmxpbmUubm9saW5rID0gZWRpdChpbmxpbmUubm9saW5rKS5yZXBsYWNlKCdyZWYnLCBibG9jay5fbGFiZWwpLmdldFJlZ2V4KCk7XG5pbmxpbmUucmVmbGlua1NlYXJjaCA9IGVkaXQoaW5saW5lLnJlZmxpbmtTZWFyY2gsICdnJykucmVwbGFjZSgncmVmbGluaycsIGlubGluZS5yZWZsaW5rKS5yZXBsYWNlKCdub2xpbmsnLCBpbmxpbmUubm9saW5rKS5nZXRSZWdleCgpO1xuXG4vKipcbiAqIE5vcm1hbCBJbmxpbmUgR3JhbW1hclxuICovXG5cbmlubGluZS5ub3JtYWwgPSBtZXJnZSh7fSwgaW5saW5lKTtcblxuLyoqXG4gKiBQZWRhbnRpYyBJbmxpbmUgR3JhbW1hclxuICovXG5cbmlubGluZS5wZWRhbnRpYyA9IG1lcmdlKHt9LCBpbmxpbmUubm9ybWFsLCB7XG4gIHN0cm9uZzoge1xuICAgIHN0YXJ0OiAvXl9ffFxcKlxcKi8sXG4gICAgbWlkZGxlOiAvXl9fKD89XFxTKShbXFxzXFxTXSo/XFxTKV9fKD8hXyl8XlxcKlxcKig/PVxcUykoW1xcc1xcU10qP1xcUylcXCpcXCooPyFcXCopLyxcbiAgICBlbmRBc3Q6IC9cXCpcXCooPyFcXCopL2csXG4gICAgZW5kVW5kOiAvX18oPyFfKS9nXG4gIH0sXG4gIGVtOiB7XG4gICAgc3RhcnQ6IC9eX3xcXCovLFxuICAgIG1pZGRsZTogL14oKVxcKig/PVxcUykoW1xcc1xcU10qP1xcUylcXCooPyFcXCopfF5fKD89XFxTKShbXFxzXFxTXSo/XFxTKV8oPyFfKS8sXG4gICAgZW5kQXN0OiAvXFwqKD8hXFwqKS9nLFxuICAgIGVuZFVuZDogL18oPyFfKS9nXG4gIH0sXG4gIGxpbms6IGVkaXQoL14hP1xcWyhsYWJlbClcXF1cXCgoLio/KVxcKS8pLnJlcGxhY2UoJ2xhYmVsJywgaW5saW5lLl9sYWJlbCkuZ2V0UmVnZXgoKSxcbiAgcmVmbGluazogZWRpdCgvXiE/XFxbKGxhYmVsKVxcXVxccypcXFsoW15cXF1dKilcXF0vKS5yZXBsYWNlKCdsYWJlbCcsIGlubGluZS5fbGFiZWwpLmdldFJlZ2V4KClcbn0pO1xuXG4vKipcbiAqIEdGTSBJbmxpbmUgR3JhbW1hclxuICovXG5cbmlubGluZS5nZm0gPSBtZXJnZSh7fSwgaW5saW5lLm5vcm1hbCwge1xuICBlc2NhcGU6IGVkaXQoaW5saW5lLmVzY2FwZSkucmVwbGFjZSgnXSknLCAnfnxdKScpLmdldFJlZ2V4KCksXG4gIF9leHRlbmRlZF9lbWFpbDogL1tBLVphLXowLTkuXystXSsoQClbYS16QS1aMC05LV9dKyg/OlxcLlthLXpBLVowLTktX10qW2EtekEtWjAtOV0pKyg/IVstX10pLyxcbiAgdXJsOiAvXigoPzpmdHB8aHR0cHM/KTpcXC9cXC98d3d3XFwuKSg/OlthLXpBLVowLTlcXC1dK1xcLj8pK1teXFxzPF0qfF5lbWFpbC8sXG4gIF9iYWNrcGVkYWw6IC8oPzpbXj8hLiw6OypfJ1wifigpJl0rfFxcKFteKV0qXFwpfCYoPyFbYS16QS1aMC05XSs7JCl8Wz8hLiw6OypfJ1wifildKyg/ISQpKSsvLFxuICBkZWw6IC9eKH5+PykoPz1bXlxcc35dKShbXFxzXFxTXSo/W15cXHN+XSlcXDEoPz1bXn5dfCQpLyxcbiAgdGV4dDogL14oW2B+XSt8W15gfl0pKD86KD89IHsyLH1cXG4pfCg/PVthLXpBLVowLTkuISMkJSYnKitcXC89P19ge1xcfH1+LV0rQCl8W1xcc1xcU10qPyg/Oig/PVtcXFxcPCFcXFtgKn5fXXxcXGJffGh0dHBzPzpcXC9cXC98ZnRwOlxcL1xcL3x3d3dcXC58JCl8W14gXSg/PSB7Mix9XFxuKXxbXmEtekEtWjAtOS4hIyQlJicqK1xcLz0/X2B7XFx8fX4tXSg/PVthLXpBLVowLTkuISMkJSYnKitcXC89P19ge1xcfH1+LV0rQCkpKS9cbn0pO1xuaW5saW5lLmdmbS51cmwgPSBlZGl0KGlubGluZS5nZm0udXJsLCAnaScpLnJlcGxhY2UoJ2VtYWlsJywgaW5saW5lLmdmbS5fZXh0ZW5kZWRfZW1haWwpLmdldFJlZ2V4KCk7XG4vKipcbiAqIEdGTSArIExpbmUgQnJlYWtzIElubGluZSBHcmFtbWFyXG4gKi9cblxuaW5saW5lLmJyZWFrcyA9IG1lcmdlKHt9LCBpbmxpbmUuZ2ZtLCB7XG4gIGJyOiBlZGl0KGlubGluZS5icikucmVwbGFjZSgnezIsfScsICcqJykuZ2V0UmVnZXgoKSxcbiAgdGV4dDogZWRpdChpbmxpbmUuZ2ZtLnRleHQpLnJlcGxhY2UoJ1xcXFxiXycsICdcXFxcYl98IHsyLH1cXFxcbicpLnJlcGxhY2UoL1xcezIsXFx9L2csICcqJykuZ2V0UmVnZXgoKVxufSk7XG5cbi8qKlxuICogc21hcnR5cGFudHMgdGV4dCByZXBsYWNlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqL1xuZnVuY3Rpb24gc21hcnR5cGFudHModGV4dCkge1xuICByZXR1cm4gdGV4dFxuICAvLyBlbS1kYXNoZXNcbiAgLnJlcGxhY2UoLy0tLS9nLCBcIlxcdTIwMTRcIilcbiAgLy8gZW4tZGFzaGVzXG4gIC5yZXBsYWNlKC8tLS9nLCBcIlxcdTIwMTNcIilcbiAgLy8gb3BlbmluZyBzaW5nbGVzXG4gIC5yZXBsYWNlKC8oXnxbLVxcdTIwMTQvKFxcW3tcIlxcc10pJy9nLCBcIiQxXFx1MjAxOFwiKVxuICAvLyBjbG9zaW5nIHNpbmdsZXMgJiBhcG9zdHJvcGhlc1xuICAucmVwbGFjZSgvJy9nLCBcIlxcdTIwMTlcIilcbiAgLy8gb3BlbmluZyBkb3VibGVzXG4gIC5yZXBsYWNlKC8oXnxbLVxcdTIwMTQvKFxcW3tcXHUyMDE4XFxzXSlcIi9nLCBcIiQxXFx1MjAxQ1wiKVxuICAvLyBjbG9zaW5nIGRvdWJsZXNcbiAgLnJlcGxhY2UoL1wiL2csIFwiXFx1MjAxRFwiKVxuICAvLyBlbGxpcHNlc1xuICAucmVwbGFjZSgvXFwuezN9L2csIFwiXFx1MjAyNlwiKTtcbn1cblxuLyoqXG4gKiBtYW5nbGUgZW1haWwgYWRkcmVzc2VzXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICovXG5mdW5jdGlvbiBtYW5nbGUodGV4dCkge1xuICB2YXIgb3V0ID0gJycsXG4gICAgaSxcbiAgICBjaDtcbiAgdmFyIGwgPSB0ZXh0Lmxlbmd0aDtcbiAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgIGNoID0gdGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChNYXRoLnJhbmRvbSgpID4gMC41KSB7XG4gICAgICBjaCA9ICd4JyArIGNoLnRvU3RyaW5nKDE2KTtcbiAgICB9XG4gICAgb3V0ICs9ICcmIycgKyBjaCArICc7JztcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIEJsb2NrIExleGVyXG4gKi9cbnZhciBMZXhlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIExleGVyKG9wdGlvbnMpIHtcbiAgICB0aGlzLnRva2VucyA9IFtdO1xuICAgIHRoaXMudG9rZW5zLmxpbmtzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IGV4cG9ydHMuZGVmYXVsdHM7XG4gICAgdGhpcy5vcHRpb25zLnRva2VuaXplciA9IHRoaXMub3B0aW9ucy50b2tlbml6ZXIgfHwgbmV3IFRva2VuaXplcigpO1xuICAgIHRoaXMudG9rZW5pemVyID0gdGhpcy5vcHRpb25zLnRva2VuaXplcjtcbiAgICB0aGlzLnRva2VuaXplci5vcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIHRoaXMudG9rZW5pemVyLmxleGVyID0gdGhpcztcbiAgICB0aGlzLmlubGluZVF1ZXVlID0gW107XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGluTGluazogZmFsc2UsXG4gICAgICBpblJhd0Jsb2NrOiBmYWxzZSxcbiAgICAgIHRvcDogdHJ1ZVxuICAgIH07XG4gICAgdmFyIHJ1bGVzID0ge1xuICAgICAgYmxvY2s6IGJsb2NrLm5vcm1hbCxcbiAgICAgIGlubGluZTogaW5saW5lLm5vcm1hbFxuICAgIH07XG4gICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgICAgcnVsZXMuYmxvY2sgPSBibG9jay5wZWRhbnRpYztcbiAgICAgIHJ1bGVzLmlubGluZSA9IGlubGluZS5wZWRhbnRpYztcbiAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9ucy5nZm0pIHtcbiAgICAgIHJ1bGVzLmJsb2NrID0gYmxvY2suZ2ZtO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5icmVha3MpIHtcbiAgICAgICAgcnVsZXMuaW5saW5lID0gaW5saW5lLmJyZWFrcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJ1bGVzLmlubGluZSA9IGlubGluZS5nZm07XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudG9rZW5pemVyLnJ1bGVzID0gcnVsZXM7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3NlIFJ1bGVzXG4gICAqL1xuICAvKipcbiAgICogU3RhdGljIExleCBNZXRob2RcbiAgICovXG4gIExleGVyLmxleCA9IGZ1bmN0aW9uIGxleChzcmMsIG9wdGlvbnMpIHtcbiAgICB2YXIgbGV4ZXIgPSBuZXcgTGV4ZXIob3B0aW9ucyk7XG4gICAgcmV0dXJuIGxleGVyLmxleChzcmMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRpYyBMZXggSW5saW5lIE1ldGhvZFxuICAgKi87XG4gIExleGVyLmxleElubGluZSA9IGZ1bmN0aW9uIGxleElubGluZShzcmMsIG9wdGlvbnMpIHtcbiAgICB2YXIgbGV4ZXIgPSBuZXcgTGV4ZXIob3B0aW9ucyk7XG4gICAgcmV0dXJuIGxleGVyLmlubGluZVRva2VucyhzcmMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXByb2Nlc3NpbmdcbiAgICovO1xuICB2YXIgX3Byb3RvID0gTGV4ZXIucHJvdG90eXBlO1xuICBfcHJvdG8ubGV4ID0gZnVuY3Rpb24gbGV4KHNyYykge1xuICAgIHNyYyA9IHNyYy5yZXBsYWNlKC9cXHJcXG58XFxyL2csICdcXG4nKTtcbiAgICB0aGlzLmJsb2NrVG9rZW5zKHNyYywgdGhpcy50b2tlbnMpO1xuICAgIHZhciBuZXh0O1xuICAgIHdoaWxlIChuZXh0ID0gdGhpcy5pbmxpbmVRdWV1ZS5zaGlmdCgpKSB7XG4gICAgICB0aGlzLmlubGluZVRva2VucyhuZXh0LnNyYywgbmV4dC50b2tlbnMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy50b2tlbnM7XG4gIH1cblxuICAvKipcbiAgICogTGV4aW5nXG4gICAqLztcbiAgX3Byb3RvLmJsb2NrVG9rZW5zID0gZnVuY3Rpb24gYmxvY2tUb2tlbnMoc3JjLCB0b2tlbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgIGlmICh0b2tlbnMgPT09IHZvaWQgMCkge1xuICAgICAgdG9rZW5zID0gW107XG4gICAgfVxuICAgIGlmICh0aGlzLm9wdGlvbnMucGVkYW50aWMpIHtcbiAgICAgIHNyYyA9IHNyYy5yZXBsYWNlKC9cXHQvZywgJyAgICAnKS5yZXBsYWNlKC9eICskL2dtLCAnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNyYyA9IHNyYy5yZXBsYWNlKC9eKCAqKShcXHQrKS9nbSwgZnVuY3Rpb24gKF8sIGxlYWRpbmcsIHRhYnMpIHtcbiAgICAgICAgcmV0dXJuIGxlYWRpbmcgKyAnICAgICcucmVwZWF0KHRhYnMubGVuZ3RoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgdG9rZW4sIGxhc3RUb2tlbiwgY3V0U3JjLCBsYXN0UGFyYWdyYXBoQ2xpcHBlZDtcbiAgICB3aGlsZSAoc3JjKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuYmxvY2sgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuYmxvY2suc29tZShmdW5jdGlvbiAoZXh0VG9rZW5pemVyKSB7XG4gICAgICAgIGlmICh0b2tlbiA9IGV4dFRva2VuaXplci5jYWxsKHtcbiAgICAgICAgICBsZXhlcjogX3RoaXNcbiAgICAgICAgfSwgc3JjLCB0b2tlbnMpKSB7XG4gICAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIG5ld2xpbmVcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLnNwYWNlKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgaWYgKHRva2VuLnJhdy5sZW5ndGggPT09IDEgJiYgdG9rZW5zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSdzIGEgc2luZ2xlIFxcbiBhcyBhIHNwYWNlciwgaXQncyB0ZXJtaW5hdGluZyB0aGUgbGFzdCBsaW5lLFxuICAgICAgICAgIC8vIHNvIG1vdmUgaXQgdGhlcmUgc28gdGhhdCB3ZSBkb24ndCBnZXQgdW5lY2Vzc2FyeSBwYXJhZ3JhcGggdGFnc1xuICAgICAgICAgIHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV0ucmF3ICs9ICdcXG4nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gY29kZVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuY29kZShzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIGxhc3RUb2tlbiA9IHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV07XG4gICAgICAgIC8vIEFuIGluZGVudGVkIGNvZGUgYmxvY2sgY2Fubm90IGludGVycnVwdCBhIHBhcmFncmFwaC5cbiAgICAgICAgaWYgKGxhc3RUb2tlbiAmJiAobGFzdFRva2VuLnR5cGUgPT09ICdwYXJhZ3JhcGgnIHx8IGxhc3RUb2tlbi50eXBlID09PSAndGV4dCcpKSB7XG4gICAgICAgICAgbGFzdFRva2VuLnJhdyArPSAnXFxuJyArIHRva2VuLnJhdztcbiAgICAgICAgICBsYXN0VG9rZW4udGV4dCArPSAnXFxuJyArIHRva2VuLnRleHQ7XG4gICAgICAgICAgdGhpcy5pbmxpbmVRdWV1ZVt0aGlzLmlubGluZVF1ZXVlLmxlbmd0aCAtIDFdLnNyYyA9IGxhc3RUb2tlbi50ZXh0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gZmVuY2VzXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5mZW5jZXMoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBoZWFkaW5nXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5oZWFkaW5nKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gaHJcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmhyKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gYmxvY2txdW90ZVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuYmxvY2txdW90ZShzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGxpc3RcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmxpc3Qoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBodG1sXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5odG1sKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gZGVmXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5kZWYoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICBsYXN0VG9rZW4gPSB0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAobGFzdFRva2VuICYmIChsYXN0VG9rZW4udHlwZSA9PT0gJ3BhcmFncmFwaCcgfHwgbGFzdFRva2VuLnR5cGUgPT09ICd0ZXh0JykpIHtcbiAgICAgICAgICBsYXN0VG9rZW4ucmF3ICs9ICdcXG4nICsgdG9rZW4ucmF3O1xuICAgICAgICAgIGxhc3RUb2tlbi50ZXh0ICs9ICdcXG4nICsgdG9rZW4ucmF3O1xuICAgICAgICAgIHRoaXMuaW5saW5lUXVldWVbdGhpcy5pbmxpbmVRdWV1ZS5sZW5ndGggLSAxXS5zcmMgPSBsYXN0VG9rZW4udGV4dDtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy50b2tlbnMubGlua3NbdG9rZW4udGFnXSkge1xuICAgICAgICAgIHRoaXMudG9rZW5zLmxpbmtzW3Rva2VuLnRhZ10gPSB7XG4gICAgICAgICAgICBocmVmOiB0b2tlbi5ocmVmLFxuICAgICAgICAgICAgdGl0bGU6IHRva2VuLnRpdGxlXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdGFibGUgKGdmbSlcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLnRhYmxlKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gbGhlYWRpbmdcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmxoZWFkaW5nKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdG9wLWxldmVsIHBhcmFncmFwaFxuICAgICAgLy8gcHJldmVudCBwYXJhZ3JhcGggY29uc3VtaW5nIGV4dGVuc2lvbnMgYnkgY2xpcHBpbmcgJ3NyYycgdG8gZXh0ZW5zaW9uIHN0YXJ0XG4gICAgICBjdXRTcmMgPSBzcmM7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuc3RhcnRCbG9jaykge1xuICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBzdGFydEluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgdmFyIHRlbXBTcmMgPSBzcmMuc2xpY2UoMSk7XG4gICAgICAgICAgdmFyIHRlbXBTdGFydCA9IHZvaWQgMDtcbiAgICAgICAgICBfdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuc3RhcnRCbG9jay5mb3JFYWNoKGZ1bmN0aW9uIChnZXRTdGFydEluZGV4KSB7XG4gICAgICAgICAgICB0ZW1wU3RhcnQgPSBnZXRTdGFydEluZGV4LmNhbGwoe1xuICAgICAgICAgICAgICBsZXhlcjogdGhpc1xuICAgICAgICAgICAgfSwgdGVtcFNyYyk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRlbXBTdGFydCA9PT0gJ251bWJlcicgJiYgdGVtcFN0YXJ0ID49IDApIHtcbiAgICAgICAgICAgICAgc3RhcnRJbmRleCA9IE1hdGgubWluKHN0YXJ0SW5kZXgsIHRlbXBTdGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKHN0YXJ0SW5kZXggPCBJbmZpbml0eSAmJiBzdGFydEluZGV4ID49IDApIHtcbiAgICAgICAgICAgIGN1dFNyYyA9IHNyYy5zdWJzdHJpbmcoMCwgc3RhcnRJbmRleCArIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnN0YXRlLnRvcCAmJiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5wYXJhZ3JhcGgoY3V0U3JjKSkpIHtcbiAgICAgICAgbGFzdFRva2VuID0gdG9rZW5zW3Rva2Vucy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGxhc3RQYXJhZ3JhcGhDbGlwcGVkICYmIGxhc3RUb2tlbi50eXBlID09PSAncGFyYWdyYXBoJykge1xuICAgICAgICAgIGxhc3RUb2tlbi5yYXcgKz0gJ1xcbicgKyB0b2tlbi5yYXc7XG4gICAgICAgICAgbGFzdFRva2VuLnRleHQgKz0gJ1xcbicgKyB0b2tlbi50ZXh0O1xuICAgICAgICAgIHRoaXMuaW5saW5lUXVldWUucG9wKCk7XG4gICAgICAgICAgdGhpcy5pbmxpbmVRdWV1ZVt0aGlzLmlubGluZVF1ZXVlLmxlbmd0aCAtIDFdLnNyYyA9IGxhc3RUb2tlbi50ZXh0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICBsYXN0UGFyYWdyYXBoQ2xpcHBlZCA9IGN1dFNyYy5sZW5ndGggIT09IHNyYy5sZW5ndGg7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyB0ZXh0XG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci50ZXh0KHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgbGFzdFRva2VuID0gdG9rZW5zW3Rva2Vucy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGxhc3RUb2tlbiAmJiBsYXN0VG9rZW4udHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgbGFzdFRva2VuLnJhdyArPSAnXFxuJyArIHRva2VuLnJhdztcbiAgICAgICAgICBsYXN0VG9rZW4udGV4dCArPSAnXFxuJyArIHRva2VuLnRleHQ7XG4gICAgICAgICAgdGhpcy5pbmxpbmVRdWV1ZS5wb3AoKTtcbiAgICAgICAgICB0aGlzLmlubGluZVF1ZXVlW3RoaXMuaW5saW5lUXVldWUubGVuZ3RoIC0gMV0uc3JjID0gbGFzdFRva2VuLnRleHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHNyYykge1xuICAgICAgICB2YXIgZXJyTXNnID0gJ0luZmluaXRlIGxvb3Agb24gYnl0ZTogJyArIHNyYy5jaGFyQ29kZUF0KDApO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNpbGVudCkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyTXNnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyTXNnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnN0YXRlLnRvcCA9IHRydWU7XG4gICAgcmV0dXJuIHRva2VucztcbiAgfTtcbiAgX3Byb3RvLmlubGluZSA9IGZ1bmN0aW9uIGlubGluZShzcmMsIHRva2Vucykge1xuICAgIGlmICh0b2tlbnMgPT09IHZvaWQgMCkge1xuICAgICAgdG9rZW5zID0gW107XG4gICAgfVxuICAgIHRoaXMuaW5saW5lUXVldWUucHVzaCh7XG4gICAgICBzcmM6IHNyYyxcbiAgICAgIHRva2VuczogdG9rZW5zXG4gICAgfSk7XG4gICAgcmV0dXJuIHRva2VucztcbiAgfVxuXG4gIC8qKlxuICAgKiBMZXhpbmcvQ29tcGlsaW5nXG4gICAqLztcbiAgX3Byb3RvLmlubGluZVRva2VucyA9IGZ1bmN0aW9uIGlubGluZVRva2VucyhzcmMsIHRva2Vucykge1xuICAgIHZhciBfdGhpczIgPSB0aGlzO1xuICAgIGlmICh0b2tlbnMgPT09IHZvaWQgMCkge1xuICAgICAgdG9rZW5zID0gW107XG4gICAgfVxuICAgIHZhciB0b2tlbiwgbGFzdFRva2VuLCBjdXRTcmM7XG5cbiAgICAvLyBTdHJpbmcgd2l0aCBsaW5rcyBtYXNrZWQgdG8gYXZvaWQgaW50ZXJmZXJlbmNlIHdpdGggZW0gYW5kIHN0cm9uZ1xuICAgIHZhciBtYXNrZWRTcmMgPSBzcmM7XG4gICAgdmFyIG1hdGNoO1xuICAgIHZhciBrZWVwUHJldkNoYXIsIHByZXZDaGFyO1xuXG4gICAgLy8gTWFzayBvdXQgcmVmbGlua3NcbiAgICBpZiAodGhpcy50b2tlbnMubGlua3MpIHtcbiAgICAgIHZhciBsaW5rcyA9IE9iamVjdC5rZXlzKHRoaXMudG9rZW5zLmxpbmtzKTtcbiAgICAgIGlmIChsaW5rcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHdoaWxlICgobWF0Y2ggPSB0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUucmVmbGlua1NlYXJjaC5leGVjKG1hc2tlZFNyYykpICE9IG51bGwpIHtcbiAgICAgICAgICBpZiAobGlua3MuaW5jbHVkZXMobWF0Y2hbMF0uc2xpY2UobWF0Y2hbMF0ubGFzdEluZGV4T2YoJ1snKSArIDEsIC0xKSkpIHtcbiAgICAgICAgICAgIG1hc2tlZFNyYyA9IG1hc2tlZFNyYy5zbGljZSgwLCBtYXRjaC5pbmRleCkgKyAnWycgKyByZXBlYXRTdHJpbmcoJ2EnLCBtYXRjaFswXS5sZW5ndGggLSAyKSArICddJyArIG1hc2tlZFNyYy5zbGljZSh0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUucmVmbGlua1NlYXJjaC5sYXN0SW5kZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBNYXNrIG91dCBvdGhlciBibG9ja3NcbiAgICB3aGlsZSAoKG1hdGNoID0gdGhpcy50b2tlbml6ZXIucnVsZXMuaW5saW5lLmJsb2NrU2tpcC5leGVjKG1hc2tlZFNyYykpICE9IG51bGwpIHtcbiAgICAgIG1hc2tlZFNyYyA9IG1hc2tlZFNyYy5zbGljZSgwLCBtYXRjaC5pbmRleCkgKyAnWycgKyByZXBlYXRTdHJpbmcoJ2EnLCBtYXRjaFswXS5sZW5ndGggLSAyKSArICddJyArIG1hc2tlZFNyYy5zbGljZSh0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUuYmxvY2tTa2lwLmxhc3RJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gTWFzayBvdXQgZXNjYXBlZCBlbSAmIHN0cm9uZyBkZWxpbWl0ZXJzXG4gICAgd2hpbGUgKChtYXRjaCA9IHRoaXMudG9rZW5pemVyLnJ1bGVzLmlubGluZS5lc2NhcGVkRW1TdC5leGVjKG1hc2tlZFNyYykpICE9IG51bGwpIHtcbiAgICAgIG1hc2tlZFNyYyA9IG1hc2tlZFNyYy5zbGljZSgwLCBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCAtIDIpICsgJysrJyArIG1hc2tlZFNyYy5zbGljZSh0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUuZXNjYXBlZEVtU3QubGFzdEluZGV4KTtcbiAgICAgIHRoaXMudG9rZW5pemVyLnJ1bGVzLmlubGluZS5lc2NhcGVkRW1TdC5sYXN0SW5kZXgtLTtcbiAgICB9XG4gICAgd2hpbGUgKHNyYykge1xuICAgICAgaWYgKCFrZWVwUHJldkNoYXIpIHtcbiAgICAgICAgcHJldkNoYXIgPSAnJztcbiAgICAgIH1cbiAgICAgIGtlZXBQcmV2Q2hhciA9IGZhbHNlO1xuXG4gICAgICAvLyBleHRlbnNpb25zXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuaW5saW5lICYmIHRoaXMub3B0aW9ucy5leHRlbnNpb25zLmlubGluZS5zb21lKGZ1bmN0aW9uIChleHRUb2tlbml6ZXIpIHtcbiAgICAgICAgaWYgKHRva2VuID0gZXh0VG9rZW5pemVyLmNhbGwoe1xuICAgICAgICAgIGxleGVyOiBfdGhpczJcbiAgICAgICAgfSwgc3JjLCB0b2tlbnMpKSB7XG4gICAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGVzY2FwZVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuZXNjYXBlKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdGFnXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci50YWcoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICBsYXN0VG9rZW4gPSB0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAobGFzdFRva2VuICYmIHRva2VuLnR5cGUgPT09ICd0ZXh0JyAmJiBsYXN0VG9rZW4udHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgbGFzdFRva2VuLnJhdyArPSB0b2tlbi5yYXc7XG4gICAgICAgICAgbGFzdFRva2VuLnRleHQgKz0gdG9rZW4udGV4dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGxpbmtcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmxpbmsoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyByZWZsaW5rLCBub2xpbmtcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLnJlZmxpbmsoc3JjLCB0aGlzLnRva2Vucy5saW5rcykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgbGFzdFRva2VuID0gdG9rZW5zW3Rva2Vucy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGxhc3RUb2tlbiAmJiB0b2tlbi50eXBlID09PSAndGV4dCcgJiYgbGFzdFRva2VuLnR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgICAgIGxhc3RUb2tlbi5yYXcgKz0gdG9rZW4ucmF3O1xuICAgICAgICAgIGxhc3RUb2tlbi50ZXh0ICs9IHRva2VuLnRleHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBlbSAmIHN0cm9uZ1xuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuZW1TdHJvbmcoc3JjLCBtYXNrZWRTcmMsIHByZXZDaGFyKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBjb2RlXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5jb2Rlc3BhbihzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGJyXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5icihzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGRlbCAoZ2ZtKVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuZGVsKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gYXV0b2xpbmtcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmF1dG9saW5rKHNyYywgbWFuZ2xlKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyB1cmwgKGdmbSlcbiAgICAgIGlmICghdGhpcy5zdGF0ZS5pbkxpbmsgJiYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIudXJsKHNyYywgbWFuZ2xlKSkpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdGV4dFxuICAgICAgLy8gcHJldmVudCBpbmxpbmVUZXh0IGNvbnN1bWluZyBleHRlbnNpb25zIGJ5IGNsaXBwaW5nICdzcmMnIHRvIGV4dGVuc2lvbiBzdGFydFxuICAgICAgY3V0U3JjID0gc3JjO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5leHRlbnNpb25zICYmIHRoaXMub3B0aW9ucy5leHRlbnNpb25zLnN0YXJ0SW5saW5lKSB7XG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIHN0YXJ0SW5kZXggPSBJbmZpbml0eTtcbiAgICAgICAgICB2YXIgdGVtcFNyYyA9IHNyYy5zbGljZSgxKTtcbiAgICAgICAgICB2YXIgdGVtcFN0YXJ0ID0gdm9pZCAwO1xuICAgICAgICAgIF90aGlzMi5vcHRpb25zLmV4dGVuc2lvbnMuc3RhcnRJbmxpbmUuZm9yRWFjaChmdW5jdGlvbiAoZ2V0U3RhcnRJbmRleCkge1xuICAgICAgICAgICAgdGVtcFN0YXJ0ID0gZ2V0U3RhcnRJbmRleC5jYWxsKHtcbiAgICAgICAgICAgICAgbGV4ZXI6IHRoaXNcbiAgICAgICAgICAgIH0sIHRlbXBTcmMpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0ZW1wU3RhcnQgPT09ICdudW1iZXInICYmIHRlbXBTdGFydCA+PSAwKSB7XG4gICAgICAgICAgICAgIHN0YXJ0SW5kZXggPSBNYXRoLm1pbihzdGFydEluZGV4LCB0ZW1wU3RhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChzdGFydEluZGV4IDwgSW5maW5pdHkgJiYgc3RhcnRJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICBjdXRTcmMgPSBzcmMuc3Vic3RyaW5nKDAsIHN0YXJ0SW5kZXggKyAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCk7XG4gICAgICB9XG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5pbmxpbmVUZXh0KGN1dFNyYywgc21hcnR5cGFudHMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIGlmICh0b2tlbi5yYXcuc2xpY2UoLTEpICE9PSAnXycpIHtcbiAgICAgICAgICAvLyBUcmFjayBwcmV2Q2hhciBiZWZvcmUgc3RyaW5nIG9mIF9fX18gc3RhcnRlZFxuICAgICAgICAgIHByZXZDaGFyID0gdG9rZW4ucmF3LnNsaWNlKC0xKTtcbiAgICAgICAgfVxuICAgICAgICBrZWVwUHJldkNoYXIgPSB0cnVlO1xuICAgICAgICBsYXN0VG9rZW4gPSB0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAobGFzdFRva2VuICYmIGxhc3RUb2tlbi50eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICBsYXN0VG9rZW4ucmF3ICs9IHRva2VuLnJhdztcbiAgICAgICAgICBsYXN0VG9rZW4udGV4dCArPSB0b2tlbi50ZXh0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChzcmMpIHtcbiAgICAgICAgdmFyIGVyck1zZyA9ICdJbmZpbml0ZSBsb29wIG9uIGJ5dGU6ICcgKyBzcmMuY2hhckNvZGVBdCgwKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVyck1zZyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVyck1zZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRva2VucztcbiAgfTtcbiAgX2NyZWF0ZUNsYXNzKExleGVyLCBudWxsLCBbe1xuICAgIGtleTogXCJydWxlc1wiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYmxvY2s6IGJsb2NrLFxuICAgICAgICBpbmxpbmU6IGlubGluZVxuICAgICAgfTtcbiAgICB9XG4gIH1dKTtcbiAgcmV0dXJuIExleGVyO1xufSgpO1xuXG4vKipcbiAqIFJlbmRlcmVyXG4gKi9cbnZhciBSZW5kZXJlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFJlbmRlcmVyKG9wdGlvbnMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IGV4cG9ydHMuZGVmYXVsdHM7XG4gIH1cbiAgdmFyIF9wcm90byA9IFJlbmRlcmVyLnByb3RvdHlwZTtcbiAgX3Byb3RvLmNvZGUgPSBmdW5jdGlvbiBjb2RlKF9jb2RlLCBpbmZvc3RyaW5nLCBlc2NhcGVkKSB7XG4gICAgdmFyIGxhbmcgPSAoaW5mb3N0cmluZyB8fCAnJykubWF0Y2goL1xcUyovKVswXTtcbiAgICBpZiAodGhpcy5vcHRpb25zLmhpZ2hsaWdodCkge1xuICAgICAgdmFyIG91dCA9IHRoaXMub3B0aW9ucy5oaWdobGlnaHQoX2NvZGUsIGxhbmcpO1xuICAgICAgaWYgKG91dCAhPSBudWxsICYmIG91dCAhPT0gX2NvZGUpIHtcbiAgICAgICAgZXNjYXBlZCA9IHRydWU7XG4gICAgICAgIF9jb2RlID0gb3V0O1xuICAgICAgfVxuICAgIH1cbiAgICBfY29kZSA9IF9jb2RlLnJlcGxhY2UoL1xcbiQvLCAnJykgKyAnXFxuJztcbiAgICBpZiAoIWxhbmcpIHtcbiAgICAgIHJldHVybiAnPHByZT48Y29kZT4nICsgKGVzY2FwZWQgPyBfY29kZSA6IGVzY2FwZShfY29kZSwgdHJ1ZSkpICsgJzwvY29kZT48L3ByZT5cXG4nO1xuICAgIH1cbiAgICByZXR1cm4gJzxwcmU+PGNvZGUgY2xhc3M9XCInICsgdGhpcy5vcHRpb25zLmxhbmdQcmVmaXggKyBlc2NhcGUobGFuZykgKyAnXCI+JyArIChlc2NhcGVkID8gX2NvZGUgOiBlc2NhcGUoX2NvZGUsIHRydWUpKSArICc8L2NvZGU+PC9wcmU+XFxuJztcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcXVvdGVcbiAgICovO1xuICBfcHJvdG8uYmxvY2txdW90ZSA9IGZ1bmN0aW9uIGJsb2NrcXVvdGUocXVvdGUpIHtcbiAgICByZXR1cm4gXCI8YmxvY2txdW90ZT5cXG5cIiArIHF1b3RlICsgXCI8L2Jsb2NrcXVvdGU+XFxuXCI7XG4gIH07XG4gIF9wcm90by5odG1sID0gZnVuY3Rpb24gaHRtbChfaHRtbCkge1xuICAgIHJldHVybiBfaHRtbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGV2ZWxcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJhd1xuICAgKiBAcGFyYW0ge2FueX0gc2x1Z2dlclxuICAgKi87XG4gIF9wcm90by5oZWFkaW5nID0gZnVuY3Rpb24gaGVhZGluZyh0ZXh0LCBsZXZlbCwgcmF3LCBzbHVnZ2VyKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5oZWFkZXJJZHMpIHtcbiAgICAgIHZhciBpZCA9IHRoaXMub3B0aW9ucy5oZWFkZXJQcmVmaXggKyBzbHVnZ2VyLnNsdWcocmF3KTtcbiAgICAgIHJldHVybiBcIjxoXCIgKyBsZXZlbCArIFwiIGlkPVxcXCJcIiArIGlkICsgXCJcXFwiPlwiICsgdGV4dCArIFwiPC9oXCIgKyBsZXZlbCArIFwiPlxcblwiO1xuICAgIH1cblxuICAgIC8vIGlnbm9yZSBJRHNcbiAgICByZXR1cm4gXCI8aFwiICsgbGV2ZWwgKyBcIj5cIiArIHRleHQgKyBcIjwvaFwiICsgbGV2ZWwgKyBcIj5cXG5cIjtcbiAgfTtcbiAgX3Byb3RvLmhyID0gZnVuY3Rpb24gaHIoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy54aHRtbCA/ICc8aHIvPlxcbicgOiAnPGhyPlxcbic7XG4gIH07XG4gIF9wcm90by5saXN0ID0gZnVuY3Rpb24gbGlzdChib2R5LCBvcmRlcmVkLCBzdGFydCkge1xuICAgIHZhciB0eXBlID0gb3JkZXJlZCA/ICdvbCcgOiAndWwnLFxuICAgICAgc3RhcnRhdHQgPSBvcmRlcmVkICYmIHN0YXJ0ICE9PSAxID8gJyBzdGFydD1cIicgKyBzdGFydCArICdcIicgOiAnJztcbiAgICByZXR1cm4gJzwnICsgdHlwZSArIHN0YXJ0YXR0ICsgJz5cXG4nICsgYm9keSArICc8LycgKyB0eXBlICsgJz5cXG4nO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gICAqLztcbiAgX3Byb3RvLmxpc3RpdGVtID0gZnVuY3Rpb24gbGlzdGl0ZW0odGV4dCkge1xuICAgIHJldHVybiBcIjxsaT5cIiArIHRleHQgKyBcIjwvbGk+XFxuXCI7XG4gIH07XG4gIF9wcm90by5jaGVja2JveCA9IGZ1bmN0aW9uIGNoZWNrYm94KGNoZWNrZWQpIHtcbiAgICByZXR1cm4gJzxpbnB1dCAnICsgKGNoZWNrZWQgPyAnY2hlY2tlZD1cIlwiICcgOiAnJykgKyAnZGlzYWJsZWQ9XCJcIiB0eXBlPVwiY2hlY2tib3hcIicgKyAodGhpcy5vcHRpb25zLnhodG1sID8gJyAvJyA6ICcnKSArICc+ICc7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICovO1xuICBfcHJvdG8ucGFyYWdyYXBoID0gZnVuY3Rpb24gcGFyYWdyYXBoKHRleHQpIHtcbiAgICByZXR1cm4gXCI8cD5cIiArIHRleHQgKyBcIjwvcD5cXG5cIjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaGVhZGVyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBib2R5XG4gICAqLztcbiAgX3Byb3RvLnRhYmxlID0gZnVuY3Rpb24gdGFibGUoaGVhZGVyLCBib2R5KSB7XG4gICAgaWYgKGJvZHkpIGJvZHkgPSBcIjx0Ym9keT5cIiArIGJvZHkgKyBcIjwvdGJvZHk+XCI7XG4gICAgcmV0dXJuICc8dGFibGU+XFxuJyArICc8dGhlYWQ+XFxuJyArIGhlYWRlciArICc8L3RoZWFkPlxcbicgKyBib2R5ICsgJzwvdGFibGU+XFxuJztcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29udGVudFxuICAgKi87XG4gIF9wcm90by50YWJsZXJvdyA9IGZ1bmN0aW9uIHRhYmxlcm93KGNvbnRlbnQpIHtcbiAgICByZXR1cm4gXCI8dHI+XFxuXCIgKyBjb250ZW50ICsgXCI8L3RyPlxcblwiO1xuICB9O1xuICBfcHJvdG8udGFibGVjZWxsID0gZnVuY3Rpb24gdGFibGVjZWxsKGNvbnRlbnQsIGZsYWdzKSB7XG4gICAgdmFyIHR5cGUgPSBmbGFncy5oZWFkZXIgPyAndGgnIDogJ3RkJztcbiAgICB2YXIgdGFnID0gZmxhZ3MuYWxpZ24gPyBcIjxcIiArIHR5cGUgKyBcIiBhbGlnbj1cXFwiXCIgKyBmbGFncy5hbGlnbiArIFwiXFxcIj5cIiA6IFwiPFwiICsgdHlwZSArIFwiPlwiO1xuICAgIHJldHVybiB0YWcgKyBjb250ZW50ICsgKFwiPC9cIiArIHR5cGUgKyBcIj5cXG5cIik7XG4gIH1cblxuICAvKipcbiAgICogc3BhbiBsZXZlbCByZW5kZXJlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICAgKi87XG4gIF9wcm90by5zdHJvbmcgPSBmdW5jdGlvbiBzdHJvbmcodGV4dCkge1xuICAgIHJldHVybiBcIjxzdHJvbmc+XCIgKyB0ZXh0ICsgXCI8L3N0cm9uZz5cIjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICAgKi87XG4gIF9wcm90by5lbSA9IGZ1bmN0aW9uIGVtKHRleHQpIHtcbiAgICByZXR1cm4gXCI8ZW0+XCIgKyB0ZXh0ICsgXCI8L2VtPlwiO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gICAqLztcbiAgX3Byb3RvLmNvZGVzcGFuID0gZnVuY3Rpb24gY29kZXNwYW4odGV4dCkge1xuICAgIHJldHVybiBcIjxjb2RlPlwiICsgdGV4dCArIFwiPC9jb2RlPlwiO1xuICB9O1xuICBfcHJvdG8uYnIgPSBmdW5jdGlvbiBicigpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnhodG1sID8gJzxici8+JyA6ICc8YnI+JztcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICAgKi87XG4gIF9wcm90by5kZWwgPSBmdW5jdGlvbiBkZWwodGV4dCkge1xuICAgIHJldHVybiBcIjxkZWw+XCIgKyB0ZXh0ICsgXCI8L2RlbD5cIjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaHJlZlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGl0bGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICovO1xuICBfcHJvdG8ubGluayA9IGZ1bmN0aW9uIGxpbmsoaHJlZiwgdGl0bGUsIHRleHQpIHtcbiAgICBocmVmID0gY2xlYW5VcmwodGhpcy5vcHRpb25zLnNhbml0aXplLCB0aGlzLm9wdGlvbnMuYmFzZVVybCwgaHJlZik7XG4gICAgaWYgKGhyZWYgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cbiAgICB2YXIgb3V0ID0gJzxhIGhyZWY9XCInICsgaHJlZiArICdcIic7XG4gICAgaWYgKHRpdGxlKSB7XG4gICAgICBvdXQgKz0gJyB0aXRsZT1cIicgKyB0aXRsZSArICdcIic7XG4gICAgfVxuICAgIG91dCArPSAnPicgKyB0ZXh0ICsgJzwvYT4nO1xuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhyZWZcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gICAqLztcbiAgX3Byb3RvLmltYWdlID0gZnVuY3Rpb24gaW1hZ2UoaHJlZiwgdGl0bGUsIHRleHQpIHtcbiAgICBocmVmID0gY2xlYW5VcmwodGhpcy5vcHRpb25zLnNhbml0aXplLCB0aGlzLm9wdGlvbnMuYmFzZVVybCwgaHJlZik7XG4gICAgaWYgKGhyZWYgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cbiAgICB2YXIgb3V0ID0gXCI8aW1nIHNyYz1cXFwiXCIgKyBocmVmICsgXCJcXFwiIGFsdD1cXFwiXCIgKyB0ZXh0ICsgXCJcXFwiXCI7XG4gICAgaWYgKHRpdGxlKSB7XG4gICAgICBvdXQgKz0gXCIgdGl0bGU9XFxcIlwiICsgdGl0bGUgKyBcIlxcXCJcIjtcbiAgICB9XG4gICAgb3V0ICs9IHRoaXMub3B0aW9ucy54aHRtbCA/ICcvPicgOiAnPic7XG4gICAgcmV0dXJuIG91dDtcbiAgfTtcbiAgX3Byb3RvLnRleHQgPSBmdW5jdGlvbiB0ZXh0KF90ZXh0KSB7XG4gICAgcmV0dXJuIF90ZXh0O1xuICB9O1xuICByZXR1cm4gUmVuZGVyZXI7XG59KCk7XG5cbi8qKlxuICogVGV4dFJlbmRlcmVyXG4gKiByZXR1cm5zIG9ubHkgdGhlIHRleHR1YWwgcGFydCBvZiB0aGUgdG9rZW5cbiAqL1xudmFyIFRleHRSZW5kZXJlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFRleHRSZW5kZXJlcigpIHt9XG4gIHZhciBfcHJvdG8gPSBUZXh0UmVuZGVyZXIucHJvdG90eXBlO1xuICAvLyBubyBuZWVkIGZvciBibG9jayBsZXZlbCByZW5kZXJlcnNcbiAgX3Byb3RvLnN0cm9uZyA9IGZ1bmN0aW9uIHN0cm9uZyh0ZXh0KSB7XG4gICAgcmV0dXJuIHRleHQ7XG4gIH07XG4gIF9wcm90by5lbSA9IGZ1bmN0aW9uIGVtKHRleHQpIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfTtcbiAgX3Byb3RvLmNvZGVzcGFuID0gZnVuY3Rpb24gY29kZXNwYW4odGV4dCkge1xuICAgIHJldHVybiB0ZXh0O1xuICB9O1xuICBfcHJvdG8uZGVsID0gZnVuY3Rpb24gZGVsKHRleHQpIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfTtcbiAgX3Byb3RvLmh0bWwgPSBmdW5jdGlvbiBodG1sKHRleHQpIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfTtcbiAgX3Byb3RvLnRleHQgPSBmdW5jdGlvbiB0ZXh0KF90ZXh0KSB7XG4gICAgcmV0dXJuIF90ZXh0O1xuICB9O1xuICBfcHJvdG8ubGluayA9IGZ1bmN0aW9uIGxpbmsoaHJlZiwgdGl0bGUsIHRleHQpIHtcbiAgICByZXR1cm4gJycgKyB0ZXh0O1xuICB9O1xuICBfcHJvdG8uaW1hZ2UgPSBmdW5jdGlvbiBpbWFnZShocmVmLCB0aXRsZSwgdGV4dCkge1xuICAgIHJldHVybiAnJyArIHRleHQ7XG4gIH07XG4gIF9wcm90by5iciA9IGZ1bmN0aW9uIGJyKCkge1xuICAgIHJldHVybiAnJztcbiAgfTtcbiAgcmV0dXJuIFRleHRSZW5kZXJlcjtcbn0oKTtcblxuLyoqXG4gKiBTbHVnZ2VyIGdlbmVyYXRlcyBoZWFkZXIgaWRcbiAqL1xudmFyIFNsdWdnZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTbHVnZ2VyKCkge1xuICAgIHRoaXMuc2VlbiA9IHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKi9cbiAgdmFyIF9wcm90byA9IFNsdWdnZXIucHJvdG90eXBlO1xuICBfcHJvdG8uc2VyaWFsaXplID0gZnVuY3Rpb24gc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvTG93ZXJDYXNlKCkudHJpbSgpXG4gICAgLy8gcmVtb3ZlIGh0bWwgdGFnc1xuICAgIC5yZXBsYWNlKC88WyFcXC9hLXpdLio/Pi9pZywgJycpXG4gICAgLy8gcmVtb3ZlIHVud2FudGVkIGNoYXJzXG4gICAgLnJlcGxhY2UoL1tcXHUyMDAwLVxcdTIwNkZcXHUyRTAwLVxcdTJFN0ZcXFxcJyFcIiMkJSYoKSorLC4vOjs8PT4/QFtcXF1eYHt8fX5dL2csICcnKS5yZXBsYWNlKC9cXHMvZywgJy0nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyB0aGUgbmV4dCBzYWZlICh1bmlxdWUpIHNsdWcgdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcmlnaW5hbFNsdWdcbiAgICogQHBhcmFtIHtib29sZWFufSBpc0RyeVJ1blxuICAgKi87XG4gIF9wcm90by5nZXROZXh0U2FmZVNsdWcgPSBmdW5jdGlvbiBnZXROZXh0U2FmZVNsdWcob3JpZ2luYWxTbHVnLCBpc0RyeVJ1bikge1xuICAgIHZhciBzbHVnID0gb3JpZ2luYWxTbHVnO1xuICAgIHZhciBvY2N1cmVuY2VBY2N1bXVsYXRvciA9IDA7XG4gICAgaWYgKHRoaXMuc2Vlbi5oYXNPd25Qcm9wZXJ0eShzbHVnKSkge1xuICAgICAgb2NjdXJlbmNlQWNjdW11bGF0b3IgPSB0aGlzLnNlZW5bb3JpZ2luYWxTbHVnXTtcbiAgICAgIGRvIHtcbiAgICAgICAgb2NjdXJlbmNlQWNjdW11bGF0b3IrKztcbiAgICAgICAgc2x1ZyA9IG9yaWdpbmFsU2x1ZyArICctJyArIG9jY3VyZW5jZUFjY3VtdWxhdG9yO1xuICAgICAgfSB3aGlsZSAodGhpcy5zZWVuLmhhc093blByb3BlcnR5KHNsdWcpKTtcbiAgICB9XG4gICAgaWYgKCFpc0RyeVJ1bikge1xuICAgICAgdGhpcy5zZWVuW29yaWdpbmFsU2x1Z10gPSBvY2N1cmVuY2VBY2N1bXVsYXRvcjtcbiAgICAgIHRoaXMuc2VlbltzbHVnXSA9IDA7XG4gICAgfVxuICAgIHJldHVybiBzbHVnO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgc3RyaW5nIHRvIHVuaXF1ZSBpZFxuICAgKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuZHJ5cnVuXSBHZW5lcmF0ZXMgdGhlIG5leHQgdW5pcXVlIHNsdWcgd2l0aG91dFxuICAgKiB1cGRhdGluZyB0aGUgaW50ZXJuYWwgYWNjdW11bGF0b3IuXG4gICAqLztcbiAgX3Byb3RvLnNsdWcgPSBmdW5jdGlvbiBzbHVnKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cbiAgICB2YXIgc2x1ZyA9IHRoaXMuc2VyaWFsaXplKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcy5nZXROZXh0U2FmZVNsdWcoc2x1Zywgb3B0aW9ucy5kcnlydW4pO1xuICB9O1xuICByZXR1cm4gU2x1Z2dlcjtcbn0oKTtcblxuLyoqXG4gKiBQYXJzaW5nICYgQ29tcGlsaW5nXG4gKi9cbnZhciBQYXJzZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBQYXJzZXIob3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwgZXhwb3J0cy5kZWZhdWx0cztcbiAgICB0aGlzLm9wdGlvbnMucmVuZGVyZXIgPSB0aGlzLm9wdGlvbnMucmVuZGVyZXIgfHwgbmV3IFJlbmRlcmVyKCk7XG4gICAgdGhpcy5yZW5kZXJlciA9IHRoaXMub3B0aW9ucy5yZW5kZXJlcjtcbiAgICB0aGlzLnJlbmRlcmVyLm9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgdGhpcy50ZXh0UmVuZGVyZXIgPSBuZXcgVGV4dFJlbmRlcmVyKCk7XG4gICAgdGhpcy5zbHVnZ2VyID0gbmV3IFNsdWdnZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGF0aWMgUGFyc2UgTWV0aG9kXG4gICAqL1xuICBQYXJzZXIucGFyc2UgPSBmdW5jdGlvbiBwYXJzZSh0b2tlbnMsIG9wdGlvbnMpIHtcbiAgICB2YXIgcGFyc2VyID0gbmV3IFBhcnNlcihvcHRpb25zKTtcbiAgICByZXR1cm4gcGFyc2VyLnBhcnNlKHRva2Vucyk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGljIFBhcnNlIElubGluZSBNZXRob2RcbiAgICovO1xuICBQYXJzZXIucGFyc2VJbmxpbmUgPSBmdW5jdGlvbiBwYXJzZUlubGluZSh0b2tlbnMsIG9wdGlvbnMpIHtcbiAgICB2YXIgcGFyc2VyID0gbmV3IFBhcnNlcihvcHRpb25zKTtcbiAgICByZXR1cm4gcGFyc2VyLnBhcnNlSW5saW5lKHRva2Vucyk7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgTG9vcFxuICAgKi87XG4gIHZhciBfcHJvdG8gPSBQYXJzZXIucHJvdG90eXBlO1xuICBfcHJvdG8ucGFyc2UgPSBmdW5jdGlvbiBwYXJzZSh0b2tlbnMsIHRvcCkge1xuICAgIGlmICh0b3AgPT09IHZvaWQgMCkge1xuICAgICAgdG9wID0gdHJ1ZTtcbiAgICB9XG4gICAgdmFyIG91dCA9ICcnLFxuICAgICAgaSxcbiAgICAgIGosXG4gICAgICBrLFxuICAgICAgbDIsXG4gICAgICBsMyxcbiAgICAgIHJvdyxcbiAgICAgIGNlbGwsXG4gICAgICBoZWFkZXIsXG4gICAgICBib2R5LFxuICAgICAgdG9rZW4sXG4gICAgICBvcmRlcmVkLFxuICAgICAgc3RhcnQsXG4gICAgICBsb29zZSxcbiAgICAgIGl0ZW1Cb2R5LFxuICAgICAgaXRlbSxcbiAgICAgIGNoZWNrZWQsXG4gICAgICB0YXNrLFxuICAgICAgY2hlY2tib3gsXG4gICAgICByZXQ7XG4gICAgdmFyIGwgPSB0b2tlbnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRva2VuID0gdG9rZW5zW2ldO1xuXG4gICAgICAvLyBSdW4gYW55IHJlbmRlcmVyIGV4dGVuc2lvbnNcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuZXh0ZW5zaW9ucyAmJiB0aGlzLm9wdGlvbnMuZXh0ZW5zaW9ucy5yZW5kZXJlcnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMucmVuZGVyZXJzW3Rva2VuLnR5cGVdKSB7XG4gICAgICAgIHJldCA9IHRoaXMub3B0aW9ucy5leHRlbnNpb25zLnJlbmRlcmVyc1t0b2tlbi50eXBlXS5jYWxsKHtcbiAgICAgICAgICBwYXJzZXI6IHRoaXNcbiAgICAgICAgfSwgdG9rZW4pO1xuICAgICAgICBpZiAocmV0ICE9PSBmYWxzZSB8fCAhWydzcGFjZScsICdocicsICdoZWFkaW5nJywgJ2NvZGUnLCAndGFibGUnLCAnYmxvY2txdW90ZScsICdsaXN0JywgJ2h0bWwnLCAncGFyYWdyYXBoJywgJ3RleHQnXS5pbmNsdWRlcyh0b2tlbi50eXBlKSkge1xuICAgICAgICAgIG91dCArPSByZXQgfHwgJyc7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgICBjYXNlICdzcGFjZSc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdocic6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuaHIoKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnaGVhZGluZyc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuaGVhZGluZyh0aGlzLnBhcnNlSW5saW5lKHRva2VuLnRva2VucyksIHRva2VuLmRlcHRoLCB1bmVzY2FwZSh0aGlzLnBhcnNlSW5saW5lKHRva2VuLnRva2VucywgdGhpcy50ZXh0UmVuZGVyZXIpKSwgdGhpcy5zbHVnZ2VyKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnY29kZSc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuY29kZSh0b2tlbi50ZXh0LCB0b2tlbi5sYW5nLCB0b2tlbi5lc2NhcGVkKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGhlYWRlciA9ICcnO1xuXG4gICAgICAgICAgICAvLyBoZWFkZXJcbiAgICAgICAgICAgIGNlbGwgPSAnJztcbiAgICAgICAgICAgIGwyID0gdG9rZW4uaGVhZGVyLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBsMjsgaisrKSB7XG4gICAgICAgICAgICAgIGNlbGwgKz0gdGhpcy5yZW5kZXJlci50YWJsZWNlbGwodGhpcy5wYXJzZUlubGluZSh0b2tlbi5oZWFkZXJbal0udG9rZW5zKSwge1xuICAgICAgICAgICAgICAgIGhlYWRlcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhbGlnbjogdG9rZW4uYWxpZ25bal1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoZWFkZXIgKz0gdGhpcy5yZW5kZXJlci50YWJsZXJvdyhjZWxsKTtcbiAgICAgICAgICAgIGJvZHkgPSAnJztcbiAgICAgICAgICAgIGwyID0gdG9rZW4ucm93cy5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbDI7IGorKykge1xuICAgICAgICAgICAgICByb3cgPSB0b2tlbi5yb3dzW2pdO1xuICAgICAgICAgICAgICBjZWxsID0gJyc7XG4gICAgICAgICAgICAgIGwzID0gcm93Lmxlbmd0aDtcbiAgICAgICAgICAgICAgZm9yIChrID0gMDsgayA8IGwzOyBrKyspIHtcbiAgICAgICAgICAgICAgICBjZWxsICs9IHRoaXMucmVuZGVyZXIudGFibGVjZWxsKHRoaXMucGFyc2VJbmxpbmUocm93W2tdLnRva2VucyksIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICBhbGlnbjogdG9rZW4uYWxpZ25ba11cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBib2R5ICs9IHRoaXMucmVuZGVyZXIudGFibGVyb3coY2VsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci50YWJsZShoZWFkZXIsIGJvZHkpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdibG9ja3F1b3RlJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBib2R5ID0gdGhpcy5wYXJzZSh0b2tlbi50b2tlbnMpO1xuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuYmxvY2txdW90ZShib2R5KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnbGlzdCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3JkZXJlZCA9IHRva2VuLm9yZGVyZWQ7XG4gICAgICAgICAgICBzdGFydCA9IHRva2VuLnN0YXJ0O1xuICAgICAgICAgICAgbG9vc2UgPSB0b2tlbi5sb29zZTtcbiAgICAgICAgICAgIGwyID0gdG9rZW4uaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgYm9keSA9ICcnO1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGwyOyBqKyspIHtcbiAgICAgICAgICAgICAgaXRlbSA9IHRva2VuLml0ZW1zW2pdO1xuICAgICAgICAgICAgICBjaGVja2VkID0gaXRlbS5jaGVja2VkO1xuICAgICAgICAgICAgICB0YXNrID0gaXRlbS50YXNrO1xuICAgICAgICAgICAgICBpdGVtQm9keSA9ICcnO1xuICAgICAgICAgICAgICBpZiAoaXRlbS50YXNrKSB7XG4gICAgICAgICAgICAgICAgY2hlY2tib3ggPSB0aGlzLnJlbmRlcmVyLmNoZWNrYm94KGNoZWNrZWQpO1xuICAgICAgICAgICAgICAgIGlmIChsb29zZSkge1xuICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0udG9rZW5zLmxlbmd0aCA+IDAgJiYgaXRlbS50b2tlbnNbMF0udHlwZSA9PT0gJ3BhcmFncmFwaCcpIHtcbiAgICAgICAgICAgICAgICAgICAgaXRlbS50b2tlbnNbMF0udGV4dCA9IGNoZWNrYm94ICsgJyAnICsgaXRlbS50b2tlbnNbMF0udGV4dDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0udG9rZW5zWzBdLnRva2VucyAmJiBpdGVtLnRva2Vuc1swXS50b2tlbnMubGVuZ3RoID4gMCAmJiBpdGVtLnRva2Vuc1swXS50b2tlbnNbMF0udHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaXRlbS50b2tlbnNbMF0udG9rZW5zWzBdLnRleHQgPSBjaGVja2JveCArICcgJyArIGl0ZW0udG9rZW5zWzBdLnRva2Vuc1swXS50ZXh0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpdGVtLnRva2Vucy51bnNoaWZ0KHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICAgICAgICAgICAgdGV4dDogY2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGl0ZW1Cb2R5ICs9IGNoZWNrYm94O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpdGVtQm9keSArPSB0aGlzLnBhcnNlKGl0ZW0udG9rZW5zLCBsb29zZSk7XG4gICAgICAgICAgICAgIGJvZHkgKz0gdGhpcy5yZW5kZXJlci5saXN0aXRlbShpdGVtQm9keSwgdGFzaywgY2hlY2tlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci5saXN0KGJvZHksIG9yZGVyZWQsIHN0YXJ0KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnaHRtbCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgLy8gVE9ETyBwYXJzZSBpbmxpbmUgY29udGVudCBpZiBwYXJhbWV0ZXIgbWFya2Rvd249MVxuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuaHRtbCh0b2tlbi50ZXh0KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAncGFyYWdyYXBoJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci5wYXJhZ3JhcGgodGhpcy5wYXJzZUlubGluZSh0b2tlbi50b2tlbnMpKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgYm9keSA9IHRva2VuLnRva2VucyA/IHRoaXMucGFyc2VJbmxpbmUodG9rZW4udG9rZW5zKSA6IHRva2VuLnRleHQ7XG4gICAgICAgICAgICB3aGlsZSAoaSArIDEgPCBsICYmIHRva2Vuc1tpICsgMV0udHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICAgIHRva2VuID0gdG9rZW5zWysraV07XG4gICAgICAgICAgICAgIGJvZHkgKz0gJ1xcbicgKyAodG9rZW4udG9rZW5zID8gdGhpcy5wYXJzZUlubGluZSh0b2tlbi50b2tlbnMpIDogdG9rZW4udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvdXQgKz0gdG9wID8gdGhpcy5yZW5kZXJlci5wYXJhZ3JhcGgoYm9keSkgOiBib2R5O1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBlcnJNc2cgPSAnVG9rZW4gd2l0aCBcIicgKyB0b2tlbi50eXBlICsgJ1wiIHR5cGUgd2FzIG5vdCBmb3VuZC4nO1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJNc2cpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyTXNnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgSW5saW5lIFRva2Vuc1xuICAgKi87XG4gIF9wcm90by5wYXJzZUlubGluZSA9IGZ1bmN0aW9uIHBhcnNlSW5saW5lKHRva2VucywgcmVuZGVyZXIpIHtcbiAgICByZW5kZXJlciA9IHJlbmRlcmVyIHx8IHRoaXMucmVuZGVyZXI7XG4gICAgdmFyIG91dCA9ICcnLFxuICAgICAgaSxcbiAgICAgIHRva2VuLFxuICAgICAgcmV0O1xuICAgIHZhciBsID0gdG9rZW5zLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICB0b2tlbiA9IHRva2Vuc1tpXTtcblxuICAgICAgLy8gUnVuIGFueSByZW5kZXJlciBleHRlbnNpb25zXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMucmVuZGVyZXJzICYmIHRoaXMub3B0aW9ucy5leHRlbnNpb25zLnJlbmRlcmVyc1t0b2tlbi50eXBlXSkge1xuICAgICAgICByZXQgPSB0aGlzLm9wdGlvbnMuZXh0ZW5zaW9ucy5yZW5kZXJlcnNbdG9rZW4udHlwZV0uY2FsbCh7XG4gICAgICAgICAgcGFyc2VyOiB0aGlzXG4gICAgICAgIH0sIHRva2VuKTtcbiAgICAgICAgaWYgKHJldCAhPT0gZmFsc2UgfHwgIVsnZXNjYXBlJywgJ2h0bWwnLCAnbGluaycsICdpbWFnZScsICdzdHJvbmcnLCAnZW0nLCAnY29kZXNwYW4nLCAnYnInLCAnZGVsJywgJ3RleHQnXS5pbmNsdWRlcyh0b2tlbi50eXBlKSkge1xuICAgICAgICAgIG91dCArPSByZXQgfHwgJyc7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgICBjYXNlICdlc2NhcGUnOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG91dCArPSByZW5kZXJlci50ZXh0KHRva2VuLnRleHQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdodG1sJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIuaHRtbCh0b2tlbi50ZXh0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnbGluayc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmxpbmsodG9rZW4uaHJlZiwgdG9rZW4udGl0bGUsIHRoaXMucGFyc2VJbmxpbmUodG9rZW4udG9rZW5zLCByZW5kZXJlcikpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdpbWFnZSc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmltYWdlKHRva2VuLmhyZWYsIHRva2VuLnRpdGxlLCB0b2tlbi50ZXh0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnc3Ryb25nJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIuc3Ryb25nKHRoaXMucGFyc2VJbmxpbmUodG9rZW4udG9rZW5zLCByZW5kZXJlcikpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdlbSc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmVtKHRoaXMucGFyc2VJbmxpbmUodG9rZW4udG9rZW5zLCByZW5kZXJlcikpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdjb2Rlc3Bhbic6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmNvZGVzcGFuKHRva2VuLnRleHQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdicic6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmJyKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2RlbCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmRlbCh0aGlzLnBhcnNlSW5saW5lKHRva2VuLnRva2VucywgcmVuZGVyZXIpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLnRleHQodG9rZW4udGV4dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIGVyck1zZyA9ICdUb2tlbiB3aXRoIFwiJyArIHRva2VuLnR5cGUgKyAnXCIgdHlwZSB3YXMgbm90IGZvdW5kLic7XG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNpbGVudCkge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVyck1zZyk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJNc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG91dDtcbiAgfTtcbiAgcmV0dXJuIFBhcnNlcjtcbn0oKTtcblxuLyoqXG4gKiBNYXJrZWRcbiAqL1xuZnVuY3Rpb24gbWFya2VkKHNyYywgb3B0LCBjYWxsYmFjaykge1xuICAvLyB0aHJvdyBlcnJvciBpbiBjYXNlIG9mIG5vbiBzdHJpbmcgaW5wdXRcbiAgaWYgKHR5cGVvZiBzcmMgPT09ICd1bmRlZmluZWQnIHx8IHNyYyA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkKCk6IGlucHV0IHBhcmFtZXRlciBpcyB1bmRlZmluZWQgb3IgbnVsbCcpO1xuICB9XG4gIGlmICh0eXBlb2Ygc3JjICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkKCk6IGlucHV0IHBhcmFtZXRlciBpcyBvZiB0eXBlICcgKyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3JjKSArICcsIHN0cmluZyBleHBlY3RlZCcpO1xuICB9XG4gIGlmICh0eXBlb2Ygb3B0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBvcHQ7XG4gICAgb3B0ID0gbnVsbDtcbiAgfVxuICBvcHQgPSBtZXJnZSh7fSwgbWFya2VkLmRlZmF1bHRzLCBvcHQgfHwge30pO1xuICBjaGVja1Nhbml0aXplRGVwcmVjYXRpb24ob3B0KTtcbiAgaWYgKGNhbGxiYWNrKSB7XG4gICAgdmFyIGhpZ2hsaWdodCA9IG9wdC5oaWdobGlnaHQ7XG4gICAgdmFyIHRva2VucztcbiAgICB0cnkge1xuICAgICAgdG9rZW5zID0gTGV4ZXIubGV4KHNyYywgb3B0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soZSk7XG4gICAgfVxuICAgIHZhciBkb25lID0gZnVuY3Rpb24gZG9uZShlcnIpIHtcbiAgICAgIHZhciBvdXQ7XG4gICAgICBpZiAoIWVycikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChvcHQud2Fsa1Rva2Vucykge1xuICAgICAgICAgICAgbWFya2VkLndhbGtUb2tlbnModG9rZW5zLCBvcHQud2Fsa1Rva2Vucyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG91dCA9IFBhcnNlci5wYXJzZSh0b2tlbnMsIG9wdCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBlcnIgPSBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBvcHQuaGlnaGxpZ2h0ID0gaGlnaGxpZ2h0O1xuICAgICAgcmV0dXJuIGVyciA/IGNhbGxiYWNrKGVycikgOiBjYWxsYmFjayhudWxsLCBvdXQpO1xuICAgIH07XG4gICAgaWYgKCFoaWdobGlnaHQgfHwgaGlnaGxpZ2h0Lmxlbmd0aCA8IDMpIHtcbiAgICAgIHJldHVybiBkb25lKCk7XG4gICAgfVxuICAgIGRlbGV0ZSBvcHQuaGlnaGxpZ2h0O1xuICAgIGlmICghdG9rZW5zLmxlbmd0aCkgcmV0dXJuIGRvbmUoKTtcbiAgICB2YXIgcGVuZGluZyA9IDA7XG4gICAgbWFya2VkLndhbGtUb2tlbnModG9rZW5zLCBmdW5jdGlvbiAodG9rZW4pIHtcbiAgICAgIGlmICh0b2tlbi50eXBlID09PSAnY29kZScpIHtcbiAgICAgICAgcGVuZGluZysrO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBoaWdobGlnaHQodG9rZW4udGV4dCwgdG9rZW4ubGFuZywgZnVuY3Rpb24gKGVyciwgY29kZSkge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICByZXR1cm4gZG9uZShlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvZGUgIT0gbnVsbCAmJiBjb2RlICE9PSB0b2tlbi50ZXh0KSB7XG4gICAgICAgICAgICAgIHRva2VuLnRleHQgPSBjb2RlO1xuICAgICAgICAgICAgICB0b2tlbi5lc2NhcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBlbmRpbmctLTtcbiAgICAgICAgICAgIGlmIChwZW5kaW5nID09PSAwKSB7XG4gICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgMCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHBlbmRpbmcgPT09IDApIHtcbiAgICAgIGRvbmUoKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG4gIGZ1bmN0aW9uIG9uRXJyb3IoZSkge1xuICAgIGUubWVzc2FnZSArPSAnXFxuUGxlYXNlIHJlcG9ydCB0aGlzIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXJrZWRqcy9tYXJrZWQuJztcbiAgICBpZiAob3B0LnNpbGVudCkge1xuICAgICAgcmV0dXJuICc8cD5BbiBlcnJvciBvY2N1cnJlZDo8L3A+PHByZT4nICsgZXNjYXBlKGUubWVzc2FnZSArICcnLCB0cnVlKSArICc8L3ByZT4nO1xuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9XG4gIHRyeSB7XG4gICAgdmFyIF90b2tlbnMgPSBMZXhlci5sZXgoc3JjLCBvcHQpO1xuICAgIGlmIChvcHQud2Fsa1Rva2Vucykge1xuICAgICAgaWYgKG9wdC5hc3luYykge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwobWFya2VkLndhbGtUb2tlbnMoX3Rva2Vucywgb3B0LndhbGtUb2tlbnMpKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gUGFyc2VyLnBhcnNlKF90b2tlbnMsIG9wdCk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ob25FcnJvcik7XG4gICAgICB9XG4gICAgICBtYXJrZWQud2Fsa1Rva2VucyhfdG9rZW5zLCBvcHQud2Fsa1Rva2Vucyk7XG4gICAgfVxuICAgIHJldHVybiBQYXJzZXIucGFyc2UoX3Rva2Vucywgb3B0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIG9uRXJyb3IoZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBPcHRpb25zXG4gKi9cblxubWFya2VkLm9wdGlvbnMgPSBtYXJrZWQuc2V0T3B0aW9ucyA9IGZ1bmN0aW9uIChvcHQpIHtcbiAgbWVyZ2UobWFya2VkLmRlZmF1bHRzLCBvcHQpO1xuICBjaGFuZ2VEZWZhdWx0cyhtYXJrZWQuZGVmYXVsdHMpO1xuICByZXR1cm4gbWFya2VkO1xufTtcbm1hcmtlZC5nZXREZWZhdWx0cyA9IGdldERlZmF1bHRzO1xubWFya2VkLmRlZmF1bHRzID0gZXhwb3J0cy5kZWZhdWx0cztcblxuLyoqXG4gKiBVc2UgRXh0ZW5zaW9uXG4gKi9cblxubWFya2VkLnVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGV4dGVuc2lvbnMgPSBtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucyB8fCB7XG4gICAgcmVuZGVyZXJzOiB7fSxcbiAgICBjaGlsZFRva2Vuczoge31cbiAgfTtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgfVxuICBhcmdzLmZvckVhY2goZnVuY3Rpb24gKHBhY2spIHtcbiAgICAvLyBjb3B5IG9wdGlvbnMgdG8gbmV3IG9iamVjdFxuICAgIHZhciBvcHRzID0gbWVyZ2Uoe30sIHBhY2spO1xuXG4gICAgLy8gc2V0IGFzeW5jIHRvIHRydWUgaWYgaXQgd2FzIHNldCB0byB0cnVlIGJlZm9yZVxuICAgIG9wdHMuYXN5bmMgPSBtYXJrZWQuZGVmYXVsdHMuYXN5bmMgfHwgb3B0cy5hc3luYztcblxuICAgIC8vID09LS0gUGFyc2UgXCJhZGRvblwiIGV4dGVuc2lvbnMgLS09PSAvL1xuICAgIGlmIChwYWNrLmV4dGVuc2lvbnMpIHtcbiAgICAgIHBhY2suZXh0ZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChleHQpIHtcbiAgICAgICAgaWYgKCFleHQubmFtZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZXh0ZW5zaW9uIG5hbWUgcmVxdWlyZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXh0LnJlbmRlcmVyKSB7XG4gICAgICAgICAgLy8gUmVuZGVyZXIgZXh0ZW5zaW9uc1xuICAgICAgICAgIHZhciBwcmV2UmVuZGVyZXIgPSBleHRlbnNpb25zLnJlbmRlcmVyc1tleHQubmFtZV07XG4gICAgICAgICAgaWYgKHByZXZSZW5kZXJlcikge1xuICAgICAgICAgICAgLy8gUmVwbGFjZSBleHRlbnNpb24gd2l0aCBmdW5jIHRvIHJ1biBuZXcgZXh0ZW5zaW9uIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICAgIGV4dGVuc2lvbnMucmVuZGVyZXJzW2V4dC5uYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgICAgICAgICAgYXJnc1tfa2V5Ml0gPSBhcmd1bWVudHNbX2tleTJdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciByZXQgPSBleHQucmVuZGVyZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICAgIGlmIChyZXQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgcmV0ID0gcHJldlJlbmRlcmVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHRlbnNpb25zLnJlbmRlcmVyc1tleHQubmFtZV0gPSBleHQucmVuZGVyZXI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChleHQudG9rZW5pemVyKSB7XG4gICAgICAgICAgLy8gVG9rZW5pemVyIEV4dGVuc2lvbnNcbiAgICAgICAgICBpZiAoIWV4dC5sZXZlbCB8fCBleHQubGV2ZWwgIT09ICdibG9jaycgJiYgZXh0LmxldmVsICE9PSAnaW5saW5lJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZXh0ZW5zaW9uIGxldmVsIG11c3QgYmUgJ2Jsb2NrJyBvciAnaW5saW5lJ1wiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGV4dGVuc2lvbnNbZXh0LmxldmVsXSkge1xuICAgICAgICAgICAgZXh0ZW5zaW9uc1tleHQubGV2ZWxdLnVuc2hpZnQoZXh0LnRva2VuaXplcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4dGVuc2lvbnNbZXh0LmxldmVsXSA9IFtleHQudG9rZW5pemVyXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGV4dC5zdGFydCkge1xuICAgICAgICAgICAgLy8gRnVuY3Rpb24gdG8gY2hlY2sgZm9yIHN0YXJ0IG9mIHRva2VuXG4gICAgICAgICAgICBpZiAoZXh0LmxldmVsID09PSAnYmxvY2snKSB7XG4gICAgICAgICAgICAgIGlmIChleHRlbnNpb25zLnN0YXJ0QmxvY2spIHtcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0QmxvY2sucHVzaChleHQuc3RhcnQpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGV4dGVuc2lvbnMuc3RhcnRCbG9jayA9IFtleHQuc3RhcnRdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGV4dC5sZXZlbCA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbnMuc3RhcnRJbmxpbmUpIHtcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0SW5saW5lLnB1c2goZXh0LnN0YXJ0KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0SW5saW5lID0gW2V4dC5zdGFydF07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dC5jaGlsZFRva2Vucykge1xuICAgICAgICAgIC8vIENoaWxkIHRva2VucyB0byBiZSB2aXNpdGVkIGJ5IHdhbGtUb2tlbnNcbiAgICAgICAgICBleHRlbnNpb25zLmNoaWxkVG9rZW5zW2V4dC5uYW1lXSA9IGV4dC5jaGlsZFRva2VucztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBvcHRzLmV4dGVuc2lvbnMgPSBleHRlbnNpb25zO1xuICAgIH1cblxuICAgIC8vID09LS0gUGFyc2UgXCJvdmVyd3JpdGVcIiBleHRlbnNpb25zIC0tPT0gLy9cbiAgICBpZiAocGFjay5yZW5kZXJlcikge1xuICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJlbmRlcmVyID0gbWFya2VkLmRlZmF1bHRzLnJlbmRlcmVyIHx8IG5ldyBSZW5kZXJlcigpO1xuICAgICAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiBfbG9vcChwcm9wKSB7XG4gICAgICAgICAgdmFyIHByZXZSZW5kZXJlciA9IHJlbmRlcmVyW3Byb3BdO1xuICAgICAgICAgIC8vIFJlcGxhY2UgcmVuZGVyZXIgd2l0aCBmdW5jIHRvIHJ1biBleHRlbnNpb24sIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICByZW5kZXJlcltwcm9wXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGZvciAodmFyIF9sZW4zID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMyksIF9rZXkzID0gMDsgX2tleTMgPCBfbGVuMzsgX2tleTMrKykge1xuICAgICAgICAgICAgICBhcmdzW19rZXkzXSA9IGFyZ3VtZW50c1tfa2V5M107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcmV0ID0gcGFjay5yZW5kZXJlcltwcm9wXS5hcHBseShyZW5kZXJlciwgYXJncyk7XG4gICAgICAgICAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICByZXQgPSBwcmV2UmVuZGVyZXIuYXBwbHkocmVuZGVyZXIsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHBhY2sucmVuZGVyZXIpIHtcbiAgICAgICAgICBfbG9vcChwcm9wKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICB9KSgpO1xuICAgIH1cbiAgICBpZiAocGFjay50b2tlbml6ZXIpIHtcbiAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0b2tlbml6ZXIgPSBtYXJrZWQuZGVmYXVsdHMudG9rZW5pemVyIHx8IG5ldyBUb2tlbml6ZXIoKTtcbiAgICAgICAgdmFyIF9sb29wMiA9IGZ1bmN0aW9uIF9sb29wMihwcm9wKSB7XG4gICAgICAgICAgdmFyIHByZXZUb2tlbml6ZXIgPSB0b2tlbml6ZXJbcHJvcF07XG4gICAgICAgICAgLy8gUmVwbGFjZSB0b2tlbml6ZXIgd2l0aCBmdW5jIHRvIHJ1biBleHRlbnNpb24sIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICB0b2tlbml6ZXJbcHJvcF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBfbGVuNCA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjQpLCBfa2V5NCA9IDA7IF9rZXk0IDwgX2xlbjQ7IF9rZXk0KyspIHtcbiAgICAgICAgICAgICAgYXJnc1tfa2V5NF0gPSBhcmd1bWVudHNbX2tleTRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHJldCA9IHBhY2sudG9rZW5pemVyW3Byb3BdLmFwcGx5KHRva2VuaXplciwgYXJncyk7XG4gICAgICAgICAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICByZXQgPSBwcmV2VG9rZW5pemVyLmFwcGx5KHRva2VuaXplciwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIGZvciAodmFyIHByb3AgaW4gcGFjay50b2tlbml6ZXIpIHtcbiAgICAgICAgICBfbG9vcDIocHJvcCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0cy50b2tlbml6ZXIgPSB0b2tlbml6ZXI7XG4gICAgICB9KSgpO1xuICAgIH1cblxuICAgIC8vID09LS0gUGFyc2UgV2Fsa1Rva2VucyBleHRlbnNpb25zIC0tPT0gLy9cbiAgICBpZiAocGFjay53YWxrVG9rZW5zKSB7XG4gICAgICB2YXIgX3dhbGtUb2tlbnMgPSBtYXJrZWQuZGVmYXVsdHMud2Fsa1Rva2VucztcbiAgICAgIG9wdHMud2Fsa1Rva2VucyA9IGZ1bmN0aW9uICh0b2tlbikge1xuICAgICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICAgIHZhbHVlcy5wdXNoKHBhY2sud2Fsa1Rva2Vucy5jYWxsKHRoaXMsIHRva2VuKSk7XG4gICAgICAgIGlmIChfd2Fsa1Rva2Vucykge1xuICAgICAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQoX3dhbGtUb2tlbnMuY2FsbCh0aGlzLCB0b2tlbikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgICB9O1xuICAgIH1cbiAgICBtYXJrZWQuc2V0T3B0aW9ucyhvcHRzKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIFJ1biBjYWxsYmFjayBmb3IgZXZlcnkgdG9rZW5cbiAqL1xuXG5tYXJrZWQud2Fsa1Rva2VucyA9IGZ1bmN0aW9uICh0b2tlbnMsIGNhbGxiYWNrKSB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgdmFyIF9sb29wMyA9IGZ1bmN0aW9uIF9sb29wMygpIHtcbiAgICB2YXIgdG9rZW4gPSBfc3RlcC52YWx1ZTtcbiAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KGNhbGxiYWNrLmNhbGwobWFya2VkLCB0b2tlbikpO1xuICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICB7XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyTG9vc2UodG9rZW4uaGVhZGVyKSwgX3N0ZXAyOyAhKF9zdGVwMiA9IF9pdGVyYXRvcjIoKSkuZG9uZTspIHtcbiAgICAgICAgICAgIHZhciBjZWxsID0gX3N0ZXAyLnZhbHVlO1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2VucyhjZWxsLnRva2VucywgY2FsbGJhY2spKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMyA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyTG9vc2UodG9rZW4ucm93cyksIF9zdGVwMzsgIShfc3RlcDMgPSBfaXRlcmF0b3IzKCkpLmRvbmU7KSB7XG4gICAgICAgICAgICB2YXIgcm93ID0gX3N0ZXAzLnZhbHVlO1xuICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yNCA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyTG9vc2Uocm93KSwgX3N0ZXA0OyAhKF9zdGVwNCA9IF9pdGVyYXRvcjQoKSkuZG9uZTspIHtcbiAgICAgICAgICAgICAgdmFyIF9jZWxsID0gX3N0ZXA0LnZhbHVlO1xuICAgICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KG1hcmtlZC53YWxrVG9rZW5zKF9jZWxsLnRva2VucywgY2FsbGJhY2spKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2xpc3QnOlxuICAgICAgICB7XG4gICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2Vucyh0b2tlbi5pdGVtcywgY2FsbGJhY2spKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAge1xuICAgICAgICAgIGlmIChtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucyAmJiBtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucy5jaGlsZFRva2VucyAmJiBtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucy5jaGlsZFRva2Vuc1t0b2tlbi50eXBlXSkge1xuICAgICAgICAgICAgLy8gV2FsayBhbnkgZXh0ZW5zaW9uc1xuICAgICAgICAgICAgbWFya2VkLmRlZmF1bHRzLmV4dGVuc2lvbnMuY2hpbGRUb2tlbnNbdG9rZW4udHlwZV0uZm9yRWFjaChmdW5jdGlvbiAoY2hpbGRUb2tlbnMpIHtcbiAgICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2Vucyh0b2tlbltjaGlsZFRva2Vuc10sIGNhbGxiYWNrKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuLnRva2Vucykge1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2Vucyh0b2tlbi50b2tlbnMsIGNhbGxiYWNrKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICB9O1xuICBmb3IgKHZhciBfaXRlcmF0b3IgPSBfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlckxvb3NlKHRva2VucyksIF9zdGVwOyAhKF9zdGVwID0gX2l0ZXJhdG9yKCkpLmRvbmU7KSB7XG4gICAgX2xvb3AzKCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlcztcbn07XG5cbi8qKlxuICogUGFyc2UgSW5saW5lXG4gKiBAcGFyYW0ge3N0cmluZ30gc3JjXG4gKi9cbm1hcmtlZC5wYXJzZUlubGluZSA9IGZ1bmN0aW9uIChzcmMsIG9wdCkge1xuICAvLyB0aHJvdyBlcnJvciBpbiBjYXNlIG9mIG5vbiBzdHJpbmcgaW5wdXRcbiAgaWYgKHR5cGVvZiBzcmMgPT09ICd1bmRlZmluZWQnIHx8IHNyYyA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkLnBhcnNlSW5saW5lKCk6IGlucHV0IHBhcmFtZXRlciBpcyB1bmRlZmluZWQgb3IgbnVsbCcpO1xuICB9XG4gIGlmICh0eXBlb2Ygc3JjICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkLnBhcnNlSW5saW5lKCk6IGlucHV0IHBhcmFtZXRlciBpcyBvZiB0eXBlICcgKyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3JjKSArICcsIHN0cmluZyBleHBlY3RlZCcpO1xuICB9XG4gIG9wdCA9IG1lcmdlKHt9LCBtYXJrZWQuZGVmYXVsdHMsIG9wdCB8fCB7fSk7XG4gIGNoZWNrU2FuaXRpemVEZXByZWNhdGlvbihvcHQpO1xuICB0cnkge1xuICAgIHZhciB0b2tlbnMgPSBMZXhlci5sZXhJbmxpbmUoc3JjLCBvcHQpO1xuICAgIGlmIChvcHQud2Fsa1Rva2Vucykge1xuICAgICAgbWFya2VkLndhbGtUb2tlbnModG9rZW5zLCBvcHQud2Fsa1Rva2Vucyk7XG4gICAgfVxuICAgIHJldHVybiBQYXJzZXIucGFyc2VJbmxpbmUodG9rZW5zLCBvcHQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgZS5tZXNzYWdlICs9ICdcXG5QbGVhc2UgcmVwb3J0IHRoaXMgdG8gaHR0cHM6Ly9naXRodWIuY29tL21hcmtlZGpzL21hcmtlZC4nO1xuICAgIGlmIChvcHQuc2lsZW50KSB7XG4gICAgICByZXR1cm4gJzxwPkFuIGVycm9yIG9jY3VycmVkOjwvcD48cHJlPicgKyBlc2NhcGUoZS5tZXNzYWdlICsgJycsIHRydWUpICsgJzwvcHJlPic7XG4gICAgfVxuICAgIHRocm93IGU7XG4gIH1cbn07XG5cbi8qKlxuICogRXhwb3NlXG4gKi9cbm1hcmtlZC5QYXJzZXIgPSBQYXJzZXI7XG5tYXJrZWQucGFyc2VyID0gUGFyc2VyLnBhcnNlO1xubWFya2VkLlJlbmRlcmVyID0gUmVuZGVyZXI7XG5tYXJrZWQuVGV4dFJlbmRlcmVyID0gVGV4dFJlbmRlcmVyO1xubWFya2VkLkxleGVyID0gTGV4ZXI7XG5tYXJrZWQubGV4ZXIgPSBMZXhlci5sZXg7XG5tYXJrZWQuVG9rZW5pemVyID0gVG9rZW5pemVyO1xubWFya2VkLlNsdWdnZXIgPSBTbHVnZ2VyO1xubWFya2VkLnBhcnNlID0gbWFya2VkO1xudmFyIG9wdGlvbnMgPSBtYXJrZWQub3B0aW9ucztcbnZhciBzZXRPcHRpb25zID0gbWFya2VkLnNldE9wdGlvbnM7XG52YXIgdXNlID0gbWFya2VkLnVzZTtcbnZhciB3YWxrVG9rZW5zID0gbWFya2VkLndhbGtUb2tlbnM7XG52YXIgcGFyc2VJbmxpbmUgPSBtYXJrZWQucGFyc2VJbmxpbmU7XG52YXIgcGFyc2UgPSBtYXJrZWQ7XG52YXIgcGFyc2VyID0gUGFyc2VyLnBhcnNlO1xudmFyIGxleGVyID0gTGV4ZXIubGV4O1xuXG5leHBvcnRzLkxleGVyID0gTGV4ZXI7XG5leHBvcnRzLlBhcnNlciA9IFBhcnNlcjtcbmV4cG9ydHMuUmVuZGVyZXIgPSBSZW5kZXJlcjtcbmV4cG9ydHMuU2x1Z2dlciA9IFNsdWdnZXI7XG5leHBvcnRzLlRleHRSZW5kZXJlciA9IFRleHRSZW5kZXJlcjtcbmV4cG9ydHMuVG9rZW5pemVyID0gVG9rZW5pemVyO1xuZXhwb3J0cy5nZXREZWZhdWx0cyA9IGdldERlZmF1bHRzO1xuZXhwb3J0cy5sZXhlciA9IGxleGVyO1xuZXhwb3J0cy5tYXJrZWQgPSBtYXJrZWQ7XG5leHBvcnRzLm9wdGlvbnMgPSBvcHRpb25zO1xuZXhwb3J0cy5wYXJzZSA9IHBhcnNlO1xuZXhwb3J0cy5wYXJzZUlubGluZSA9IHBhcnNlSW5saW5lO1xuZXhwb3J0cy5wYXJzZXIgPSBwYXJzZXI7XG5leHBvcnRzLnNldE9wdGlvbnMgPSBzZXRPcHRpb25zO1xuZXhwb3J0cy51c2UgPSB1c2U7XG5leHBvcnRzLndhbGtUb2tlbnMgPSB3YWxrVG9rZW5zO1xuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHRpZDogbW9kdWxlSWQsXG5cdFx0bG9hZGVkOiBmYWxzZSxcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG5cdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuLy8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbl9fd2VicGFja19yZXF1aXJlX18ubSA9IF9fd2VicGFja19tb2R1bGVzX187XG5cbiIsIi8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb25zIGZvciBoYXJtb255IGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uZCA9IChleHBvcnRzLCBkZWZpbml0aW9uKSA9PiB7XG5cdGZvcih2YXIga2V5IGluIGRlZmluaXRpb24pIHtcblx0XHRpZihfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZGVmaW5pdGlvbiwga2V5KSAmJiAhX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIGtleSkpIHtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBrZXksIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBkZWZpbml0aW9uW2tleV0gfSk7XG5cdFx0fVxuXHR9XG59OyIsIl9fd2VicGFja19yZXF1aXJlX18uZiA9IHt9O1xuLy8gVGhpcyBmaWxlIGNvbnRhaW5zIG9ubHkgdGhlIGVudHJ5IGNodW5rLlxuLy8gVGhlIGNodW5rIGxvYWRpbmcgZnVuY3Rpb24gZm9yIGFkZGl0aW9uYWwgY2h1bmtzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmUgPSAoY2h1bmtJZCkgPT4ge1xuXHRyZXR1cm4gUHJvbWlzZS5hbGwoT2JqZWN0LmtleXMoX193ZWJwYWNrX3JlcXVpcmVfXy5mKS5yZWR1Y2UoKHByb21pc2VzLCBrZXkpID0+IHtcblx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmZba2V5XShjaHVua0lkLCBwcm9taXNlcyk7XG5cdFx0cmV0dXJuIHByb21pc2VzO1xuXHR9LCBbXSkpO1xufTsiLCIvLyBUaGlzIGZ1bmN0aW9uIGFsbG93IHRvIHJlZmVyZW5jZSBhc3luYyBjaHVua3Ncbl9fd2VicGFja19yZXF1aXJlX18udSA9IChjaHVua0lkKSA9PiB7XG5cdC8vIHJldHVybiB1cmwgZm9yIGZpbGVuYW1lcyBiYXNlZCBvbiB0ZW1wbGF0ZVxuXHRyZXR1cm4gXCJcIiArIGNodW5rSWQgKyBcIi5idW5kbGUuanNcIjtcbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5nID0gKGZ1bmN0aW9uKCkge1xuXHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgPT09ICdvYmplY3QnKSByZXR1cm4gZ2xvYmFsVGhpcztcblx0dHJ5IHtcblx0XHRyZXR1cm4gdGhpcyB8fCBuZXcgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JykgcmV0dXJuIHdpbmRvdztcblx0fVxufSkoKTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwidmFyIGluUHJvZ3Jlc3MgPSB7fTtcbnZhciBkYXRhV2VicGFja1ByZWZpeCA9IFwib3V0bGluZS1icm93c2VyOlwiO1xuLy8gbG9hZFNjcmlwdCBmdW5jdGlvbiB0byBsb2FkIGEgc2NyaXB0IHZpYSBzY3JpcHQgdGFnXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmwgPSAodXJsLCBkb25lLCBrZXksIGNodW5rSWQpID0+IHtcblx0aWYoaW5Qcm9ncmVzc1t1cmxdKSB7IGluUHJvZ3Jlc3NbdXJsXS5wdXNoKGRvbmUpOyByZXR1cm47IH1cblx0dmFyIHNjcmlwdCwgbmVlZEF0dGFjaDtcblx0aWYoa2V5ICE9PSB1bmRlZmluZWQpIHtcblx0XHR2YXIgc2NyaXB0cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwic2NyaXB0XCIpO1xuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCBzY3JpcHRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgcyA9IHNjcmlwdHNbaV07XG5cdFx0XHRpZihzLmdldEF0dHJpYnV0ZShcInNyY1wiKSA9PSB1cmwgfHwgcy5nZXRBdHRyaWJ1dGUoXCJkYXRhLXdlYnBhY2tcIikgPT0gZGF0YVdlYnBhY2tQcmVmaXggKyBrZXkpIHsgc2NyaXB0ID0gczsgYnJlYWs7IH1cblx0XHR9XG5cdH1cblx0aWYoIXNjcmlwdCkge1xuXHRcdG5lZWRBdHRhY2ggPSB0cnVlO1xuXHRcdHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG5cdFx0c2NyaXB0LmNoYXJzZXQgPSAndXRmLTgnO1xuXHRcdHNjcmlwdC50aW1lb3V0ID0gMTIwO1xuXHRcdGlmIChfX3dlYnBhY2tfcmVxdWlyZV9fLm5jKSB7XG5cdFx0XHRzY3JpcHQuc2V0QXR0cmlidXRlKFwibm9uY2VcIiwgX193ZWJwYWNrX3JlcXVpcmVfXy5uYyk7XG5cdFx0fVxuXHRcdHNjcmlwdC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXdlYnBhY2tcIiwgZGF0YVdlYnBhY2tQcmVmaXggKyBrZXkpO1xuXHRcdHNjcmlwdC5zcmMgPSB1cmw7XG5cdH1cblx0aW5Qcm9ncmVzc1t1cmxdID0gW2RvbmVdO1xuXHR2YXIgb25TY3JpcHRDb21wbGV0ZSA9IChwcmV2LCBldmVudCkgPT4ge1xuXHRcdC8vIGF2b2lkIG1lbSBsZWFrcyBpbiBJRS5cblx0XHRzY3JpcHQub25lcnJvciA9IHNjcmlwdC5vbmxvYWQgPSBudWxsO1xuXHRcdGNsZWFyVGltZW91dCh0aW1lb3V0KTtcblx0XHR2YXIgZG9uZUZucyA9IGluUHJvZ3Jlc3NbdXJsXTtcblx0XHRkZWxldGUgaW5Qcm9ncmVzc1t1cmxdO1xuXHRcdHNjcmlwdC5wYXJlbnROb2RlICYmIHNjcmlwdC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHNjcmlwdCk7XG5cdFx0ZG9uZUZucyAmJiBkb25lRm5zLmZvckVhY2goKGZuKSA9PiAoZm4oZXZlbnQpKSk7XG5cdFx0aWYocHJldikgcmV0dXJuIHByZXYoZXZlbnQpO1xuXHR9O1xuXHR2YXIgdGltZW91dCA9IHNldFRpbWVvdXQob25TY3JpcHRDb21wbGV0ZS5iaW5kKG51bGwsIHVuZGVmaW5lZCwgeyB0eXBlOiAndGltZW91dCcsIHRhcmdldDogc2NyaXB0IH0pLCAxMjAwMDApO1xuXHRzY3JpcHQub25lcnJvciA9IG9uU2NyaXB0Q29tcGxldGUuYmluZChudWxsLCBzY3JpcHQub25lcnJvcik7XG5cdHNjcmlwdC5vbmxvYWQgPSBvblNjcmlwdENvbXBsZXRlLmJpbmQobnVsbCwgc2NyaXB0Lm9ubG9hZCk7XG5cdG5lZWRBdHRhY2ggJiYgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xufTsiLCIvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSAoZXhwb3J0cykgPT4ge1xuXHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcblx0fVxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm5tZCA9IChtb2R1bGUpID0+IHtcblx0bW9kdWxlLnBhdGhzID0gW107XG5cdGlmICghbW9kdWxlLmNoaWxkcmVuKSBtb2R1bGUuY2hpbGRyZW4gPSBbXTtcblx0cmV0dXJuIG1vZHVsZTtcbn07IiwidmFyIHNjcmlwdFVybDtcbmlmIChfX3dlYnBhY2tfcmVxdWlyZV9fLmcuaW1wb3J0U2NyaXB0cykgc2NyaXB0VXJsID0gX193ZWJwYWNrX3JlcXVpcmVfXy5nLmxvY2F0aW9uICsgXCJcIjtcbnZhciBkb2N1bWVudCA9IF9fd2VicGFja19yZXF1aXJlX18uZy5kb2N1bWVudDtcbmlmICghc2NyaXB0VXJsICYmIGRvY3VtZW50KSB7XG5cdGlmIChkb2N1bWVudC5jdXJyZW50U2NyaXB0KVxuXHRcdHNjcmlwdFVybCA9IGRvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjXG5cdGlmICghc2NyaXB0VXJsKSB7XG5cdFx0dmFyIHNjcmlwdHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInNjcmlwdFwiKTtcblx0XHRpZihzY3JpcHRzLmxlbmd0aCkgc2NyaXB0VXJsID0gc2NyaXB0c1tzY3JpcHRzLmxlbmd0aCAtIDFdLnNyY1xuXHR9XG59XG4vLyBXaGVuIHN1cHBvcnRpbmcgYnJvd3NlcnMgd2hlcmUgYW4gYXV0b21hdGljIHB1YmxpY1BhdGggaXMgbm90IHN1cHBvcnRlZCB5b3UgbXVzdCBzcGVjaWZ5IGFuIG91dHB1dC5wdWJsaWNQYXRoIG1hbnVhbGx5IHZpYSBjb25maWd1cmF0aW9uXG4vLyBvciBwYXNzIGFuIGVtcHR5IHN0cmluZyAoXCJcIikgYW5kIHNldCB0aGUgX193ZWJwYWNrX3B1YmxpY19wYXRoX18gdmFyaWFibGUgZnJvbSB5b3VyIGNvZGUgdG8gdXNlIHlvdXIgb3duIGxvZ2ljLlxuaWYgKCFzY3JpcHRVcmwpIHRocm93IG5ldyBFcnJvcihcIkF1dG9tYXRpYyBwdWJsaWNQYXRoIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyXCIpO1xuc2NyaXB0VXJsID0gc2NyaXB0VXJsLnJlcGxhY2UoLyMuKiQvLCBcIlwiKS5yZXBsYWNlKC9cXD8uKiQvLCBcIlwiKS5yZXBsYWNlKC9cXC9bXlxcL10rJC8sIFwiL1wiKTtcbl9fd2VicGFja19yZXF1aXJlX18ucCA9IHNjcmlwdFVybDsiLCIvLyBubyBiYXNlVVJJXG5cbi8vIG9iamVjdCB0byBzdG9yZSBsb2FkZWQgYW5kIGxvYWRpbmcgY2h1bmtzXG4vLyB1bmRlZmluZWQgPSBjaHVuayBub3QgbG9hZGVkLCBudWxsID0gY2h1bmsgcHJlbG9hZGVkL3ByZWZldGNoZWRcbi8vIFtyZXNvbHZlLCByZWplY3QsIFByb21pc2VdID0gY2h1bmsgbG9hZGluZywgMCA9IGNodW5rIGxvYWRlZFxudmFyIGluc3RhbGxlZENodW5rcyA9IHtcblx0XCJtYWluXCI6IDBcbn07XG5cbl9fd2VicGFja19yZXF1aXJlX18uZi5qID0gKGNodW5rSWQsIHByb21pc2VzKSA9PiB7XG5cdFx0Ly8gSlNPTlAgY2h1bmsgbG9hZGluZyBmb3IgamF2YXNjcmlwdFxuXHRcdHZhciBpbnN0YWxsZWRDaHVua0RhdGEgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLm8oaW5zdGFsbGVkQ2h1bmtzLCBjaHVua0lkKSA/IGluc3RhbGxlZENodW5rc1tjaHVua0lkXSA6IHVuZGVmaW5lZDtcblx0XHRpZihpbnN0YWxsZWRDaHVua0RhdGEgIT09IDApIHsgLy8gMCBtZWFucyBcImFscmVhZHkgaW5zdGFsbGVkXCIuXG5cblx0XHRcdC8vIGEgUHJvbWlzZSBtZWFucyBcImN1cnJlbnRseSBsb2FkaW5nXCIuXG5cdFx0XHRpZihpbnN0YWxsZWRDaHVua0RhdGEpIHtcblx0XHRcdFx0cHJvbWlzZXMucHVzaChpbnN0YWxsZWRDaHVua0RhdGFbMl0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYodHJ1ZSkgeyAvLyBhbGwgY2h1bmtzIGhhdmUgSlNcblx0XHRcdFx0XHQvLyBzZXR1cCBQcm9taXNlIGluIGNodW5rIGNhY2hlXG5cdFx0XHRcdFx0dmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiAoaW5zdGFsbGVkQ2h1bmtEYXRhID0gaW5zdGFsbGVkQ2h1bmtzW2NodW5rSWRdID0gW3Jlc29sdmUsIHJlamVjdF0pKTtcblx0XHRcdFx0XHRwcm9taXNlcy5wdXNoKGluc3RhbGxlZENodW5rRGF0YVsyXSA9IHByb21pc2UpO1xuXG5cdFx0XHRcdFx0Ly8gc3RhcnQgY2h1bmsgbG9hZGluZ1xuXHRcdFx0XHRcdHZhciB1cmwgPSBfX3dlYnBhY2tfcmVxdWlyZV9fLnAgKyBfX3dlYnBhY2tfcmVxdWlyZV9fLnUoY2h1bmtJZCk7XG5cdFx0XHRcdFx0Ly8gY3JlYXRlIGVycm9yIGJlZm9yZSBzdGFjayB1bndvdW5kIHRvIGdldCB1c2VmdWwgc3RhY2t0cmFjZSBsYXRlclxuXHRcdFx0XHRcdHZhciBlcnJvciA9IG5ldyBFcnJvcigpO1xuXHRcdFx0XHRcdHZhciBsb2FkaW5nRW5kZWQgPSAoZXZlbnQpID0+IHtcblx0XHRcdFx0XHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhpbnN0YWxsZWRDaHVua3MsIGNodW5rSWQpKSB7XG5cdFx0XHRcdFx0XHRcdGluc3RhbGxlZENodW5rRGF0YSA9IGluc3RhbGxlZENodW5rc1tjaHVua0lkXTtcblx0XHRcdFx0XHRcdFx0aWYoaW5zdGFsbGVkQ2h1bmtEYXRhICE9PSAwKSBpbnN0YWxsZWRDaHVua3NbY2h1bmtJZF0gPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdGlmKGluc3RhbGxlZENodW5rRGF0YSkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciBlcnJvclR5cGUgPSBldmVudCAmJiAoZXZlbnQudHlwZSA9PT0gJ2xvYWQnID8gJ21pc3NpbmcnIDogZXZlbnQudHlwZSk7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIHJlYWxTcmMgPSBldmVudCAmJiBldmVudC50YXJnZXQgJiYgZXZlbnQudGFyZ2V0LnNyYztcblx0XHRcdFx0XHRcdFx0XHRlcnJvci5tZXNzYWdlID0gJ0xvYWRpbmcgY2h1bmsgJyArIGNodW5rSWQgKyAnIGZhaWxlZC5cXG4oJyArIGVycm9yVHlwZSArICc6ICcgKyByZWFsU3JjICsgJyknO1xuXHRcdFx0XHRcdFx0XHRcdGVycm9yLm5hbWUgPSAnQ2h1bmtMb2FkRXJyb3InO1xuXHRcdFx0XHRcdFx0XHRcdGVycm9yLnR5cGUgPSBlcnJvclR5cGU7XG5cdFx0XHRcdFx0XHRcdFx0ZXJyb3IucmVxdWVzdCA9IHJlYWxTcmM7XG5cdFx0XHRcdFx0XHRcdFx0aW5zdGFsbGVkQ2h1bmtEYXRhWzFdKGVycm9yKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5sKHVybCwgbG9hZGluZ0VuZGVkLCBcImNodW5rLVwiICsgY2h1bmtJZCwgY2h1bmtJZCk7XG5cdFx0XHRcdH0gZWxzZSBpbnN0YWxsZWRDaHVua3NbY2h1bmtJZF0gPSAwO1xuXHRcdFx0fVxuXHRcdH1cbn07XG5cbi8vIG5vIHByZWZldGNoaW5nXG5cbi8vIG5vIHByZWxvYWRlZFxuXG4vLyBubyBITVJcblxuLy8gbm8gSE1SIG1hbmlmZXN0XG5cbi8vIG5vIG9uIGNodW5rcyBsb2FkZWRcblxuLy8gaW5zdGFsbCBhIEpTT05QIGNhbGxiYWNrIGZvciBjaHVuayBsb2FkaW5nXG52YXIgd2VicGFja0pzb25wQ2FsbGJhY2sgPSAocGFyZW50Q2h1bmtMb2FkaW5nRnVuY3Rpb24sIGRhdGEpID0+IHtcblx0dmFyIFtjaHVua0lkcywgbW9yZU1vZHVsZXMsIHJ1bnRpbWVdID0gZGF0YTtcblx0Ly8gYWRkIFwibW9yZU1vZHVsZXNcIiB0byB0aGUgbW9kdWxlcyBvYmplY3QsXG5cdC8vIHRoZW4gZmxhZyBhbGwgXCJjaHVua0lkc1wiIGFzIGxvYWRlZCBhbmQgZmlyZSBjYWxsYmFja1xuXHR2YXIgbW9kdWxlSWQsIGNodW5rSWQsIGkgPSAwO1xuXHRpZihjaHVua0lkcy5zb21lKChpZCkgPT4gKGluc3RhbGxlZENodW5rc1tpZF0gIT09IDApKSkge1xuXHRcdGZvcihtb2R1bGVJZCBpbiBtb3JlTW9kdWxlcykge1xuXHRcdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKG1vcmVNb2R1bGVzLCBtb2R1bGVJZCkpIHtcblx0XHRcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tW21vZHVsZUlkXSA9IG1vcmVNb2R1bGVzW21vZHVsZUlkXTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYocnVudGltZSkgdmFyIHJlc3VsdCA9IHJ1bnRpbWUoX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cdH1cblx0aWYocGFyZW50Q2h1bmtMb2FkaW5nRnVuY3Rpb24pIHBhcmVudENodW5rTG9hZGluZ0Z1bmN0aW9uKGRhdGEpO1xuXHRmb3IoO2kgPCBjaHVua0lkcy5sZW5ndGg7IGkrKykge1xuXHRcdGNodW5rSWQgPSBjaHVua0lkc1tpXTtcblx0XHRpZihfX3dlYnBhY2tfcmVxdWlyZV9fLm8oaW5zdGFsbGVkQ2h1bmtzLCBjaHVua0lkKSAmJiBpbnN0YWxsZWRDaHVua3NbY2h1bmtJZF0pIHtcblx0XHRcdGluc3RhbGxlZENodW5rc1tjaHVua0lkXVswXSgpO1xuXHRcdH1cblx0XHRpbnN0YWxsZWRDaHVua3NbY2h1bmtJZF0gPSAwO1xuXHR9XG5cbn1cblxudmFyIGNodW5rTG9hZGluZ0dsb2JhbCA9IHNlbGZbXCJ3ZWJwYWNrQ2h1bmtvdXRsaW5lX2Jyb3dzZXJcIl0gPSBzZWxmW1wid2VicGFja0NodW5rb3V0bGluZV9icm93c2VyXCJdIHx8IFtdO1xuY2h1bmtMb2FkaW5nR2xvYmFsLmZvckVhY2god2VicGFja0pzb25wQ2FsbGJhY2suYmluZChudWxsLCAwKSk7XG5jaHVua0xvYWRpbmdHbG9iYWwucHVzaCA9IHdlYnBhY2tKc29ucENhbGxiYWNrLmJpbmQobnVsbCwgY2h1bmtMb2FkaW5nR2xvYmFsLnB1c2guYmluZChjaHVua0xvYWRpbmdHbG9iYWwpKTsiLCIiLCIvLyBzdGFydHVwXG4vLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbi8vIFRoaXMgZW50cnkgbW9kdWxlIGlzIHJlZmVyZW5jZWQgYnkgb3RoZXIgbW9kdWxlcyBzbyBpdCBjYW4ndCBiZSBpbmxpbmVkXG52YXIgX193ZWJwYWNrX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oXCIuL3NyYy9jbGllbnQudHNcIik7XG4iLCIiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=