shortcut: $ to jump to end of contenteditable node
[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 __importDefault = (this && this.__importDefault) || function (mod) {
18348     return (mod && mod.__esModule) ? mod : { "default": mod };
18349 };
18350 Object.defineProperty(exports, "__esModule", ({ value: true }));
18351 const outline_1 = __webpack_require__(/*! ./outline */ "./src/outline.ts");
18352 const cursor_1 = __webpack_require__(/*! ./cursor */ "./src/cursor.ts");
18353 const keyboardjs_1 = __importDefault(__webpack_require__(/*! keyboardjs */ "./node_modules/keyboardjs/dist/keyboard.js"));
18354 const rawOutline = __importStar(__webpack_require__(/*! ./test-data.json */ "./src/test-data.json"));
18355 let outlineData = rawOutline;
18356 if (localStorage.getItem('activeOutline')) {
18357     const outlineId = localStorage.getItem('activeOutline');
18358     outlineData = JSON.parse(localStorage.getItem(outlineId));
18359 }
18360 const state = new Map();
18361 const outline = new outline_1.Outline(outlineData);
18362 outliner().innerHTML = outline.render();
18363 const cursor = new cursor_1.Cursor();
18364 cursor.set('.node');
18365 function outliner() {
18366     return document.querySelector('#outliner');
18367 }
18368 keyboardjs_1.default.withContext('navigation', () => {
18369     keyboardjs_1.default.bind('j', e => {
18370         const sibling = cursor.get().nextElementSibling;
18371         if (sibling) {
18372             if (e.shiftKey) {
18373                 const res = outline.swapNodeWithNextSibling(cursor.getIdOfNode());
18374                 const html = outline.renderNode(res.parentNode);
18375                 if (res.parentNode.id === '000000') {
18376                     cursor.get().parentElement.innerHTML = html;
18377                 }
18378                 else {
18379                     cursor.get().parentElement.outerHTML = html;
18380                 }
18381                 cursor.set(`#id-${res.targetNode.id}`);
18382                 save();
18383             }
18384             else {
18385                 cursor.set(`#id-${sibling.getAttribute('data-id')}`);
18386             }
18387         }
18388     });
18389     keyboardjs_1.default.bind('k', e => {
18390         const sibling = cursor.get().previousElementSibling;
18391         if (sibling && !sibling.classList.contains('nodeContent')) {
18392             if (e.shiftKey) {
18393                 const res = outline.swapNodeWithPreviousSibling(cursor.getIdOfNode());
18394                 const html = outline.renderNode(res.parentNode);
18395                 if (res.parentNode.id === '000000') {
18396                     cursor.get().parentElement.innerHTML = html;
18397                 }
18398                 else {
18399                     cursor.get().parentElement.outerHTML = html;
18400                 }
18401                 cursor.set(`#id-${res.targetNode.id}`);
18402                 save();
18403             }
18404             else {
18405                 cursor.set(`#id-${sibling.getAttribute('data-id')}`);
18406             }
18407         }
18408     });
18409     keyboardjs_1.default.bind('l', e => {
18410         if (cursor.isNodeCollapsed()) {
18411             return;
18412         }
18413         if (e.shiftKey) {
18414             const res = outline.lowerNodeToChild(cursor.getIdOfNode());
18415             const html = outline.renderNode(res.oldParentNode);
18416             if (res.oldParentNode.id === '000000') {
18417                 cursor.get().parentElement.innerHTML = html;
18418             }
18419             else {
18420                 cursor.get().parentElement.outerHTML = html;
18421             }
18422             cursor.set(`#id-${res.targetNode.id}`);
18423         }
18424         else {
18425             const children = cursor.get().querySelector('.node');
18426             if (children) {
18427                 cursor.set(`#id-${children.getAttribute('data-id')}`);
18428             }
18429         }
18430     });
18431     keyboardjs_1.default.bind('h', e => {
18432         const parent = cursor.get().parentElement;
18433         if (parent && parent.classList.contains('node')) {
18434             if (e.shiftKey) {
18435                 if (outline.data.tree.children.map(n => n.id).includes(cursor.getIdOfNode())) {
18436                     return;
18437                 }
18438                 const res = outline.liftNodeToParent(cursor.getIdOfNode());
18439                 const html = outline.renderNode(res.parentNode);
18440                 if (res.parentNode.id === '000000') {
18441                     cursor.get().parentElement.parentElement.innerHTML = html;
18442                 }
18443                 else {
18444                     cursor.get().parentElement.parentElement.outerHTML = html;
18445                 }
18446                 cursor.set(`#id-${res.targetNode.id}`);
18447                 save();
18448             }
18449             else {
18450                 cursor.set(`#id-${parent.getAttribute('data-id')}`);
18451             }
18452         }
18453     });
18454     keyboardjs_1.default.bind('z', e => {
18455         if (cursor.isNodeExpanded()) {
18456             cursor.collapse();
18457             outline.fold(cursor.getIdOfNode());
18458         }
18459         else if (cursor.isNodeCollapsed()) {
18460             cursor.expand();
18461             outline.unfold(cursor.getIdOfNode());
18462         }
18463         save();
18464     });
18465     keyboardjs_1.default.bind('shift + 4', e => {
18466         e.preventDefault();
18467         cursor.get().classList.add('hidden-cursor');
18468         const contentNode = cursor.get().querySelector('.nodeContent');
18469         contentNode.innerHTML = outline.data.contentNodes[cursor.getIdOfNode()].content;
18470         contentNode.contentEditable = "true";
18471         const range = document.createRange();
18472         range.selectNodeContents(contentNode);
18473         range.collapse(false);
18474         const selection = window.getSelection();
18475         selection.removeAllRanges();
18476         selection.addRange(range);
18477         contentNode.focus();
18478         keyboardjs_1.default.setContext('editing');
18479     });
18480     keyboardjs_1.default.bind('i', e => {
18481         e.preventDefault();
18482         cursor.get().classList.add('hidden-cursor');
18483         const contentNode = cursor.get().querySelector('.nodeContent');
18484         contentNode.innerHTML = outline.data.contentNodes[cursor.getIdOfNode()].content;
18485         contentNode.contentEditable = "true";
18486         contentNode.focus();
18487         keyboardjs_1.default.setContext('editing');
18488     });
18489     keyboardjs_1.default.bind('tab', e => {
18490         e.preventDefault();
18491         const res = outline.createChildNode(cursor.getIdOfNode());
18492         const html = outline.renderNode(res.parentNode);
18493         cursor.get().outerHTML = html;
18494         cursor.set(`#id-${res.node.id}`);
18495         save();
18496     });
18497     keyboardjs_1.default.bind('enter', e => {
18498         if (e.shiftKey) {
18499             return;
18500         }
18501         e.preventDefault();
18502         e.preventRepeat();
18503         const res = outline.createSiblingNode(cursor.getIdOfNode());
18504         const html = outline.renderNode(res.parentNode);
18505         if (res.parentNode.id === '000000') {
18506             cursor.get().parentElement.innerHTML = html;
18507         }
18508         else {
18509             cursor.get().parentElement.outerHTML = html;
18510         }
18511         cursor.set(`#id-${res.node.id}`);
18512         save();
18513     });
18514     keyboardjs_1.default.bind('d', e => {
18515         if (!e.shiftKey) {
18516             return;
18517         }
18518         const res = outline.removeNode(cursor.getIdOfNode());
18519         const html = outline.renderNode(res.parentNode);
18520         const prevSibling = cursor.get().previousElementSibling;
18521         const nextSibling = cursor.get().nextElementSibling;
18522         if (res.parentNode.id === '000000') {
18523             cursor.get().parentElement.innerHTML = html;
18524         }
18525         else {
18526             cursor.get().parentElement.outerHTML = html;
18527         }
18528         if (prevSibling.getAttribute('data-id')) {
18529             cursor.set(`#id-${prevSibling.getAttribute('data-id')}`);
18530         }
18531         else if (nextSibling.getAttribute('data-id')) {
18532             cursor.set(`#id-${nextSibling.getAttribute('data-id')}`);
18533         }
18534         else {
18535             console.log(res.parentNode.id);
18536             cursor.set(`#id-${res.parentNode.id}`);
18537         }
18538         save();
18539     });
18540 });
18541 keyboardjs_1.default.withContext('editing', () => {
18542     keyboardjs_1.default.bind(['esc', 'enter'], e => {
18543         cursor.get().classList.remove('hidden-cursor');
18544         const contentNode = cursor.get().querySelector('.nodeContent');
18545         contentNode.contentEditable = "false";
18546         contentNode.blur();
18547         keyboardjs_1.default.setContext('navigation');
18548         outline.updateContent(cursor.getIdOfNode(), contentNode.innerHTML.trim());
18549         contentNode.innerHTML = outline.renderContent(cursor.getIdOfNode());
18550         save();
18551     });
18552 });
18553 keyboardjs_1.default.setContext('navigation');
18554 function saveImmediate() {
18555     localStorage.setItem(outline.data.id, JSON.stringify(outline.data));
18556     localStorage.setItem('activeOutline', outline.data.id);
18557     console.log('saved...', outline.data);
18558     state.delete('saveTimeout');
18559 }
18560 function save() {
18561     if (!state.has('saveTimeout')) {
18562         state.set('saveTimeout', setTimeout(saveImmediate, 2000));
18563     }
18564 }
18565 save();
18566
18567
18568 /***/ }),
18569
18570 /***/ "./src/cursor.ts":
18571 /*!***********************!*\
18572   !*** ./src/cursor.ts ***!
18573   \***********************/
18574 /***/ ((__unused_webpack_module, exports) => {
18575
18576 "use strict";
18577
18578 Object.defineProperty(exports, "__esModule", ({ value: true }));
18579 exports.Cursor = void 0;
18580 class Cursor {
18581     constructor() {
18582     }
18583     get() {
18584         return document.querySelector('.cursor');
18585     }
18586     getIdOfNode() {
18587         return this.get().getAttribute('data-id');
18588     }
18589     unset() {
18590         const el = this.get();
18591         if (el) {
18592             el.classList.remove('cursor');
18593         }
18594     }
18595     set(elementId) {
18596         this.unset();
18597         const el = document.querySelector(elementId);
18598         if (el) {
18599             el.classList.add('cursor');
18600             if (!this.isVisible(elementId)) {
18601                 el.scrollIntoView(true);
18602             }
18603         }
18604     }
18605     collapse() {
18606         this.get().classList.remove('expanded');
18607         this.get().classList.add('collapsed');
18608     }
18609     expand() {
18610         this.get().classList.remove('collapsed');
18611         this.get().classList.add('expanded');
18612     }
18613     isNodeCollapsed() {
18614         return this.get().classList.contains('collapsed');
18615     }
18616     isNodeExpanded() {
18617         return this.get().classList.contains('expanded');
18618     }
18619     isVisible(elementId) {
18620         const el = document.querySelector(elementId);
18621         var rect = el.getBoundingClientRect();
18622         return (rect.top >= 0 &&
18623             rect.left >= 0 &&
18624             rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
18625             rect.right <= (window.innerWidth || document.documentElement.clientWidth));
18626     }
18627 }
18628 exports.Cursor = Cursor;
18629
18630
18631 /***/ }),
18632
18633 /***/ "./src/outline.ts":
18634 /*!************************!*\
18635   !*** ./src/outline.ts ***!
18636   \************************/
18637 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
18638
18639 "use strict";
18640
18641 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18642     if (k2 === undefined) k2 = k;
18643     var desc = Object.getOwnPropertyDescriptor(m, k);
18644     if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18645       desc = { enumerable: true, get: function() { return m[k]; } };
18646     }
18647     Object.defineProperty(o, k2, desc);
18648 }) : (function(o, m, k, k2) {
18649     if (k2 === undefined) k2 = k;
18650     o[k2] = m[k];
18651 }));
18652 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18653     Object.defineProperty(o, "default", { enumerable: true, value: v });
18654 }) : function(o, v) {
18655     o["default"] = v;
18656 });
18657 var __importStar = (this && this.__importStar) || function (mod) {
18658     if (mod && mod.__esModule) return mod;
18659     var result = {};
18660     if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18661     __setModuleDefault(result, mod);
18662     return result;
18663 };
18664 Object.defineProperty(exports, "__esModule", ({ value: true }));
18665 exports.Outline = void 0;
18666 const _ = __importStar(__webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"));
18667 const uuid_1 = __webpack_require__(/*! uuid */ "./node_modules/uuid/dist/commonjs-browser/index.js");
18668 const marked_1 = __webpack_require__(/*! marked */ "./node_modules/marked/lib/marked.cjs");
18669 ;
18670 class Outline {
18671     constructor(outlineData) {
18672         this.data = outlineData;
18673     }
18674     findNodeInTree(root, id, action, runState = false) {
18675         let run = runState;
18676         if (run) {
18677             return;
18678         }
18679         _.each(root.children, (childNode, idx) => {
18680             if (childNode.id === id) {
18681                 action(childNode, root);
18682                 run = true;
18683                 return false;
18684             }
18685             else if (childNode.children) {
18686                 this.findNodeInTree(childNode, id, action, run);
18687             }
18688         });
18689     }
18690     fold(nodeId) {
18691         this.findNodeInTree(this.data.tree, nodeId, item => {
18692             item.collapsed = true;
18693         });
18694     }
18695     unfold(nodeId) {
18696         this.findNodeInTree(this.data.tree, nodeId, item => {
18697             item.collapsed = true;
18698         });
18699     }
18700     flattenOutlineTreeChildren(tree) {
18701         return tree.children.map(node => node.id);
18702     }
18703     liftNodeToParent(nodeId) {
18704         let run = false;
18705         let targetNode, parentNode;
18706         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18707             targetNode = tNode;
18708             this.findNodeInTree(this.data.tree, pNode.id, (originalParentNode, newParentNode) => {
18709                 ;
18710                 if (run) {
18711                     return;
18712                 }
18713                 parentNode = newParentNode;
18714                 run = true;
18715                 const flatId = newParentNode.children.map(n => n.id);
18716                 const originalNodePosition = originalParentNode.children.map(n => n.id).indexOf(targetNode.id);
18717                 const newNodePosition = flatId.indexOf(originalParentNode.id);
18718                 originalParentNode.children.splice(originalNodePosition, 1);
18719                 newParentNode.children.splice(newNodePosition + 1, 0, targetNode);
18720             });
18721         });
18722         return {
18723             targetNode,
18724             parentNode
18725         };
18726     }
18727     lowerNodeToChild(nodeId) {
18728         let run = false;
18729         let targetNode, newParentNode, oldParentNode;
18730         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18731             if (run) {
18732                 return;
18733             }
18734             run = true;
18735             targetNode = tNode;
18736             let idList = pNode.children.map(n => n.id);
18737             if (idList.length === 1) {
18738                 return;
18739             }
18740             const position = idList.indexOf(targetNode.id);
18741             const prevSiblingPosition = position - 1;
18742             pNode.children[prevSiblingPosition].children.splice(0, 0, targetNode);
18743             pNode.children.splice(position, 1);
18744             newParentNode = pNode.children[prevSiblingPosition];
18745             oldParentNode = pNode;
18746         });
18747         return {
18748             targetNode,
18749             newParentNode,
18750             oldParentNode
18751         };
18752     }
18753     swapNodeWithNextSibling(nodeId) {
18754         let targetNode, parentNode;
18755         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18756             targetNode = tNode;
18757             parentNode = pNode;
18758             const flatId = parentNode.children.map(n => n.id);
18759             const nodePosition = flatId.indexOf(targetNode.id);
18760             if (nodePosition === (flatId.length - 1)) {
18761                 return;
18762             }
18763             parentNode.children.splice(nodePosition, 1);
18764             parentNode.children.splice(nodePosition + 1, 0, targetNode);
18765         });
18766         return {
18767             targetNode,
18768             parentNode
18769         };
18770     }
18771     swapNodeWithPreviousSibling(nodeId) {
18772         let targetNode, parentNode;
18773         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18774             targetNode = tNode;
18775             parentNode = pNode;
18776             const flatId = parentNode.children.map(n => n.id);
18777             const nodePosition = flatId.indexOf(targetNode.id);
18778             if (nodePosition === 0) {
18779                 return;
18780             }
18781             parentNode.children.splice(nodePosition, 1);
18782             parentNode.children.splice(nodePosition - 1, 0, targetNode);
18783         });
18784         return {
18785             targetNode,
18786             parentNode
18787         };
18788     }
18789     createSiblingNode(targetNode, nodeData) {
18790         const outlineNode = nodeData || {
18791             id: (0, uuid_1.v4)(),
18792             created: Date.now(),
18793             type: 'text',
18794             content: '---'
18795         };
18796         this.data.contentNodes[outlineNode.id] = outlineNode;
18797         let parentNode;
18798         this.findNodeInTree(this.data.tree, targetNode, (node, parent) => {
18799             const position = parent.children.map(n => n.id).indexOf(targetNode);
18800             parent.children.splice(position + 1, 0, {
18801                 id: outlineNode.id,
18802                 collapsed: false,
18803                 children: []
18804             });
18805             parentNode = parent;
18806         });
18807         return {
18808             node: outlineNode,
18809             parentNode
18810         };
18811     }
18812     createChildNode(currentNode, nodeId) {
18813         const node = nodeId ? this.data.contentNodes[nodeId] :
18814             {
18815                 id: (0, uuid_1.v4)(),
18816                 created: Date.now(),
18817                 type: 'text',
18818                 content: '---'
18819             };
18820         if (!nodeId) {
18821             this.data.contentNodes[node.id] = node;
18822         }
18823         let parentNode;
18824         this.findNodeInTree(this.data.tree, currentNode, (foundNode, parent) => {
18825             foundNode.children.unshift({
18826                 id: node.id,
18827                 children: [],
18828                 collapsed: false
18829             });
18830             parentNode = foundNode;
18831         });
18832         return {
18833             node,
18834             parentNode
18835         };
18836     }
18837     removeNode(nodeId) {
18838         let run = false;
18839         let removedNode, parentNode;
18840         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18841             if (run) {
18842                 return;
18843             }
18844             run = true;
18845             removedNode = tNode;
18846             parentNode = pNode;
18847             let position = parentNode.children.map(n => n.id).indexOf(tNode.id);
18848             parentNode.children.splice(position, 1);
18849         });
18850         return {
18851             removedNode,
18852             parentNode
18853         };
18854     }
18855     updateContent(id, content) {
18856         if (!this.data.contentNodes[id]) {
18857             throw new Error('Invalid node');
18858         }
18859         this.data.contentNodes[id].content = content;
18860     }
18861     renderContent(nodeId) {
18862         let node = this.data.contentNodes[nodeId];
18863         let content;
18864         switch (node.type) {
18865             case 'text':
18866                 content = marked_1.marked.parse(node.content);
18867                 break;
18868             default:
18869                 content = node.content;
18870                 break;
18871         }
18872         return content;
18873     }
18874     renderNode(node) {
18875         if (node.id === '000000') {
18876             return this.render();
18877         }
18878         const collapse = node.collapsed ? 'collapsed' : 'expanded';
18879         const content = this.data.contentNodes[node.id] || {
18880             id: node.id,
18881             created: Date.now(),
18882             type: 'text',
18883             content: ''
18884         };
18885         let html = `<div class="node ${collapse}" data-id="${node.id}" id="id-${node.id}">
18886     <div class="nodeContent" data-type="${content.type}">
18887       ${this.renderContent(node.id)}
18888     </div>
18889     ${node.children.length ? _.map(node.children, this.renderNode.bind(this)).join("\n") : ''}
18890     </div>`;
18891         return html;
18892     }
18893     render() {
18894         return _.map(this.data.tree.children, this.renderNode.bind(this)).join("\n");
18895     }
18896 }
18897 exports.Outline = Outline;
18898
18899
18900 /***/ }),
18901
18902 /***/ "./node_modules/uuid/dist/commonjs-browser/index.js":
18903 /*!**********************************************************!*\
18904   !*** ./node_modules/uuid/dist/commonjs-browser/index.js ***!
18905   \**********************************************************/
18906 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
18907
18908 "use strict";
18909
18910
18911 Object.defineProperty(exports, "__esModule", ({
18912   value: true
18913 }));
18914 Object.defineProperty(exports, "NIL", ({
18915   enumerable: true,
18916   get: function get() {
18917     return _nil.default;
18918   }
18919 }));
18920 Object.defineProperty(exports, "parse", ({
18921   enumerable: true,
18922   get: function get() {
18923     return _parse.default;
18924   }
18925 }));
18926 Object.defineProperty(exports, "stringify", ({
18927   enumerable: true,
18928   get: function get() {
18929     return _stringify.default;
18930   }
18931 }));
18932 Object.defineProperty(exports, "v1", ({
18933   enumerable: true,
18934   get: function get() {
18935     return _v.default;
18936   }
18937 }));
18938 Object.defineProperty(exports, "v3", ({
18939   enumerable: true,
18940   get: function get() {
18941     return _v2.default;
18942   }
18943 }));
18944 Object.defineProperty(exports, "v4", ({
18945   enumerable: true,
18946   get: function get() {
18947     return _v3.default;
18948   }
18949 }));
18950 Object.defineProperty(exports, "v5", ({
18951   enumerable: true,
18952   get: function get() {
18953     return _v4.default;
18954   }
18955 }));
18956 Object.defineProperty(exports, "validate", ({
18957   enumerable: true,
18958   get: function get() {
18959     return _validate.default;
18960   }
18961 }));
18962 Object.defineProperty(exports, "version", ({
18963   enumerable: true,
18964   get: function get() {
18965     return _version.default;
18966   }
18967 }));
18968
18969 var _v = _interopRequireDefault(__webpack_require__(/*! ./v1.js */ "./node_modules/uuid/dist/commonjs-browser/v1.js"));
18970
18971 var _v2 = _interopRequireDefault(__webpack_require__(/*! ./v3.js */ "./node_modules/uuid/dist/commonjs-browser/v3.js"));
18972
18973 var _v3 = _interopRequireDefault(__webpack_require__(/*! ./v4.js */ "./node_modules/uuid/dist/commonjs-browser/v4.js"));
18974
18975 var _v4 = _interopRequireDefault(__webpack_require__(/*! ./v5.js */ "./node_modules/uuid/dist/commonjs-browser/v5.js"));
18976
18977 var _nil = _interopRequireDefault(__webpack_require__(/*! ./nil.js */ "./node_modules/uuid/dist/commonjs-browser/nil.js"));
18978
18979 var _version = _interopRequireDefault(__webpack_require__(/*! ./version.js */ "./node_modules/uuid/dist/commonjs-browser/version.js"));
18980
18981 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
18982
18983 var _stringify = _interopRequireDefault(__webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js"));
18984
18985 var _parse = _interopRequireDefault(__webpack_require__(/*! ./parse.js */ "./node_modules/uuid/dist/commonjs-browser/parse.js"));
18986
18987 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18988
18989 /***/ }),
18990
18991 /***/ "./node_modules/uuid/dist/commonjs-browser/md5.js":
18992 /*!********************************************************!*\
18993   !*** ./node_modules/uuid/dist/commonjs-browser/md5.js ***!
18994   \********************************************************/
18995 /***/ ((__unused_webpack_module, exports) => {
18996
18997 "use strict";
18998
18999
19000 Object.defineProperty(exports, "__esModule", ({
19001   value: true
19002 }));
19003 exports["default"] = void 0;
19004
19005 /*
19006  * Browser-compatible JavaScript MD5
19007  *
19008  * Modification of JavaScript MD5
19009  * https://github.com/blueimp/JavaScript-MD5
19010  *
19011  * Copyright 2011, Sebastian Tschan
19012  * https://blueimp.net
19013  *
19014  * Licensed under the MIT license:
19015  * https://opensource.org/licenses/MIT
19016  *
19017  * Based on
19018  * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
19019  * Digest Algorithm, as defined in RFC 1321.
19020  * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
19021  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
19022  * Distributed under the BSD License
19023  * See http://pajhome.org.uk/crypt/md5 for more info.
19024  */
19025 function md5(bytes) {
19026   if (typeof bytes === 'string') {
19027     const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
19028
19029     bytes = new Uint8Array(msg.length);
19030
19031     for (let i = 0; i < msg.length; ++i) {
19032       bytes[i] = msg.charCodeAt(i);
19033     }
19034   }
19035
19036   return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8));
19037 }
19038 /*
19039  * Convert an array of little-endian words to an array of bytes
19040  */
19041
19042
19043 function md5ToHexEncodedArray(input) {
19044   const output = [];
19045   const length32 = input.length * 32;
19046   const hexTab = '0123456789abcdef';
19047
19048   for (let i = 0; i < length32; i += 8) {
19049     const x = input[i >> 5] >>> i % 32 & 0xff;
19050     const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16);
19051     output.push(hex);
19052   }
19053
19054   return output;
19055 }
19056 /**
19057  * Calculate output length with padding and bit length
19058  */
19059
19060
19061 function getOutputLength(inputLength8) {
19062   return (inputLength8 + 64 >>> 9 << 4) + 14 + 1;
19063 }
19064 /*
19065  * Calculate the MD5 of an array of little-endian words, and a bit length.
19066  */
19067
19068
19069 function wordsToMd5(x, len) {
19070   /* append padding */
19071   x[len >> 5] |= 0x80 << len % 32;
19072   x[getOutputLength(len) - 1] = len;
19073   let a = 1732584193;
19074   let b = -271733879;
19075   let c = -1732584194;
19076   let d = 271733878;
19077
19078   for (let i = 0; i < x.length; i += 16) {
19079     const olda = a;
19080     const oldb = b;
19081     const oldc = c;
19082     const oldd = d;
19083     a = md5ff(a, b, c, d, x[i], 7, -680876936);
19084     d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
19085     c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
19086     b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
19087     a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
19088     d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
19089     c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
19090     b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
19091     a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
19092     d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
19093     c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
19094     b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
19095     a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
19096     d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
19097     c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
19098     b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
19099     a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
19100     d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
19101     c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
19102     b = md5gg(b, c, d, a, x[i], 20, -373897302);
19103     a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
19104     d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
19105     c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
19106     b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
19107     a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
19108     d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
19109     c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
19110     b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
19111     a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
19112     d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
19113     c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
19114     b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
19115     a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
19116     d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
19117     c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
19118     b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
19119     a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
19120     d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
19121     c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
19122     b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
19123     a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
19124     d = md5hh(d, a, b, c, x[i], 11, -358537222);
19125     c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
19126     b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
19127     a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
19128     d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
19129     c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
19130     b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
19131     a = md5ii(a, b, c, d, x[i], 6, -198630844);
19132     d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
19133     c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
19134     b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
19135     a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
19136     d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
19137     c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
19138     b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
19139     a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
19140     d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
19141     c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
19142     b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
19143     a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
19144     d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
19145     c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
19146     b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
19147     a = safeAdd(a, olda);
19148     b = safeAdd(b, oldb);
19149     c = safeAdd(c, oldc);
19150     d = safeAdd(d, oldd);
19151   }
19152
19153   return [a, b, c, d];
19154 }
19155 /*
19156  * Convert an array bytes to an array of little-endian words
19157  * Characters >255 have their high-byte silently ignored.
19158  */
19159
19160
19161 function bytesToWords(input) {
19162   if (input.length === 0) {
19163     return [];
19164   }
19165
19166   const length8 = input.length * 8;
19167   const output = new Uint32Array(getOutputLength(length8));
19168
19169   for (let i = 0; i < length8; i += 8) {
19170     output[i >> 5] |= (input[i / 8] & 0xff) << i % 32;
19171   }
19172
19173   return output;
19174 }
19175 /*
19176  * Add integers, wrapping at 2^32. This uses 16-bit operations internally
19177  * to work around bugs in some JS interpreters.
19178  */
19179
19180
19181 function safeAdd(x, y) {
19182   const lsw = (x & 0xffff) + (y & 0xffff);
19183   const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
19184   return msw << 16 | lsw & 0xffff;
19185 }
19186 /*
19187  * Bitwise rotate a 32-bit number to the left.
19188  */
19189
19190
19191 function bitRotateLeft(num, cnt) {
19192   return num << cnt | num >>> 32 - cnt;
19193 }
19194 /*
19195  * These functions implement the four basic operations the algorithm uses.
19196  */
19197
19198
19199 function md5cmn(q, a, b, x, s, t) {
19200   return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
19201 }
19202
19203 function md5ff(a, b, c, d, x, s, t) {
19204   return md5cmn(b & c | ~b & d, a, b, x, s, t);
19205 }
19206
19207 function md5gg(a, b, c, d, x, s, t) {
19208   return md5cmn(b & d | c & ~d, a, b, x, s, t);
19209 }
19210
19211 function md5hh(a, b, c, d, x, s, t) {
19212   return md5cmn(b ^ c ^ d, a, b, x, s, t);
19213 }
19214
19215 function md5ii(a, b, c, d, x, s, t) {
19216   return md5cmn(c ^ (b | ~d), a, b, x, s, t);
19217 }
19218
19219 var _default = md5;
19220 exports["default"] = _default;
19221
19222 /***/ }),
19223
19224 /***/ "./node_modules/uuid/dist/commonjs-browser/native.js":
19225 /*!***********************************************************!*\
19226   !*** ./node_modules/uuid/dist/commonjs-browser/native.js ***!
19227   \***********************************************************/
19228 /***/ ((__unused_webpack_module, exports) => {
19229
19230 "use strict";
19231
19232
19233 Object.defineProperty(exports, "__esModule", ({
19234   value: true
19235 }));
19236 exports["default"] = void 0;
19237 const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
19238 var _default = {
19239   randomUUID
19240 };
19241 exports["default"] = _default;
19242
19243 /***/ }),
19244
19245 /***/ "./node_modules/uuid/dist/commonjs-browser/nil.js":
19246 /*!********************************************************!*\
19247   !*** ./node_modules/uuid/dist/commonjs-browser/nil.js ***!
19248   \********************************************************/
19249 /***/ ((__unused_webpack_module, exports) => {
19250
19251 "use strict";
19252
19253
19254 Object.defineProperty(exports, "__esModule", ({
19255   value: true
19256 }));
19257 exports["default"] = void 0;
19258 var _default = '00000000-0000-0000-0000-000000000000';
19259 exports["default"] = _default;
19260
19261 /***/ }),
19262
19263 /***/ "./node_modules/uuid/dist/commonjs-browser/parse.js":
19264 /*!**********************************************************!*\
19265   !*** ./node_modules/uuid/dist/commonjs-browser/parse.js ***!
19266   \**********************************************************/
19267 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19268
19269 "use strict";
19270
19271
19272 Object.defineProperty(exports, "__esModule", ({
19273   value: true
19274 }));
19275 exports["default"] = void 0;
19276
19277 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19278
19279 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19280
19281 function parse(uuid) {
19282   if (!(0, _validate.default)(uuid)) {
19283     throw TypeError('Invalid UUID');
19284   }
19285
19286   let v;
19287   const arr = new Uint8Array(16); // Parse ########-....-....-....-............
19288
19289   arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
19290   arr[1] = v >>> 16 & 0xff;
19291   arr[2] = v >>> 8 & 0xff;
19292   arr[3] = v & 0xff; // Parse ........-####-....-....-............
19293
19294   arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
19295   arr[5] = v & 0xff; // Parse ........-....-####-....-............
19296
19297   arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
19298   arr[7] = v & 0xff; // Parse ........-....-....-####-............
19299
19300   arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
19301   arr[9] = v & 0xff; // Parse ........-....-....-....-############
19302   // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
19303
19304   arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;
19305   arr[11] = v / 0x100000000 & 0xff;
19306   arr[12] = v >>> 24 & 0xff;
19307   arr[13] = v >>> 16 & 0xff;
19308   arr[14] = v >>> 8 & 0xff;
19309   arr[15] = v & 0xff;
19310   return arr;
19311 }
19312
19313 var _default = parse;
19314 exports["default"] = _default;
19315
19316 /***/ }),
19317
19318 /***/ "./node_modules/uuid/dist/commonjs-browser/regex.js":
19319 /*!**********************************************************!*\
19320   !*** ./node_modules/uuid/dist/commonjs-browser/regex.js ***!
19321   \**********************************************************/
19322 /***/ ((__unused_webpack_module, exports) => {
19323
19324 "use strict";
19325
19326
19327 Object.defineProperty(exports, "__esModule", ({
19328   value: true
19329 }));
19330 exports["default"] = void 0;
19331 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;
19332 exports["default"] = _default;
19333
19334 /***/ }),
19335
19336 /***/ "./node_modules/uuid/dist/commonjs-browser/rng.js":
19337 /*!********************************************************!*\
19338   !*** ./node_modules/uuid/dist/commonjs-browser/rng.js ***!
19339   \********************************************************/
19340 /***/ ((__unused_webpack_module, exports) => {
19341
19342 "use strict";
19343
19344
19345 Object.defineProperty(exports, "__esModule", ({
19346   value: true
19347 }));
19348 exports["default"] = rng;
19349 // Unique ID creation requires a high quality random # generator. In the browser we therefore
19350 // require the crypto API and do not support built-in fallback to lower quality random number
19351 // generators (like Math.random()).
19352 let getRandomValues;
19353 const rnds8 = new Uint8Array(16);
19354
19355 function rng() {
19356   // lazy load so that environments that need to polyfill have a chance to do so
19357   if (!getRandomValues) {
19358     // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
19359     getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
19360
19361     if (!getRandomValues) {
19362       throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
19363     }
19364   }
19365
19366   return getRandomValues(rnds8);
19367 }
19368
19369 /***/ }),
19370
19371 /***/ "./node_modules/uuid/dist/commonjs-browser/sha1.js":
19372 /*!*********************************************************!*\
19373   !*** ./node_modules/uuid/dist/commonjs-browser/sha1.js ***!
19374   \*********************************************************/
19375 /***/ ((__unused_webpack_module, exports) => {
19376
19377 "use strict";
19378
19379
19380 Object.defineProperty(exports, "__esModule", ({
19381   value: true
19382 }));
19383 exports["default"] = void 0;
19384
19385 // Adapted from Chris Veness' SHA1 code at
19386 // http://www.movable-type.co.uk/scripts/sha1.html
19387 function f(s, x, y, z) {
19388   switch (s) {
19389     case 0:
19390       return x & y ^ ~x & z;
19391
19392     case 1:
19393       return x ^ y ^ z;
19394
19395     case 2:
19396       return x & y ^ x & z ^ y & z;
19397
19398     case 3:
19399       return x ^ y ^ z;
19400   }
19401 }
19402
19403 function ROTL(x, n) {
19404   return x << n | x >>> 32 - n;
19405 }
19406
19407 function sha1(bytes) {
19408   const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
19409   const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
19410
19411   if (typeof bytes === 'string') {
19412     const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
19413
19414     bytes = [];
19415
19416     for (let i = 0; i < msg.length; ++i) {
19417       bytes.push(msg.charCodeAt(i));
19418     }
19419   } else if (!Array.isArray(bytes)) {
19420     // Convert Array-like to Array
19421     bytes = Array.prototype.slice.call(bytes);
19422   }
19423
19424   bytes.push(0x80);
19425   const l = bytes.length / 4 + 2;
19426   const N = Math.ceil(l / 16);
19427   const M = new Array(N);
19428
19429   for (let i = 0; i < N; ++i) {
19430     const arr = new Uint32Array(16);
19431
19432     for (let j = 0; j < 16; ++j) {
19433       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];
19434     }
19435
19436     M[i] = arr;
19437   }
19438
19439   M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32);
19440   M[N - 1][14] = Math.floor(M[N - 1][14]);
19441   M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff;
19442
19443   for (let i = 0; i < N; ++i) {
19444     const W = new Uint32Array(80);
19445
19446     for (let t = 0; t < 16; ++t) {
19447       W[t] = M[i][t];
19448     }
19449
19450     for (let t = 16; t < 80; ++t) {
19451       W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
19452     }
19453
19454     let a = H[0];
19455     let b = H[1];
19456     let c = H[2];
19457     let d = H[3];
19458     let e = H[4];
19459
19460     for (let t = 0; t < 80; ++t) {
19461       const s = Math.floor(t / 20);
19462       const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0;
19463       e = d;
19464       d = c;
19465       c = ROTL(b, 30) >>> 0;
19466       b = a;
19467       a = T;
19468     }
19469
19470     H[0] = H[0] + a >>> 0;
19471     H[1] = H[1] + b >>> 0;
19472     H[2] = H[2] + c >>> 0;
19473     H[3] = H[3] + d >>> 0;
19474     H[4] = H[4] + e >>> 0;
19475   }
19476
19477   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];
19478 }
19479
19480 var _default = sha1;
19481 exports["default"] = _default;
19482
19483 /***/ }),
19484
19485 /***/ "./node_modules/uuid/dist/commonjs-browser/stringify.js":
19486 /*!**************************************************************!*\
19487   !*** ./node_modules/uuid/dist/commonjs-browser/stringify.js ***!
19488   \**************************************************************/
19489 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19490
19491 "use strict";
19492
19493
19494 Object.defineProperty(exports, "__esModule", ({
19495   value: true
19496 }));
19497 exports["default"] = void 0;
19498 exports.unsafeStringify = unsafeStringify;
19499
19500 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19501
19502 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19503
19504 /**
19505  * Convert array of 16 byte values to UUID string format of the form:
19506  * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
19507  */
19508 const byteToHex = [];
19509
19510 for (let i = 0; i < 256; ++i) {
19511   byteToHex.push((i + 0x100).toString(16).slice(1));
19512 }
19513
19514 function unsafeStringify(arr, offset = 0) {
19515   // Note: Be careful editing this code!  It's been tuned for performance
19516   // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
19517   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();
19518 }
19519
19520 function stringify(arr, offset = 0) {
19521   const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID.  If this throws, it's likely due to one
19522   // of the following:
19523   // - One or more input array values don't map to a hex octet (leading to
19524   // "undefined" in the uuid)
19525   // - Invalid input values for the RFC `version` or `variant` fields
19526
19527   if (!(0, _validate.default)(uuid)) {
19528     throw TypeError('Stringified UUID is invalid');
19529   }
19530
19531   return uuid;
19532 }
19533
19534 var _default = stringify;
19535 exports["default"] = _default;
19536
19537 /***/ }),
19538
19539 /***/ "./node_modules/uuid/dist/commonjs-browser/v1.js":
19540 /*!*******************************************************!*\
19541   !*** ./node_modules/uuid/dist/commonjs-browser/v1.js ***!
19542   \*******************************************************/
19543 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19544
19545 "use strict";
19546
19547
19548 Object.defineProperty(exports, "__esModule", ({
19549   value: true
19550 }));
19551 exports["default"] = void 0;
19552
19553 var _rng = _interopRequireDefault(__webpack_require__(/*! ./rng.js */ "./node_modules/uuid/dist/commonjs-browser/rng.js"));
19554
19555 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19556
19557 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19558
19559 // **`v1()` - Generate time-based UUID**
19560 //
19561 // Inspired by https://github.com/LiosK/UUID.js
19562 // and http://docs.python.org/library/uuid.html
19563 let _nodeId;
19564
19565 let _clockseq; // Previous uuid creation time
19566
19567
19568 let _lastMSecs = 0;
19569 let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details
19570
19571 function v1(options, buf, offset) {
19572   let i = buf && offset || 0;
19573   const b = buf || new Array(16);
19574   options = options || {};
19575   let node = options.node || _nodeId;
19576   let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not
19577   // specified.  We do this lazily to minimize issues related to insufficient
19578   // system entropy.  See #189
19579
19580   if (node == null || clockseq == null) {
19581     const seedBytes = options.random || (options.rng || _rng.default)();
19582
19583     if (node == null) {
19584       // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
19585       node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
19586     }
19587
19588     if (clockseq == null) {
19589       // Per 4.2.2, randomize (14 bit) clockseq
19590       clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
19591     }
19592   } // UUID timestamps are 100 nano-second units since the Gregorian epoch,
19593   // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
19594   // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
19595   // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
19596
19597
19598   let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock
19599   // cycle to simulate higher resolution clock
19600
19601   let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)
19602
19603   const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression
19604
19605   if (dt < 0 && options.clockseq === undefined) {
19606     clockseq = clockseq + 1 & 0x3fff;
19607   } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
19608   // time interval
19609
19610
19611   if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
19612     nsecs = 0;
19613   } // Per 4.2.1.2 Throw error if too many uuids are requested
19614
19615
19616   if (nsecs >= 10000) {
19617     throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
19618   }
19619
19620   _lastMSecs = msecs;
19621   _lastNSecs = nsecs;
19622   _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
19623
19624   msecs += 12219292800000; // `time_low`
19625
19626   const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
19627   b[i++] = tl >>> 24 & 0xff;
19628   b[i++] = tl >>> 16 & 0xff;
19629   b[i++] = tl >>> 8 & 0xff;
19630   b[i++] = tl & 0xff; // `time_mid`
19631
19632   const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;
19633   b[i++] = tmh >>> 8 & 0xff;
19634   b[i++] = tmh & 0xff; // `time_high_and_version`
19635
19636   b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
19637
19638   b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
19639
19640   b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`
19641
19642   b[i++] = clockseq & 0xff; // `node`
19643
19644   for (let n = 0; n < 6; ++n) {
19645     b[i + n] = node[n];
19646   }
19647
19648   return buf || (0, _stringify.unsafeStringify)(b);
19649 }
19650
19651 var _default = v1;
19652 exports["default"] = _default;
19653
19654 /***/ }),
19655
19656 /***/ "./node_modules/uuid/dist/commonjs-browser/v3.js":
19657 /*!*******************************************************!*\
19658   !*** ./node_modules/uuid/dist/commonjs-browser/v3.js ***!
19659   \*******************************************************/
19660 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19661
19662 "use strict";
19663
19664
19665 Object.defineProperty(exports, "__esModule", ({
19666   value: true
19667 }));
19668 exports["default"] = void 0;
19669
19670 var _v = _interopRequireDefault(__webpack_require__(/*! ./v35.js */ "./node_modules/uuid/dist/commonjs-browser/v35.js"));
19671
19672 var _md = _interopRequireDefault(__webpack_require__(/*! ./md5.js */ "./node_modules/uuid/dist/commonjs-browser/md5.js"));
19673
19674 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19675
19676 const v3 = (0, _v.default)('v3', 0x30, _md.default);
19677 var _default = v3;
19678 exports["default"] = _default;
19679
19680 /***/ }),
19681
19682 /***/ "./node_modules/uuid/dist/commonjs-browser/v35.js":
19683 /*!********************************************************!*\
19684   !*** ./node_modules/uuid/dist/commonjs-browser/v35.js ***!
19685   \********************************************************/
19686 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19687
19688 "use strict";
19689
19690
19691 Object.defineProperty(exports, "__esModule", ({
19692   value: true
19693 }));
19694 exports.URL = exports.DNS = void 0;
19695 exports["default"] = v35;
19696
19697 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19698
19699 var _parse = _interopRequireDefault(__webpack_require__(/*! ./parse.js */ "./node_modules/uuid/dist/commonjs-browser/parse.js"));
19700
19701 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19702
19703 function stringToBytes(str) {
19704   str = unescape(encodeURIComponent(str)); // UTF8 escape
19705
19706   const bytes = [];
19707
19708   for (let i = 0; i < str.length; ++i) {
19709     bytes.push(str.charCodeAt(i));
19710   }
19711
19712   return bytes;
19713 }
19714
19715 const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
19716 exports.DNS = DNS;
19717 const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
19718 exports.URL = URL;
19719
19720 function v35(name, version, hashfunc) {
19721   function generateUUID(value, namespace, buf, offset) {
19722     var _namespace;
19723
19724     if (typeof value === 'string') {
19725       value = stringToBytes(value);
19726     }
19727
19728     if (typeof namespace === 'string') {
19729       namespace = (0, _parse.default)(namespace);
19730     }
19731
19732     if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) {
19733       throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
19734     } // Compute hash of namespace and value, Per 4.3
19735     // Future: Use spread syntax when supported on all platforms, e.g. `bytes =
19736     // hashfunc([...namespace, ... value])`
19737
19738
19739     let bytes = new Uint8Array(16 + value.length);
19740     bytes.set(namespace);
19741     bytes.set(value, namespace.length);
19742     bytes = hashfunc(bytes);
19743     bytes[6] = bytes[6] & 0x0f | version;
19744     bytes[8] = bytes[8] & 0x3f | 0x80;
19745
19746     if (buf) {
19747       offset = offset || 0;
19748
19749       for (let i = 0; i < 16; ++i) {
19750         buf[offset + i] = bytes[i];
19751       }
19752
19753       return buf;
19754     }
19755
19756     return (0, _stringify.unsafeStringify)(bytes);
19757   } // Function#name is not settable on some platforms (#270)
19758
19759
19760   try {
19761     generateUUID.name = name; // eslint-disable-next-line no-empty
19762   } catch (err) {} // For CommonJS default export support
19763
19764
19765   generateUUID.DNS = DNS;
19766   generateUUID.URL = URL;
19767   return generateUUID;
19768 }
19769
19770 /***/ }),
19771
19772 /***/ "./node_modules/uuid/dist/commonjs-browser/v4.js":
19773 /*!*******************************************************!*\
19774   !*** ./node_modules/uuid/dist/commonjs-browser/v4.js ***!
19775   \*******************************************************/
19776 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19777
19778 "use strict";
19779
19780
19781 Object.defineProperty(exports, "__esModule", ({
19782   value: true
19783 }));
19784 exports["default"] = void 0;
19785
19786 var _native = _interopRequireDefault(__webpack_require__(/*! ./native.js */ "./node_modules/uuid/dist/commonjs-browser/native.js"));
19787
19788 var _rng = _interopRequireDefault(__webpack_require__(/*! ./rng.js */ "./node_modules/uuid/dist/commonjs-browser/rng.js"));
19789
19790 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19791
19792 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19793
19794 function v4(options, buf, offset) {
19795   if (_native.default.randomUUID && !buf && !options) {
19796     return _native.default.randomUUID();
19797   }
19798
19799   options = options || {};
19800
19801   const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
19802
19803
19804   rnds[6] = rnds[6] & 0x0f | 0x40;
19805   rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
19806
19807   if (buf) {
19808     offset = offset || 0;
19809
19810     for (let i = 0; i < 16; ++i) {
19811       buf[offset + i] = rnds[i];
19812     }
19813
19814     return buf;
19815   }
19816
19817   return (0, _stringify.unsafeStringify)(rnds);
19818 }
19819
19820 var _default = v4;
19821 exports["default"] = _default;
19822
19823 /***/ }),
19824
19825 /***/ "./node_modules/uuid/dist/commonjs-browser/v5.js":
19826 /*!*******************************************************!*\
19827   !*** ./node_modules/uuid/dist/commonjs-browser/v5.js ***!
19828   \*******************************************************/
19829 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19830
19831 "use strict";
19832
19833
19834 Object.defineProperty(exports, "__esModule", ({
19835   value: true
19836 }));
19837 exports["default"] = void 0;
19838
19839 var _v = _interopRequireDefault(__webpack_require__(/*! ./v35.js */ "./node_modules/uuid/dist/commonjs-browser/v35.js"));
19840
19841 var _sha = _interopRequireDefault(__webpack_require__(/*! ./sha1.js */ "./node_modules/uuid/dist/commonjs-browser/sha1.js"));
19842
19843 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19844
19845 const v5 = (0, _v.default)('v5', 0x50, _sha.default);
19846 var _default = v5;
19847 exports["default"] = _default;
19848
19849 /***/ }),
19850
19851 /***/ "./node_modules/uuid/dist/commonjs-browser/validate.js":
19852 /*!*************************************************************!*\
19853   !*** ./node_modules/uuid/dist/commonjs-browser/validate.js ***!
19854   \*************************************************************/
19855 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19856
19857 "use strict";
19858
19859
19860 Object.defineProperty(exports, "__esModule", ({
19861   value: true
19862 }));
19863 exports["default"] = void 0;
19864
19865 var _regex = _interopRequireDefault(__webpack_require__(/*! ./regex.js */ "./node_modules/uuid/dist/commonjs-browser/regex.js"));
19866
19867 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19868
19869 function validate(uuid) {
19870   return typeof uuid === 'string' && _regex.default.test(uuid);
19871 }
19872
19873 var _default = validate;
19874 exports["default"] = _default;
19875
19876 /***/ }),
19877
19878 /***/ "./node_modules/uuid/dist/commonjs-browser/version.js":
19879 /*!************************************************************!*\
19880   !*** ./node_modules/uuid/dist/commonjs-browser/version.js ***!
19881   \************************************************************/
19882 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19883
19884 "use strict";
19885
19886
19887 Object.defineProperty(exports, "__esModule", ({
19888   value: true
19889 }));
19890 exports["default"] = void 0;
19891
19892 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19893
19894 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19895
19896 function version(uuid) {
19897   if (!(0, _validate.default)(uuid)) {
19898     throw TypeError('Invalid UUID');
19899   }
19900
19901   return parseInt(uuid.slice(14, 15), 16);
19902 }
19903
19904 var _default = version;
19905 exports["default"] = _default;
19906
19907 /***/ }),
19908
19909 /***/ "./node_modules/marked/lib/marked.cjs":
19910 /*!********************************************!*\
19911   !*** ./node_modules/marked/lib/marked.cjs ***!
19912   \********************************************/
19913 /***/ ((__unused_webpack_module, exports) => {
19914
19915 "use strict";
19916 /**
19917  * marked v4.2.12 - a markdown parser
19918  * Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)
19919  * https://github.com/markedjs/marked
19920  */
19921
19922 /**
19923  * DO NOT EDIT THIS FILE
19924  * The code in this file is generated from files in ./src/
19925  */
19926
19927
19928
19929 function _defineProperties(target, props) {
19930   for (var i = 0; i < props.length; i++) {
19931     var descriptor = props[i];
19932     descriptor.enumerable = descriptor.enumerable || false;
19933     descriptor.configurable = true;
19934     if ("value" in descriptor) descriptor.writable = true;
19935     Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
19936   }
19937 }
19938 function _createClass(Constructor, protoProps, staticProps) {
19939   if (protoProps) _defineProperties(Constructor.prototype, protoProps);
19940   if (staticProps) _defineProperties(Constructor, staticProps);
19941   Object.defineProperty(Constructor, "prototype", {
19942     writable: false
19943   });
19944   return Constructor;
19945 }
19946 function _unsupportedIterableToArray(o, minLen) {
19947   if (!o) return;
19948   if (typeof o === "string") return _arrayLikeToArray(o, minLen);
19949   var n = Object.prototype.toString.call(o).slice(8, -1);
19950   if (n === "Object" && o.constructor) n = o.constructor.name;
19951   if (n === "Map" || n === "Set") return Array.from(o);
19952   if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
19953 }
19954 function _arrayLikeToArray(arr, len) {
19955   if (len == null || len > arr.length) len = arr.length;
19956   for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
19957   return arr2;
19958 }
19959 function _createForOfIteratorHelperLoose(o, allowArrayLike) {
19960   var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
19961   if (it) return (it = it.call(o)).next.bind(it);
19962   if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
19963     if (it) o = it;
19964     var i = 0;
19965     return function () {
19966       if (i >= o.length) return {
19967         done: true
19968       };
19969       return {
19970         done: false,
19971         value: o[i++]
19972       };
19973     };
19974   }
19975   throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
19976 }
19977 function _toPrimitive(input, hint) {
19978   if (typeof input !== "object" || input === null) return input;
19979   var prim = input[Symbol.toPrimitive];
19980   if (prim !== undefined) {
19981     var res = prim.call(input, hint || "default");
19982     if (typeof res !== "object") return res;
19983     throw new TypeError("@@toPrimitive must return a primitive value.");
19984   }
19985   return (hint === "string" ? String : Number)(input);
19986 }
19987 function _toPropertyKey(arg) {
19988   var key = _toPrimitive(arg, "string");
19989   return typeof key === "symbol" ? key : String(key);
19990 }
19991
19992 function getDefaults() {
19993   return {
19994     async: false,
19995     baseUrl: null,
19996     breaks: false,
19997     extensions: null,
19998     gfm: true,
19999     headerIds: true,
20000     headerPrefix: '',
20001     highlight: null,
20002     langPrefix: 'language-',
20003     mangle: true,
20004     pedantic: false,
20005     renderer: null,
20006     sanitize: false,
20007     sanitizer: null,
20008     silent: false,
20009     smartypants: false,
20010     tokenizer: null,
20011     walkTokens: null,
20012     xhtml: false
20013   };
20014 }
20015 exports.defaults = getDefaults();
20016 function changeDefaults(newDefaults) {
20017   exports.defaults = newDefaults;
20018 }
20019
20020 /**
20021  * Helpers
20022  */
20023 var escapeTest = /[&<>"']/;
20024 var escapeReplace = new RegExp(escapeTest.source, 'g');
20025 var escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
20026 var escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
20027 var escapeReplacements = {
20028   '&': '&amp;',
20029   '<': '&lt;',
20030   '>': '&gt;',
20031   '"': '&quot;',
20032   "'": '&#39;'
20033 };
20034 var getEscapeReplacement = function getEscapeReplacement(ch) {
20035   return escapeReplacements[ch];
20036 };
20037 function escape(html, encode) {
20038   if (encode) {
20039     if (escapeTest.test(html)) {
20040       return html.replace(escapeReplace, getEscapeReplacement);
20041     }
20042   } else {
20043     if (escapeTestNoEncode.test(html)) {
20044       return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
20045     }
20046   }
20047   return html;
20048 }
20049 var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
20050
20051 /**
20052  * @param {string} html
20053  */
20054 function unescape(html) {
20055   // explicitly match decimal, hex, and named HTML entities
20056   return html.replace(unescapeTest, function (_, n) {
20057     n = n.toLowerCase();
20058     if (n === 'colon') return ':';
20059     if (n.charAt(0) === '#') {
20060       return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1));
20061     }
20062     return '';
20063   });
20064 }
20065 var caret = /(^|[^\[])\^/g;
20066
20067 /**
20068  * @param {string | RegExp} regex
20069  * @param {string} opt
20070  */
20071 function edit(regex, opt) {
20072   regex = typeof regex === 'string' ? regex : regex.source;
20073   opt = opt || '';
20074   var obj = {
20075     replace: function replace(name, val) {
20076       val = val.source || val;
20077       val = val.replace(caret, '$1');
20078       regex = regex.replace(name, val);
20079       return obj;
20080     },
20081     getRegex: function getRegex() {
20082       return new RegExp(regex, opt);
20083     }
20084   };
20085   return obj;
20086 }
20087 var nonWordAndColonTest = /[^\w:]/g;
20088 var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
20089
20090 /**
20091  * @param {boolean} sanitize
20092  * @param {string} base
20093  * @param {string} href
20094  */
20095 function cleanUrl(sanitize, base, href) {
20096   if (sanitize) {
20097     var prot;
20098     try {
20099       prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, '').toLowerCase();
20100     } catch (e) {
20101       return null;
20102     }
20103     if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
20104       return null;
20105     }
20106   }
20107   if (base && !originIndependentUrl.test(href)) {
20108     href = resolveUrl(base, href);
20109   }
20110   try {
20111     href = encodeURI(href).replace(/%25/g, '%');
20112   } catch (e) {
20113     return null;
20114   }
20115   return href;
20116 }
20117 var baseUrls = {};
20118 var justDomain = /^[^:]+:\/*[^/]*$/;
20119 var protocol = /^([^:]+:)[\s\S]*$/;
20120 var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
20121
20122 /**
20123  * @param {string} base
20124  * @param {string} href
20125  */
20126 function resolveUrl(base, href) {
20127   if (!baseUrls[' ' + base]) {
20128     // we can ignore everything in base after the last slash of its path component,
20129     // but we might need to add _that_
20130     // https://tools.ietf.org/html/rfc3986#section-3
20131     if (justDomain.test(base)) {
20132       baseUrls[' ' + base] = base + '/';
20133     } else {
20134       baseUrls[' ' + base] = rtrim(base, '/', true);
20135     }
20136   }
20137   base = baseUrls[' ' + base];
20138   var relativeBase = base.indexOf(':') === -1;
20139   if (href.substring(0, 2) === '//') {
20140     if (relativeBase) {
20141       return href;
20142     }
20143     return base.replace(protocol, '$1') + href;
20144   } else if (href.charAt(0) === '/') {
20145     if (relativeBase) {
20146       return href;
20147     }
20148     return base.replace(domain, '$1') + href;
20149   } else {
20150     return base + href;
20151   }
20152 }
20153 var noopTest = {
20154   exec: function noopTest() {}
20155 };
20156 function merge(obj) {
20157   var i = 1,
20158     target,
20159     key;
20160   for (; i < arguments.length; i++) {
20161     target = arguments[i];
20162     for (key in target) {
20163       if (Object.prototype.hasOwnProperty.call(target, key)) {
20164         obj[key] = target[key];
20165       }
20166     }
20167   }
20168   return obj;
20169 }
20170 function splitCells(tableRow, count) {
20171   // ensure that every cell-delimiting pipe has a space
20172   // before it to distinguish it from an escaped pipe
20173   var row = tableRow.replace(/\|/g, function (match, offset, str) {
20174       var escaped = false,
20175         curr = offset;
20176       while (--curr >= 0 && str[curr] === '\\') {
20177         escaped = !escaped;
20178       }
20179       if (escaped) {
20180         // odd number of slashes means | is escaped
20181         // so we leave it alone
20182         return '|';
20183       } else {
20184         // add space before unescaped |
20185         return ' |';
20186       }
20187     }),
20188     cells = row.split(/ \|/);
20189   var i = 0;
20190
20191   // First/last cell in a row cannot be empty if it has no leading/trailing pipe
20192   if (!cells[0].trim()) {
20193     cells.shift();
20194   }
20195   if (cells.length > 0 && !cells[cells.length - 1].trim()) {
20196     cells.pop();
20197   }
20198   if (cells.length > count) {
20199     cells.splice(count);
20200   } else {
20201     while (cells.length < count) {
20202       cells.push('');
20203     }
20204   }
20205   for (; i < cells.length; i++) {
20206     // leading or trailing whitespace is ignored per the gfm spec
20207     cells[i] = cells[i].trim().replace(/\\\|/g, '|');
20208   }
20209   return cells;
20210 }
20211
20212 /**
20213  * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
20214  * /c*$/ is vulnerable to REDOS.
20215  *
20216  * @param {string} str
20217  * @param {string} c
20218  * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey.
20219  */
20220 function rtrim(str, c, invert) {
20221   var l = str.length;
20222   if (l === 0) {
20223     return '';
20224   }
20225
20226   // Length of suffix matching the invert condition.
20227   var suffLen = 0;
20228
20229   // Step left until we fail to match the invert condition.
20230   while (suffLen < l) {
20231     var currChar = str.charAt(l - suffLen - 1);
20232     if (currChar === c && !invert) {
20233       suffLen++;
20234     } else if (currChar !== c && invert) {
20235       suffLen++;
20236     } else {
20237       break;
20238     }
20239   }
20240   return str.slice(0, l - suffLen);
20241 }
20242 function findClosingBracket(str, b) {
20243   if (str.indexOf(b[1]) === -1) {
20244     return -1;
20245   }
20246   var l = str.length;
20247   var level = 0,
20248     i = 0;
20249   for (; i < l; i++) {
20250     if (str[i] === '\\') {
20251       i++;
20252     } else if (str[i] === b[0]) {
20253       level++;
20254     } else if (str[i] === b[1]) {
20255       level--;
20256       if (level < 0) {
20257         return i;
20258       }
20259     }
20260   }
20261   return -1;
20262 }
20263 function checkSanitizeDeprecation(opt) {
20264   if (opt && opt.sanitize && !opt.silent) {
20265     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');
20266   }
20267 }
20268
20269 // copied from https://stackoverflow.com/a/5450113/806777
20270 /**
20271  * @param {string} pattern
20272  * @param {number} count
20273  */
20274 function repeatString(pattern, count) {
20275   if (count < 1) {
20276     return '';
20277   }
20278   var result = '';
20279   while (count > 1) {
20280     if (count & 1) {
20281       result += pattern;
20282     }
20283     count >>= 1;
20284     pattern += pattern;
20285   }
20286   return result + pattern;
20287 }
20288
20289 function outputLink(cap, link, raw, lexer) {
20290   var href = link.href;
20291   var title = link.title ? escape(link.title) : null;
20292   var text = cap[1].replace(/\\([\[\]])/g, '$1');
20293   if (cap[0].charAt(0) !== '!') {
20294     lexer.state.inLink = true;
20295     var token = {
20296       type: 'link',
20297       raw: raw,
20298       href: href,
20299       title: title,
20300       text: text,
20301       tokens: lexer.inlineTokens(text)
20302     };
20303     lexer.state.inLink = false;
20304     return token;
20305   }
20306   return {
20307     type: 'image',
20308     raw: raw,
20309     href: href,
20310     title: title,
20311     text: escape(text)
20312   };
20313 }
20314 function indentCodeCompensation(raw, text) {
20315   var matchIndentToCode = raw.match(/^(\s+)(?:```)/);
20316   if (matchIndentToCode === null) {
20317     return text;
20318   }
20319   var indentToCode = matchIndentToCode[1];
20320   return text.split('\n').map(function (node) {
20321     var matchIndentInNode = node.match(/^\s+/);
20322     if (matchIndentInNode === null) {
20323       return node;
20324     }
20325     var indentInNode = matchIndentInNode[0];
20326     if (indentInNode.length >= indentToCode.length) {
20327       return node.slice(indentToCode.length);
20328     }
20329     return node;
20330   }).join('\n');
20331 }
20332
20333 /**
20334  * Tokenizer
20335  */
20336 var Tokenizer = /*#__PURE__*/function () {
20337   function Tokenizer(options) {
20338     this.options = options || exports.defaults;
20339   }
20340   var _proto = Tokenizer.prototype;
20341   _proto.space = function space(src) {
20342     var cap = this.rules.block.newline.exec(src);
20343     if (cap && cap[0].length > 0) {
20344       return {
20345         type: 'space',
20346         raw: cap[0]
20347       };
20348     }
20349   };
20350   _proto.code = function code(src) {
20351     var cap = this.rules.block.code.exec(src);
20352     if (cap) {
20353       var text = cap[0].replace(/^ {1,4}/gm, '');
20354       return {
20355         type: 'code',
20356         raw: cap[0],
20357         codeBlockStyle: 'indented',
20358         text: !this.options.pedantic ? rtrim(text, '\n') : text
20359       };
20360     }
20361   };
20362   _proto.fences = function fences(src) {
20363     var cap = this.rules.block.fences.exec(src);
20364     if (cap) {
20365       var raw = cap[0];
20366       var text = indentCodeCompensation(raw, cap[3] || '');
20367       return {
20368         type: 'code',
20369         raw: raw,
20370         lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
20371         text: text
20372       };
20373     }
20374   };
20375   _proto.heading = function heading(src) {
20376     var cap = this.rules.block.heading.exec(src);
20377     if (cap) {
20378       var text = cap[2].trim();
20379
20380       // remove trailing #s
20381       if (/#$/.test(text)) {
20382         var trimmed = rtrim(text, '#');
20383         if (this.options.pedantic) {
20384           text = trimmed.trim();
20385         } else if (!trimmed || / $/.test(trimmed)) {
20386           // CommonMark requires space before trailing #s
20387           text = trimmed.trim();
20388         }
20389       }
20390       return {
20391         type: 'heading',
20392         raw: cap[0],
20393         depth: cap[1].length,
20394         text: text,
20395         tokens: this.lexer.inline(text)
20396       };
20397     }
20398   };
20399   _proto.hr = function hr(src) {
20400     var cap = this.rules.block.hr.exec(src);
20401     if (cap) {
20402       return {
20403         type: 'hr',
20404         raw: cap[0]
20405       };
20406     }
20407   };
20408   _proto.blockquote = function blockquote(src) {
20409     var cap = this.rules.block.blockquote.exec(src);
20410     if (cap) {
20411       var text = cap[0].replace(/^ *>[ \t]?/gm, '');
20412       var top = this.lexer.state.top;
20413       this.lexer.state.top = true;
20414       var tokens = this.lexer.blockTokens(text);
20415       this.lexer.state.top = top;
20416       return {
20417         type: 'blockquote',
20418         raw: cap[0],
20419         tokens: tokens,
20420         text: text
20421       };
20422     }
20423   };
20424   _proto.list = function list(src) {
20425     var cap = this.rules.block.list.exec(src);
20426     if (cap) {
20427       var raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
20428       var bull = cap[1].trim();
20429       var isordered = bull.length > 1;
20430       var list = {
20431         type: 'list',
20432         raw: '',
20433         ordered: isordered,
20434         start: isordered ? +bull.slice(0, -1) : '',
20435         loose: false,
20436         items: []
20437       };
20438       bull = isordered ? "\\d{1,9}\\" + bull.slice(-1) : "\\" + bull;
20439       if (this.options.pedantic) {
20440         bull = isordered ? bull : '[*+-]';
20441       }
20442
20443       // Get next list item
20444       var itemRegex = new RegExp("^( {0,3}" + bull + ")((?:[\t ][^\\n]*)?(?:\\n|$))");
20445
20446       // Check if current bullet point can start a new List Item
20447       while (src) {
20448         endEarly = false;
20449         if (!(cap = itemRegex.exec(src))) {
20450           break;
20451         }
20452         if (this.rules.block.hr.test(src)) {
20453           // End list if bullet was actually HR (possibly move into itemRegex?)
20454           break;
20455         }
20456         raw = cap[0];
20457         src = src.substring(raw.length);
20458         line = cap[2].split('\n', 1)[0].replace(/^\t+/, function (t) {
20459           return ' '.repeat(3 * t.length);
20460         });
20461         nextLine = src.split('\n', 1)[0];
20462         if (this.options.pedantic) {
20463           indent = 2;
20464           itemContents = line.trimLeft();
20465         } else {
20466           indent = cap[2].search(/[^ ]/); // Find first non-space char
20467           indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
20468           itemContents = line.slice(indent);
20469           indent += cap[1].length;
20470         }
20471         blankLine = false;
20472         if (!line && /^ *$/.test(nextLine)) {
20473           // Items begin with at most one blank line
20474           raw += nextLine + '\n';
20475           src = src.substring(nextLine.length + 1);
20476           endEarly = true;
20477         }
20478         if (!endEarly) {
20479           var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))");
20480           var hrRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)");
20481           var fencesBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:```|~~~)");
20482           var headingBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}#");
20483
20484           // Check if following lines should be included in List Item
20485           while (src) {
20486             rawLine = src.split('\n', 1)[0];
20487             nextLine = rawLine;
20488
20489             // Re-align to follow commonmark nesting rules
20490             if (this.options.pedantic) {
20491               nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, '  ');
20492             }
20493
20494             // End list item if found code fences
20495             if (fencesBeginRegex.test(nextLine)) {
20496               break;
20497             }
20498
20499             // End list item if found start of new heading
20500             if (headingBeginRegex.test(nextLine)) {
20501               break;
20502             }
20503
20504             // End list item if found start of new bullet
20505             if (nextBulletRegex.test(nextLine)) {
20506               break;
20507             }
20508
20509             // Horizontal rule found
20510             if (hrRegex.test(src)) {
20511               break;
20512             }
20513             if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) {
20514               // Dedent if possible
20515               itemContents += '\n' + nextLine.slice(indent);
20516             } else {
20517               // not enough indentation
20518               if (blankLine) {
20519                 break;
20520               }
20521
20522               // paragraph continuation unless last line was a different block level element
20523               if (line.search(/[^ ]/) >= 4) {
20524                 // indented code block
20525                 break;
20526               }
20527               if (fencesBeginRegex.test(line)) {
20528                 break;
20529               }
20530               if (headingBeginRegex.test(line)) {
20531                 break;
20532               }
20533               if (hrRegex.test(line)) {
20534                 break;
20535               }
20536               itemContents += '\n' + nextLine;
20537             }
20538             if (!blankLine && !nextLine.trim()) {
20539               // Check if current line is blank
20540               blankLine = true;
20541             }
20542             raw += rawLine + '\n';
20543             src = src.substring(rawLine.length + 1);
20544             line = nextLine.slice(indent);
20545           }
20546         }
20547         if (!list.loose) {
20548           // If the previous item ended with a blank line, the list is loose
20549           if (endsWithBlankLine) {
20550             list.loose = true;
20551           } else if (/\n *\n *$/.test(raw)) {
20552             endsWithBlankLine = true;
20553           }
20554         }
20555
20556         // Check for task list items
20557         if (this.options.gfm) {
20558           istask = /^\[[ xX]\] /.exec(itemContents);
20559           if (istask) {
20560             ischecked = istask[0] !== '[ ] ';
20561             itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
20562           }
20563         }
20564         list.items.push({
20565           type: 'list_item',
20566           raw: raw,
20567           task: !!istask,
20568           checked: ischecked,
20569           loose: false,
20570           text: itemContents
20571         });
20572         list.raw += raw;
20573       }
20574
20575       // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
20576       list.items[list.items.length - 1].raw = raw.trimRight();
20577       list.items[list.items.length - 1].text = itemContents.trimRight();
20578       list.raw = list.raw.trimRight();
20579       var l = list.items.length;
20580
20581       // Item child tokens handled here at end because we needed to have the final item to trim it first
20582       for (i = 0; i < l; i++) {
20583         this.lexer.state.top = false;
20584         list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
20585         if (!list.loose) {
20586           // Check if list should be loose
20587           var spacers = list.items[i].tokens.filter(function (t) {
20588             return t.type === 'space';
20589           });
20590           var hasMultipleLineBreaks = spacers.length > 0 && spacers.some(function (t) {
20591             return /\n.*\n/.test(t.raw);
20592           });
20593           list.loose = hasMultipleLineBreaks;
20594         }
20595       }
20596
20597       // Set all items to loose if list is loose
20598       if (list.loose) {
20599         for (i = 0; i < l; i++) {
20600           list.items[i].loose = true;
20601         }
20602       }
20603       return list;
20604     }
20605   };
20606   _proto.html = function html(src) {
20607     var cap = this.rules.block.html.exec(src);
20608     if (cap) {
20609       var token = {
20610         type: 'html',
20611         raw: cap[0],
20612         pre: !this.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
20613         text: cap[0]
20614       };
20615       if (this.options.sanitize) {
20616         var text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
20617         token.type = 'paragraph';
20618         token.text = text;
20619         token.tokens = this.lexer.inline(text);
20620       }
20621       return token;
20622     }
20623   };
20624   _proto.def = function def(src) {
20625     var cap = this.rules.block.def.exec(src);
20626     if (cap) {
20627       var tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
20628       var href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';
20629       var title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];
20630       return {
20631         type: 'def',
20632         tag: tag,
20633         raw: cap[0],
20634         href: href,
20635         title: title
20636       };
20637     }
20638   };
20639   _proto.table = function table(src) {
20640     var cap = this.rules.block.table.exec(src);
20641     if (cap) {
20642       var item = {
20643         type: 'table',
20644         header: splitCells(cap[1]).map(function (c) {
20645           return {
20646             text: c
20647           };
20648         }),
20649         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
20650         rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
20651       };
20652       if (item.header.length === item.align.length) {
20653         item.raw = cap[0];
20654         var l = item.align.length;
20655         var i, j, k, row;
20656         for (i = 0; i < l; i++) {
20657           if (/^ *-+: *$/.test(item.align[i])) {
20658             item.align[i] = 'right';
20659           } else if (/^ *:-+: *$/.test(item.align[i])) {
20660             item.align[i] = 'center';
20661           } else if (/^ *:-+ *$/.test(item.align[i])) {
20662             item.align[i] = 'left';
20663           } else {
20664             item.align[i] = null;
20665           }
20666         }
20667         l = item.rows.length;
20668         for (i = 0; i < l; i++) {
20669           item.rows[i] = splitCells(item.rows[i], item.header.length).map(function (c) {
20670             return {
20671               text: c
20672             };
20673           });
20674         }
20675
20676         // parse child tokens inside headers and cells
20677
20678         // header child tokens
20679         l = item.header.length;
20680         for (j = 0; j < l; j++) {
20681           item.header[j].tokens = this.lexer.inline(item.header[j].text);
20682         }
20683
20684         // cell child tokens
20685         l = item.rows.length;
20686         for (j = 0; j < l; j++) {
20687           row = item.rows[j];
20688           for (k = 0; k < row.length; k++) {
20689             row[k].tokens = this.lexer.inline(row[k].text);
20690           }
20691         }
20692         return item;
20693       }
20694     }
20695   };
20696   _proto.lheading = function lheading(src) {
20697     var cap = this.rules.block.lheading.exec(src);
20698     if (cap) {
20699       return {
20700         type: 'heading',
20701         raw: cap[0],
20702         depth: cap[2].charAt(0) === '=' ? 1 : 2,
20703         text: cap[1],
20704         tokens: this.lexer.inline(cap[1])
20705       };
20706     }
20707   };
20708   _proto.paragraph = function paragraph(src) {
20709     var cap = this.rules.block.paragraph.exec(src);
20710     if (cap) {
20711       var text = cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1];
20712       return {
20713         type: 'paragraph',
20714         raw: cap[0],
20715         text: text,
20716         tokens: this.lexer.inline(text)
20717       };
20718     }
20719   };
20720   _proto.text = function text(src) {
20721     var cap = this.rules.block.text.exec(src);
20722     if (cap) {
20723       return {
20724         type: 'text',
20725         raw: cap[0],
20726         text: cap[0],
20727         tokens: this.lexer.inline(cap[0])
20728       };
20729     }
20730   };
20731   _proto.escape = function escape$1(src) {
20732     var cap = this.rules.inline.escape.exec(src);
20733     if (cap) {
20734       return {
20735         type: 'escape',
20736         raw: cap[0],
20737         text: escape(cap[1])
20738       };
20739     }
20740   };
20741   _proto.tag = function tag(src) {
20742     var cap = this.rules.inline.tag.exec(src);
20743     if (cap) {
20744       if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
20745         this.lexer.state.inLink = true;
20746       } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
20747         this.lexer.state.inLink = false;
20748       }
20749       if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
20750         this.lexer.state.inRawBlock = true;
20751       } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
20752         this.lexer.state.inRawBlock = false;
20753       }
20754       return {
20755         type: this.options.sanitize ? 'text' : 'html',
20756         raw: cap[0],
20757         inLink: this.lexer.state.inLink,
20758         inRawBlock: this.lexer.state.inRawBlock,
20759         text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]
20760       };
20761     }
20762   };
20763   _proto.link = function link(src) {
20764     var cap = this.rules.inline.link.exec(src);
20765     if (cap) {
20766       var trimmedUrl = cap[2].trim();
20767       if (!this.options.pedantic && /^</.test(trimmedUrl)) {
20768         // commonmark requires matching angle brackets
20769         if (!/>$/.test(trimmedUrl)) {
20770           return;
20771         }
20772
20773         // ending angle bracket cannot be escaped
20774         var rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
20775         if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
20776           return;
20777         }
20778       } else {
20779         // find closing parenthesis
20780         var lastParenIndex = findClosingBracket(cap[2], '()');
20781         if (lastParenIndex > -1) {
20782           var start = cap[0].indexOf('!') === 0 ? 5 : 4;
20783           var linkLen = start + cap[1].length + lastParenIndex;
20784           cap[2] = cap[2].substring(0, lastParenIndex);
20785           cap[0] = cap[0].substring(0, linkLen).trim();
20786           cap[3] = '';
20787         }
20788       }
20789       var href = cap[2];
20790       var title = '';
20791       if (this.options.pedantic) {
20792         // split pedantic href and title
20793         var link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
20794         if (link) {
20795           href = link[1];
20796           title = link[3];
20797         }
20798       } else {
20799         title = cap[3] ? cap[3].slice(1, -1) : '';
20800       }
20801       href = href.trim();
20802       if (/^</.test(href)) {
20803         if (this.options.pedantic && !/>$/.test(trimmedUrl)) {
20804           // pedantic allows starting angle bracket without ending angle bracket
20805           href = href.slice(1);
20806         } else {
20807           href = href.slice(1, -1);
20808         }
20809       }
20810       return outputLink(cap, {
20811         href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
20812         title: title ? title.replace(this.rules.inline._escapes, '$1') : title
20813       }, cap[0], this.lexer);
20814     }
20815   };
20816   _proto.reflink = function reflink(src, links) {
20817     var cap;
20818     if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
20819       var link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
20820       link = links[link.toLowerCase()];
20821       if (!link) {
20822         var text = cap[0].charAt(0);
20823         return {
20824           type: 'text',
20825           raw: text,
20826           text: text
20827         };
20828       }
20829       return outputLink(cap, link, cap[0], this.lexer);
20830     }
20831   };
20832   _proto.emStrong = function emStrong(src, maskedSrc, prevChar) {
20833     if (prevChar === void 0) {
20834       prevChar = '';
20835     }
20836     var match = this.rules.inline.emStrong.lDelim.exec(src);
20837     if (!match) return;
20838
20839     // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
20840     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;
20841     var nextChar = match[1] || match[2] || '';
20842     if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) {
20843       var lLength = match[0].length - 1;
20844       var rDelim,
20845         rLength,
20846         delimTotal = lLength,
20847         midDelimTotal = 0;
20848       var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
20849       endReg.lastIndex = 0;
20850
20851       // Clip maskedSrc to same section of string as src (move to lexer?)
20852       maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
20853       while ((match = endReg.exec(maskedSrc)) != null) {
20854         rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
20855         if (!rDelim) continue; // skip single * in __abc*abc__
20856
20857         rLength = rDelim.length;
20858         if (match[3] || match[4]) {
20859           // found another Left Delim
20860           delimTotal += rLength;
20861           continue;
20862         } else if (match[5] || match[6]) {
20863           // either Left or Right Delim
20864           if (lLength % 3 && !((lLength + rLength) % 3)) {
20865             midDelimTotal += rLength;
20866             continue; // CommonMark Emphasis Rules 9-10
20867           }
20868         }
20869
20870         delimTotal -= rLength;
20871         if (delimTotal > 0) continue; // Haven't found enough closing delimiters
20872
20873         // Remove extra characters. *a*** -> *a*
20874         rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
20875         var raw = src.slice(0, lLength + match.index + (match[0].length - rDelim.length) + rLength);
20876
20877         // Create `em` if smallest delimiter has odd char count. *a***
20878         if (Math.min(lLength, rLength) % 2) {
20879           var _text = raw.slice(1, -1);
20880           return {
20881             type: 'em',
20882             raw: raw,
20883             text: _text,
20884             tokens: this.lexer.inlineTokens(_text)
20885           };
20886         }
20887
20888         // Create 'strong' if smallest delimiter has even char count. **a***
20889         var text = raw.slice(2, -2);
20890         return {
20891           type: 'strong',
20892           raw: raw,
20893           text: text,
20894           tokens: this.lexer.inlineTokens(text)
20895         };
20896       }
20897     }
20898   };
20899   _proto.codespan = function codespan(src) {
20900     var cap = this.rules.inline.code.exec(src);
20901     if (cap) {
20902       var text = cap[2].replace(/\n/g, ' ');
20903       var hasNonSpaceChars = /[^ ]/.test(text);
20904       var hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
20905       if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
20906         text = text.substring(1, text.length - 1);
20907       }
20908       text = escape(text, true);
20909       return {
20910         type: 'codespan',
20911         raw: cap[0],
20912         text: text
20913       };
20914     }
20915   };
20916   _proto.br = function br(src) {
20917     var cap = this.rules.inline.br.exec(src);
20918     if (cap) {
20919       return {
20920         type: 'br',
20921         raw: cap[0]
20922       };
20923     }
20924   };
20925   _proto.del = function del(src) {
20926     var cap = this.rules.inline.del.exec(src);
20927     if (cap) {
20928       return {
20929         type: 'del',
20930         raw: cap[0],
20931         text: cap[2],
20932         tokens: this.lexer.inlineTokens(cap[2])
20933       };
20934     }
20935   };
20936   _proto.autolink = function autolink(src, mangle) {
20937     var cap = this.rules.inline.autolink.exec(src);
20938     if (cap) {
20939       var text, href;
20940       if (cap[2] === '@') {
20941         text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
20942         href = 'mailto:' + text;
20943       } else {
20944         text = escape(cap[1]);
20945         href = text;
20946       }
20947       return {
20948         type: 'link',
20949         raw: cap[0],
20950         text: text,
20951         href: href,
20952         tokens: [{
20953           type: 'text',
20954           raw: text,
20955           text: text
20956         }]
20957       };
20958     }
20959   };
20960   _proto.url = function url(src, mangle) {
20961     var cap;
20962     if (cap = this.rules.inline.url.exec(src)) {
20963       var text, href;
20964       if (cap[2] === '@') {
20965         text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
20966         href = 'mailto:' + text;
20967       } else {
20968         // do extended autolink path validation
20969         var prevCapZero;
20970         do {
20971           prevCapZero = cap[0];
20972           cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
20973         } while (prevCapZero !== cap[0]);
20974         text = escape(cap[0]);
20975         if (cap[1] === 'www.') {
20976           href = 'http://' + cap[0];
20977         } else {
20978           href = cap[0];
20979         }
20980       }
20981       return {
20982         type: 'link',
20983         raw: cap[0],
20984         text: text,
20985         href: href,
20986         tokens: [{
20987           type: 'text',
20988           raw: text,
20989           text: text
20990         }]
20991       };
20992     }
20993   };
20994   _proto.inlineText = function inlineText(src, smartypants) {
20995     var cap = this.rules.inline.text.exec(src);
20996     if (cap) {
20997       var text;
20998       if (this.lexer.state.inRawBlock) {
20999         text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0];
21000       } else {
21001         text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
21002       }
21003       return {
21004         type: 'text',
21005         raw: cap[0],
21006         text: text
21007       };
21008     }
21009   };
21010   return Tokenizer;
21011 }();
21012
21013 /**
21014  * Block-Level Grammar
21015  */
21016 var block = {
21017   newline: /^(?: *(?:\n|$))+/,
21018   code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
21019   fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
21020   hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
21021   heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
21022   blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
21023   list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
21024   html: '^ {0,3}(?:' // optional indentation
21025   + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
21026   + '|comment[^\\n]*(\\n+|$)' // (2)
21027   + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
21028   + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
21029   + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
21030   + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
21031   + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
21032   + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
21033   + ')',
21034   def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
21035   table: noopTest,
21036   lheading: /^((?:.|\n(?!\n))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
21037   // regex template, placeholders will be replaced according to different paragraph
21038   // interruption rules of commonmark and the original markdown spec:
21039   _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
21040   text: /^[^\n]+/
21041 };
21042 block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
21043 block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
21044 block.def = edit(block.def).replace('label', block._label).replace('title', block._title).getRegex();
21045 block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
21046 block.listItemStart = edit(/^( *)(bull) */).replace('bull', block.bullet).getRegex();
21047 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();
21048 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';
21049 block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
21050 block.html = edit(block.html, 'i').replace('comment', block._comment).replace('tag', block._tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
21051 block.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
21052 .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
21053 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
21054 .getRegex();
21055 block.blockquote = edit(block.blockquote).replace('paragraph', block.paragraph).getRegex();
21056
21057 /**
21058  * Normal Block Grammar
21059  */
21060
21061 block.normal = merge({}, block);
21062
21063 /**
21064  * GFM Block Grammar
21065  */
21066
21067 block.gfm = merge({}, block.normal, {
21068   table: '^ *([^\\n ].*\\|.*)\\n' // Header
21069   + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
21070   + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
21071 });
21072
21073 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
21074 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
21075 .getRegex();
21076 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
21077 .replace('table', block.gfm.table) // interrupt paragraphs with table
21078 .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
21079 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
21080 .getRegex();
21081 /**
21082  * Pedantic grammar (original John Gruber's loose markdown specification)
21083  */
21084
21085 block.pedantic = merge({}, block.normal, {
21086   html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
21087   + '|<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(),
21088   def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
21089   heading: /^(#{1,6})(.*)(?:\n+|$)/,
21090   fences: noopTest,
21091   // fences not supported
21092   lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
21093   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()
21094 });
21095
21096 /**
21097  * Inline-Level Grammar
21098  */
21099 var inline = {
21100   escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
21101   autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
21102   url: noopTest,
21103   tag: '^comment' + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
21104   + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
21105   + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
21106   + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
21107   + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
21108   // CDATA section
21109   link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
21110   reflink: /^!?\[(label)\]\[(ref)\]/,
21111   nolink: /^!?\[(ref)\](?:\[\])?/,
21112   reflinkSearch: 'reflink|nolink(?!\\()',
21113   emStrong: {
21114     lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
21115     //        (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.
21116     //          () Skip orphan inside strong                                      () Consume to delim     (1) #***                (2) a***#, a***                             (3) #***a, ***a                 (4) ***#              (5) #***#                 (6) a***a
21117     rDelimAst: /^(?:[^_*\\]|\\.)*?\_\_(?:[^_*\\]|\\.)*?\*(?:[^_*\\]|\\.)*?(?=\_\_)|(?:[^*\\]|\\.)+(?=[^*])|[punct_](\*+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|(?:[^punct*_\s\\]|\\.)(\*+)(?=[^punct*_\s])/,
21118     rDelimUnd: /^(?:[^_*\\]|\\.)*?\*\*(?:[^_*\\]|\\.)*?\_(?:[^_*\\]|\\.)*?(?=\*\*)|(?:[^_\\]|\\.)+(?=[^_])|[punct*](\_+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
21119   },
21120
21121   code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
21122   br: /^( {2,}|\\)\n(?!\s*$)/,
21123   del: noopTest,
21124   text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
21125   punctuation: /^([\spunctuation])/
21126 };
21127
21128 // list of punctuation marks from CommonMark spec
21129 // without * and _ to handle the different emphasis markers * and _
21130 inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
21131 inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
21132
21133 // sequences em should skip over [title](link), `code`, <html>
21134 inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
21135 // lookbehind is not available on Safari as of version 16
21136 // inline.escapedEmSt = /(?<=(?:^|[^\\)(?:\\[^])*)\\[*_]/g;
21137 inline.escapedEmSt = /(?:^|[^\\])(?:\\\\)*\\[*_]/g;
21138 inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
21139 inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex();
21140 inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g').replace(/punct/g, inline._punctuation).getRegex();
21141 inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g').replace(/punct/g, inline._punctuation).getRegex();
21142 inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
21143 inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
21144 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])?)+(?![-_])/;
21145 inline.autolink = edit(inline.autolink).replace('scheme', inline._scheme).replace('email', inline._email).getRegex();
21146 inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
21147 inline.tag = edit(inline.tag).replace('comment', inline._comment).replace('attribute', inline._attribute).getRegex();
21148 inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
21149 inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
21150 inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
21151 inline.link = edit(inline.link).replace('label', inline._label).replace('href', inline._href).replace('title', inline._title).getRegex();
21152 inline.reflink = edit(inline.reflink).replace('label', inline._label).replace('ref', block._label).getRegex();
21153 inline.nolink = edit(inline.nolink).replace('ref', block._label).getRegex();
21154 inline.reflinkSearch = edit(inline.reflinkSearch, 'g').replace('reflink', inline.reflink).replace('nolink', inline.nolink).getRegex();
21155
21156 /**
21157  * Normal Inline Grammar
21158  */
21159
21160 inline.normal = merge({}, inline);
21161
21162 /**
21163  * Pedantic Inline Grammar
21164  */
21165
21166 inline.pedantic = merge({}, inline.normal, {
21167   strong: {
21168     start: /^__|\*\*/,
21169     middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
21170     endAst: /\*\*(?!\*)/g,
21171     endUnd: /__(?!_)/g
21172   },
21173   em: {
21174     start: /^_|\*/,
21175     middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
21176     endAst: /\*(?!\*)/g,
21177     endUnd: /_(?!_)/g
21178   },
21179   link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', inline._label).getRegex(),
21180   reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', inline._label).getRegex()
21181 });
21182
21183 /**
21184  * GFM Inline Grammar
21185  */
21186
21187 inline.gfm = merge({}, inline.normal, {
21188   escape: edit(inline.escape).replace('])', '~|])').getRegex(),
21189   _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
21190   url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
21191   _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
21192   del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
21193   text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
21194 });
21195 inline.gfm.url = edit(inline.gfm.url, 'i').replace('email', inline.gfm._extended_email).getRegex();
21196 /**
21197  * GFM + Line Breaks Inline Grammar
21198  */
21199
21200 inline.breaks = merge({}, inline.gfm, {
21201   br: edit(inline.br).replace('{2,}', '*').getRegex(),
21202   text: edit(inline.gfm.text).replace('\\b_', '\\b_| {2,}\\n').replace(/\{2,\}/g, '*').getRegex()
21203 });
21204
21205 /**
21206  * smartypants text replacement
21207  * @param {string} text
21208  */
21209 function smartypants(text) {
21210   return text
21211   // em-dashes
21212   .replace(/---/g, "\u2014")
21213   // en-dashes
21214   .replace(/--/g, "\u2013")
21215   // opening singles
21216   .replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018")
21217   // closing singles & apostrophes
21218   .replace(/'/g, "\u2019")
21219   // opening doubles
21220   .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C")
21221   // closing doubles
21222   .replace(/"/g, "\u201D")
21223   // ellipses
21224   .replace(/\.{3}/g, "\u2026");
21225 }
21226
21227 /**
21228  * mangle email addresses
21229  * @param {string} text
21230  */
21231 function mangle(text) {
21232   var out = '',
21233     i,
21234     ch;
21235   var l = text.length;
21236   for (i = 0; i < l; i++) {
21237     ch = text.charCodeAt(i);
21238     if (Math.random() > 0.5) {
21239       ch = 'x' + ch.toString(16);
21240     }
21241     out += '&#' + ch + ';';
21242   }
21243   return out;
21244 }
21245
21246 /**
21247  * Block Lexer
21248  */
21249 var Lexer = /*#__PURE__*/function () {
21250   function Lexer(options) {
21251     this.tokens = [];
21252     this.tokens.links = Object.create(null);
21253     this.options = options || exports.defaults;
21254     this.options.tokenizer = this.options.tokenizer || new Tokenizer();
21255     this.tokenizer = this.options.tokenizer;
21256     this.tokenizer.options = this.options;
21257     this.tokenizer.lexer = this;
21258     this.inlineQueue = [];
21259     this.state = {
21260       inLink: false,
21261       inRawBlock: false,
21262       top: true
21263     };
21264     var rules = {
21265       block: block.normal,
21266       inline: inline.normal
21267     };
21268     if (this.options.pedantic) {
21269       rules.block = block.pedantic;
21270       rules.inline = inline.pedantic;
21271     } else if (this.options.gfm) {
21272       rules.block = block.gfm;
21273       if (this.options.breaks) {
21274         rules.inline = inline.breaks;
21275       } else {
21276         rules.inline = inline.gfm;
21277       }
21278     }
21279     this.tokenizer.rules = rules;
21280   }
21281
21282   /**
21283    * Expose Rules
21284    */
21285   /**
21286    * Static Lex Method
21287    */
21288   Lexer.lex = function lex(src, options) {
21289     var lexer = new Lexer(options);
21290     return lexer.lex(src);
21291   }
21292
21293   /**
21294    * Static Lex Inline Method
21295    */;
21296   Lexer.lexInline = function lexInline(src, options) {
21297     var lexer = new Lexer(options);
21298     return lexer.inlineTokens(src);
21299   }
21300
21301   /**
21302    * Preprocessing
21303    */;
21304   var _proto = Lexer.prototype;
21305   _proto.lex = function lex(src) {
21306     src = src.replace(/\r\n|\r/g, '\n');
21307     this.blockTokens(src, this.tokens);
21308     var next;
21309     while (next = this.inlineQueue.shift()) {
21310       this.inlineTokens(next.src, next.tokens);
21311     }
21312     return this.tokens;
21313   }
21314
21315   /**
21316    * Lexing
21317    */;
21318   _proto.blockTokens = function blockTokens(src, tokens) {
21319     var _this = this;
21320     if (tokens === void 0) {
21321       tokens = [];
21322     }
21323     if (this.options.pedantic) {
21324       src = src.replace(/\t/g, '    ').replace(/^ +$/gm, '');
21325     } else {
21326       src = src.replace(/^( *)(\t+)/gm, function (_, leading, tabs) {
21327         return leading + '    '.repeat(tabs.length);
21328       });
21329     }
21330     var token, lastToken, cutSrc, lastParagraphClipped;
21331     while (src) {
21332       if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some(function (extTokenizer) {
21333         if (token = extTokenizer.call({
21334           lexer: _this
21335         }, src, tokens)) {
21336           src = src.substring(token.raw.length);
21337           tokens.push(token);
21338           return true;
21339         }
21340         return false;
21341       })) {
21342         continue;
21343       }
21344
21345       // newline
21346       if (token = this.tokenizer.space(src)) {
21347         src = src.substring(token.raw.length);
21348         if (token.raw.length === 1 && tokens.length > 0) {
21349           // if there's a single \n as a spacer, it's terminating the last line,
21350           // so move it there so that we don't get unecessary paragraph tags
21351           tokens[tokens.length - 1].raw += '\n';
21352         } else {
21353           tokens.push(token);
21354         }
21355         continue;
21356       }
21357
21358       // code
21359       if (token = this.tokenizer.code(src)) {
21360         src = src.substring(token.raw.length);
21361         lastToken = tokens[tokens.length - 1];
21362         // An indented code block cannot interrupt a paragraph.
21363         if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
21364           lastToken.raw += '\n' + token.raw;
21365           lastToken.text += '\n' + token.text;
21366           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21367         } else {
21368           tokens.push(token);
21369         }
21370         continue;
21371       }
21372
21373       // fences
21374       if (token = this.tokenizer.fences(src)) {
21375         src = src.substring(token.raw.length);
21376         tokens.push(token);
21377         continue;
21378       }
21379
21380       // heading
21381       if (token = this.tokenizer.heading(src)) {
21382         src = src.substring(token.raw.length);
21383         tokens.push(token);
21384         continue;
21385       }
21386
21387       // hr
21388       if (token = this.tokenizer.hr(src)) {
21389         src = src.substring(token.raw.length);
21390         tokens.push(token);
21391         continue;
21392       }
21393
21394       // blockquote
21395       if (token = this.tokenizer.blockquote(src)) {
21396         src = src.substring(token.raw.length);
21397         tokens.push(token);
21398         continue;
21399       }
21400
21401       // list
21402       if (token = this.tokenizer.list(src)) {
21403         src = src.substring(token.raw.length);
21404         tokens.push(token);
21405         continue;
21406       }
21407
21408       // html
21409       if (token = this.tokenizer.html(src)) {
21410         src = src.substring(token.raw.length);
21411         tokens.push(token);
21412         continue;
21413       }
21414
21415       // def
21416       if (token = this.tokenizer.def(src)) {
21417         src = src.substring(token.raw.length);
21418         lastToken = tokens[tokens.length - 1];
21419         if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
21420           lastToken.raw += '\n' + token.raw;
21421           lastToken.text += '\n' + token.raw;
21422           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21423         } else if (!this.tokens.links[token.tag]) {
21424           this.tokens.links[token.tag] = {
21425             href: token.href,
21426             title: token.title
21427           };
21428         }
21429         continue;
21430       }
21431
21432       // table (gfm)
21433       if (token = this.tokenizer.table(src)) {
21434         src = src.substring(token.raw.length);
21435         tokens.push(token);
21436         continue;
21437       }
21438
21439       // lheading
21440       if (token = this.tokenizer.lheading(src)) {
21441         src = src.substring(token.raw.length);
21442         tokens.push(token);
21443         continue;
21444       }
21445
21446       // top-level paragraph
21447       // prevent paragraph consuming extensions by clipping 'src' to extension start
21448       cutSrc = src;
21449       if (this.options.extensions && this.options.extensions.startBlock) {
21450         (function () {
21451           var startIndex = Infinity;
21452           var tempSrc = src.slice(1);
21453           var tempStart = void 0;
21454           _this.options.extensions.startBlock.forEach(function (getStartIndex) {
21455             tempStart = getStartIndex.call({
21456               lexer: this
21457             }, tempSrc);
21458             if (typeof tempStart === 'number' && tempStart >= 0) {
21459               startIndex = Math.min(startIndex, tempStart);
21460             }
21461           });
21462           if (startIndex < Infinity && startIndex >= 0) {
21463             cutSrc = src.substring(0, startIndex + 1);
21464           }
21465         })();
21466       }
21467       if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
21468         lastToken = tokens[tokens.length - 1];
21469         if (lastParagraphClipped && lastToken.type === 'paragraph') {
21470           lastToken.raw += '\n' + token.raw;
21471           lastToken.text += '\n' + token.text;
21472           this.inlineQueue.pop();
21473           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21474         } else {
21475           tokens.push(token);
21476         }
21477         lastParagraphClipped = cutSrc.length !== src.length;
21478         src = src.substring(token.raw.length);
21479         continue;
21480       }
21481
21482       // text
21483       if (token = this.tokenizer.text(src)) {
21484         src = src.substring(token.raw.length);
21485         lastToken = tokens[tokens.length - 1];
21486         if (lastToken && lastToken.type === 'text') {
21487           lastToken.raw += '\n' + token.raw;
21488           lastToken.text += '\n' + token.text;
21489           this.inlineQueue.pop();
21490           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21491         } else {
21492           tokens.push(token);
21493         }
21494         continue;
21495       }
21496       if (src) {
21497         var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
21498         if (this.options.silent) {
21499           console.error(errMsg);
21500           break;
21501         } else {
21502           throw new Error(errMsg);
21503         }
21504       }
21505     }
21506     this.state.top = true;
21507     return tokens;
21508   };
21509   _proto.inline = function inline(src, tokens) {
21510     if (tokens === void 0) {
21511       tokens = [];
21512     }
21513     this.inlineQueue.push({
21514       src: src,
21515       tokens: tokens
21516     });
21517     return tokens;
21518   }
21519
21520   /**
21521    * Lexing/Compiling
21522    */;
21523   _proto.inlineTokens = function inlineTokens(src, tokens) {
21524     var _this2 = this;
21525     if (tokens === void 0) {
21526       tokens = [];
21527     }
21528     var token, lastToken, cutSrc;
21529
21530     // String with links masked to avoid interference with em and strong
21531     var maskedSrc = src;
21532     var match;
21533     var keepPrevChar, prevChar;
21534
21535     // Mask out reflinks
21536     if (this.tokens.links) {
21537       var links = Object.keys(this.tokens.links);
21538       if (links.length > 0) {
21539         while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
21540           if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
21541             maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
21542           }
21543         }
21544       }
21545     }
21546     // Mask out other blocks
21547     while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
21548       maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
21549     }
21550
21551     // Mask out escaped em & strong delimiters
21552     while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
21553       maskedSrc = maskedSrc.slice(0, match.index + match[0].length - 2) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
21554       this.tokenizer.rules.inline.escapedEmSt.lastIndex--;
21555     }
21556     while (src) {
21557       if (!keepPrevChar) {
21558         prevChar = '';
21559       }
21560       keepPrevChar = false;
21561
21562       // extensions
21563       if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some(function (extTokenizer) {
21564         if (token = extTokenizer.call({
21565           lexer: _this2
21566         }, src, tokens)) {
21567           src = src.substring(token.raw.length);
21568           tokens.push(token);
21569           return true;
21570         }
21571         return false;
21572       })) {
21573         continue;
21574       }
21575
21576       // escape
21577       if (token = this.tokenizer.escape(src)) {
21578         src = src.substring(token.raw.length);
21579         tokens.push(token);
21580         continue;
21581       }
21582
21583       // tag
21584       if (token = this.tokenizer.tag(src)) {
21585         src = src.substring(token.raw.length);
21586         lastToken = tokens[tokens.length - 1];
21587         if (lastToken && token.type === 'text' && lastToken.type === 'text') {
21588           lastToken.raw += token.raw;
21589           lastToken.text += token.text;
21590         } else {
21591           tokens.push(token);
21592         }
21593         continue;
21594       }
21595
21596       // link
21597       if (token = this.tokenizer.link(src)) {
21598         src = src.substring(token.raw.length);
21599         tokens.push(token);
21600         continue;
21601       }
21602
21603       // reflink, nolink
21604       if (token = this.tokenizer.reflink(src, this.tokens.links)) {
21605         src = src.substring(token.raw.length);
21606         lastToken = tokens[tokens.length - 1];
21607         if (lastToken && token.type === 'text' && lastToken.type === 'text') {
21608           lastToken.raw += token.raw;
21609           lastToken.text += token.text;
21610         } else {
21611           tokens.push(token);
21612         }
21613         continue;
21614       }
21615
21616       // em & strong
21617       if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
21618         src = src.substring(token.raw.length);
21619         tokens.push(token);
21620         continue;
21621       }
21622
21623       // code
21624       if (token = this.tokenizer.codespan(src)) {
21625         src = src.substring(token.raw.length);
21626         tokens.push(token);
21627         continue;
21628       }
21629
21630       // br
21631       if (token = this.tokenizer.br(src)) {
21632         src = src.substring(token.raw.length);
21633         tokens.push(token);
21634         continue;
21635       }
21636
21637       // del (gfm)
21638       if (token = this.tokenizer.del(src)) {
21639         src = src.substring(token.raw.length);
21640         tokens.push(token);
21641         continue;
21642       }
21643
21644       // autolink
21645       if (token = this.tokenizer.autolink(src, mangle)) {
21646         src = src.substring(token.raw.length);
21647         tokens.push(token);
21648         continue;
21649       }
21650
21651       // url (gfm)
21652       if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
21653         src = src.substring(token.raw.length);
21654         tokens.push(token);
21655         continue;
21656       }
21657
21658       // text
21659       // prevent inlineText consuming extensions by clipping 'src' to extension start
21660       cutSrc = src;
21661       if (this.options.extensions && this.options.extensions.startInline) {
21662         (function () {
21663           var startIndex = Infinity;
21664           var tempSrc = src.slice(1);
21665           var tempStart = void 0;
21666           _this2.options.extensions.startInline.forEach(function (getStartIndex) {
21667             tempStart = getStartIndex.call({
21668               lexer: this
21669             }, tempSrc);
21670             if (typeof tempStart === 'number' && tempStart >= 0) {
21671               startIndex = Math.min(startIndex, tempStart);
21672             }
21673           });
21674           if (startIndex < Infinity && startIndex >= 0) {
21675             cutSrc = src.substring(0, startIndex + 1);
21676           }
21677         })();
21678       }
21679       if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
21680         src = src.substring(token.raw.length);
21681         if (token.raw.slice(-1) !== '_') {
21682           // Track prevChar before string of ____ started
21683           prevChar = token.raw.slice(-1);
21684         }
21685         keepPrevChar = true;
21686         lastToken = tokens[tokens.length - 1];
21687         if (lastToken && lastToken.type === 'text') {
21688           lastToken.raw += token.raw;
21689           lastToken.text += token.text;
21690         } else {
21691           tokens.push(token);
21692         }
21693         continue;
21694       }
21695       if (src) {
21696         var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
21697         if (this.options.silent) {
21698           console.error(errMsg);
21699           break;
21700         } else {
21701           throw new Error(errMsg);
21702         }
21703       }
21704     }
21705     return tokens;
21706   };
21707   _createClass(Lexer, null, [{
21708     key: "rules",
21709     get: function get() {
21710       return {
21711         block: block,
21712         inline: inline
21713       };
21714     }
21715   }]);
21716   return Lexer;
21717 }();
21718
21719 /**
21720  * Renderer
21721  */
21722 var Renderer = /*#__PURE__*/function () {
21723   function Renderer(options) {
21724     this.options = options || exports.defaults;
21725   }
21726   var _proto = Renderer.prototype;
21727   _proto.code = function code(_code, infostring, escaped) {
21728     var lang = (infostring || '').match(/\S*/)[0];
21729     if (this.options.highlight) {
21730       var out = this.options.highlight(_code, lang);
21731       if (out != null && out !== _code) {
21732         escaped = true;
21733         _code = out;
21734       }
21735     }
21736     _code = _code.replace(/\n$/, '') + '\n';
21737     if (!lang) {
21738       return '<pre><code>' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n';
21739     }
21740     return '<pre><code class="' + this.options.langPrefix + escape(lang) + '">' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n';
21741   }
21742
21743   /**
21744    * @param {string} quote
21745    */;
21746   _proto.blockquote = function blockquote(quote) {
21747     return "<blockquote>\n" + quote + "</blockquote>\n";
21748   };
21749   _proto.html = function html(_html) {
21750     return _html;
21751   }
21752
21753   /**
21754    * @param {string} text
21755    * @param {string} level
21756    * @param {string} raw
21757    * @param {any} slugger
21758    */;
21759   _proto.heading = function heading(text, level, raw, slugger) {
21760     if (this.options.headerIds) {
21761       var id = this.options.headerPrefix + slugger.slug(raw);
21762       return "<h" + level + " id=\"" + id + "\">" + text + "</h" + level + ">\n";
21763     }
21764
21765     // ignore IDs
21766     return "<h" + level + ">" + text + "</h" + level + ">\n";
21767   };
21768   _proto.hr = function hr() {
21769     return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
21770   };
21771   _proto.list = function list(body, ordered, start) {
21772     var type = ordered ? 'ol' : 'ul',
21773       startatt = ordered && start !== 1 ? ' start="' + start + '"' : '';
21774     return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
21775   }
21776
21777   /**
21778    * @param {string} text
21779    */;
21780   _proto.listitem = function listitem(text) {
21781     return "<li>" + text + "</li>\n";
21782   };
21783   _proto.checkbox = function checkbox(checked) {
21784     return '<input ' + (checked ? 'checked="" ' : '') + 'disabled="" type="checkbox"' + (this.options.xhtml ? ' /' : '') + '> ';
21785   }
21786
21787   /**
21788    * @param {string} text
21789    */;
21790   _proto.paragraph = function paragraph(text) {
21791     return "<p>" + text + "</p>\n";
21792   }
21793
21794   /**
21795    * @param {string} header
21796    * @param {string} body
21797    */;
21798   _proto.table = function table(header, body) {
21799     if (body) body = "<tbody>" + body + "</tbody>";
21800     return '<table>\n' + '<thead>\n' + header + '</thead>\n' + body + '</table>\n';
21801   }
21802
21803   /**
21804    * @param {string} content
21805    */;
21806   _proto.tablerow = function tablerow(content) {
21807     return "<tr>\n" + content + "</tr>\n";
21808   };
21809   _proto.tablecell = function tablecell(content, flags) {
21810     var type = flags.header ? 'th' : 'td';
21811     var tag = flags.align ? "<" + type + " align=\"" + flags.align + "\">" : "<" + type + ">";
21812     return tag + content + ("</" + type + ">\n");
21813   }
21814
21815   /**
21816    * span level renderer
21817    * @param {string} text
21818    */;
21819   _proto.strong = function strong(text) {
21820     return "<strong>" + text + "</strong>";
21821   }
21822
21823   /**
21824    * @param {string} text
21825    */;
21826   _proto.em = function em(text) {
21827     return "<em>" + text + "</em>";
21828   }
21829
21830   /**
21831    * @param {string} text
21832    */;
21833   _proto.codespan = function codespan(text) {
21834     return "<code>" + text + "</code>";
21835   };
21836   _proto.br = function br() {
21837     return this.options.xhtml ? '<br/>' : '<br>';
21838   }
21839
21840   /**
21841    * @param {string} text
21842    */;
21843   _proto.del = function del(text) {
21844     return "<del>" + text + "</del>";
21845   }
21846
21847   /**
21848    * @param {string} href
21849    * @param {string} title
21850    * @param {string} text
21851    */;
21852   _proto.link = function link(href, title, text) {
21853     href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
21854     if (href === null) {
21855       return text;
21856     }
21857     var out = '<a href="' + href + '"';
21858     if (title) {
21859       out += ' title="' + title + '"';
21860     }
21861     out += '>' + text + '</a>';
21862     return out;
21863   }
21864
21865   /**
21866    * @param {string} href
21867    * @param {string} title
21868    * @param {string} text
21869    */;
21870   _proto.image = function image(href, title, text) {
21871     href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
21872     if (href === null) {
21873       return text;
21874     }
21875     var out = "<img src=\"" + href + "\" alt=\"" + text + "\"";
21876     if (title) {
21877       out += " title=\"" + title + "\"";
21878     }
21879     out += this.options.xhtml ? '/>' : '>';
21880     return out;
21881   };
21882   _proto.text = function text(_text) {
21883     return _text;
21884   };
21885   return Renderer;
21886 }();
21887
21888 /**
21889  * TextRenderer
21890  * returns only the textual part of the token
21891  */
21892 var TextRenderer = /*#__PURE__*/function () {
21893   function TextRenderer() {}
21894   var _proto = TextRenderer.prototype;
21895   // no need for block level renderers
21896   _proto.strong = function strong(text) {
21897     return text;
21898   };
21899   _proto.em = function em(text) {
21900     return text;
21901   };
21902   _proto.codespan = function codespan(text) {
21903     return text;
21904   };
21905   _proto.del = function del(text) {
21906     return text;
21907   };
21908   _proto.html = function html(text) {
21909     return text;
21910   };
21911   _proto.text = function text(_text) {
21912     return _text;
21913   };
21914   _proto.link = function link(href, title, text) {
21915     return '' + text;
21916   };
21917   _proto.image = function image(href, title, text) {
21918     return '' + text;
21919   };
21920   _proto.br = function br() {
21921     return '';
21922   };
21923   return TextRenderer;
21924 }();
21925
21926 /**
21927  * Slugger generates header id
21928  */
21929 var Slugger = /*#__PURE__*/function () {
21930   function Slugger() {
21931     this.seen = {};
21932   }
21933
21934   /**
21935    * @param {string} value
21936    */
21937   var _proto = Slugger.prototype;
21938   _proto.serialize = function serialize(value) {
21939     return value.toLowerCase().trim()
21940     // remove html tags
21941     .replace(/<[!\/a-z].*?>/ig, '')
21942     // remove unwanted chars
21943     .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '').replace(/\s/g, '-');
21944   }
21945
21946   /**
21947    * Finds the next safe (unique) slug to use
21948    * @param {string} originalSlug
21949    * @param {boolean} isDryRun
21950    */;
21951   _proto.getNextSafeSlug = function getNextSafeSlug(originalSlug, isDryRun) {
21952     var slug = originalSlug;
21953     var occurenceAccumulator = 0;
21954     if (this.seen.hasOwnProperty(slug)) {
21955       occurenceAccumulator = this.seen[originalSlug];
21956       do {
21957         occurenceAccumulator++;
21958         slug = originalSlug + '-' + occurenceAccumulator;
21959       } while (this.seen.hasOwnProperty(slug));
21960     }
21961     if (!isDryRun) {
21962       this.seen[originalSlug] = occurenceAccumulator;
21963       this.seen[slug] = 0;
21964     }
21965     return slug;
21966   }
21967
21968   /**
21969    * Convert string to unique id
21970    * @param {object} [options]
21971    * @param {boolean} [options.dryrun] Generates the next unique slug without
21972    * updating the internal accumulator.
21973    */;
21974   _proto.slug = function slug(value, options) {
21975     if (options === void 0) {
21976       options = {};
21977     }
21978     var slug = this.serialize(value);
21979     return this.getNextSafeSlug(slug, options.dryrun);
21980   };
21981   return Slugger;
21982 }();
21983
21984 /**
21985  * Parsing & Compiling
21986  */
21987 var Parser = /*#__PURE__*/function () {
21988   function Parser(options) {
21989     this.options = options || exports.defaults;
21990     this.options.renderer = this.options.renderer || new Renderer();
21991     this.renderer = this.options.renderer;
21992     this.renderer.options = this.options;
21993     this.textRenderer = new TextRenderer();
21994     this.slugger = new Slugger();
21995   }
21996
21997   /**
21998    * Static Parse Method
21999    */
22000   Parser.parse = function parse(tokens, options) {
22001     var parser = new Parser(options);
22002     return parser.parse(tokens);
22003   }
22004
22005   /**
22006    * Static Parse Inline Method
22007    */;
22008   Parser.parseInline = function parseInline(tokens, options) {
22009     var parser = new Parser(options);
22010     return parser.parseInline(tokens);
22011   }
22012
22013   /**
22014    * Parse Loop
22015    */;
22016   var _proto = Parser.prototype;
22017   _proto.parse = function parse(tokens, top) {
22018     if (top === void 0) {
22019       top = true;
22020     }
22021     var out = '',
22022       i,
22023       j,
22024       k,
22025       l2,
22026       l3,
22027       row,
22028       cell,
22029       header,
22030       body,
22031       token,
22032       ordered,
22033       start,
22034       loose,
22035       itemBody,
22036       item,
22037       checked,
22038       task,
22039       checkbox,
22040       ret;
22041     var l = tokens.length;
22042     for (i = 0; i < l; i++) {
22043       token = tokens[i];
22044
22045       // Run any renderer extensions
22046       if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
22047         ret = this.options.extensions.renderers[token.type].call({
22048           parser: this
22049         }, token);
22050         if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
22051           out += ret || '';
22052           continue;
22053         }
22054       }
22055       switch (token.type) {
22056         case 'space':
22057           {
22058             continue;
22059           }
22060         case 'hr':
22061           {
22062             out += this.renderer.hr();
22063             continue;
22064           }
22065         case 'heading':
22066           {
22067             out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger);
22068             continue;
22069           }
22070         case 'code':
22071           {
22072             out += this.renderer.code(token.text, token.lang, token.escaped);
22073             continue;
22074           }
22075         case 'table':
22076           {
22077             header = '';
22078
22079             // header
22080             cell = '';
22081             l2 = token.header.length;
22082             for (j = 0; j < l2; j++) {
22083               cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), {
22084                 header: true,
22085                 align: token.align[j]
22086               });
22087             }
22088             header += this.renderer.tablerow(cell);
22089             body = '';
22090             l2 = token.rows.length;
22091             for (j = 0; j < l2; j++) {
22092               row = token.rows[j];
22093               cell = '';
22094               l3 = row.length;
22095               for (k = 0; k < l3; k++) {
22096                 cell += this.renderer.tablecell(this.parseInline(row[k].tokens), {
22097                   header: false,
22098                   align: token.align[k]
22099                 });
22100               }
22101               body += this.renderer.tablerow(cell);
22102             }
22103             out += this.renderer.table(header, body);
22104             continue;
22105           }
22106         case 'blockquote':
22107           {
22108             body = this.parse(token.tokens);
22109             out += this.renderer.blockquote(body);
22110             continue;
22111           }
22112         case 'list':
22113           {
22114             ordered = token.ordered;
22115             start = token.start;
22116             loose = token.loose;
22117             l2 = token.items.length;
22118             body = '';
22119             for (j = 0; j < l2; j++) {
22120               item = token.items[j];
22121               checked = item.checked;
22122               task = item.task;
22123               itemBody = '';
22124               if (item.task) {
22125                 checkbox = this.renderer.checkbox(checked);
22126                 if (loose) {
22127                   if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
22128                     item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
22129                     if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
22130                       item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
22131                     }
22132                   } else {
22133                     item.tokens.unshift({
22134                       type: 'text',
22135                       text: checkbox
22136                     });
22137                   }
22138                 } else {
22139                   itemBody += checkbox;
22140                 }
22141               }
22142               itemBody += this.parse(item.tokens, loose);
22143               body += this.renderer.listitem(itemBody, task, checked);
22144             }
22145             out += this.renderer.list(body, ordered, start);
22146             continue;
22147           }
22148         case 'html':
22149           {
22150             // TODO parse inline content if parameter markdown=1
22151             out += this.renderer.html(token.text);
22152             continue;
22153           }
22154         case 'paragraph':
22155           {
22156             out += this.renderer.paragraph(this.parseInline(token.tokens));
22157             continue;
22158           }
22159         case 'text':
22160           {
22161             body = token.tokens ? this.parseInline(token.tokens) : token.text;
22162             while (i + 1 < l && tokens[i + 1].type === 'text') {
22163               token = tokens[++i];
22164               body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
22165             }
22166             out += top ? this.renderer.paragraph(body) : body;
22167             continue;
22168           }
22169         default:
22170           {
22171             var errMsg = 'Token with "' + token.type + '" type was not found.';
22172             if (this.options.silent) {
22173               console.error(errMsg);
22174               return;
22175             } else {
22176               throw new Error(errMsg);
22177             }
22178           }
22179       }
22180     }
22181     return out;
22182   }
22183
22184   /**
22185    * Parse Inline Tokens
22186    */;
22187   _proto.parseInline = function parseInline(tokens, renderer) {
22188     renderer = renderer || this.renderer;
22189     var out = '',
22190       i,
22191       token,
22192       ret;
22193     var l = tokens.length;
22194     for (i = 0; i < l; i++) {
22195       token = tokens[i];
22196
22197       // Run any renderer extensions
22198       if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
22199         ret = this.options.extensions.renderers[token.type].call({
22200           parser: this
22201         }, token);
22202         if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
22203           out += ret || '';
22204           continue;
22205         }
22206       }
22207       switch (token.type) {
22208         case 'escape':
22209           {
22210             out += renderer.text(token.text);
22211             break;
22212           }
22213         case 'html':
22214           {
22215             out += renderer.html(token.text);
22216             break;
22217           }
22218         case 'link':
22219           {
22220             out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
22221             break;
22222           }
22223         case 'image':
22224           {
22225             out += renderer.image(token.href, token.title, token.text);
22226             break;
22227           }
22228         case 'strong':
22229           {
22230             out += renderer.strong(this.parseInline(token.tokens, renderer));
22231             break;
22232           }
22233         case 'em':
22234           {
22235             out += renderer.em(this.parseInline(token.tokens, renderer));
22236             break;
22237           }
22238         case 'codespan':
22239           {
22240             out += renderer.codespan(token.text);
22241             break;
22242           }
22243         case 'br':
22244           {
22245             out += renderer.br();
22246             break;
22247           }
22248         case 'del':
22249           {
22250             out += renderer.del(this.parseInline(token.tokens, renderer));
22251             break;
22252           }
22253         case 'text':
22254           {
22255             out += renderer.text(token.text);
22256             break;
22257           }
22258         default:
22259           {
22260             var errMsg = 'Token with "' + token.type + '" type was not found.';
22261             if (this.options.silent) {
22262               console.error(errMsg);
22263               return;
22264             } else {
22265               throw new Error(errMsg);
22266             }
22267           }
22268       }
22269     }
22270     return out;
22271   };
22272   return Parser;
22273 }();
22274
22275 /**
22276  * Marked
22277  */
22278 function marked(src, opt, callback) {
22279   // throw error in case of non string input
22280   if (typeof src === 'undefined' || src === null) {
22281     throw new Error('marked(): input parameter is undefined or null');
22282   }
22283   if (typeof src !== 'string') {
22284     throw new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected');
22285   }
22286   if (typeof opt === 'function') {
22287     callback = opt;
22288     opt = null;
22289   }
22290   opt = merge({}, marked.defaults, opt || {});
22291   checkSanitizeDeprecation(opt);
22292   if (callback) {
22293     var highlight = opt.highlight;
22294     var tokens;
22295     try {
22296       tokens = Lexer.lex(src, opt);
22297     } catch (e) {
22298       return callback(e);
22299     }
22300     var done = function done(err) {
22301       var out;
22302       if (!err) {
22303         try {
22304           if (opt.walkTokens) {
22305             marked.walkTokens(tokens, opt.walkTokens);
22306           }
22307           out = Parser.parse(tokens, opt);
22308         } catch (e) {
22309           err = e;
22310         }
22311       }
22312       opt.highlight = highlight;
22313       return err ? callback(err) : callback(null, out);
22314     };
22315     if (!highlight || highlight.length < 3) {
22316       return done();
22317     }
22318     delete opt.highlight;
22319     if (!tokens.length) return done();
22320     var pending = 0;
22321     marked.walkTokens(tokens, function (token) {
22322       if (token.type === 'code') {
22323         pending++;
22324         setTimeout(function () {
22325           highlight(token.text, token.lang, function (err, code) {
22326             if (err) {
22327               return done(err);
22328             }
22329             if (code != null && code !== token.text) {
22330               token.text = code;
22331               token.escaped = true;
22332             }
22333             pending--;
22334             if (pending === 0) {
22335               done();
22336             }
22337           });
22338         }, 0);
22339       }
22340     });
22341     if (pending === 0) {
22342       done();
22343     }
22344     return;
22345   }
22346   function onError(e) {
22347     e.message += '\nPlease report this to https://github.com/markedjs/marked.';
22348     if (opt.silent) {
22349       return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>';
22350     }
22351     throw e;
22352   }
22353   try {
22354     var _tokens = Lexer.lex(src, opt);
22355     if (opt.walkTokens) {
22356       if (opt.async) {
22357         return Promise.all(marked.walkTokens(_tokens, opt.walkTokens)).then(function () {
22358           return Parser.parse(_tokens, opt);
22359         })["catch"](onError);
22360       }
22361       marked.walkTokens(_tokens, opt.walkTokens);
22362     }
22363     return Parser.parse(_tokens, opt);
22364   } catch (e) {
22365     onError(e);
22366   }
22367 }
22368
22369 /**
22370  * Options
22371  */
22372
22373 marked.options = marked.setOptions = function (opt) {
22374   merge(marked.defaults, opt);
22375   changeDefaults(marked.defaults);
22376   return marked;
22377 };
22378 marked.getDefaults = getDefaults;
22379 marked.defaults = exports.defaults;
22380
22381 /**
22382  * Use Extension
22383  */
22384
22385 marked.use = function () {
22386   var extensions = marked.defaults.extensions || {
22387     renderers: {},
22388     childTokens: {}
22389   };
22390   for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
22391     args[_key] = arguments[_key];
22392   }
22393   args.forEach(function (pack) {
22394     // copy options to new object
22395     var opts = merge({}, pack);
22396
22397     // set async to true if it was set to true before
22398     opts.async = marked.defaults.async || opts.async;
22399
22400     // ==-- Parse "addon" extensions --== //
22401     if (pack.extensions) {
22402       pack.extensions.forEach(function (ext) {
22403         if (!ext.name) {
22404           throw new Error('extension name required');
22405         }
22406         if (ext.renderer) {
22407           // Renderer extensions
22408           var prevRenderer = extensions.renderers[ext.name];
22409           if (prevRenderer) {
22410             // Replace extension with func to run new extension but fall back if false
22411             extensions.renderers[ext.name] = function () {
22412               for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22413                 args[_key2] = arguments[_key2];
22414               }
22415               var ret = ext.renderer.apply(this, args);
22416               if (ret === false) {
22417                 ret = prevRenderer.apply(this, args);
22418               }
22419               return ret;
22420             };
22421           } else {
22422             extensions.renderers[ext.name] = ext.renderer;
22423           }
22424         }
22425         if (ext.tokenizer) {
22426           // Tokenizer Extensions
22427           if (!ext.level || ext.level !== 'block' && ext.level !== 'inline') {
22428             throw new Error("extension level must be 'block' or 'inline'");
22429           }
22430           if (extensions[ext.level]) {
22431             extensions[ext.level].unshift(ext.tokenizer);
22432           } else {
22433             extensions[ext.level] = [ext.tokenizer];
22434           }
22435           if (ext.start) {
22436             // Function to check for start of token
22437             if (ext.level === 'block') {
22438               if (extensions.startBlock) {
22439                 extensions.startBlock.push(ext.start);
22440               } else {
22441                 extensions.startBlock = [ext.start];
22442               }
22443             } else if (ext.level === 'inline') {
22444               if (extensions.startInline) {
22445                 extensions.startInline.push(ext.start);
22446               } else {
22447                 extensions.startInline = [ext.start];
22448               }
22449             }
22450           }
22451         }
22452         if (ext.childTokens) {
22453           // Child tokens to be visited by walkTokens
22454           extensions.childTokens[ext.name] = ext.childTokens;
22455         }
22456       });
22457       opts.extensions = extensions;
22458     }
22459
22460     // ==-- Parse "overwrite" extensions --== //
22461     if (pack.renderer) {
22462       (function () {
22463         var renderer = marked.defaults.renderer || new Renderer();
22464         var _loop = function _loop(prop) {
22465           var prevRenderer = renderer[prop];
22466           // Replace renderer with func to run extension, but fall back if false
22467           renderer[prop] = function () {
22468             for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
22469               args[_key3] = arguments[_key3];
22470             }
22471             var ret = pack.renderer[prop].apply(renderer, args);
22472             if (ret === false) {
22473               ret = prevRenderer.apply(renderer, args);
22474             }
22475             return ret;
22476           };
22477         };
22478         for (var prop in pack.renderer) {
22479           _loop(prop);
22480         }
22481         opts.renderer = renderer;
22482       })();
22483     }
22484     if (pack.tokenizer) {
22485       (function () {
22486         var tokenizer = marked.defaults.tokenizer || new Tokenizer();
22487         var _loop2 = function _loop2(prop) {
22488           var prevTokenizer = tokenizer[prop];
22489           // Replace tokenizer with func to run extension, but fall back if false
22490           tokenizer[prop] = function () {
22491             for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
22492               args[_key4] = arguments[_key4];
22493             }
22494             var ret = pack.tokenizer[prop].apply(tokenizer, args);
22495             if (ret === false) {
22496               ret = prevTokenizer.apply(tokenizer, args);
22497             }
22498             return ret;
22499           };
22500         };
22501         for (var prop in pack.tokenizer) {
22502           _loop2(prop);
22503         }
22504         opts.tokenizer = tokenizer;
22505       })();
22506     }
22507
22508     // ==-- Parse WalkTokens extensions --== //
22509     if (pack.walkTokens) {
22510       var _walkTokens = marked.defaults.walkTokens;
22511       opts.walkTokens = function (token) {
22512         var values = [];
22513         values.push(pack.walkTokens.call(this, token));
22514         if (_walkTokens) {
22515           values = values.concat(_walkTokens.call(this, token));
22516         }
22517         return values;
22518       };
22519     }
22520     marked.setOptions(opts);
22521   });
22522 };
22523
22524 /**
22525  * Run callback for every token
22526  */
22527
22528 marked.walkTokens = function (tokens, callback) {
22529   var values = [];
22530   var _loop3 = function _loop3() {
22531     var token = _step.value;
22532     values = values.concat(callback.call(marked, token));
22533     switch (token.type) {
22534       case 'table':
22535         {
22536           for (var _iterator2 = _createForOfIteratorHelperLoose(token.header), _step2; !(_step2 = _iterator2()).done;) {
22537             var cell = _step2.value;
22538             values = values.concat(marked.walkTokens(cell.tokens, callback));
22539           }
22540           for (var _iterator3 = _createForOfIteratorHelperLoose(token.rows), _step3; !(_step3 = _iterator3()).done;) {
22541             var row = _step3.value;
22542             for (var _iterator4 = _createForOfIteratorHelperLoose(row), _step4; !(_step4 = _iterator4()).done;) {
22543               var _cell = _step4.value;
22544               values = values.concat(marked.walkTokens(_cell.tokens, callback));
22545             }
22546           }
22547           break;
22548         }
22549       case 'list':
22550         {
22551           values = values.concat(marked.walkTokens(token.items, callback));
22552           break;
22553         }
22554       default:
22555         {
22556           if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) {
22557             // Walk any extensions
22558             marked.defaults.extensions.childTokens[token.type].forEach(function (childTokens) {
22559               values = values.concat(marked.walkTokens(token[childTokens], callback));
22560             });
22561           } else if (token.tokens) {
22562             values = values.concat(marked.walkTokens(token.tokens, callback));
22563           }
22564         }
22565     }
22566   };
22567   for (var _iterator = _createForOfIteratorHelperLoose(tokens), _step; !(_step = _iterator()).done;) {
22568     _loop3();
22569   }
22570   return values;
22571 };
22572
22573 /**
22574  * Parse Inline
22575  * @param {string} src
22576  */
22577 marked.parseInline = function (src, opt) {
22578   // throw error in case of non string input
22579   if (typeof src === 'undefined' || src === null) {
22580     throw new Error('marked.parseInline(): input parameter is undefined or null');
22581   }
22582   if (typeof src !== 'string') {
22583     throw new Error('marked.parseInline(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected');
22584   }
22585   opt = merge({}, marked.defaults, opt || {});
22586   checkSanitizeDeprecation(opt);
22587   try {
22588     var tokens = Lexer.lexInline(src, opt);
22589     if (opt.walkTokens) {
22590       marked.walkTokens(tokens, opt.walkTokens);
22591     }
22592     return Parser.parseInline(tokens, opt);
22593   } catch (e) {
22594     e.message += '\nPlease report this to https://github.com/markedjs/marked.';
22595     if (opt.silent) {
22596       return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>';
22597     }
22598     throw e;
22599   }
22600 };
22601
22602 /**
22603  * Expose
22604  */
22605 marked.Parser = Parser;
22606 marked.parser = Parser.parse;
22607 marked.Renderer = Renderer;
22608 marked.TextRenderer = TextRenderer;
22609 marked.Lexer = Lexer;
22610 marked.lexer = Lexer.lex;
22611 marked.Tokenizer = Tokenizer;
22612 marked.Slugger = Slugger;
22613 marked.parse = marked;
22614 var options = marked.options;
22615 var setOptions = marked.setOptions;
22616 var use = marked.use;
22617 var walkTokens = marked.walkTokens;
22618 var parseInline = marked.parseInline;
22619 var parse = marked;
22620 var parser = Parser.parse;
22621 var lexer = Lexer.lex;
22622
22623 exports.Lexer = Lexer;
22624 exports.Parser = Parser;
22625 exports.Renderer = Renderer;
22626 exports.Slugger = Slugger;
22627 exports.TextRenderer = TextRenderer;
22628 exports.Tokenizer = Tokenizer;
22629 exports.getDefaults = getDefaults;
22630 exports.lexer = lexer;
22631 exports.marked = marked;
22632 exports.options = options;
22633 exports.parse = parse;
22634 exports.parseInline = parseInline;
22635 exports.parser = parser;
22636 exports.setOptions = setOptions;
22637 exports.use = use;
22638 exports.walkTokens = walkTokens;
22639
22640
22641 /***/ }),
22642
22643 /***/ "./src/test-data.json":
22644 /*!****************************!*\
22645   !*** ./src/test-data.json ***!
22646   \****************************/
22647 /***/ ((module) => {
22648
22649 "use strict";
22650 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"}}}');
22651
22652 /***/ })
22653
22654 /******/        });
22655 /************************************************************************/
22656 /******/        // The module cache
22657 /******/        var __webpack_module_cache__ = {};
22658 /******/        
22659 /******/        // The require function
22660 /******/        function __webpack_require__(moduleId) {
22661 /******/                // Check if module is in cache
22662 /******/                var cachedModule = __webpack_module_cache__[moduleId];
22663 /******/                if (cachedModule !== undefined) {
22664 /******/                        return cachedModule.exports;
22665 /******/                }
22666 /******/                // Create a new module (and put it into the cache)
22667 /******/                var module = __webpack_module_cache__[moduleId] = {
22668 /******/                        id: moduleId,
22669 /******/                        loaded: false,
22670 /******/                        exports: {}
22671 /******/                };
22672 /******/        
22673 /******/                // Execute the module function
22674 /******/                __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22675 /******/        
22676 /******/                // Flag the module as loaded
22677 /******/                module.loaded = true;
22678 /******/        
22679 /******/                // Return the exports of the module
22680 /******/                return module.exports;
22681 /******/        }
22682 /******/        
22683 /************************************************************************/
22684 /******/        /* webpack/runtime/global */
22685 /******/        (() => {
22686 /******/                __webpack_require__.g = (function() {
22687 /******/                        if (typeof globalThis === 'object') return globalThis;
22688 /******/                        try {
22689 /******/                                return this || new Function('return this')();
22690 /******/                        } catch (e) {
22691 /******/                                if (typeof window === 'object') return window;
22692 /******/                        }
22693 /******/                })();
22694 /******/        })();
22695 /******/        
22696 /******/        /* webpack/runtime/node module decorator */
22697 /******/        (() => {
22698 /******/                __webpack_require__.nmd = (module) => {
22699 /******/                        module.paths = [];
22700 /******/                        if (!module.children) module.children = [];
22701 /******/                        return module;
22702 /******/                };
22703 /******/        })();
22704 /******/        
22705 /************************************************************************/
22706 /******/        
22707 /******/        // startup
22708 /******/        // Load entry module and return exports
22709 /******/        // This entry module is referenced by other modules so it can't be inlined
22710 /******/        var __webpack_exports__ = __webpack_require__("./src/client.ts");
22711 /******/        
22712 /******/ })()
22713 ;
22714 //# 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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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVEsV0FBVztBQUNsQyxlQUFlLFNBQVM7QUFDeEI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQSxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLG1EQUFtRCxpQkFBaUI7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsTUFBTTtBQUNyQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxNQUFNO0FBQ3JCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsMEJBQTBCO0FBQ3pDO0FBQ0EsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsZUFBZSxNQUFNO0FBQ3JCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLE1BQU07QUFDckIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLHNCQUFzQjtBQUNyQyxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixRQUFRO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEIscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGVBQWUsR0FBRztBQUNsQixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBLDJCQUEyQixRQUFRO0FBQ25DO0FBQ0E7QUFDQSwyQkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixnQkFBZ0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFNBQVM7QUFDeEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDLEtBQUs7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsZUFBZTtBQUM5QixlQUFlLGlCQUFpQjtBQUNoQyxpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxlQUFlO0FBQzlCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVEsV0FBVztBQUNsQyxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixnQkFBZ0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7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QTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBLHdCQUF3QixRQUFRLElBQUksUUFBUSxJQUFJLFFBQVEsSUFBSSxRQUFRO0FBQ3BFO0FBQ0Esc0NBQXNDLGFBQWE7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxLQUFLLE9BQU8sZ0JBQWdCOztBQUU1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQywyREFBMkQ7QUFDL0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FB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QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0JBQWtCLGNBQWM7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixjQUFjO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxrQkFBa0IsYUFBYTtBQUMvQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWU7Ozs7Ozs7Ozs7O0FDOU5GOztBQUVi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O0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsU0FBUztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsT0FBTztBQUNoQjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsSUFBSTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUVBO0FBQ0E7QUFDQSxvQkFBb0IsT0FBTztBQUMzQjtBQUNBLHNCQUFzQixnQkFBZ0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdEQUFnRCxFQUFFLEdBQUcsR0FBRztBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTs7QUFFQTtBQUNBLHNDQUFzQzs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxFQUFFO0FB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQSxlQUFlLEVBQUU7QUFDakI7O0FBRUE7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQixhQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQixhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyREFBMkQsV0FBVyxFQUFFO0FBQ3hFOztBQUVBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsT0FBTztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsUUFBUTtBQUNsQztBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixPQUFPO0FBQ3ZCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLDRCQUE0QjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsU0FBUztBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFD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InNvdXJjZXMiOlsid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy9rZXlib2FyZGpzL2Rpc3Qva2V5Ym9hcmQuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL2xvZGFzaC9sb2Rhc2guanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vc3JjL2NsaWVudC50cyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9zcmMvY3Vyc29yLnRzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL3NyYy9vdXRsaW5lLnRzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9pbmRleC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvbWQ1LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9uYXRpdmUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL25pbC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvcGFyc2UuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3JlZ2V4LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9ybmcuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3NoYTEuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3N0cmluZ2lmeS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvdjEuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3YzLmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci92MzUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3Y0LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci92NS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvdmFsaWRhdGUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3ZlcnNpb24uanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL21hcmtlZC9saWIvbWFya2VkLmNqcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svcnVudGltZS9nbG9iYWwiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svYmVmb3JlLXN0YXJ0dXAiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svc3RhcnR1cCIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9hZnRlci1zdGFydHVwIl0sInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/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/IHZhbHVlIDogW10sIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBNYXAgbWluaWZpZWQgbWV0aG9kIG5hbWVzIHRvIHRoZWlyIHJlYWwgbmFtZXMuXG4gICAgYmFzZUZvck93bihMYXp5V3JhcHBlci5wcm90b3R5cGUsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBsb2Rhc2hGdW5jID0gbG9kYXNoW21ldGhvZE5hbWVdO1xuICAgICAgaWYgKGxvZGFzaEZ1bmMpIHtcbiAgICAgICAgdmFyIGtleSA9IGxvZGFzaEZ1bmMubmFtZSArICcnO1xuICAgICAgICBpZiAoIWhhc093blByb3BlcnR5LmNhbGwocmVhbE5hbWVzLCBrZXkpKSB7XG4gICAgICAgICAgcmVhbE5hbWVzW2tleV0gPSBbXTtcbiAgICAgICAgfVxuICAgICAgICByZWFsTmFtZXNba2V5XS5wdXNoKHsgJ25hbWUnOiBtZXRob2ROYW1lLCAnZnVuYyc6IGxvZGFzaEZ1bmMgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZWFsTmFtZXNbY3JlYXRlSHlicmlkKHVuZGVmaW5lZCwgV1JBUF9CSU5EX0tFWV9GTEFHKS5uYW1lXSA9IFt7XG4gICAgICAnbmFtZSc6ICd3cmFwcGVyJyxcbiAgICAgICdmdW5jJzogdW5kZWZpbmVkXG4gICAgfV07XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgTGF6eVdyYXBwZXJgLlxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jbG9uZSA9IGxhenlDbG9uZTtcbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUucmV2ZXJzZSA9IGxhenlSZXZlcnNlO1xuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS52YWx1ZSA9IGxhenlWYWx1ZTtcblxuICAgIC8vIEFkZCBjaGFpbiBzZXF1ZW5jZSBtZXRob2RzIHRvIHRoZSBgbG9kYXNoYCB3cmFwcGVyLlxuICAgIGxvZGFzaC5wcm90b3R5cGUuYXQgPSB3cmFwcGVyQXQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5jaGFpbiA9IHdyYXBwZXJDaGFpbjtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmNvbW1pdCA9IHdyYXBwZXJDb21taXQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5uZXh0ID0gd3JhcHBlck5leHQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5wbGFudCA9IHdyYXBwZXJQbGFudDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnJldmVyc2UgPSB3cmFwcGVyUmV2ZXJzZTtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnRvSlNPTiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWVPZiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWUgPSB3cmFwcGVyVmFsdWU7XG5cbiAgICAvLyBBZGQgbGF6eSBhbGlhc2VzLlxuICAgIGxvZGFzaC5wcm90b3R5cGUuZmlyc3QgPSBsb2Rhc2gucHJvdG90eXBlLmhlYWQ7XG5cbiAgICBpZiAoc3ltSXRlcmF0b3IpIHtcbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbc3ltSXRlcmF0b3JdID0gd3JhcHBlclRvSXRlcmF0b3I7XG4gICAgfVxuICAgIHJldHVybiBsb2Rhc2g7XG4gIH0pO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8vIEV4cG9ydCBsb2Rhc2guXG4gIHZhciBfID0gcnVuSW5Db250ZXh0KCk7XG5cbiAgLy8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3IgY29uZGl0aW9uIHBhdHRlcm5zIGxpa2U6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBMb2Rhc2ggb24gdGhlIGdsb2JhbCBvYmplY3QgdG8gcHJldmVudCBlcnJvcnMgd2hlbiBMb2Rhc2ggaXNcbiAgICAvLyBsb2FkZWQgYnkgYSBzY3JpcHQgdGFnIGluIHRoZSBwcmVzZW5jZSBvZiBhbiBBTUQgbG9hZGVyLlxuICAgIC8vIFNlZSBodHRwOi8vcmVxdWlyZWpzLm9yZy9kb2NzL2Vycm9ycy5odG1sI21pc21hdGNoIGZvciBtb3JlIGRldGFpbHMuXG4gICAgLy8gVXNlIGBfLm5vQ29uZmxpY3RgIHRvIHJlbW92ZSBMb2Rhc2ggZnJvbSB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290Ll8gPSBfO1xuXG4gICAgLy8gRGVmaW5lIGFzIGFuIGFub255bW91cyBtb2R1bGUgc28sIHRocm91Z2ggcGF0aCBtYXBwaW5nLCBpdCBjYW4gYmVcbiAgICAvLyByZWZlcmVuY2VkIGFzIHRoZSBcInVuZGVyc2NvcmVcIiBtb2R1bGUuXG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIF87XG4gICAgfSk7XG4gIH1cbiAgLy8gQ2hlY2sgZm9yIGBleHBvcnRzYCBhZnRlciBgZGVmaW5lYCBpbiBjYXNlIGEgYnVpbGQgb3B0aW1pemVyIGFkZHMgaXQuXG4gIGVsc2UgaWYgKGZyZWVNb2R1bGUpIHtcbiAgICAvLyBFeHBvcnQgZm9yIE5vZGUuanMuXG4gICAgKGZyZWVNb2R1bGUuZXhwb3J0cyA9IF8pLl8gPSBfO1xuICAgIC8vIEV4cG9ydCBmb3IgQ29tbW9uSlMgc3VwcG9ydC5cbiAgICBmcmVlRXhwb3J0cy5fID0gXztcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBFeHBvcnQgdG8gdGhlIGdsb2JhbCBvYmplY3QuXG4gICAgcm9vdC5fID0gXztcbiAgfVxufS5jYWxsKHRoaXMpKTtcbiIsImltcG9ydCB7IE91dGxpbmUsIFJhd091dGxpbmUgfSBmcm9tICcuL291dGxpbmUnO1xuaW1wb3J0IHsgQ3Vyc29yIH0gZnJvbSAnLi9jdXJzb3InO1xuaW1wb3J0IGtleWJvYXJkSlMgZnJvbSAna2V5Ym9hcmRqcyc7XG5pbXBvcnQgKiBhcyByYXdPdXRsaW5lIGZyb20gJy4vdGVzdC1kYXRhLmpzb24nO1xuXG5sZXQgb3V0bGluZURhdGEgPSByYXdPdXRsaW5lO1xuaWYobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2FjdGl2ZU91dGxpbmUnKSkge1xuICBjb25zdCBvdXRsaW5lSWQgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYWN0aXZlT3V0bGluZScpO1xuICBvdXRsaW5lRGF0YSA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0ob3V0bGluZUlkKSk7XG59XG5cbmNvbnN0IHN0YXRlID0gbmV3IE1hcDxzdHJpbmcsIGFueT4oKTtcbmNvbnN0IG91dGxpbmUgPSBuZXcgT3V0bGluZShvdXRsaW5lRGF0YSBhcyB1bmtub3duIGFzIFJhd091dGxpbmUpO1xub3V0bGluZXIoKS5pbm5lckhUTUwgPSBvdXRsaW5lLnJlbmRlcigpO1xuXG5jb25zdCBjdXJzb3IgPSBuZXcgQ3Vyc29yKCk7XG4vLyBwbGFjZSB0aGUgY3Vyc29yIGF0IHRoZSB0b3AhXG5jdXJzb3Iuc2V0KCcubm9kZScpO1xuXG5mdW5jdGlvbiBvdXRsaW5lcigpIHtcbiAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNvdXRsaW5lcicpO1xufVxuXG4vLyBtb3ZlIGRvd25cbmtleWJvYXJkSlMud2l0aENvbnRleHQoJ25hdmlnYXRpb24nLCAoKSA9PiB7XG4gIGtleWJvYXJkSlMuYmluZCgnaicsIGUgPT4ge1xuICAgIC8vIG1vdmUgY3Vyc29yIGRvd25cbiAgICAvLyBpZiBzaGlmdCBrZXkgaXMgaGVsZCwgc3dhcCB0aGUgbm9kZSB3aXRoIGl0cyBuZXh0IHNpYmxpbmdcbiAgICBjb25zdCBzaWJsaW5nID0gY3Vyc29yLmdldCgpLm5leHRFbGVtZW50U2libGluZztcblxuICAgIGlmKHNpYmxpbmcpIHtcbiAgICAgIGlmKGUuc2hpZnRLZXkpIHtcbiAgICAgICAgLy8gc3dhcCB0aGlzIG5vZGUgd2l0aCBpdHMgcHJldmlvdXMgc2libGluZ1xuICAgICAgICBjb25zdCByZXMgPSBvdXRsaW5lLnN3YXBOb2RlV2l0aE5leHRTaWJsaW5nKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICAgICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMucGFyZW50Tm9kZSk7XG5cbiAgICAgICAgaWYocmVzLnBhcmVudE5vZGUuaWQgPT09ICcwMDAwMDAnKSB7XG4gICAgICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5vdXRlckhUTUwgPSBodG1sO1xuICAgICAgICB9XG5cbiAgICAgICAgY3Vyc29yLnNldChgI2lkLSR7cmVzLnRhcmdldE5vZGUuaWR9YCk7XG4gICAgICAgIHNhdmUoKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtzaWJsaW5nLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpfWApO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdrJywgZSA9PiB7XG4gICAgLy8gbW92ZSBjdXJzb3IgdXBcbiAgICAvLyBpZiBzaGlmdCBrZXkgaXMgaGVsZCwgc3dhcCB0aGUgbm9kZSB3aXRoIGl0cyBwcmV2aW91cyBzaWJsaW5nXG4gICAgY29uc3Qgc2libGluZyA9IGN1cnNvci5nZXQoKS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuXG4gICAgaWYoc2libGluZyAmJiAhc2libGluZy5jbGFzc0xpc3QuY29udGFpbnMoJ25vZGVDb250ZW50JykpIHtcbiAgICAgIGlmKGUuc2hpZnRLZXkpIHtcbiAgICAgICAgLy8gc3dhcCB0aGlzIG5vZGUgd2l0aCBpdHMgcHJldmlvdXMgc2libGluZ1xuICAgICAgICBjb25zdCByZXMgPSBvdXRsaW5lLnN3YXBOb2RlV2l0aFByZXZpb3VzU2libGluZyhjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgICAgIC8vIHJlLXJlbmRlciB0aGUgcGFyZW50IG5vZGUgYW5kIGRpc3BsYXkgdGhhdCFcbiAgICAgICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMucGFyZW50Tm9kZSk7XG5cbiAgICAgICAgaWYocmVzLnBhcmVudE5vZGUuaWQgPT09ICcwMDAwMDAnKSB7XG4gICAgICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5vdXRlckhUTUwgPSBodG1sO1xuICAgICAgICB9XG5cbiAgICAgICAgY3Vyc29yLnNldChgI2lkLSR7cmVzLnRhcmdldE5vZGUuaWR9YCk7XG4gICAgICAgIHNhdmUoKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtzaWJsaW5nLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpfWApO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdsJywgZSA9PiB7XG4gICAgLy8gaWYgdGhlIG5vZGUgaXMgY29sbGFwc2VkLCB3ZSBjYW4ndCBnbyBpbnRvIGl0cyBjaGlsZHJlblxuICAgIGlmKGN1cnNvci5pc05vZGVDb2xsYXBzZWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZihlLnNoaWZ0S2V5KSB7XG4gICAgICBjb25zdCByZXMgPSBvdXRsaW5lLmxvd2VyTm9kZVRvQ2hpbGQoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMub2xkUGFyZW50Tm9kZSk7XG5cbiAgICAgIGlmKHJlcy5vbGRQYXJlbnROb2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50Lm91dGVySFRNTCA9IGh0bWw7XG4gICAgICB9XG4gICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMudGFyZ2V0Tm9kZS5pZH1gKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IGN1cnNvci5nZXQoKS5xdWVyeVNlbGVjdG9yKCcubm9kZScpO1xuICAgICAgaWYoY2hpbGRyZW4pIHtcbiAgICAgICAgY3Vyc29yLnNldChgI2lkLSR7Y2hpbGRyZW4uZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyl9YCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ2gnLCBlID0+IHtcbiAgICBjb25zdCBwYXJlbnQgPSBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudDtcbiAgICBpZihwYXJlbnQgJiYgcGFyZW50LmNsYXNzTGlzdC5jb250YWlucygnbm9kZScpKSB7XG4gICAgICBpZihlLnNoaWZ0S2V5KSB7XG4gICAgICAgIGlmKG91dGxpbmUuZGF0YS50cmVlLmNoaWxkcmVuLm1hcChuID0+IG4uaWQpLmluY2x1ZGVzKGN1cnNvci5nZXRJZE9mTm9kZSgpKSkge1xuICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSB0b3AgbGV2ZWwgaXRlbSwgd2UgY2FuJ3QgZWxldmF0ZSBhbnkgZnVydGhlclxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXMgPSBvdXRsaW5lLmxpZnROb2RlVG9QYXJlbnQoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuXG4gICAgICAgIGNvbnN0IGh0bWwgPSBvdXRsaW5lLnJlbmRlck5vZGUocmVzLnBhcmVudE5vZGUpO1xuXG4gICAgICAgIGlmKHJlcy5wYXJlbnROb2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50Lm91dGVySFRNTCA9IGh0bWw7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMudGFyZ2V0Tm9kZS5pZH1gKTtcbiAgICAgICAgc2F2ZSgpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3BhcmVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGtleWJvYXJkSlMuYmluZCgneicsIGUgPT4ge1xuICAgIC8vIHRvZ2dsZSBjb2xsYXBzZVxuICAgIGlmKGN1cnNvci5pc05vZGVFeHBhbmRlZCgpKSB7XG4gICAgICBjdXJzb3IuY29sbGFwc2UoKTtcbiAgICAgIG91dGxpbmUuZm9sZChjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgfVxuICAgIGVsc2UgaWYoY3Vyc29yLmlzTm9kZUNvbGxhcHNlZCgpKSB7XG4gICAgICBjdXJzb3IuZXhwYW5kKCk7XG4gICAgICBvdXRsaW5lLnVuZm9sZChjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgfVxuICAgIHNhdmUoKTtcbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdzaGlmdCArIDQnLCBlID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgLy8gc3dpdGNoIHRvIGVkaXRpbmcgbW9kZVxuICAgIGN1cnNvci5nZXQoKS5jbGFzc0xpc3QuYWRkKCdoaWRkZW4tY3Vyc29yJyk7XG4gICAgY29uc3QgY29udGVudE5vZGUgPSBjdXJzb3IuZ2V0KCkucXVlcnlTZWxlY3RvcignLm5vZGVDb250ZW50JykgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAvLyBzd2FwIHRoZSBjb250ZW50IHRvIHRoZSBkZWZhdWx0IVxuICAgIGNvbnRlbnROb2RlLmlubmVySFRNTCA9IG91dGxpbmUuZGF0YS5jb250ZW50Tm9kZXNbY3Vyc29yLmdldElkT2ZOb2RlKCldLmNvbnRlbnQ7XG4gICAgY29udGVudE5vZGUuY29udGVudEVkaXRhYmxlID0gXCJ0cnVlXCI7XG5cbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKGNvbnRlbnROb2RlKTtcbiAgICByYW5nZS5jb2xsYXBzZShmYWxzZSk7XG5cbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIHNlbGVjdGlvbi5hZGRSYW5nZShyYW5nZSk7XG5cbiAgICBjb250ZW50Tm9kZS5mb2N1cygpO1xuICAgIGtleWJvYXJkSlMuc2V0Q29udGV4dCgnZWRpdGluZycpO1xuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ2knLCBlID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgLy8gc3dpdGNoIHRvIGVkaXRpbmcgbW9kZVxuICAgIGN1cnNvci5nZXQoKS5jbGFzc0xpc3QuYWRkKCdoaWRkZW4tY3Vyc29yJyk7XG4gICAgY29uc3QgY29udGVudE5vZGUgPSBjdXJzb3IuZ2V0KCkucXVlcnlTZWxlY3RvcignLm5vZGVDb250ZW50JykgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAvLyBzd2FwIHRoZSBjb250ZW50IHRvIHRoZSBkZWZhdWx0IVxuICAgIGNvbnRlbnROb2RlLmlubmVySFRNTCA9IG91dGxpbmUuZGF0YS5jb250ZW50Tm9kZXNbY3Vyc29yLmdldElkT2ZOb2RlKCldLmNvbnRlbnQ7XG4gICAgY29udGVudE5vZGUuY29udGVudEVkaXRhYmxlID0gXCJ0cnVlXCI7XG4gICAgY29udGVudE5vZGUuZm9jdXMoKTtcbiAgICBrZXlib2FyZEpTLnNldENvbnRleHQoJ2VkaXRpbmcnKTtcbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCd0YWInLCBlID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBjb25zdCByZXMgPSBvdXRsaW5lLmNyZWF0ZUNoaWxkTm9kZShjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMucGFyZW50Tm9kZSk7XG5cbiAgICBjdXJzb3IuZ2V0KCkub3V0ZXJIVE1MID0gaHRtbDtcblxuICAgIGN1cnNvci5zZXQoYCNpZC0ke3Jlcy5ub2RlLmlkfWApO1xuICAgIHNhdmUoKTtcbiAgfSk7XG4gIFxuICBrZXlib2FyZEpTLmJpbmQoJ2VudGVyJywgZSA9PiB7XG4gICAgLy8gY3JlYXRlIGEgbmV3IG5vZGUgYXMgYSBzaWJsaW5nIG9mIHRoZSBzZWxlY3RlZCBub2RlXG4gICAgaWYoZS5zaGlmdEtleSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5wcmV2ZW50UmVwZWF0KCk7XG5cbiAgICBjb25zdCByZXMgPSBvdXRsaW5lLmNyZWF0ZVNpYmxpbmdOb2RlKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcblxuICAgIGNvbnN0IGh0bWwgPSBvdXRsaW5lLnJlbmRlck5vZGUocmVzLnBhcmVudE5vZGUpO1xuICAgIGlmKHJlcy5wYXJlbnROb2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5vdXRlckhUTUwgPSBodG1sO1xuICAgIH1cblxuICAgIGN1cnNvci5zZXQoYCNpZC0ke3Jlcy5ub2RlLmlkfWApO1xuICAgIHNhdmUoKTtcbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdkJywgZSA9PiB7XG4gICAgLy8gZGVsZXRpbmcgYSBub2RlIHJlcXVpcmVzIGQgKyBzaGlmdFxuICAgIGlmKCFlLnNoaWZ0S2V5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVzID0gb3V0bGluZS5yZW1vdmVOb2RlKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICBjb25zdCBodG1sID0gb3V0bGluZS5yZW5kZXJOb2RlKHJlcy5wYXJlbnROb2RlKTtcbiAgICAvLyB0aGUgcHJldmlvdXMgc2libGluZyFcbiAgICBjb25zdCBwcmV2U2libGluZyA9IGN1cnNvci5nZXQoKS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuICAgIGNvbnN0IG5leHRTaWJsaW5nID0gY3Vyc29yLmdldCgpLm5leHRFbGVtZW50U2libGluZztcbiAgICBpZihyZXMucGFyZW50Tm9kZS5pZCA9PT0gJzAwMDAwMCcpIHtcbiAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQub3V0ZXJIVE1MID0gaHRtbDtcbiAgICB9XG5cbiAgICBpZihwcmV2U2libGluZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSkge1xuICAgICAgY3Vyc29yLnNldChgI2lkLSR7cHJldlNpYmxpbmcuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyl9YCk7XG4gICAgfVxuICAgIGVsc2UgaWYobmV4dFNpYmxpbmcuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJykpIHtcbiAgICAgIGN1cnNvci5zZXQoYCNpZC0ke25leHRTaWJsaW5nLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpfWApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKHJlcy5wYXJlbnROb2RlLmlkKTtcbiAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3Jlcy5wYXJlbnROb2RlLmlkfWApO1xuICAgIH1cblxuICAgIHNhdmUoKTtcbiAgfSk7XG59KTtcblxua2V5Ym9hcmRKUy53aXRoQ29udGV4dCgnZWRpdGluZycsICgpID0+IHtcbiAga2V5Ym9hcmRKUy5iaW5kKFsnZXNjJywgJ2VudGVyJ10sIGUgPT4ge1xuICAgIGN1cnNvci5nZXQoKS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRkZW4tY3Vyc29yJyk7XG5cbiAgICBjb25zdCBjb250ZW50Tm9kZSA9IGN1cnNvci5nZXQoKS5xdWVyeVNlbGVjdG9yKCcubm9kZUNvbnRlbnQnKSBhcyBIVE1MRWxlbWVudDtcblxuICAgIGNvbnRlbnROb2RlLmNvbnRlbnRFZGl0YWJsZSA9IFwiZmFsc2VcIjtcbiAgICBjb250ZW50Tm9kZS5ibHVyKCk7XG4gICAga2V5Ym9hcmRKUy5zZXRDb250ZXh0KCduYXZpZ2F0aW9uJyk7XG5cbiAgICBvdXRsaW5lLnVwZGF0ZUNvbnRlbnQoY3Vyc29yLmdldElkT2ZOb2RlKCksIGNvbnRlbnROb2RlLmlubmVySFRNTC50cmltKCkpO1xuICAgIC8vIHJlLXJlbmRlciB0aGlzIG5vZGUhXG4gICAgY29udGVudE5vZGUuaW5uZXJIVE1MID0gb3V0bGluZS5yZW5kZXJDb250ZW50KGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICBzYXZlKCk7XG4gIH0pO1xufSk7XG5cbmtleWJvYXJkSlMuc2V0Q29udGV4dCgnbmF2aWdhdGlvbicpO1xuXG5mdW5jdGlvbiBzYXZlSW1tZWRpYXRlKCkge1xuICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShvdXRsaW5lLmRhdGEuaWQsIEpTT04uc3RyaW5naWZ5KG91dGxpbmUuZGF0YSkpO1xuICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnYWN0aXZlT3V0bGluZScsIG91dGxpbmUuZGF0YS5pZCk7XG4gIGNvbnNvbGUubG9nKCdzYXZlZC4uLicsIG91dGxpbmUuZGF0YSk7XG4gIHN0YXRlLmRlbGV0ZSgnc2F2ZVRpbWVvdXQnKTtcbn1cblxuZnVuY3Rpb24gc2F2ZSgpIHtcbiAgaWYoIXN0YXRlLmhhcygnc2F2ZVRpbWVvdXQnKSkge1xuICAgIHN0YXRlLnNldCgnc2F2ZVRpbWVvdXQnLCBzZXRUaW1lb3V0KHNhdmVJbW1lZGlhdGUsIDIwMDApKTtcbiAgfVxufVxuXG5cbnNhdmUoKTtcbiIsImV4cG9ydCBjbGFzcyBDdXJzb3Ige1xuICBjb25zdHJ1Y3RvcigpIHtcblxuICB9XG5cbiAgZ2V0KCkge1xuICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY3Vyc29yJyk7XG4gIH1cblxuICBnZXRJZE9mTm9kZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpO1xuICB9XG5cbiAgdW5zZXQoKSB7XG4gICAgY29uc3QgZWwgPSB0aGlzLmdldCgpO1xuICAgIGlmKGVsKSB7XG4gICAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKCdjdXJzb3InKTtcbiAgICB9XG4gIH1cblxuICBzZXQoZWxlbWVudElkOiBzdHJpbmcpIHtcbiAgICB0aGlzLnVuc2V0KCk7XG4gICAgY29uc3QgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsZW1lbnRJZCk7XG5cbiAgICBpZihlbCkge1xuICAgICAgZWwuY2xhc3NMaXN0LmFkZCgnY3Vyc29yJyk7XG4gICAgICBpZighdGhpcy5pc1Zpc2libGUoZWxlbWVudElkKSkge1xuICAgICAgICBlbC5zY3JvbGxJbnRvVmlldyh0cnVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb2xsYXBzZSgpIHtcbiAgICB0aGlzLmdldCgpLmNsYXNzTGlzdC5yZW1vdmUoJ2V4cGFuZGVkJyk7XG4gICAgdGhpcy5nZXQoKS5jbGFzc0xpc3QuYWRkKCdjb2xsYXBzZWQnKTtcbiAgfVxuXG4gIGV4cGFuZCgpIHtcbiAgICB0aGlzLmdldCgpLmNsYXNzTGlzdC5yZW1vdmUoJ2NvbGxhcHNlZCcpO1xuICAgIHRoaXMuZ2V0KCkuY2xhc3NMaXN0LmFkZCgnZXhwYW5kZWQnKTtcbiAgfVxuXG4gIGlzTm9kZUNvbGxhcHNlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5jbGFzc0xpc3QuY29udGFpbnMoJ2NvbGxhcHNlZCcpO1xuICB9XG4gIFxuICBpc05vZGVFeHBhbmRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5jbGFzc0xpc3QuY29udGFpbnMoJ2V4cGFuZGVkJyk7XG4gIH1cblxuICBpc1Zpc2libGUoZWxlbWVudElkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudElkKSBhcyBIVE1MRWxlbWVudDtcbiAgICB2YXIgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiAoXG4gICAgICAgIHJlY3QudG9wID49IDAgJiZcbiAgICAgICAgcmVjdC5sZWZ0ID49IDAgJiZcbiAgICAgICAgcmVjdC5ib3R0b20gPD0gKHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KSAmJiAgICAgXG4gICAgICAgIHJlY3QucmlnaHQgPD0gKHdpbmRvdy5pbm5lcldpZHRoIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aClcbiAgICApO1xuICB9XG59XG4iLCJpbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgeyBtYXJrZWQgfSBmcm9tICdtYXJrZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJhd091dGxpbmUge1xuICBpZDogc3RyaW5nO1xuICBjcmVhdGVkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbiAgdHJlZTogT3V0bGluZVRyZWU7XG4gIGNvbnRlbnROb2RlczogUmVjb3JkPHN0cmluZywgT3V0bGluZU5vZGU+XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3V0bGluZVRyZWUge1xuICBpZDogc3RyaW5nO1xuICBjaGlsZHJlbjogT3V0bGluZVRyZWVbXVxuICBjb2xsYXBzZWQ6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3V0bGluZU5vZGUge1xuICBpZDogc3RyaW5nO1xuICBjcmVhdGVkOiBudW1iZXI7XG4gIHR5cGU6ICd0ZXh0JyxcbiAgY29udGVudDogc3RyaW5nLFxufTtcblxuZXhwb3J0IGNsYXNzIE91dGxpbmUge1xuICBkYXRhOiBSYXdPdXRsaW5lO1xuXG4gIGNvbnN0cnVjdG9yKG91dGxpbmVEYXRhOiBSYXdPdXRsaW5lKSB7XG4gICAgdGhpcy5kYXRhID0gb3V0bGluZURhdGE7XG4gIH1cblxuICBmaW5kTm9kZUluVHJlZShyb290OiBPdXRsaW5lVHJlZSwgaWQ6IHN0cmluZywgYWN0aW9uOiAoaXRlbTogT3V0bGluZVRyZWUsIHBhcmVudDogT3V0bGluZVRyZWUpID0+IHZvaWQsIHJ1blN0YXRlOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICBsZXQgcnVuID0gcnVuU3RhdGU7XG4gICAgaWYocnVuKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIF8uZWFjaChyb290LmNoaWxkcmVuLCAoY2hpbGROb2RlLCBpZHgpID0+IHtcbiAgICAgIGlmKGNoaWxkTm9kZS5pZCA9PT0gaWQpIHtcbiAgICAgICAgYWN0aW9uKGNoaWxkTm9kZSwgcm9vdCk7XG4gICAgICAgIHJ1biA9IHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoY2hpbGROb2RlLmNoaWxkcmVuKSB7XG4gICAgICAgIHRoaXMuZmluZE5vZGVJblRyZWUoY2hpbGROb2RlLCBpZCwgYWN0aW9uLCBydW4pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZm9sZChub2RlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuZmluZE5vZGVJblRyZWUodGhpcy5kYXRhLnRyZWUsIG5vZGVJZCwgaXRlbSA9PiB7XG4gICAgICBpdGVtLmNvbGxhcHNlZCA9IHRydWU7XG4gICAgfSk7XG4gIH1cblxuICB1bmZvbGQobm9kZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmZpbmROb2RlSW5UcmVlKHRoaXMuZGF0YS50cmVlLCBub2RlSWQsIGl0ZW0gPT4ge1xuICAgICAgaXRlbS5jb2xsYXBzZWQgPSB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgZmxhdHRlbk91dGxpbmVUcmVlQ2hpbGRyZW4odHJlZTogT3V0bGluZVRyZWUpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRyZWUuY2hpbGRyZW4ubWFwKG5vZGUgPT4gbm9kZS5pZCk7XG4gIH1cblxuICBsaWZ0Tm9kZVRvUGFyZW50KG5vZGVJZDogc3RyaW5nKSB7XG4gICAgbGV0IHJ1biA9IGZhbHNlO1xuICAgIGxldCB0YXJnZXROb2RlOiBPdXRsaW5lVHJlZSwgcGFyZW50Tm9kZTogT3V0bGluZVRyZWU7XG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgbm9kZUlkLCAodE5vZGUsIHBOb2RlKSA9PiB7XG4gICAgICB0YXJnZXROb2RlID0gdE5vZGU7XG4gICAgICB0aGlzLmZpbmROb2RlSW5UcmVlKHRoaXMuZGF0YS50cmVlLCBwTm9kZS5pZCwgKG9yaWdpbmFsUGFyZW50Tm9kZSwgbmV3UGFyZW50Tm9kZSkgPT4geztcbiAgICAgICAgICBpZihydW4pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGFyZW50Tm9kZSA9IG5ld1BhcmVudE5vZGU7XG4gICAgICAgICAgcnVuID0gdHJ1ZTtcblxuICAgICAgICAgIGNvbnN0IGZsYXRJZCA9IG5ld1BhcmVudE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCk7XG5cbiAgICAgICAgICBjb25zdCBvcmlnaW5hbE5vZGVQb3NpdGlvbiA9IG9yaWdpbmFsUGFyZW50Tm9kZS5jaGlsZHJlbi5tYXAobiA9PiBuLmlkKS5pbmRleE9mKHRhcmdldE5vZGUuaWQpO1xuICAgICAgICAgIGNvbnN0IG5ld05vZGVQb3NpdGlvbiA9IGZsYXRJZC5pbmRleE9mKG9yaWdpbmFsUGFyZW50Tm9kZS5pZCk7XG5cbiAgICAgICAgICBvcmlnaW5hbFBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG9yaWdpbmFsTm9kZVBvc2l0aW9uLCAxKTtcblxuICAgICAgICAgIG5ld1BhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5ld05vZGVQb3NpdGlvbiArIDEsIDAsIHRhcmdldE5vZGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdGFyZ2V0Tm9kZSxcbiAgICAgIHBhcmVudE5vZGVcbiAgICB9XG4gIH1cbiAgXG4gIGxvd2VyTm9kZVRvQ2hpbGQobm9kZUlkOiBzdHJpbmcpIHtcbiAgICBsZXQgcnVuID0gZmFsc2U7XG4gICAgLy8gZmluZCB0aGUgcHJldmlvdXMgc2libGluZ1xuICAgIC8vIG1ha2UgdGhpcyBub2RlIGEgY2hpbGQgb2YgdGhlIHNpYmxpbmcgbm9kZVxuICAgIGxldCB0YXJnZXROb2RlOiBPdXRsaW5lVHJlZSwgbmV3UGFyZW50Tm9kZTogT3V0bGluZVRyZWUsIG9sZFBhcmVudE5vZGU6IE91dGxpbmVUcmVlO1xuICAgIHRoaXMuZmluZE5vZGVJblRyZWUodGhpcy5kYXRhLnRyZWUsIG5vZGVJZCwgKHROb2RlLCBwTm9kZSkgPT4ge1xuICAgICAgaWYocnVuKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJ1biAgPSB0cnVlO1xuICAgICAgdGFyZ2V0Tm9kZSA9IHROb2RlO1xuICAgICAgXG4gICAgICBsZXQgaWRMaXN0ID0gcE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCk7XG4gICAgICAvLyB0aGVyZSBhcmUgbm8gb3RoZXIgc2libGluZ3Mgc28gd2UgY2FuJ3QgZG8gYW55dGhpbmdcbiAgICAgIGlmKGlkTGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGlkTGlzdC5pbmRleE9mKHRhcmdldE5vZGUuaWQpO1xuICAgICAgY29uc3QgcHJldlNpYmxpbmdQb3NpdGlvbiA9IHBvc2l0aW9uIC0gMTtcblxuICAgICAgcE5vZGUuY2hpbGRyZW5bcHJldlNpYmxpbmdQb3NpdGlvbl0uY2hpbGRyZW4uc3BsaWNlKDAsIDAsIHRhcmdldE5vZGUpO1xuICAgICAgcE5vZGUuY2hpbGRyZW4uc3BsaWNlKHBvc2l0aW9uLCAxKTtcblxuICAgICAgbmV3UGFyZW50Tm9kZSA9IHBOb2RlLmNoaWxkcmVuW3ByZXZTaWJsaW5nUG9zaXRpb25dO1xuICAgICAgb2xkUGFyZW50Tm9kZSA9IHBOb2RlO1xuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICB0YXJnZXROb2RlLFxuICAgICAgbmV3UGFyZW50Tm9kZSxcbiAgICAgIG9sZFBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICBzd2FwTm9kZVdpdGhOZXh0U2libGluZyhub2RlSWQ6IHN0cmluZykge1xuICAgIGxldCB0YXJnZXROb2RlOiBPdXRsaW5lVHJlZSwgcGFyZW50Tm9kZTogT3V0bGluZVRyZWU7XG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgbm9kZUlkLCAodE5vZGUsIHBOb2RlKSA9PiB7XG4gICAgICAgIHRhcmdldE5vZGUgPSB0Tm9kZTtcbiAgICAgICAgcGFyZW50Tm9kZSA9IHBOb2RlO1xuICAgICAgICBjb25zdCBmbGF0SWQgPSBwYXJlbnROb2RlLmNoaWxkcmVuLm1hcChuID0+IG4uaWQpO1xuICAgICAgICBjb25zdCBub2RlUG9zaXRpb24gPSBmbGF0SWQuaW5kZXhPZih0YXJnZXROb2RlLmlkKTtcblxuICAgICAgICBpZihub2RlUG9zaXRpb24gPT09IChmbGF0SWQubGVuZ3RoIC0gMSkpIHtcbiAgICAgICAgICAvLyB0aGlzIGlzIHRoZSBsYXN0IG5vZGUgaW4gdGhlIGxpc3QsIHRoZXJlJ3Mgbm90aGluZyB0byBzd2FwXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBub2RlIGZyb20gdGhpcyBwb2ludCwgYW5kIHB1c2ggaXQgb25lIGxhdGVyXG4gICAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5vZGVQb3NpdGlvbiwgMSk7XG4gICAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5vZGVQb3NpdGlvbiArIDEsIDAsIHRhcmdldE5vZGUpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRhcmdldE5vZGUsXG4gICAgICBwYXJlbnROb2RlXG4gICAgfVxuICB9XG5cbiAgc3dhcE5vZGVXaXRoUHJldmlvdXNTaWJsaW5nKG5vZGVJZDogc3RyaW5nKSB7XG4gICAgbGV0IHRhcmdldE5vZGU6IE91dGxpbmVUcmVlLCBwYXJlbnROb2RlOiBPdXRsaW5lVHJlZTtcbiAgICB0aGlzLmZpbmROb2RlSW5UcmVlKHRoaXMuZGF0YS50cmVlLCBub2RlSWQsICh0Tm9kZSwgcE5vZGUpID0+IHtcbiAgICAgICAgdGFyZ2V0Tm9kZSA9IHROb2RlO1xuICAgICAgICBwYXJlbnROb2RlID0gcE5vZGU7XG4gICAgICAgIGNvbnN0IGZsYXRJZCA9IHBhcmVudE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCk7XG4gICAgICAgIGNvbnN0IG5vZGVQb3NpdGlvbiA9IGZsYXRJZC5pbmRleE9mKHRhcmdldE5vZGUuaWQpO1xuXG4gICAgICAgIGlmKG5vZGVQb3NpdGlvbiA9PT0gMCkge1xuICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIGxpc3QsIHRoZXJlJ3Mgbm90aGluZyB0byBzd2FwXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBub2RlIGZyb20gdGhpcyBwb2ludCwgYW5kIHB1c2ggaXQgb25lIGxhdGVyXG4gICAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5vZGVQb3NpdGlvbiwgMSk7XG4gICAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5vZGVQb3NpdGlvbiAtIDEsIDAsIHRhcmdldE5vZGUpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRhcmdldE5vZGUsXG4gICAgICBwYXJlbnROb2RlXG4gICAgfVxuICB9XG5cbiAgY3JlYXRlU2libGluZ05vZGUodGFyZ2V0Tm9kZTogc3RyaW5nLCBub2RlRGF0YT86IE91dGxpbmVOb2RlKSB7XG4gICAgY29uc3Qgb3V0bGluZU5vZGU6IE91dGxpbmVOb2RlID0gbm9kZURhdGEgfHwge1xuICAgICAgaWQ6IHV1aWQoKSxcbiAgICAgIGNyZWF0ZWQ6IERhdGUubm93KCksXG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBjb250ZW50OiAnLS0tJ1xuICAgIH07XG5cbiAgICB0aGlzLmRhdGEuY29udGVudE5vZGVzW291dGxpbmVOb2RlLmlkXSA9IG91dGxpbmVOb2RlO1xuXG4gICAgbGV0IHBhcmVudE5vZGU6IE91dGxpbmVUcmVlO1xuXG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgdGFyZ2V0Tm9kZSwgKG5vZGUsIHBhcmVudCkgPT4ge1xuICAgICAgY29uc3QgcG9zaXRpb24gPSBwYXJlbnQuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCkuaW5kZXhPZih0YXJnZXROb2RlKTtcbiAgICAgIHBhcmVudC5jaGlsZHJlbi5zcGxpY2UocG9zaXRpb24gKyAxLCAwLCB7XG4gICAgICAgIGlkOiBvdXRsaW5lTm9kZS5pZCxcbiAgICAgICAgY29sbGFwc2VkOiBmYWxzZSxcbiAgICAgICAgY2hpbGRyZW46IFtdXG4gICAgICB9KTtcblxuICAgICAgcGFyZW50Tm9kZSA9IHBhcmVudDtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBub2RlOiBvdXRsaW5lTm9kZSxcbiAgICAgIHBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICBjcmVhdGVDaGlsZE5vZGUoY3VycmVudE5vZGU6IHN0cmluZywgbm9kZUlkPzogc3RyaW5nKSB7XG4gICAgY29uc3Qgbm9kZTogT3V0bGluZU5vZGUgPSBub2RlSWQgPyB0aGlzLmRhdGEuY29udGVudE5vZGVzW25vZGVJZF0gOlxuICAgIHtcbiAgICAgIGlkOiB1dWlkKCksXG4gICAgICBjcmVhdGVkOiBEYXRlLm5vdygpLFxuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgY29udGVudDogJy0tLSdcbiAgICB9O1xuXG4gICAgaWYoIW5vZGVJZCkge1xuICAgICAgdGhpcy5kYXRhLmNvbnRlbnROb2Rlc1tub2RlLmlkXSA9IG5vZGU7XG4gICAgfVxuXG4gICAgbGV0IHBhcmVudE5vZGU6IE91dGxpbmVUcmVlO1xuXG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgY3VycmVudE5vZGUsIChmb3VuZE5vZGUsIHBhcmVudCkgPT4ge1xuICAgICAgZm91bmROb2RlLmNoaWxkcmVuLnVuc2hpZnQoe1xuICAgICAgICBpZDogbm9kZS5pZCxcbiAgICAgICAgY2hpbGRyZW46IFtdLFxuICAgICAgICBjb2xsYXBzZWQ6IGZhbHNlXG4gICAgICB9KTtcblxuICAgICAgcGFyZW50Tm9kZSA9IGZvdW5kTm9kZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBub2RlLFxuICAgICAgcGFyZW50Tm9kZVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZU5vZGUobm9kZUlkOiBzdHJpbmcpIHtcbiAgICBsZXQgcnVuID0gZmFsc2U7XG4gICAgbGV0IHJlbW92ZWROb2RlOiBPdXRsaW5lVHJlZSwgcGFyZW50Tm9kZTogT3V0bGluZVRyZWU7XG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgbm9kZUlkLCAodE5vZGUsIHBOb2RlKSA9PiB7XG4gICAgICBpZihydW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcnVuID0gdHJ1ZTtcbiAgICAgIHJlbW92ZWROb2RlID0gdE5vZGU7XG4gICAgICBwYXJlbnROb2RlID0gcE5vZGU7XG5cbiAgICAgIGxldCBwb3NpdGlvbiA9IHBhcmVudE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCkuaW5kZXhPZih0Tm9kZS5pZCk7XG5cbiAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICByZW1vdmVkTm9kZSxcbiAgICAgIHBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICB1cGRhdGVDb250ZW50KGlkOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZykge1xuICAgIGlmKCF0aGlzLmRhdGEuY29udGVudE5vZGVzW2lkXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG5vZGUnKTtcbiAgICB9XG5cbiAgICB0aGlzLmRhdGEuY29udGVudE5vZGVzW2lkXS5jb250ZW50ID0gY29udGVudDtcbiAgfVxuXG4gIHJlbmRlckNvbnRlbnQobm9kZUlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCBub2RlID0gdGhpcy5kYXRhLmNvbnRlbnROb2Rlc1tub2RlSWRdO1xuICAgIGxldCBjb250ZW50OiBzdHJpbmc7XG4gICAgc3dpdGNoKG5vZGUudHlwZSkge1xuICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgIGNvbnRlbnQgPSBtYXJrZWQucGFyc2Uobm9kZS5jb250ZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OiBcbiAgICAgICAgY29udGVudCA9IG5vZGUuY29udGVudDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRlbnQ7XG4gIH1cblxuICByZW5kZXJOb2RlKG5vZGU6IE91dGxpbmVUcmVlKTogc3RyaW5nIHtcbiAgICBpZihub2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgcmV0dXJuIHRoaXMucmVuZGVyKCk7XG4gICAgfVxuICAgIGNvbnN0IGNvbGxhcHNlID0gbm9kZS5jb2xsYXBzZWQgPyAnY29sbGFwc2VkJzogJ2V4cGFuZGVkJztcbiAgICBjb25zdCBjb250ZW50OiBPdXRsaW5lTm9kZSA9IHRoaXMuZGF0YS5jb250ZW50Tm9kZXNbbm9kZS5pZF0gfHwge1xuICAgICAgaWQ6IG5vZGUuaWQsXG4gICAgICBjcmVhdGVkOiBEYXRlLm5vdygpLFxuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgY29udGVudDogJydcbiAgICB9O1xuXG4gICAgbGV0IGh0bWwgPSBgPGRpdiBjbGFzcz1cIm5vZGUgJHtjb2xsYXBzZX1cIiBkYXRhLWlkPVwiJHtub2RlLmlkfVwiIGlkPVwiaWQtJHtub2RlLmlkfVwiPlxuICAgIDxkaXYgY2xhc3M9XCJub2RlQ29udGVudFwiIGRhdGEtdHlwZT1cIiR7Y29udGVudC50eXBlfVwiPlxuICAgICAgJHt0aGlzLnJlbmRlckNvbnRlbnQobm9kZS5pZCl9XG4gICAgPC9kaXY+XG4gICAgJHtub2RlLmNoaWxkcmVuLmxlbmd0aCA/IF8ubWFwKG5vZGUuY2hpbGRyZW4sIHRoaXMucmVuZGVyTm9kZS5iaW5kKHRoaXMpKS5qb2luKFwiXFxuXCIpIDogJyd9XG4gICAgPC9kaXY+YFxuXG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgLypcbiAgICAgKiByZW5kZXIgc3RhcnRzIGF0IHRoZSByb290IG5vZGUgYW5kIG9ubHkgcmVuZGVycyBpdHMgY2hpbGRyZW4uIFRoZSByb290IFxuICAgICAqIG5vZGUgb25seSBleGlzdHMgYXMgYSBjb250YWluZXIgYXJvdW5kIHRoZSByZXN0IHRvIGVuc3VyZSBhIHN0YW5kYXJkIGZvcm1hdFxuICAgICAqIGZvciB0aGUgdHJlZVxuICAgICAqL1xuICAgIHJldHVybiBfLm1hcCh0aGlzLmRhdGEudHJlZS5jaGlsZHJlbiwgdGhpcy5yZW5kZXJOb2RlLmJpbmQodGhpcykpLmpvaW4oXCJcXG5cIik7XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTklMXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIF9uaWwuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJwYXJzZVwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiBfcGFyc2UuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJzdHJpbmdpZnlcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3N0cmluZ2lmeS5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInYxXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIF92LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjNcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3YyLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjRcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3YzLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjVcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3Y0LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidmFsaWRhdGVcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3ZhbGlkYXRlLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidmVyc2lvblwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiBfdmVyc2lvbi5kZWZhdWx0O1xuICB9XG59KTtcblxudmFyIF92ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92MS5qc1wiKSk7XG5cbnZhciBfdjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3YzLmpzXCIpKTtcblxudmFyIF92MyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjQuanNcIikpO1xuXG52YXIgX3Y0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92NS5qc1wiKSk7XG5cbnZhciBfbmlsID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9uaWwuanNcIikpO1xuXG52YXIgX3ZlcnNpb24gPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZlcnNpb24uanNcIikpO1xuXG52YXIgX3ZhbGlkYXRlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92YWxpZGF0ZS5qc1wiKSk7XG5cbnZhciBfc3RyaW5naWZ5ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9zdHJpbmdpZnkuanNcIikpO1xuXG52YXIgX3BhcnNlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9wYXJzZS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbi8qXG4gKiBCcm93c2VyLWNvbXBhdGlibGUgSmF2YVNjcmlwdCBNRDVcbiAqXG4gKiBNb2RpZmljYXRpb24gb2YgSmF2YVNjcmlwdCBNRDVcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ibHVlaW1wL0phdmFTY3JpcHQtTUQ1XG4gKlxuICogQ29weXJpZ2h0IDIwMTEsIFNlYmFzdGlhbiBUc2NoYW5cbiAqIGh0dHBzOi8vYmx1ZWltcC5uZXRcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2U6XG4gKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVFxuICpcbiAqIEJhc2VkIG9uXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFJTQSBEYXRhIFNlY3VyaXR5LCBJbmMuIE1ENSBNZXNzYWdlXG4gKiBEaWdlc3QgQWxnb3JpdGhtLCBhcyBkZWZpbmVkIGluIFJGQyAxMzIxLlxuICogVmVyc2lvbiAyLjIgQ29weXJpZ2h0IChDKSBQYXVsIEpvaG5zdG9uIDE5OTkgLSAyMDA5XG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBtb3JlIGluZm8uXG4gKi9cbmZ1bmN0aW9uIG1kNShieXRlcykge1xuICBpZiAodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IG1zZyA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChieXRlcykpOyAvLyBVVEY4IGVzY2FwZVxuXG4gICAgYnl0ZXMgPSBuZXcgVWludDhBcnJheShtc2cubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgKytpKSB7XG4gICAgICBieXRlc1tpXSA9IG1zZy5jaGFyQ29kZUF0KGkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtZDVUb0hleEVuY29kZWRBcnJheSh3b3Jkc1RvTWQ1KGJ5dGVzVG9Xb3JkcyhieXRlcyksIGJ5dGVzLmxlbmd0aCAqIDgpKTtcbn1cbi8qXG4gKiBDb252ZXJ0IGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMgdG8gYW4gYXJyYXkgb2YgYnl0ZXNcbiAqL1xuXG5cbmZ1bmN0aW9uIG1kNVRvSGV4RW5jb2RlZEFycmF5KGlucHV0KSB7XG4gIGNvbnN0IG91dHB1dCA9IFtdO1xuICBjb25zdCBsZW5ndGgzMiA9IGlucHV0Lmxlbmd0aCAqIDMyO1xuICBjb25zdCBoZXhUYWIgPSAnMDEyMzQ1Njc4OWFiY2RlZic7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGgzMjsgaSArPSA4KSB7XG4gICAgY29uc3QgeCA9IGlucHV0W2kgPj4gNV0gPj4+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/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdmVyc2lvbih1dWlkKSB7XG4gIGlmICghKDAsIF92YWxpZGF0ZS5kZWZhdWx0KSh1dWlkKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignSW52YWxpZCBVVUlEJyk7XG4gIH1cblxuICByZXR1cm4gcGFyc2VJbnQodXVpZC5zbGljZSgxNCwgMTUpLCAxNik7XG59XG5cbnZhciBfZGVmYXVsdCA9IHZlcnNpb247XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCIvKipcbiAqIG1hcmtlZCB2NC4yLjEyIC0gYSBtYXJrZG93biBwYXJzZXJcbiAqIENvcHlyaWdodCAoYykgMjAxMS0yMDIzLCBDaHJpc3RvcGhlciBKZWZmcmV5LiAoTUlUIExpY2Vuc2VkKVxuICogaHR0cHM6Ly9naXRodWIuY29tL21hcmtlZGpzL21hcmtlZFxuICovXG5cbi8qKlxuICogRE8gTk9UIEVESVQgVEhJUyBGSUxFXG4gKiBUaGUgY29kZSBpbiB0aGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGZyb20gZmlsZXMgaW4gLi9zcmMvXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTtcbiAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7XG4gICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBfdG9Qcm9wZXJ0eUtleShkZXNjcmlwdG9yLmtleSksIGRlc2NyaXB0b3IpO1xuICB9XG59XG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb25zdHJ1Y3RvciwgXCJwcm90b3R5cGVcIiwge1xuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KTtcbiAgcmV0dXJuIENvbnN0cnVjdG9yO1xufVxuZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikge1xuICBpZiAoIW8pIHJldHVybjtcbiAgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTtcbiAgdmFyIG4gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobykuc2xpY2UoOCwgLTEpO1xuICBpZiAobiA9PT0gXCJPYmplY3RcIiAmJiBvLmNvbnN0cnVjdG9yKSBuID0gby5jb25zdHJ1Y3Rvci5uYW1lO1xuICBpZiAobiA9PT0gXCJNYXBcIiB8fCBuID09PSBcIlNldFwiKSByZXR1cm4gQXJyYXkuZnJvbShvKTtcbiAgaWYgKG4gPT09IFwiQXJndW1lbnRzXCIgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QobikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xufVxuZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHtcbiAgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+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+PHByZT4nICsgZXNjYXBlKGUubWVzc2FnZSArICcnLCB0cnVlKSArICc8L3ByZT4nO1xuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9XG4gIHRyeSB7XG4gICAgdmFyIF90b2tlbnMgPSBMZXhlci5sZXgoc3JjLCBvcHQpO1xuICAgIGlmIChvcHQud2Fsa1Rva2Vucykge1xuICAgICAgaWYgKG9wdC5hc3luYykge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwobWFya2VkLndhbGtUb2tlbnMoX3Rva2Vucywgb3B0LndhbGtUb2tlbnMpKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gUGFyc2VyLnBhcnNlKF90b2tlbnMsIG9wdCk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ob25FcnJvcik7XG4gICAgICB9XG4gICAgICBtYXJrZWQud2Fsa1Rva2VucyhfdG9rZW5zLCBvcHQud2Fsa1Rva2Vucyk7XG4gICAgfVxuICAgIHJldHVybiBQYXJzZXIucGFyc2UoX3Rva2Vucywgb3B0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIG9uRXJyb3IoZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBPcHRpb25zXG4gKi9cblxubWFya2VkLm9wdGlvbnMgPSBtYXJrZWQuc2V0T3B0aW9ucyA9IGZ1bmN0aW9uIChvcHQpIHtcbiAgbWVyZ2UobWFya2VkLmRlZmF1bHRzLCBvcHQpO1xuICBjaGFuZ2VEZWZhdWx0cyhtYXJrZWQuZGVmYXVsdHMpO1xuICByZXR1cm4gbWFya2VkO1xufTtcbm1hcmtlZC5nZXREZWZhdWx0cyA9IGdldERlZmF1bHRzO1xubWFya2VkLmRlZmF1bHRzID0gZXhwb3J0cy5kZWZhdWx0cztcblxuLyoqXG4gKiBVc2UgRXh0ZW5zaW9uXG4gKi9cblxubWFya2VkLnVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGV4dGVuc2lvbnMgPSBtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucyB8fCB7XG4gICAgcmVuZGVyZXJzOiB7fSxcbiAgICBjaGlsZFRva2Vuczoge31cbiAgfTtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgfVxuICBhcmdzLmZvckVhY2goZnVuY3Rpb24gKHBhY2spIHtcbiAgICAvLyBjb3B5IG9wdGlvbnMgdG8gbmV3IG9iamVjdFxuICAgIHZhciBvcHRzID0gbWVyZ2Uoe30sIHBhY2spO1xuXG4gICAgLy8gc2V0IGFzeW5jIHRvIHRydWUgaWYgaXQgd2FzIHNldCB0byB0cnVlIGJlZm9yZVxuICAgIG9wdHMuYXN5bmMgPSBtYXJrZWQuZGVmYXVsdHMuYXN5bmMgfHwgb3B0cy5hc3luYztcblxuICAgIC8vID09LS0gUGFyc2UgXCJhZGRvblwiIGV4dGVuc2lvbnMgLS09PSAvL1xuICAgIGlmIChwYWNrLmV4dGVuc2lvbnMpIHtcbiAgICAgIHBhY2suZXh0ZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChleHQpIHtcbiAgICAgICAgaWYgKCFleHQubmFtZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZXh0ZW5zaW9uIG5hbWUgcmVxdWlyZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXh0LnJlbmRlcmVyKSB7XG4gICAgICAgICAgLy8gUmVuZGVyZXIgZXh0ZW5zaW9uc1xuICAgICAgICAgIHZhciBwcmV2UmVuZGVyZXIgPSBleHRlbnNpb25zLnJlbmRlcmVyc1tleHQubmFtZV07XG4gICAgICAgICAgaWYgKHByZXZSZW5kZXJlcikge1xuICAgICAgICAgICAgLy8gUmVwbGFjZSBleHRlbnNpb24gd2l0aCBmdW5jIHRvIHJ1biBuZXcgZXh0ZW5zaW9uIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICAgIGV4dGVuc2lvbnMucmVuZGVyZXJzW2V4dC5uYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgICAgICAgICAgYXJnc1tfa2V5Ml0gPSBhcmd1bWVudHNbX2tleTJdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciByZXQgPSBleHQucmVuZGVyZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICAgIGlmIChyZXQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgcmV0ID0gcHJldlJlbmRlcmVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHRlbnNpb25zLnJlbmRlcmVyc1tleHQubmFtZV0gPSBleHQucmVuZGVyZXI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChleHQudG9rZW5pemVyKSB7XG4gICAgICAgICAgLy8gVG9rZW5pemVyIEV4dGVuc2lvbnNcbiAgICAgICAgICBpZiAoIWV4dC5sZXZlbCB8fCBleHQubGV2ZWwgIT09ICdibG9jaycgJiYgZXh0LmxldmVsICE9PSAnaW5saW5lJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZXh0ZW5zaW9uIGxldmVsIG11c3QgYmUgJ2Jsb2NrJyBvciAnaW5saW5lJ1wiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGV4dGVuc2lvbnNbZXh0LmxldmVsXSkge1xuICAgICAgICAgICAgZXh0ZW5zaW9uc1tleHQubGV2ZWxdLnVuc2hpZnQoZXh0LnRva2VuaXplcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4dGVuc2lvbnNbZXh0LmxldmVsXSA9IFtleHQudG9rZW5pemVyXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGV4dC5zdGFydCkge1xuICAgICAgICAgICAgLy8gRnVuY3Rpb24gdG8gY2hlY2sgZm9yIHN0YXJ0IG9mIHRva2VuXG4gICAgICAgICAgICBpZiAoZXh0LmxldmVsID09PSAnYmxvY2snKSB7XG4gICAgICAgICAgICAgIGlmIChleHRlbnNpb25zLnN0YXJ0QmxvY2spIHtcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0QmxvY2sucHVzaChleHQuc3RhcnQpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGV4dGVuc2lvbnMuc3RhcnRCbG9jayA9IFtleHQuc3RhcnRdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGV4dC5sZXZlbCA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbnMuc3RhcnRJbmxpbmUpIHtcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0SW5saW5lLnB1c2goZXh0LnN0YXJ0KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0SW5saW5lID0gW2V4dC5zdGFydF07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dC5jaGlsZFRva2Vucykge1xuICAgICAgICAgIC8vIENoaWxkIHRva2VucyB0byBiZSB2aXNpdGVkIGJ5IHdhbGtUb2tlbnNcbiAgICAgICAgICBleHRlbnNpb25zLmNoaWxkVG9rZW5zW2V4dC5uYW1lXSA9IGV4dC5jaGlsZFRva2VucztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBvcHRzLmV4dGVuc2lvbnMgPSBleHRlbnNpb25zO1xuICAgIH1cblxuICAgIC8vID09LS0gUGFyc2UgXCJvdmVyd3JpdGVcIiBleHRlbnNpb25zIC0tPT0gLy9cbiAgICBpZiAocGFjay5yZW5kZXJlcikge1xuICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJlbmRlcmVyID0gbWFya2VkLmRlZmF1bHRzLnJlbmRlcmVyIHx8IG5ldyBSZW5kZXJlcigpO1xuICAgICAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiBfbG9vcChwcm9wKSB7XG4gICAgICAgICAgdmFyIHByZXZSZW5kZXJlciA9IHJlbmRlcmVyW3Byb3BdO1xuICAgICAgICAgIC8vIFJlcGxhY2UgcmVuZGVyZXIgd2l0aCBmdW5jIHRvIHJ1biBleHRlbnNpb24sIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICByZW5kZXJlcltwcm9wXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGZvciAodmFyIF9sZW4zID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMyksIF9rZXkzID0gMDsgX2tleTMgPCBfbGVuMzsgX2tleTMrKykge1xuICAgICAgICAgICAgICBhcmdzW19rZXkzXSA9IGFyZ3VtZW50c1tfa2V5M107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcmV0ID0gcGFjay5yZW5kZXJlcltwcm9wXS5hcHBseShyZW5kZXJlciwgYXJncyk7XG4gICAgICAgICAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICByZXQgPSBwcmV2UmVuZGVyZXIuYXBwbHkocmVuZGVyZXIsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHBhY2sucmVuZGVyZXIpIHtcbiAgICAgICAgICBfbG9vcChwcm9wKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICB9KSgpO1xuICAgIH1cbiAgICBpZiAocGFjay50b2tlbml6ZXIpIHtcbiAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0b2tlbml6ZXIgPSBtYXJrZWQuZGVmYXVsdHMudG9rZW5pemVyIHx8IG5ldyBUb2tlbml6ZXIoKTtcbiAgICAgICAgdmFyIF9sb29wMiA9IGZ1bmN0aW9uIF9sb29wMihwcm9wKSB7XG4gICAgICAgICAgdmFyIHByZXZUb2tlbml6ZXIgPSB0b2tlbml6ZXJbcHJvcF07XG4gICAgICAgICAgLy8gUmVwbGFjZSB0b2tlbml6ZXIgd2l0aCBmdW5jIHRvIHJ1biBleHRlbnNpb24sIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICB0b2tlbml6ZXJbcHJvcF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBfbGVuNCA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjQpLCBfa2V5NCA9IDA7IF9rZXk0IDwgX2xlbjQ7IF9rZXk0KyspIHtcbiAgICAgICAgICAgICAgYXJnc1tfa2V5NF0gPSBhcmd1bWVudHNbX2tleTRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHJldCA9IHBhY2sudG9rZW5pemVyW3Byb3BdLmFwcGx5KHRva2VuaXplciwgYXJncyk7XG4gICAgICAgICAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICByZXQgPSBwcmV2VG9rZW5pemVyLmFwcGx5KHRva2VuaXplciwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIGZvciAodmFyIHByb3AgaW4gcGFjay50b2tlbml6ZXIpIHtcbiAgICAgICAgICBfbG9vcDIocHJvcCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0cy50b2tlbml6ZXIgPSB0b2tlbml6ZXI7XG4gICAgICB9KSgpO1xuICAgIH1cblxuICAgIC8vID09LS0gUGFyc2UgV2Fsa1Rva2VucyBleHRlbnNpb25zIC0tPT0gLy9cbiAgICBpZiAocGFjay53YWxrVG9rZW5zKSB7XG4gICAgICB2YXIgX3dhbGtUb2tlbnMgPSBtYXJrZWQuZGVmYXVsdHMud2Fsa1Rva2VucztcbiAgICAgIG9wdHMud2Fsa1Rva2VucyA9IGZ1bmN0aW9uICh0b2tlbikge1xuICAgICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICAgIHZhbHVlcy5wdXNoKHBhY2sud2Fsa1Rva2Vucy5jYWxsKHRoaXMsIHRva2VuKSk7XG4gICAgICAgIGlmIChfd2Fsa1Rva2Vucykge1xuICAgICAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQoX3dhbGtUb2tlbnMuY2FsbCh0aGlzLCB0b2tlbikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgICB9O1xuICAgIH1cbiAgICBtYXJrZWQuc2V0T3B0aW9ucyhvcHRzKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIFJ1biBjYWxsYmFjayBmb3IgZXZlcnkgdG9rZW5cbiAqL1xuXG5tYXJrZWQud2Fsa1Rva2VucyA9IGZ1bmN0aW9uICh0b2tlbnMsIGNhbGxiYWNrKSB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgdmFyIF9sb29wMyA9IGZ1bmN0aW9uIF9sb29wMygpIHtcbiAgICB2YXIgdG9rZW4gPSBfc3RlcC52YWx1ZTtcbiAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KGNhbGxiYWNrLmNhbGwobWFya2VkLCB0b2tlbikpO1xuICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICB7XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyTG9vc2UodG9rZW4uaGVhZGVyKSwgX3N0ZXAyOyAhKF9zdGVwMiA9IF9pdGVyYXRvcjIoKSkuZG9uZTspIHtcbiAgICAgICAgICAgIHZhciBjZWxsID0gX3N0ZXAyLnZhbHVlO1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2VucyhjZWxsLnRva2VucywgY2FsbGJhY2spKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMyA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyTG9vc2UodG9rZW4ucm93cyksIF9zdGVwMzsgIShfc3RlcDMgPSBfaXRlcmF0b3IzKCkpLmRvbmU7KSB7XG4gICAgICAgICAgICB2YXIgcm93ID0gX3N0ZXAzLnZhbHVlO1xuICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yNCA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyTG9vc2Uocm93KSwgX3N0ZXA0OyAhKF9zdGVwNCA9IF9pdGVyYXRvcjQoKSkuZG9uZTspIHtcbiAgICAgICAgICAgICAgdmFyIF9jZWxsID0gX3N0ZXA0LnZhbHVlO1xuICAgICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KG1hcmtlZC53YWxrVG9rZW5zKF9jZWxsLnRva2VucywgY2FsbGJhY2spKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2xpc3QnOlxuICAgICAgICB7XG4gICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2Vucyh0b2tlbi5pdGVtcywgY2FsbGJhY2spKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAge1xuICAgICAgICAgIGlmIChtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucyAmJiBtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucy5jaGlsZFRva2VucyAmJiBtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucy5jaGlsZFRva2Vuc1t0b2tlbi50eXBlXSkge1xuICAgICAgICAgICAgLy8gV2FsayBhbnkgZXh0ZW5zaW9uc1xuICAgICAgICAgICAgbWFya2VkLmRlZmF1bHRzLmV4dGVuc2lvbnMuY2hpbGRUb2tlbnNbdG9rZW4udHlwZV0uZm9yRWFjaChmdW5jdGlvbiAoY2hpbGRUb2tlbnMpIHtcbiAgICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2Vucyh0b2tlbltjaGlsZFRva2Vuc10sIGNhbGxiYWNrKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuLnRva2Vucykge1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2Vucyh0b2tlbi50b2tlbnMsIGNhbGxiYWNrKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICB9O1xuICBmb3IgKHZhciBfaXRlcmF0b3IgPSBfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlckxvb3NlKHRva2VucyksIF9zdGVwOyAhKF9zdGVwID0gX2l0ZXJhdG9yKCkpLmRvbmU7KSB7XG4gICAgX2xvb3AzKCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlcztcbn07XG5cbi8qKlxuICogUGFyc2UgSW5saW5lXG4gKiBAcGFyYW0ge3N0cmluZ30gc3JjXG4gKi9cbm1hcmtlZC5wYXJzZUlubGluZSA9IGZ1bmN0aW9uIChzcmMsIG9wdCkge1xuICAvLyB0aHJvdyBlcnJvciBpbiBjYXNlIG9mIG5vbiBzdHJpbmcgaW5wdXRcbiAgaWYgKHR5cGVvZiBzcmMgPT09ICd1bmRlZmluZWQnIHx8IHNyYyA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkLnBhcnNlSW5saW5lKCk6IGlucHV0IHBhcmFtZXRlciBpcyB1bmRlZmluZWQgb3IgbnVsbCcpO1xuICB9XG4gIGlmICh0eXBlb2Ygc3JjICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkLnBhcnNlSW5saW5lKCk6IGlucHV0IHBhcmFtZXRlciBpcyBvZiB0eXBlICcgKyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3JjKSArICcsIHN0cmluZyBleHBlY3RlZCcpO1xuICB9XG4gIG9wdCA9IG1lcmdlKHt9LCBtYXJrZWQuZGVmYXVsdHMsIG9wdCB8fCB7fSk7XG4gIGNoZWNrU2FuaXRpemVEZXByZWNhdGlvbihvcHQpO1xuICB0cnkge1xuICAgIHZhciB0b2tlbnMgPSBMZXhlci5sZXhJbmxpbmUoc3JjLCBvcHQpO1xuICAgIGlmIChvcHQud2Fsa1Rva2Vucykge1xuICAgICAgbWFya2VkLndhbGtUb2tlbnModG9rZW5zLCBvcHQud2Fsa1Rva2Vucyk7XG4gICAgfVxuICAgIHJldHVybiBQYXJzZXIucGFyc2VJbmxpbmUodG9rZW5zLCBvcHQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgZS5tZXNzYWdlICs9ICdcXG5QbGVhc2UgcmVwb3J0IHRoaXMgdG8gaHR0cHM6Ly9naXRodWIuY29tL21hcmtlZGpzL21hcmtlZC4nO1xuICAgIGlmIChvcHQuc2lsZW50KSB7XG4gICAgICByZXR1cm4gJzxwPkFuIGVycm9yIG9jY3VycmVkOjwvcD48cHJlPicgKyBlc2NhcGUoZS5tZXNzYWdlICsgJycsIHRydWUpICsgJzwvcHJlPic7XG4gICAgfVxuICAgIHRocm93IGU7XG4gIH1cbn07XG5cbi8qKlxuICogRXhwb3NlXG4gKi9cbm1hcmtlZC5QYXJzZXIgPSBQYXJzZXI7XG5tYXJrZWQucGFyc2VyID0gUGFyc2VyLnBhcnNlO1xubWFya2VkLlJlbmRlcmVyID0gUmVuZGVyZXI7XG5tYXJrZWQuVGV4dFJlbmRlcmVyID0gVGV4dFJlbmRlcmVyO1xubWFya2VkLkxleGVyID0gTGV4ZXI7XG5tYXJrZWQubGV4ZXIgPSBMZXhlci5sZXg7XG5tYXJrZWQuVG9rZW5pemVyID0gVG9rZW5pemVyO1xubWFya2VkLlNsdWdnZXIgPSBTbHVnZ2VyO1xubWFya2VkLnBhcnNlID0gbWFya2VkO1xudmFyIG9wdGlvbnMgPSBtYXJrZWQub3B0aW9ucztcbnZhciBzZXRPcHRpb25zID0gbWFya2VkLnNldE9wdGlvbnM7XG52YXIgdXNlID0gbWFya2VkLnVzZTtcbnZhciB3YWxrVG9rZW5zID0gbWFya2VkLndhbGtUb2tlbnM7XG52YXIgcGFyc2VJbmxpbmUgPSBtYXJrZWQucGFyc2VJbmxpbmU7XG52YXIgcGFyc2UgPSBtYXJrZWQ7XG52YXIgcGFyc2VyID0gUGFyc2VyLnBhcnNlO1xudmFyIGxleGVyID0gTGV4ZXIubGV4O1xuXG5leHBvcnRzLkxleGVyID0gTGV4ZXI7XG5leHBvcnRzLlBhcnNlciA9IFBhcnNlcjtcbmV4cG9ydHMuUmVuZGVyZXIgPSBSZW5kZXJlcjtcbmV4cG9ydHMuU2x1Z2dlciA9IFNsdWdnZXI7XG5leHBvcnRzLlRleHRSZW5kZXJlciA9IFRleHRSZW5kZXJlcjtcbmV4cG9ydHMuVG9rZW5pemVyID0gVG9rZW5pemVyO1xuZXhwb3J0cy5nZXREZWZhdWx0cyA9IGdldERlZmF1bHRzO1xuZXhwb3J0cy5sZXhlciA9IGxleGVyO1xuZXhwb3J0cy5tYXJrZWQgPSBtYXJrZWQ7XG5leHBvcnRzLm9wdGlvbnMgPSBvcHRpb25zO1xuZXhwb3J0cy5wYXJzZSA9IHBhcnNlO1xuZXhwb3J0cy5wYXJzZUlubGluZSA9IHBhcnNlSW5saW5lO1xuZXhwb3J0cy5wYXJzZXIgPSBwYXJzZXI7XG5leHBvcnRzLnNldE9wdGlvbnMgPSBzZXRPcHRpb25zO1xuZXhwb3J0cy51c2UgPSB1c2U7XG5leHBvcnRzLndhbGtUb2tlbnMgPSB3YWxrVG9rZW5zO1xuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHRpZDogbW9kdWxlSWQsXG5cdFx0bG9hZGVkOiBmYWxzZSxcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG5cdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiX193ZWJwYWNrX3JlcXVpcmVfXy5nID0gKGZ1bmN0aW9uKCkge1xuXHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgPT09ICdvYmplY3QnKSByZXR1cm4gZ2xvYmFsVGhpcztcblx0dHJ5IHtcblx0XHRyZXR1cm4gdGhpcyB8fCBuZXcgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JykgcmV0dXJuIHdpbmRvdztcblx0fVxufSkoKTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm5tZCA9IChtb2R1bGUpID0+IHtcblx0bW9kdWxlLnBhdGhzID0gW107XG5cdGlmICghbW9kdWxlLmNoaWxkcmVuKSBtb2R1bGUuY2hpbGRyZW4gPSBbXTtcblx0cmV0dXJuIG1vZHVsZTtcbn07IiwiIiwiLy8gc3RhcnR1cFxuLy8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4vLyBUaGlzIGVudHJ5IG1vZHVsZSBpcyByZWZlcmVuY2VkIGJ5IG90aGVyIG1vZHVsZXMgc28gaXQgY2FuJ3QgYmUgaW5saW5lZFxudmFyIF9fd2VicGFja19leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKFwiLi9zcmMvY2xpZW50LnRzXCIpO1xuIiwiIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9