UNPKG

87.4 kBJavaScriptView Raw
1'use strict';
2
3var _keys = require('babel-runtime/core-js/object/keys');
4
5var _keys2 = _interopRequireDefault(_keys);
6
7var _typeof2 = require('babel-runtime/helpers/typeof');
8
9var _typeof3 = _interopRequireDefault(_typeof2);
10
11function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
13// code is from https://github.com/AnAppAMonth/linewrap
14
15// Presets
16var presetMap = {
17 'html': {
18 skipScheme: 'html',
19 lineBreakScheme: 'html',
20 whitespace: 'collapse'
21 }
22};
23
24// lineBreak Schemes
25var brPat = /<\s*br(?:[\s/]*|\s[^>]*)>/gi;
26var lineBreakSchemeMap = {
27 'unix': [/\n/g, '\n'],
28 'dos': [/\r\n/g, '\r\n'],
29 'mac': [/\r/g, '\r'],
30 'html': [brPat, '<br>'],
31 'xhtml': [brPat, '<br/>']
32};
33
34// skip Schemes
35var skipSchemeMap = {
36 'ansi-color': /\x1B\[[^m]*m/g,
37 'html': /<[^>]*>/g,
38 'bbcode': /\[[^]]*\]/g
39};
40
41var modeMap = {
42 'soft': 1,
43 'hard': 1
44};
45
46var wsMap = {
47 'collapse': 1,
48 'default': 1,
49 'line': 1,
50 'all': 1
51};
52
53var rlbMap = {
54 'all': 1,
55 'multi': 1,
56 'none': 1
57};
58var rlbSMPat = /([sm])(\d+)/;
59
60var escapePat = /[-/\\^$*+?.()|[\]{}]/g;
61function escapeRegExp(s) {
62 return s.replace(escapePat, '\\$&');
63}
64
65var linewrap = module.exports = function (start, stop, params) {
66 if ((typeof start === 'undefined' ? 'undefined' : (0, _typeof3.default)(start)) === 'object') {
67 params = start;
68 start = params.start;
69 stop = params.stop;
70 }
71
72 if ((typeof stop === 'undefined' ? 'undefined' : (0, _typeof3.default)(stop)) === 'object') {
73 params = stop;
74 start = start || params.start;
75 stop = undefined;
76 }
77
78 if (!stop) {
79 stop = start;
80 start = 0;
81 }
82
83 if (!params) {
84 params = {};
85 }
86 // Supported options and default values.
87 var preset,
88 mode = 'soft',
89 whitespace = 'default',
90 tabWidth = 4,
91 skip,
92 skipScheme,
93 lineBreak,
94 lineBreakScheme,
95 respectLineBreaks = 'all',
96 respectNum,
97 preservedLineIndent,
98 wrapLineIndent,
99 wrapLineIndentBase;
100
101 var skipPat;
102 var lineBreakPat, lineBreakStr;
103 var multiLineBreakPat;
104 var preservedLinePrefix = '';
105 var wrapLineIndentPat,
106 wrapLineInitPrefix = '';
107 var tabRepl;
108 var item, flags;
109 var i;
110
111 // First process presets, because these settings can be overwritten later.
112 preset = params.preset;
113 if (preset) {
114 if (!(preset instanceof Array)) {
115 preset = [preset];
116 }
117 for (i = 0; i < preset.length; i++) {
118 item = presetMap[preset[i]];
119 if (item) {
120 if (item.mode) {
121 mode = item.mode;
122 }
123 if (item.whitespace) {
124 whitespace = item.whitespace;
125 }
126 if (item.tabWidth !== undefined) {
127 tabWidth = item.tabWidth;
128 }
129 if (item.skip) {
130 skip = item.skip;
131 }
132 if (item.skipScheme) {
133 skipScheme = item.skipScheme;
134 }
135 if (item.lineBreak) {
136 lineBreak = item.lineBreak;
137 }
138 if (item.lineBreakScheme) {
139 lineBreakScheme = item.lineBreakScheme;
140 }
141 if (item.respectLineBreaks) {
142 respectLineBreaks = item.respectLineBreaks;
143 }
144 if (item.preservedLineIndent !== undefined) {
145 preservedLineIndent = item.preservedLineIndent;
146 }
147 if (item.wrapLineIndent !== undefined) {
148 wrapLineIndent = item.wrapLineIndent;
149 }
150 if (item.wrapLineIndentBase) {
151 wrapLineIndentBase = item.wrapLineIndentBase;
152 }
153 } else {
154 throw new TypeError('preset must be one of "' + (0, _keys2.default)(presetMap).join('", "') + '"');
155 }
156 }
157 }
158
159 if (params.mode) {
160 if (modeMap[params.mode]) {
161 mode = params.mode;
162 } else {
163 throw new TypeError('mode must be one of "' + (0, _keys2.default)(modeMap).join('", "') + '"');
164 }
165 }
166 // Available options: 'collapse', 'default', 'line', and 'all'
167 if (params.whitespace) {
168 if (wsMap[params.whitespace]) {
169 whitespace = params.whitespace;
170 } else {
171 throw new TypeError('whitespace must be one of "' + (0, _keys2.default)(wsMap).join('", "') + '"');
172 }
173 }
174
175 if (params.tabWidth !== undefined) {
176 if (parseInt(params.tabWidth, 10) >= 0) {
177 tabWidth = parseInt(params.tabWidth, 10);
178 } else {
179 throw new TypeError('tabWidth must be a non-negative integer');
180 }
181 }
182 tabRepl = new Array(tabWidth + 1).join(' ');
183
184 // Available options: 'all', 'multi', 'm\d+', 's\d+', 'none'
185 if (params.respectLineBreaks) {
186 if (rlbMap[params.respectLineBreaks] || rlbSMPat.test(params.respectLineBreaks)) {
187 respectLineBreaks = params.respectLineBreaks;
188 } else {
189 throw new TypeError('respectLineBreaks must be one of "' + (0, _keys2.default)(rlbMap).join('", "') + '", "m<num>", "s<num>"');
190 }
191 }
192 // After these conversions, now we have 4 options in `respectLineBreaks`:
193 // 'all', 'none', 'm' and 's'.
194 // `respectNum` is applicable iff `respectLineBreaks` is either 'm' or 's'.
195 if (respectLineBreaks === 'multi') {
196 respectLineBreaks = 'm';
197 respectNum = 2;
198 } else if (!rlbMap[respectLineBreaks]) {
199 var match = rlbSMPat.exec(respectLineBreaks);
200 respectLineBreaks = match[1];
201 respectNum = parseInt(match[2], 10);
202 }
203
204 if (params.preservedLineIndent !== undefined) {
205 if (parseInt(params.preservedLineIndent, 10) >= 0) {
206 preservedLineIndent = parseInt(params.preservedLineIndent, 10);
207 } else {
208 throw new TypeError('preservedLineIndent must be a non-negative integer');
209 }
210 }
211
212 if (preservedLineIndent > 0) {
213 preservedLinePrefix = new Array(preservedLineIndent + 1).join(' ');
214 }
215
216 if (params.wrapLineIndent !== undefined) {
217 if (!isNaN(parseInt(params.wrapLineIndent, 10))) {
218 wrapLineIndent = parseInt(params.wrapLineIndent, 10);
219 } else {
220 throw new TypeError('wrapLineIndent must be an integer');
221 }
222 }
223 if (params.wrapLineIndentBase) {
224 wrapLineIndentBase = params.wrapLineIndentBase;
225 }
226
227 if (wrapLineIndentBase) {
228 if (wrapLineIndent === undefined) {
229 throw new TypeError('wrapLineIndent must be specified when wrapLineIndentBase is specified');
230 }
231 if (wrapLineIndentBase instanceof RegExp) {
232 wrapLineIndentPat = wrapLineIndentBase;
233 } else if (typeof wrapLineIndentBase === 'string') {
234 wrapLineIndentPat = new RegExp(escapeRegExp(wrapLineIndentBase));
235 } else {
236 throw new TypeError('wrapLineIndentBase must be either a RegExp object or a string');
237 }
238 } else if (wrapLineIndent > 0) {
239 wrapLineInitPrefix = new Array(wrapLineIndent + 1).join(' ');
240 } else if (wrapLineIndent < 0) {
241 throw new TypeError('wrapLineIndent must be non-negative when a base is not specified');
242 }
243
244 // NOTE: For the two RegExps `skipPat` and `lineBreakPat` that can be specified
245 // by the user:
246 // 1. We require them to be "global", so we have to convert them to global
247 // if the user specifies a non-global regex.
248 // 2. We cannot call `split()` on them, because they may or may not contain
249 // capturing parentheses which affect the output of `split()`.
250
251 // Precedence: Regex = Str > Scheme
252 if (params.skipScheme) {
253 if (skipSchemeMap[params.skipScheme]) {
254 skipScheme = params.skipScheme;
255 } else {
256 throw new TypeError('skipScheme must be one of "' + (0, _keys2.default)(skipSchemeMap).join('", "') + '"');
257 }
258 }
259 if (params.skip) {
260 skip = params.skip;
261 }
262
263 if (skip) {
264 if (skip instanceof RegExp) {
265 skipPat = skip;
266 if (!skipPat.global) {
267 flags = 'g';
268 if (skipPat.ignoreCase) {
269 flags += 'i';
270 }
271 if (skipPat.multiline) {
272 flags += 'm';
273 }
274 skipPat = new RegExp(skipPat.source, flags);
275 }
276 } else if (typeof skip === 'string') {
277 skipPat = new RegExp(escapeRegExp(skip), 'g');
278 } else {
279 throw new TypeError('skip must be either a RegExp object or a string');
280 }
281 }
282 if (!skipPat && skipScheme) {
283 skipPat = skipSchemeMap[skipScheme];
284 }
285
286 // Precedence:
287 // - for lineBreakPat: Regex > Scheme > Str
288 // - for lineBreakStr: Str > Scheme > Regex
289 if (params.lineBreakScheme) {
290 if (lineBreakSchemeMap[params.lineBreakScheme]) {
291 lineBreakScheme = params.lineBreakScheme;
292 } else {
293 throw new TypeError('lineBreakScheme must be one of "' + (0, _keys2.default)(lineBreakSchemeMap).join('", "') + '"');
294 }
295 }
296 if (params.lineBreak) {
297 lineBreak = params.lineBreak;
298 }
299
300 if (lineBreakScheme) {
301 // Supported schemes: 'unix', 'dos', 'mac', 'html', 'xhtml'
302 item = lineBreakSchemeMap[lineBreakScheme];
303 if (item) {
304 lineBreakPat = item[0];
305 lineBreakStr = item[1];
306 }
307 }
308 if (lineBreak) {
309 if (lineBreak instanceof Array) {
310 if (lineBreak.length === 1) {
311 lineBreak = lineBreak[0];
312 } else if (lineBreak.length >= 2) {
313 if (lineBreak[0] instanceof RegExp) {
314 lineBreakPat = lineBreak[0];
315 if (typeof lineBreak[1] === 'string') {
316 lineBreakStr = lineBreak[1];
317 }
318 } else if (lineBreak[1] instanceof RegExp) {
319 lineBreakPat = lineBreak[1];
320 if (typeof lineBreak[0] === 'string') {
321 lineBreakStr = lineBreak[0];
322 }
323 } else if (typeof lineBreak[0] === 'string' && typeof lineBreak[1] === 'string') {
324 lineBreakPat = new RegExp(escapeRegExp(lineBreak[0]), 'g');
325 lineBreakStr = lineBreak[1];
326 } else {
327 lineBreak = lineBreak[0];
328 }
329 }
330 }
331 if (typeof lineBreak === 'string') {
332 lineBreakStr = lineBreak;
333 if (!lineBreakPat) {
334 lineBreakPat = new RegExp(escapeRegExp(lineBreak), 'g');
335 }
336 } else if (lineBreak instanceof RegExp) {
337 lineBreakPat = lineBreak;
338 } else if (!(lineBreak instanceof Array)) {
339 throw new TypeError('lineBreak must be a RegExp object, a string, or an array consisted of a RegExp object and a string');
340 }
341 }
342 // Only assign defaults when `lineBreakPat` is not assigned.
343 // So if `params.lineBreak` is a RegExp, we don't have a value in `lineBreakStr`
344 // yet. We will try to get the value from the input string, and if failed, we
345 // will throw an exception.
346 if (!lineBreakPat) {
347 lineBreakPat = /\n/g;
348 lineBreakStr = '\n';
349 }
350
351 // Create `multiLineBreakPat` based on `lineBreakPat`, that matches strings
352 // consisted of one or more line breaks and zero or more whitespaces.
353 // Also convert `lineBreakPat` to global if not already so.
354 flags = 'g';
355 if (lineBreakPat.ignoreCase) {
356 flags += 'i';
357 }
358 if (lineBreakPat.multiline) {
359 flags += 'm';
360 }
361 multiLineBreakPat = new RegExp('\\s*(?:' + lineBreakPat.source + ')(?:' + lineBreakPat.source + '|\\s)*', flags);
362 if (!lineBreakPat.global) {
363 lineBreakPat = new RegExp(lineBreakPat.source, flags);
364 }
365
366 // Initialize other useful variables.
367 var re = mode === 'hard' ? /\b/ : /(\S+\s+)/;
368 var prefix = new Array(start + 1).join(' ');
369 var wsStrip = whitespace === 'default' || whitespace === 'collapse',
370 wsCollapse = whitespace === 'collapse',
371 wsLine = whitespace === 'line',
372 wsAll = whitespace === 'all';
373 var tabPat = /\t/g,
374 collapsePat = / +/g,
375 pPat = /^\s+/,
376 tPat = /\s+$/,
377 nonWsPat = /\S/,
378 wsPat = /\s/;
379 var wrapLen = stop - start;
380
381 return function (text) {
382 text = text.toString().replace(tabPat, tabRepl);
383
384 var match;
385 if (!lineBreakStr) {
386 // Try to get lineBreakStr from `text`
387 lineBreakPat.lastIndex = 0;
388 match = lineBreakPat.exec(text);
389 if (match) {
390 lineBreakStr = match[0];
391 } else {
392 throw new TypeError('Line break string for the output not specified');
393 }
394 }
395
396 // text -> blocks; each bloc -> segments; each segment -> chunks
397 var blocks,
398 base = 0;
399 var mo, arr, b, res;
400 // Split `text` by line breaks.
401 blocks = [];
402 multiLineBreakPat.lastIndex = 0;
403 match = multiLineBreakPat.exec(text);
404 while (match) {
405 blocks.push(text.substring(base, match.index));
406
407 if (respectLineBreaks !== 'none') {
408 arr = [];
409 b = 0;
410 lineBreakPat.lastIndex = 0;
411 mo = lineBreakPat.exec(match[0]);
412 while (mo) {
413 arr.push(match[0].substring(b, mo.index));
414 b = mo.index + mo[0].length;
415 mo = lineBreakPat.exec(match[0]);
416 }
417 arr.push(match[0].substring(b));
418 blocks.push({ type: 'break', breaks: arr });
419 } else {
420 // Strip line breaks and insert spaces when necessary.
421 if (wsCollapse) {
422 res = ' ';
423 } else {
424 res = match[0].replace(lineBreakPat, '');
425 }
426 blocks.push({ type: 'break', remaining: res });
427 }
428
429 base = match.index + match[0].length;
430 match = multiLineBreakPat.exec(text);
431 }
432 blocks.push(text.substring(base));
433
434 var i, j, k;
435 var segments;
436 if (skipPat) {
437 segments = [];
438 for (i = 0; i < blocks.length; i++) {
439 var bloc = blocks[i];
440 if (typeof bloc !== 'string') {
441 // This is an object.
442 segments.push(bloc);
443 } else {
444 base = 0;
445 skipPat.lastIndex = 0;
446 match = skipPat.exec(bloc);
447 while (match) {
448 segments.push(bloc.substring(base, match.index));
449 segments.push({ type: 'skip', value: match[0] });
450 base = match.index + match[0].length;
451 match = skipPat.exec(bloc);
452 }
453 segments.push(bloc.substring(base));
454 }
455 }
456 } else {
457 segments = blocks;
458 }
459
460 var chunks = [];
461 for (i = 0; i < segments.length; i++) {
462 var segment = segments[i];
463 if (typeof segment !== 'string') {
464 // This is an object.
465 chunks.push(segment);
466 } else {
467 if (wsCollapse) {
468 segment = segment.replace(collapsePat, ' ');
469 }
470
471 var parts = segment.split(re),
472 acc = [];
473
474 for (j = 0; j < parts.length; j++) {
475 var x = parts[j];
476 if (mode === 'hard') {
477 for (k = 0; k < x.length; k += wrapLen) {
478 acc.push(x.slice(k, k + wrapLen));
479 }
480 } else {
481 acc.push(x);
482 }
483 }
484 chunks = chunks.concat(acc);
485 }
486 }
487
488 var curLine = 0,
489 curLineLength = start + preservedLinePrefix.length,
490 lines = [prefix + preservedLinePrefix],
491
492 // Holds the "real length" (excluding trailing whitespaces) of the
493 // current line if it exceeds `stop`, otherwise 0.
494 // ONLY USED when `wsAll` is true, in `finishOffCurLine()`.
495 bulge = 0,
496
497 // `cleanLine` is true iff we are at the beginning of an output line. By
498 // "beginning" we mean it doesn't contain any non-whitespace char yet.
499 // But its `curLineLength` can be greater than `start`, or even possibly
500 // be greater than `stop`, if `wsStrip` is false.
501 //
502 // Note that a "clean" line can still contain skip strings, in addition
503 // to whitespaces.
504 //
505 // This variable is used to allow us strip preceding whitespaces when
506 // `wsStrip` is true, or `wsLine` is true and `preservedLine` is false.
507 cleanLine = true,
508
509 // `preservedLine` is true iff we are in a preserved input line.
510 //
511 // It's used when `wsLine` is true to (combined with `cleanLine`) decide
512 // whether a whitespace is at the beginning of a preserved input line and
513 // should not be stripped.
514 preservedLine = true,
515
516 // The current indent prefix for wrapped lines.
517 wrapLinePrefix = wrapLineInitPrefix,
518 remnant;
519
520 // Always returns '' if `beforeHardBreak` is true.
521 //
522 // Assumption: Each call of this function is always followed by a `lines.push()` call.
523 //
524 // This function can change the status of `cleanLine`, but we don't modify the value of
525 // `cleanLine` in this function. It's fine because `cleanLine` will be set to the correct
526 // value after the `lines.push()` call following this function call. We also don't update
527 // `curLineLength` when pushing a new line and it's safe for the same reason.
528 function finishOffCurLine(beforeHardBreak) {
529 var str = lines[curLine],
530 idx,
531 ln,
532 rBase;
533
534 if (!wsAll) {
535 // Strip all trailing whitespaces past `start`.
536 idx = str.length - 1;
537 while (idx >= start && str[idx] === ' ') {
538 idx--;
539 }
540 while (idx >= start && wsPat.test(str[idx])) {
541 idx--;
542 }
543 idx++;
544
545 if (idx !== str.length) {
546 lines[curLine] = str.substring(0, idx);
547 }
548
549 if (preservedLine && cleanLine && wsLine && curLineLength > stop) {
550 // Add the remnants to the next line, just like when `wsAll` is true.
551 rBase = str.length - (curLineLength - stop);
552 if (rBase < idx) {
553 // We didn't reach `stop` when stripping due to a bulge.
554 rBase = idx;
555 }
556 }
557 } else {
558 // Strip trailing whitespaces exceeding stop.
559 if (curLineLength > stop) {
560 bulge = bulge || stop;
561 rBase = str.length - (curLineLength - bulge);
562 lines[curLine] = str.substring(0, rBase);
563 }
564 bulge = 0;
565 }
566
567 // Bug: the current implementation of `wrapLineIndent` is buggy: we are not
568 // taking the extra space occupied by the additional indentation into account
569 // when wrapping the line. For example, in "hard" mode, we should hard-wrap
570 // long words at `wrapLen - wrapLinePrefix.length` instead of `wrapLen`
571 // and remnants should also be wrapped at `wrapLen - wrapLinePrefix.length`.
572 if (preservedLine) {
573 // This is a preserved line, and the next output line isn't a
574 // preserved line.
575 preservedLine = false;
576 if (wrapLineIndentPat) {
577 idx = lines[curLine].substring(start).search(wrapLineIndentPat);
578 if (idx >= 0 && idx + wrapLineIndent > 0) {
579 wrapLinePrefix = new Array(idx + wrapLineIndent + 1).join(' ');
580 } else {
581 wrapLinePrefix = '';
582 }
583 }
584 }
585
586 // Some remnants are left to the next line.
587 if (rBase) {
588 while (rBase + wrapLen < str.length) {
589 if (wsAll) {
590 ln = str.substring(rBase, rBase + wrapLen);
591 lines.push(prefix + wrapLinePrefix + ln);
592 } else {
593 lines.push(prefix + wrapLinePrefix);
594 }
595 rBase += wrapLen;
596 curLine++;
597 }
598 if (beforeHardBreak) {
599 if (wsAll) {
600 ln = str.substring(rBase);
601 lines.push(prefix + wrapLinePrefix + ln);
602 } else {
603 lines.push(prefix + wrapLinePrefix);
604 }
605 curLine++;
606 } else {
607 ln = str.substring(rBase);
608 return wrapLinePrefix + ln;
609 }
610 }
611
612 return '';
613 }
614
615 for (i = 0; i < chunks.length; i++) {
616 var chunk = chunks[i];
617
618 if (chunk === '') {
619 continue;
620 }
621
622 if (typeof chunk !== 'string') {
623 if (chunk.type === 'break') {
624 // This is one or more line breaks.
625 // Each entry in `breaks` is just zero or more whitespaces.
626 if (respectLineBreaks !== 'none') {
627 // Note that if `whitespace` is "collapse", we still need
628 // to collapse whitespaces in entries of `breaks`.
629 var breaks = chunk.breaks;
630 var num = breaks.length - 1;
631
632 if (respectLineBreaks === 's') {
633 // This is the most complex scenario. We have to check
634 // the line breaks one by one.
635 for (j = 0; j < num; j++) {
636 if (breaks[j + 1].length < respectNum) {
637 // This line break should be stripped.
638 if (wsCollapse) {
639 breaks[j + 1] = ' ';
640 } else {
641 breaks[j + 1] = breaks[j] + breaks[j + 1];
642 }
643 } else {
644 // This line break should be preserved.
645 // First finish off the current line.
646 if (wsAll) {
647 lines[curLine] += breaks[j];
648 curLineLength += breaks[j].length;
649 }
650 finishOffCurLine(true);
651
652 lines.push(prefix + preservedLinePrefix);
653 curLine++;
654 curLineLength = start + preservedLinePrefix.length;
655
656 preservedLine = cleanLine = true;
657 }
658 }
659 // We are adding to either the existing line (if no line break
660 // is qualified for preservance) or a "new" line.
661 if (!cleanLine || wsAll || wsLine && preservedLine) {
662 if (wsCollapse || !cleanLine && breaks[num] === '') {
663 breaks[num] = ' ';
664 }
665 lines[curLine] += breaks[num];
666 curLineLength += breaks[num].length;
667 }
668 } else if (respectLineBreaks === 'm' && num < respectNum) {
669 // These line breaks should be stripped.
670 if (!cleanLine || wsAll || wsLine && preservedLine) {
671 if (wsCollapse) {
672 chunk = ' ';
673 } else {
674 chunk = breaks.join('');
675 if (!cleanLine && chunk === '') {
676 chunk = ' ';
677 }
678 }
679 lines[curLine] += chunk;
680 curLineLength += chunk.length;
681 }
682 } else {
683 // 'all' || ('m' && num >= respectNum)
684 // These line breaks should be preserved.
685 if (wsStrip) {
686 // Finish off the current line.
687 finishOffCurLine(true);
688
689 for (j = 0; j < num; j++) {
690 lines.push(prefix + preservedLinePrefix);
691 curLine++;
692 }
693
694 curLineLength = start + preservedLinePrefix.length;
695 preservedLine = cleanLine = true;
696 } else {
697 if (wsAll || preservedLine && cleanLine) {
698 lines[curLine] += breaks[0];
699 curLineLength += breaks[0].length;
700 }
701
702 for (j = 0; j < num; j++) {
703 // Finish off the current line.
704 finishOffCurLine(true);
705
706 lines.push(prefix + preservedLinePrefix + breaks[j + 1]);
707 curLine++;
708 curLineLength = start + preservedLinePrefix.length + breaks[j + 1].length;
709
710 preservedLine = cleanLine = true;
711 }
712 }
713 }
714 } else {
715 // These line breaks should be stripped.
716 if (!cleanLine || wsAll || wsLine && preservedLine) {
717 chunk = chunk.remaining;
718
719 // Bug: If `wsAll` is true, `cleanLine` is false, and `chunk`
720 // is '', we insert a space to replace the line break. This
721 // space will be preserved even if we are at the end of an
722 // output line, which is wrong behavior. However, I'm not
723 // sure it's worth it to fix this edge case.
724 if (wsCollapse || !cleanLine && chunk === '') {
725 chunk = ' ';
726 }
727 lines[curLine] += chunk;
728 curLineLength += chunk.length;
729 }
730 }
731 } else if (chunk.type === 'skip') {
732 // This is a skip string.
733 // Assumption: skip strings don't end with whitespaces.
734 if (curLineLength > stop) {
735 remnant = finishOffCurLine(false);
736
737 lines.push(prefix + wrapLinePrefix);
738 curLine++;
739 curLineLength = start + wrapLinePrefix.length;
740
741 if (remnant) {
742 lines[curLine] += remnant;
743 curLineLength += remnant.length;
744 }
745
746 cleanLine = true;
747 }
748 lines[curLine] += chunk.value;
749 }
750 continue;
751 }
752
753 var chunk2;
754 while (1) {
755 chunk2 = undefined;
756 if (curLineLength + chunk.length > stop && curLineLength + (chunk2 = chunk.replace(tPat, '')).length > stop && chunk2 !== '' && curLineLength > start) {
757 // This line is full, add `chunk` to the next line
758 remnant = finishOffCurLine(false);
759
760 lines.push(prefix + wrapLinePrefix);
761 curLine++;
762 curLineLength = start + wrapLinePrefix.length;
763
764 if (remnant) {
765 lines[curLine] += remnant;
766 curLineLength += remnant.length;
767 cleanLine = true;
768 continue;
769 }
770
771 if (wsStrip || wsLine && !(preservedLine && cleanLine)) {
772 chunk = chunk.replace(pPat, '');
773 }
774 cleanLine = false;
775 } else {
776 // Add `chunk` to this line
777 if (cleanLine) {
778 if (wsStrip || wsLine && !(preservedLine && cleanLine)) {
779 chunk = chunk.replace(pPat, '');
780 if (chunk !== '') {
781 cleanLine = false;
782 }
783 } else {
784 if (nonWsPat.test(chunk)) {
785 cleanLine = false;
786 }
787 }
788 }
789 }
790 break;
791 }
792 if (wsAll && chunk2 && curLineLength + chunk2.length > stop) {
793 bulge = curLineLength + chunk2.length;
794 }
795 lines[curLine] += chunk;
796 curLineLength += chunk.length;
797 }
798 // Finally, finish off the last line.
799 finishOffCurLine(true);
800 return lines.join(lineBreakStr);
801 };
802};
803
804linewrap.soft = linewrap;
805
806linewrap.hard = function () /*start, stop, params*/{
807 var args = [].slice.call(arguments);
808 var last = args.length - 1;
809 if ((0, _typeof3.default)(args[last]) === 'object') {
810 args[last].mode = 'hard';
811 } else {
812 args.push({ mode: 'hard' });
813 }
814 return linewrap.apply(null, args);
815};
816
817linewrap.wrap = function (text /*, start, stop, params*/) {
818 var args = [].slice.call(arguments);
819 args.shift();
820 return linewrap.apply(null, args)(text);
821};
822//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9saW5ld3JhcC5qcyJdLCJuYW1lcyI6WyJwcmVzZXRNYXAiLCJza2lwU2NoZW1lIiwibGluZUJyZWFrU2NoZW1lIiwid2hpdGVzcGFjZSIsImJyUGF0IiwibGluZUJyZWFrU2NoZW1lTWFwIiwic2tpcFNjaGVtZU1hcCIsIm1vZGVNYXAiLCJ3c01hcCIsInJsYk1hcCIsInJsYlNNUGF0IiwiZXNjYXBlUGF0IiwiZXNjYXBlUmVnRXhwIiwicyIsInJlcGxhY2UiLCJsaW5ld3JhcCIsIm1vZHVsZSIsImV4cG9ydHMiLCJzdGFydCIsInN0b3AiLCJwYXJhbXMiLCJ1bmRlZmluZWQiLCJwcmVzZXQiLCJtb2RlIiwidGFiV2lkdGgiLCJza2lwIiwibGluZUJyZWFrIiwicmVzcGVjdExpbmVCcmVha3MiLCJyZXNwZWN0TnVtIiwicHJlc2VydmVkTGluZUluZGVudCIsIndyYXBMaW5lSW5kZW50Iiwid3JhcExpbmVJbmRlbnRCYXNlIiwic2tpcFBhdCIsImxpbmVCcmVha1BhdCIsImxpbmVCcmVha1N0ciIsIm11bHRpTGluZUJyZWFrUGF0IiwicHJlc2VydmVkTGluZVByZWZpeCIsIndyYXBMaW5lSW5kZW50UGF0Iiwid3JhcExpbmVJbml0UHJlZml4IiwidGFiUmVwbCIsIml0ZW0iLCJmbGFncyIsImkiLCJBcnJheSIsImxlbmd0aCIsIlR5cGVFcnJvciIsImpvaW4iLCJwYXJzZUludCIsInRlc3QiLCJtYXRjaCIsImV4ZWMiLCJpc05hTiIsIlJlZ0V4cCIsImdsb2JhbCIsImlnbm9yZUNhc2UiLCJtdWx0aWxpbmUiLCJzb3VyY2UiLCJyZSIsInByZWZpeCIsIndzU3RyaXAiLCJ3c0NvbGxhcHNlIiwid3NMaW5lIiwid3NBbGwiLCJ0YWJQYXQiLCJjb2xsYXBzZVBhdCIsInBQYXQiLCJ0UGF0Iiwibm9uV3NQYXQiLCJ3c1BhdCIsIndyYXBMZW4iLCJ0ZXh0IiwidG9TdHJpbmciLCJsYXN0SW5kZXgiLCJibG9ja3MiLCJiYXNlIiwibW8iLCJhcnIiLCJiIiwicmVzIiwicHVzaCIsInN1YnN0cmluZyIsImluZGV4IiwidHlwZSIsImJyZWFrcyIsInJlbWFpbmluZyIsImoiLCJrIiwic2VnbWVudHMiLCJibG9jIiwidmFsdWUiLCJjaHVua3MiLCJzZWdtZW50IiwicGFydHMiLCJzcGxpdCIsImFjYyIsIngiLCJzbGljZSIsImNvbmNhdCIsImN1ckxpbmUiLCJjdXJMaW5lTGVuZ3RoIiwibGluZXMiLCJidWxnZSIsImNsZWFuTGluZSIsInByZXNlcnZlZExpbmUiLCJ3cmFwTGluZVByZWZpeCIsInJlbW5hbnQiLCJmaW5pc2hPZmZDdXJMaW5lIiwiYmVmb3JlSGFyZEJyZWFrIiwic3RyIiwiaWR4IiwibG4iLCJyQmFzZSIsInNlYXJjaCIsImNodW5rIiwibnVtIiwiY2h1bmsyIiwic29mdCIsImhhcmQiLCJhcmdzIiwiY2FsbCIsImFyZ3VtZW50cyIsImxhc3QiLCJhcHBseSIsIndyYXAiLCJzaGlmdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUE7O0FBRUE7QUFDQSxJQUFJQSxZQUFZO0FBQ2QsVUFBUTtBQUNOQyxnQkFBWSxNQUROO0FBRU5DLHFCQUFpQixNQUZYO0FBR05DLGdCQUFZO0FBSE47QUFETSxDQUFoQjs7QUFRQTtBQUNBLElBQUlDLFFBQVEsNkJBQVo7QUFDQSxJQUFJQyxxQkFBcUI7QUFDdkIsVUFBUSxDQUFDLEtBQUQsRUFBUSxJQUFSLENBRGU7QUFFdkIsU0FBTyxDQUFDLE9BQUQsRUFBVSxNQUFWLENBRmdCO0FBR3ZCLFNBQU8sQ0FBQyxLQUFELEVBQVEsSUFBUixDQUhnQjtBQUl2QixVQUFRLENBQUNELEtBQUQsRUFBUSxNQUFSLENBSmU7QUFLdkIsV0FBUyxDQUFDQSxLQUFELEVBQVEsT0FBUjtBQUxjLENBQXpCOztBQVFBO0FBQ0EsSUFBSUUsZ0JBQWdCO0FBQ2xCLGdCQUFjLGVBREk7QUFFbEIsVUFBUSxVQUZVO0FBR2xCLFlBQVU7QUFIUSxDQUFwQjs7QUFNQSxJQUFJQyxVQUFVO0FBQ1osVUFBUSxDQURJO0FBRVosVUFB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O0FBQzNEa0YsZ0JBQVFGLGdCQUFnQmdCLE9BQU92RSxNQUEvQjtBQUNEO0FBQ0R3RCxZQUFNRixPQUFOLEtBQWtCZSxLQUFsQjtBQUNBZCx1QkFBaUJjLE1BQU1yRSxNQUF2QjtBQUNEO0FBQ0Q7QUFDQThELHFCQUFpQixJQUFqQjtBQUNBLFdBQU9OLE1BQU10RCxJQUFOLENBQVdaLFlBQVgsQ0FBUDtBQUNELEdBdlpEO0FBd1pELENBdnNCRDs7QUF5c0JBbkIsU0FBU3FHLElBQVQsR0FBZ0JyRyxRQUFoQjs7QUFFQUEsU0FBU3NHLElBQVQsR0FBZ0IsWUFBVyx1QkFBeUI7QUFDbEQsTUFBSUMsT0FBTyxHQUFHdEIsS0FBSCxDQUFTdUIsSUFBVCxDQUFjQyxTQUFkLENBQVg7QUFDQSxNQUFJQyxPQUFPSCxLQUFLMUUsTUFBTCxHQUFjLENBQXpCO0FBQ0EsTUFBSSxzQkFBTzBFLEtBQUtHLElBQUwsQ0FBUCxNQUFzQixRQUExQixFQUFvQztBQUNsQ0gsU0FBS0csSUFBTCxFQUFXbEcsSUFBWCxHQUFrQixNQUFsQjtBQUNELEdBRkQsTUFFTztBQUNMK0YsU0FBS3ZDLElBQUwsQ0FBVSxFQUFFeEQsTUFBTSxNQUFSLEVBQVY7QUFDRDtBQUNELFNBQU9SLFNBQVMyRyxLQUFULENBQWUsSUFBZixFQUFxQkosSUFBckIsQ0FBUDtBQUNELENBVEQ7O0FBV0F2RyxTQUFTNEcsSUFBVCxHQUFnQixVQUFVckQsSUFBVixDQUFlLHlCQUFmLEVBQTBDO0FBQ3hELE1BQUlnRCxPQUFPLEdBQUd0QixLQUFILENBQVN1QixJQUFULENBQWNDLFNBQWQsQ0FBWDtBQUNBRixPQUFLTSxLQUFMO0FBQ0EsU0FBTzdHLFNBQVMyRyxLQUFULENBQWUsSUFBZixFQUFxQkosSUFBckIsRUFBMkJoRCxJQUEzQixDQUFQO0FBQ0QsQ0FKRCIsImZpbGUiOiJsaW5ld3JhcC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIGNvZGUgaXMgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vQW5BcHBBTW9udGgvbGluZXdyYXBcblxuLy8gUHJlc2V0c1xudmFyIHByZXNldE1hcCA9IHtcbiAgJ2h0bWwnOiB7XG4gICAgc2tpcFNjaGVtZTogJ2h0bWwnLFxuICAgIGxpbmVCcmVha1NjaGVtZTogJ2h0bWwnLFxuICAgIHdoaXRlc3BhY2U6ICdjb2xsYXBzZSdcbiAgfVxufVxuXG4vLyBsaW5lQnJlYWsgU2NoZW1lc1xudmFyIGJyUGF0ID0gLzxcXHMqYnIoPzpbXFxzL10qfFxcc1tePl0qKT4vZ2lcbnZhciBsaW5lQnJlYWtTY2hlbWVNYXAgPSB7XG4gICd1bml4JzogWy9cXG4vZywgJ1xcbiddLFxuICAnZG9zJzogWy9cXHJcXG4vZywgJ1xcclxcbiddLFxuICAnbWFjJzogWy9cXHIvZywgJ1xcciddLFxuICAnaHRtbCc6IFticlBhdCwgJzxicj4nXSxcbiAgJ3hodG1sJzogW2JyUGF0LCAnPGJyLz4nXVxufVxuXG4vLyBza2lwIFNjaGVtZXNcbnZhciBza2lwU2NoZW1lTWFwID0ge1xuICAnYW5zaS1jb2xvcic6IC9cXHgxQlxcW1tebV0qbS9nLFxuICAnaHRtbCc6IC88W14+XSo+L2csXG4gICdiYmNvZGUnOiAvXFxbW15dXSpcXF0vZ1xufVxuXG52YXIgbW9kZU1hcCA9IHtcbiAgJ3NvZnQnOiAxLFxuICAnaGFyZCc6IDFcbn1cblxudmFyIHdzTWFwID0ge1xuICAnY29sbGFwc2UnOiAxLFxuICAnZGVmYXVsdCc6IDEsXG4gICdsaW5lJzogMSxcbiAgJ2FsbCc6IDFcbn1cblxudmFyIHJsYk1hcCA9IHtcbiAgJ2FsbCc6IDEsXG4gICdtdWx0aSc6IDEsXG4gICdub25lJzogMVxufVxudmFyIHJsYlNNUGF0ID0gLyhbc21dKShcXGQrKS9cblxudmFyIGVzY2FwZVBhdCA9IC9bLS9cXFxcXiQqKz8uKCl8W1xcXXt9XS9nXG5mdW5jdGlvbiBlc2NhcGVSZWdFeHAgKHMpIHtcbiAgcmV0dXJuIHMucmVwbGFjZShlc2NhcGVQYXQsICdcXFxcJCYnKVxufVxuXG52YXIgbGluZXdyYXAgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzdGFydCwgc3RvcCwgcGFyYW1zKSB7XG4gIGlmICh0eXBlb2Ygc3RhcnQgPT09ICdvYmplY3QnKSB7XG4gICAgcGFyYW1zID0gc3RhcnRcbiAgICBzdGFydCA9IHBhcmFtcy5zdGFydFxuICAgIHN0b3AgPSBwYXJhbXMuc3RvcFxuICB9XG5cbiAgaWYgKHR5cGVvZiBzdG9wID09PSAnb2JqZWN0Jykge1xuICAgIHBhcmFtcyA9IHN0b3BcbiAgICBzdGFydCA9IHN0YXJ0IHx8IHBhcmFtcy5zdGFydFxuICAgIHN0b3AgPSB1bmRlZmluZWRcbiAgfVxuXG4gIGlmICghc3RvcCkge1xuICAgIHN0b3AgPSBzdGFydFxuICAgIHN0YXJ0ID0gMFxuICB9XG5cbiAgaWYgKCFwYXJhbXMpIHsgcGFyYW1zID0ge307IH1cbiAgLy8gU3VwcG9ydGVkIG9wdGlvbnMgYW5kIGRlZmF1bHQgdmFsdWVzLlxuICB2YXIgcHJlc2V0LFxuICAgIG1vZGUgPSAnc29mdCcsXG4gICAgd2hpdGVzcGFjZSA9ICdkZWZhdWx0JyxcbiAgICB0YWJXaWR0aCA9IDQsXG4gICAgc2tpcCwgc2tpcFNjaGVtZSwgbGluZUJyZWFrLCBsaW5lQnJlYWtTY2hlbWUsXG4gICAgcmVzcGVjdExpbmVCcmVha3MgPSAnYWxsJyxcbiAgICByZXNwZWN0TnVtLFxuICAgIHByZXNlcnZlZExpbmVJbmRlbnQsXG4gICAgd3JhcExpbmVJbmRlbnQsIHdyYXBMaW5lSW5kZW50QmFzZVxuXG4gIHZhciBza2lwUGF0XG4gIHZhciBsaW5lQnJlYWtQYXQsIGxpbmVCcmVha1N0clxuICB2YXIgbXVsdGlMaW5lQnJlYWtQYXRcbiAgdmFyIHByZXNlcnZlZExpbmVQcmVmaXggPSAnJ1xuICB2YXIgd3JhcExpbmVJbmRlbnRQYXQsIHdyYXBMaW5lSW5pdFByZWZpeCA9ICcnXG4gIHZhciB0YWJSZXBsXG4gIHZhciBpdGVtLCBmbGFnc1xuICB2YXIgaVxuXG4gIC8vIEZpcnN0IHByb2Nlc3MgcHJlc2V0cywgYmVjYXVzZSB0aGVzZSBzZXR0aW5ncyBjYW4gYmUgb3ZlcndyaXR0ZW4gbGF0ZXIuXG4gIHByZXNldCA9IHBhcmFtcy5wcmVzZXRcbiAgaWYgKHByZXNldCkge1xuICAgIGlmICghKHByZXNldCBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgcHJlc2V0ID0gW3ByZXNldF1cbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IHByZXNldC5sZW5ndGg7IGkrKykge1xuICAgICAgaXRlbSA9IHByZXNldE1hcFtwcmVzZXRbaV1dXG4gICAgICBpZiAoaXRlbSkge1xuICAgICAgICBpZiAoaXRlbS5tb2RlKSB7XG4gICAgICAgICAgbW9kZSA9IGl0ZW0ubW9kZVxuICAgICAgICB9XG4gICAgICAgIGlmIChpdGVtLndoaXRlc3BhY2UpIHtcbiAgICAgICAgICB3aGl0ZXNwYWNlID0gaXRlbS53aGl0ZXNwYWNlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGl0ZW0udGFiV2lkdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRhYldpZHRoID0gaXRlbS50YWJXaWR0aFxuICAgICAgICB9XG4gICAgICAgIGlmIChpdGVtLnNraXApIHtcbiAgICAgICAgICBza2lwID0gaXRlbS5za2lwXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGl0ZW0uc2tpcFNjaGVtZSkge1xuICAgICAgICAgIHNraXBTY2hlbWUgPSBpdGVtLnNraXBTY2hlbWVcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbS5saW5lQnJlYWspIHtcbiAgICAgICAgICBsaW5lQnJlYWsgPSBpdGVtLmxpbmVCcmVha1xuICAgICAgICB9XG4gICAgICAgIGlmIChpdGVtLmxpbmVCcmVha1NjaGVtZSkge1xuICAgICAgICAgIGxpbmVCcmVha1NjaGVtZSA9IGl0ZW0ubGluZUJyZWFrU2NoZW1lXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGl0ZW0ucmVzcGVjdExpbmVCcmVha3MpIHtcbiAgICAgICAgICByZXNwZWN0TGluZUJyZWFrcyA9IGl0ZW0ucmVzcGVjdExpbmVCcmVha3NcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbS5wcmVzZXJ2ZWRMaW5lSW5kZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBwcmVzZXJ2ZWRMaW5lSW5kZW50ID0gaXRlbS5wcmVzZXJ2ZWRMaW5lSW5kZW50XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGl0ZW0ud3JhcExpbmVJbmRlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHdyYXBMaW5lSW5kZW50ID0gaXRlbS53cmFwTGluZUluZGVudFxuICAgICAgICB9XG4gICAgICAgIGlmIChpdGVtLndyYXBMaW5lSW5kZW50QmFzZSkge1xuICAgICAgICAgIHdyYXBMaW5lSW5kZW50QmFzZSA9IGl0ZW0ud3JhcExpbmVJbmRlbnRCYXNlXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ByZXNldCBtdXN0IGJlIG9uZSBvZiBcIicgKyBPYmplY3Qua2V5cyhwcmVzZXRNYXApLmpvaW4oJ1wiLCBcIicpICsgJ1wiJylcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAocGFyYW1zLm1vZGUpIHtcbiAgICBpZiAobW9kZU1hcFtwYXJhbXMubW9kZV0pIHtcbiAgICAgIG1vZGUgPSBwYXJhbXMubW9kZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtb2RlIG11c3QgYmUgb25lIG9mIFwiJyArIE9iamVjdC5rZXlzKG1vZGVNYXApLmpvaW4oJ1wiLCBcIicpICsgJ1wiJylcbiAgICB9XG4gIH1cbiAgLy8gQXZhaWxhYmxlIG9wdGlvbnM6ICdjb2xsYXBzZScsICdkZWZhdWx0JywgJ2xpbmUnLCBhbmQgJ2FsbCdcbiAgaWYgKHBhcmFtcy53aGl0ZXNwYWNlKSB7XG4gICAgaWYgKHdzTWFwW3BhcmFtcy53aGl0ZXNwYWNlXSkge1xuICAgICAgd2hpdGVzcGFjZSA9IHBhcmFtcy53aGl0ZXNwYWNlXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3doaXRlc3BhY2UgbXVzdCBiZSBvbmUgb2YgXCInICsgT2JqZWN0LmtleXMod3NNYXApLmpvaW4oJ1wiLCBcIicpICsgJ1wiJylcbiAgICB9XG4gIH1cblxuICBpZiAocGFyYW1zLnRhYldpZHRoICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAocGFyc2VJbnQocGFyYW1zLnRhYldpZHRoLCAxMCkgPj0gMCkge1xuICAgICAgdGFiV2lkdGggPSBwYXJzZUludChwYXJhbXMudGFiV2lkdGgsIDEwKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0YWJXaWR0aCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXInKVxuICAgIH1cbiAgfVxuICB0YWJSZXBsID0gbmV3IEFycmF5KHRhYldpZHRoICsgMSkuam9pbignICcpXG5cbiAgLy8gQXZhaWxhYmxlIG9wdGlvbnM6ICdhbGwnLCAnbXVsdGknLCAnbVxcZCsnLCAnc1xcZCsnLCAnbm9uZSdcbiAgaWYgKHBhcmFtcy5yZXNwZWN0TGluZUJyZWFrcykge1xuICAgIGlmIChybGJNYXBbcGFyYW1zLnJlc3BlY3RMaW5lQnJlYWtzXSB8fCBybGJTTVBhdC50ZXN0KHBhcmFtcy5yZXNwZWN0TGluZUJyZWFrcykpIHtcbiAgICAgIHJlc3BlY3RMaW5lQnJlYWtzID0gcGFyYW1zLnJlc3BlY3RMaW5lQnJlYWtzXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3Jlc3BlY3RMaW5lQnJlYWtzIG11c3QgYmUgb25lIG9mIFwiJyArIE9iamVjdC5rZXlzKHJsYk1hcCkuam9pbignXCIsIFwiJykgK1xuICAgICAgICAnXCIsIFwibTxudW0+XCIsIFwiczxudW0+XCInKVxuICAgIH1cbiAgfVxuICAvLyBBZnRlciB0aGVzZSBjb252ZXJzaW9ucywgbm93IHdlIGhhdmUgNCBvcHRpb25zIGluIGByZXNwZWN0TGluZUJyZWFrc2A6XG4gIC8vICdhbGwnLCAnbm9uZScsICdtJyBhbmQgJ3MnLlxuICAvLyBgcmVzcGVjdE51bWAgaXMgYXBwbGljYWJsZSBpZmYgYHJlc3BlY3RMaW5lQnJlYWtzYCBpcyBlaXRoZXIgJ20nIG9yICdzJy5cbiAgaWYgKHJlc3BlY3RMaW5lQnJlYWtzID09PSAnbXVsdGknKSB7XG4gICAgcmVzcGVjdExpbmVCcmVha3MgPSAnbSdcbiAgICByZXNwZWN0TnVtID0gMlxuICB9IGVsc2UgaWYgKCFybGJNYXBbcmVzcGVjdExpbmVCcmVha3NdKSB7XG4gICAgdmFyIG1hdGNoID0gcmxiU01QYXQuZXhlYyhyZXNwZWN0TGluZUJyZWFrcylcbiAgICByZXNwZWN0TGluZUJyZWFrcyA9IG1hdGNoWzFdXG4gICAgcmVzcGVjdE51bSA9IHBhcnNlSW50KG1hdGNoWzJdLCAxMClcbiAgfVxuXG4gIGlmIChwYXJhbXMucHJlc2VydmVkTGluZUluZGVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHBhcnNlSW50KHBhcmFtcy5wcmVzZXJ2ZWRMaW5lSW5kZW50LCAxMCkgPj0gMCkge1xuICAgICAgcHJlc2VydmVkTGluZUluZGVudCA9IHBhcnNlSW50KHBhcmFtcy5wcmVzZXJ2ZWRMaW5lSW5kZW50LCAxMClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncHJlc2VydmVkTGluZUluZGVudCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXInKVxuICAgIH1cbiAgfVxuXG4gIGlmIChwcmVzZXJ2ZWRMaW5lSW5kZW50ID4gMCkge1xuICAgIHByZXNlcnZlZExpbmVQcmVmaXggPSBuZXcgQXJyYXkocHJlc2VydmVkTGluZUluZGVudCArIDEpLmpvaW4oJyAnKVxuICB9XG5cbiAgaWYgKHBhcmFtcy53cmFwTGluZUluZGVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKCFpc05hTihwYXJzZUludChwYXJhbXMud3JhcExpbmVJbmRlbnQsIDEwKSkpIHtcbiAgICAgIHdyYXBMaW5lSW5kZW50ID0gcGFyc2VJbnQocGFyYW1zLndyYXBMaW5lSW5kZW50LCAxMClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignd3JhcExpbmVJbmRlbnQgbXVzdCBiZSBhbiBpbnRlZ2VyJylcbiAgICB9XG4gIH1cbiAgaWYgKHBhcmFtcy53cmFwTGluZUluZGVudEJhc2UpIHtcbiAgICB3cmFwTGluZUluZGVudEJhc2UgPSBwYXJhbXMud3JhcExpbmVJbmRlbnRCYXNlXG4gIH1cblxuICBpZiAod3JhcExpbmVJbmRlbnRCYXNlKSB7XG4gICAgaWYgKHdyYXBMaW5lSW5kZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3dyYXBMaW5lSW5kZW50IG11c3QgYmUgc3BlY2lmaWVkIHdoZW4gd3JhcExpbmVJbmRlbnRCYXNlIGlzIHNwZWNpZmllZCcpXG4gICAgfVxuICAgIGlmICh3cmFwTGluZUluZGVudEJhc2UgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgIHdyYXBMaW5lSW5kZW50UGF0ID0gd3JhcExpbmVJbmRlbnRCYXNlXG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygd3JhcExpbmVJbmRlbnRCYXNlID09PSAnc3RyaW5nJykge1xuICAgICAgd3JhcExpbmVJbmRlbnRQYXQgPSBuZXcgUmVnRXhwKGVzY2FwZVJlZ0V4cCh3cmFwTGluZUluZGVudEJhc2UpKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd3cmFwTGluZUluZGVudEJhc2UgbXVzdCBiZSBlaXRoZXIgYSBSZWdFeHAgb2JqZWN0IG9yIGEgc3RyaW5nJylcbiAgICB9XG4gIH0gZWxzZSBpZiAod3JhcExpbmVJbmRlbnQgPiAwKSB7XG4gICAgd3JhcExpbmVJbml0UHJlZml4ID0gbmV3IEFycmF5KHdyYXBMaW5lSW5kZW50ICsgMSkuam9pbignICcpXG4gIH0gZWxzZSBpZiAod3JhcExpbmVJbmRlbnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignd3JhcExpbmVJbmRlbnQgbXVzdCBiZSBub24tbmVnYXRpdmUgd2hlbiBhIGJhc2UgaXMgbm90IHNwZWNpZmllZCcpXG4gIH1cblxuICAvLyBOT1RFOiBGb3IgdGhlIHR3byBSZWdFeHBzIGBza2lwUGF0YCBhbmQgYGxpbmVCcmVha1BhdGAgdGhhdCBjYW4gYmUgc3BlY2lmaWVkXG4gIC8vICAgICAgIGJ5IHRoZSB1c2VyOlxuICAvLyAgICAgICAxLiBXZSByZXF1aXJlIHRoZW0gdG8gYmUgXCJnbG9iYWxcIiwgc28gd2UgaGF2ZSB0byBjb252ZXJ0IHRoZW0gdG8gZ2xvYmFsXG4gIC8vICAgICAgICAgIGlmIHRoZSB1c2VyIHNwZWNpZmllcyBhIG5vbi1nbG9iYWwgcmVnZXguXG4gIC8vICAgICAgIDIuIFdlIGNhbm5vdCBjYWxsIGBzcGxpdCgpYCBvbiB0aGVtLCBiZWNhdXNlIHRoZXkgbWF5IG9yIG1heSBub3QgY29udGFpblxuICAvLyAgICAgICAgICBjYXB0dXJpbmcgcGFyZW50aGVzZXMgd2hpY2ggYWZmZWN0IHRoZSBvdXRwdXQgb2YgYHNwbGl0KClgLlxuXG4gIC8vIFByZWNlZGVuY2U6IFJlZ2V4ID0gU3RyID4gU2NoZW1lXG4gIGlmIChwYXJhbXMuc2tpcFNjaGVtZSkge1xuICAgIGlmIChza2lwU2NoZW1lTWFwW3BhcmFtcy5za2lwU2NoZW1lXSkge1xuICAgICAgc2tpcFNjaGVtZSA9IHBhcmFtcy5za2lwU2NoZW1lXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3NraXBTY2hlbWUgbXVzdCBiZSBvbmUgb2YgXCInICsgT2JqZWN0LmtleXMoc2tpcFNjaGVtZU1hcCkuam9pbignXCIsIFwiJykgKyAnXCInKVxuICAgIH1cbiAgfVxuICBpZiAocGFyYW1zLnNraXApIHtcbiAgICBza2lwID0gcGFyYW1zLnNraXBcbiAgfVxuXG4gIGlmIChza2lwKSB7XG4gICAgaWYgKHNraXAgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgIHNraXBQYXQgPSBza2lwXG4gICAgICBpZiAoIXNraXBQYXQuZ2xvYmFsKSB7XG4gICAgICAgIGZsYWdzID0gJ2cnXG4gICAgICAgIGlmIChza2lwUGF0Lmlnbm9yZUNhc2UpIHsgZmxhZ3MgKz0gJ2knOyB9XG4gICAgICAgIGlmIChza2lwUGF0Lm11bHRpbGluZSkgeyBmbGFncyArPSAnbSc7IH1cbiAgICAgICAgc2tpcFBhdCA9IG5ldyBSZWdFeHAoc2tpcFBhdC5zb3VyY2UsIGZsYWdzKVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNraXAgPT09ICdzdHJpbmcnKSB7XG4gICAgICBza2lwUGF0ID0gbmV3IFJlZ0V4cChlc2NhcGVSZWdFeHAoc2tpcCksICdnJylcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc2tpcCBtdXN0IGJlIGVpdGhlciBhIFJlZ0V4cCBvYmplY3Qgb3IgYSBzdHJpbmcnKVxuICAgIH1cbiAgfVxuICBpZiAoIXNraXBQYXQgJiYgc2tpcFNjaGVtZSkge1xuICAgIHNraXBQYXQgPSBza2lwU2NoZW1lTWFwW3NraXBTY2hlbWVdXG4gIH1cblxuICAvLyBQcmVjZWRlbmNlOlxuICAvLyAtIGZvciBsaW5lQnJlYWtQYXQ6IFJlZ2V4ID4gU2NoZW1lID4gU3RyXG4gIC8vIC0gZm9yIGxpbmVCcmVha1N0cjogU3RyID4gU2NoZW1lID4gUmVnZXhcbiAgaWYgKHBhcmFtcy5saW5lQnJlYWtTY2hlbWUpIHtcbiAgICBpZiAobGluZUJyZWFrU2NoZW1lTWFwW3BhcmFtcy5saW5lQnJlYWtTY2hlbWVdKSB7XG4gICAgICBsaW5lQnJlYWtTY2hlbWUgPSBwYXJhbXMubGluZUJyZWFrU2NoZW1lXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2xpbmVCcmVha1NjaGVtZSBtdXN0IGJlIG9uZSBvZiBcIicgKyBPYmplY3Qua2V5cyhsaW5lQnJlYWtTY2hlbWVNYXApLmpvaW4oJ1wiLCBcIicpICsgJ1wiJylcbiAgICB9XG4gIH1cbiAgaWYgKHBhcmFtcy5saW5lQnJlYWspIHtcbiAgICBsaW5lQnJlYWsgPSBwYXJhbXMubGluZUJyZWFrXG4gIH1cblxuICBpZiAobGluZUJyZWFrU2NoZW1lKSB7XG4gICAgLy8gU3VwcG9ydGVkIHNjaGVtZXM6ICd1bml4JywgJ2RvcycsICdtYWMnLCAnaHRtbCcsICd4aHRtbCdcbiAgICBpdGVtID0gbGluZUJyZWFrU2NoZW1lTWFwW2xpbmVCcmVha1NjaGVtZV1cbiAgICBpZiAoaXRlbSkge1xuICAgICAgbGluZUJyZWFrUGF0ID0gaXRlbVswXVxuICAgICAgbGluZUJyZWFrU3RyID0gaXRlbVsxXVxuICAgIH1cbiAgfVxuICBpZiAobGluZUJyZWFrKSB7XG4gICAgaWYgKGxpbmVCcmVhayBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBpZiAobGluZUJyZWFrLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBsaW5lQnJlYWsgPSBsaW5lQnJlYWtbMF1cbiAgICAgIH0gZWxzZSBpZiAobGluZUJyZWFrLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgIGlmIChsaW5lQnJlYWtbMF0gaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICBsaW5lQnJlYWtQYXQgPSBsaW5lQnJlYWtbMF1cbiAgICAgICAgICBpZiAodHlwZW9mIGxpbmVCcmVha1sxXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGxpbmVCcmVha1N0ciA9IGxpbmVCcmVha1sxXVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChsaW5lQnJlYWtbMV0gaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICBsaW5lQnJlYWtQYXQgPSBsaW5lQnJlYWtbMV1cbiAgICAgICAgICBpZiAodHlwZW9mIGxpbmVCcmVha1swXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGxpbmVCcmVha1N0ciA9IGxpbmVCcmVha1swXVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGluZUJyZWFrWzBdID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgbGluZUJyZWFrWzFdID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGxpbmVCcmVha1BhdCA9IG5ldyBSZWdFeHAoZXNjYXBlUmVnRXhwKGxpbmVCcmVha1swXSksICdnJylcbiAgICAgICAgICBsaW5lQnJlYWtTdHIgPSBsaW5lQnJlYWtbMV1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsaW5lQnJlYWsgPSBsaW5lQnJlYWtbMF1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGxpbmVCcmVhayA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGxpbmVCcmVha1N0ciA9IGxpbmVCcmVha1xuICAgICAgaWYgKCFsaW5lQnJlYWtQYXQpIHtcbiAgICAgICAgbGluZUJyZWFrUGF0ID0gbmV3IFJlZ0V4cChlc2NhcGVSZWdFeHAobGluZUJyZWFrKSwgJ2cnKVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobGluZUJyZWFrIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICBsaW5lQnJlYWtQYXQgPSBsaW5lQnJlYWtcbiAgICB9IGVsc2UgaWYgKCEobGluZUJyZWFrIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaW5lQnJlYWsgbXVzdCBiZSBhIFJlZ0V4cCBvYmplY3QsIGEgc3RyaW5nLCBvciBhbiBhcnJheSBjb25zaXN0ZWQgb2YgYSBSZWdFeHAgb2JqZWN0IGFuZCBhIHN0cmluZycpXG4gICAgfVxuICB9XG4gIC8vIE9ubHkgYXNzaWduIGRlZmF1bHRzIHdoZW4gYGxpbmVCcmVha1BhdGAgaXMgbm90IGFzc2lnbmVkLlxuICAvLyBTbyBpZiBgcGFyYW1zLmxpbmVCcmVha2AgaXMgYSBSZWdFeHAsIHdlIGRvbid0IGhhdmUgYSB2YWx1ZSBpbiBgbGluZUJyZWFrU3RyYFxuICAvLyB5ZXQuIFdlIHdpbGwgdHJ5IHRvIGdldCB0aGUgdmFsdWUgZnJvbSB0aGUgaW5wdXQgc3RyaW5nLCBhbmQgaWYgZmFpbGVkLCB3ZVxuICAvLyB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbi5cbiAgaWYgKCFsaW5lQnJlYWtQYXQpIHtcbiAgICBsaW5lQnJlYWtQYXQgPSAvXFxuL2dcbiAgICBsaW5lQnJlYWtTdHIgPSAnXFxuJ1xuICB9XG5cbiAgLy8gQ3JlYXRlIGBtdWx0aUxpbmVCcmVha1BhdGAgYmFzZWQgb24gYGxpbmVCcmVha1BhdGAsIHRoYXQgbWF0Y2hlcyBzdHJpbmdzXG4gIC8vIGNvbnNpc3RlZCBvZiBvbmUgb3IgbW9yZSBsaW5lIGJyZWFrcyBhbmQgemVybyBvciBtb3JlIHdoaXRlc3BhY2VzLlxuICAvLyBBbHNvIGNvbnZlcnQgYGxpbmVCcmVha1BhdGAgdG8gZ2xvYmFsIGlmIG5vdCBhbHJlYWR5IHNvLlxuICBmbGFncyA9ICdnJ1xuICBpZiAobGluZUJyZWFrUGF0Lmlnbm9yZUNhc2UpIHsgZmxhZ3MgKz0gJ2knOyB9XG4gIGlmIChsaW5lQnJlYWtQYXQubXVsdGlsaW5lKSB7IGZsYWdzICs9ICdtJzsgfVxuICBtdWx0aUxpbmVCcmVha1BhdCA9IG5ldyBSZWdFeHAoJ1xcXFxzKig/OicgKyBsaW5lQnJlYWtQYXQuc291cmNlICsgJykoPzonICtcbiAgICBsaW5lQnJlYWtQYXQuc291cmNlICsgJ3xcXFxccykqJywgZmxhZ3MpXG4gIGlmICghbGluZUJyZWFrUGF0Lmdsb2JhbCkge1xuICAgIGxpbmVCcmVha1BhdCA9IG5ldyBSZWdFeHAobGluZUJyZWFrUGF0LnNvdXJjZSwgZmxhZ3MpXG4gIH1cblxuICAvLyBJbml0aWFsaXplIG90aGVyIHVzZWZ1bCB2YXJpYWJsZXMuXG4gIHZhciByZSA9IG1vZGUgPT09ICdoYXJkJyA/IC9cXGIvIDogLyhcXFMrXFxzKykvXG4gIHZhciBwcmVmaXggPSBuZXcgQXJyYXkoc3RhcnQgKyAxKS5qb2luKCcgJylcbiAgdmFyIHdzU3RyaXAgPSAod2hpdGVzcGFjZSA9PT0gJ2RlZmF1bHQnIHx8IHdoaXRlc3BhY2UgPT09ICdjb2xsYXBzZScpLFxuICAgIHdzQ29sbGFwc2UgPSAod2hpdGVzcGFjZSA9PT0gJ2NvbGxhcHNlJyksXG4gICAgd3NMaW5lID0gKHdoaXRlc3BhY2UgPT09ICdsaW5lJyksXG4gICAgd3NBbGwgPSAod2hpdGVzcGFjZSA9PT0gJ2FsbCcpXG4gIHZhciB0YWJQYXQgPSAvXFx0L2csXG4gICAgY29sbGFwc2VQYXQgPSAvICArL2csXG4gICAgcFBhdCA9IC9eXFxzKy8sXG4gICAgdFBhdCA9IC9cXHMrJC8sXG4gICAgbm9uV3NQYXQgPSAvXFxTLyxcbiAgICB3c1BhdCA9IC9cXHMvXG4gIHZhciB3cmFwTGVuID0gc3RvcCAtIHN0YXJ0XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgdGV4dCA9IHRleHQudG9TdHJpbmcoKS5yZXBsYWNlKHRhYlBhdCwgdGFiUmVwbClcblxuICAgIHZhciBtYXRjaFxuICAgIGlmICghbGluZUJyZWFrU3RyKSB7XG4gICAgICAvLyBUcnkgdG8gZ2V0IGxpbmVCcmVha1N0ciBmcm9tIGB0ZXh0YFxuICAgICAgbGluZUJyZWFrUGF0Lmxhc3RJbmRleCA9IDBcbiAgICAgIG1hdGNoID0gbGluZUJyZWFrUGF0LmV4ZWModGV4dClcbiAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICBsaW5lQnJlYWtTdHIgPSBtYXRjaFswXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTGluZSBicmVhayBzdHJpbmcgZm9yIHRoZSBvdXRwdXQgbm90IHNwZWNpZmllZCcpXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGV4dCAtPiBibG9ja3M7IGVhY2ggYmxvYyAtPiBzZWdtZW50czsgZWFjaCBzZWdtZW50IC0+IGNodW5rc1xuICAgIHZhciBibG9ja3MsIGJhc2UgPSAwXG4gICAgdmFyIG1vLCBhcnIsIGIsIHJlc1xuICAgIC8vIFNwbGl0IGB0ZXh0YCBieSBsaW5lIGJyZWFrcy5cbiAgICBibG9ja3MgPSBbXVxuICAgIG11bHRpTGluZUJyZWFrUGF0Lmxhc3RJbmRleCA9IDBcbiAgICBtYXRjaCA9IG11bHRpTGluZUJyZWFrUGF0LmV4ZWModGV4dClcbiAgICB3aGlsZShtYXRjaCkge1xuICAgICAgYmxvY2tzLnB1c2godGV4dC5zdWJzdHJpbmcoYmFzZSwgbWF0Y2guaW5kZXgpKVxuXG4gICAgICBpZiAocmVzcGVjdExpbmVCcmVha3MgIT09ICdub25lJykge1xuICAgICAgICBhcnIgPSBbXVxuICAgICAgICBiID0gMFxuICAgICAgICBsaW5lQnJlYWtQYXQubGFzdEluZGV4ID0gMFxuICAgICAgICBtbyA9IGxpbmVCcmVha1BhdC5leGVjKG1hdGNoWzBdKVxuICAgICAgICB3aGlsZShtbykge1xuICAgICAgICAgIGFyci5wdXNoKG1hdGNoWzBdLnN1YnN0cmluZyhiLCBtby5pbmRleCkpXG4gICAgICAgICAgYiA9IG1vLmluZGV4ICsgbW9bMF0ubGVuZ3RoXG4gICAgICAgICAgbW8gPSBsaW5lQnJlYWtQYXQuZXhlYyhtYXRjaFswXSlcbiAgICAgICAgfVxuICAgICAgICBhcnIucHVzaChtYXRjaFswXS5zdWJzdHJpbmcoYikpXG4gICAgICAgIGJsb2Nrcy5wdXNoKHt0eXBlOiAnYnJlYWsnLCBicmVha3M6IGFycn0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTdHJpcCBsaW5lIGJyZWFrcyBhbmQgaW5zZXJ0IHNwYWNlcyB3aGVuIG5lY2Vzc2FyeS5cbiAgICAgICAgaWYgKHdzQ29sbGFwc2UpIHtcbiAgICAgICAgICByZXMgPSAnICdcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXMgPSBtYXRjaFswXS5yZXBsYWNlKGxpbmVCcmVha1BhdCwgJycpXG4gICAgICAgIH1cbiAgICAgICAgYmxvY2tzLnB1c2goe3R5cGU6ICdicmVhaycsIHJlbWFpbmluZzogcmVzfSlcbiAgICAgIH1cblxuICAgICAgYmFzZSA9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoXG4gICAgICBtYXRjaCA9IG11bHRpTGluZUJyZWFrUGF0LmV4ZWModGV4dClcbiAgICB9XG4gICAgYmxvY2tzLnB1c2godGV4dC5zdWJzdHJpbmcoYmFzZSkpXG5cbiAgICB2YXIgaSwgaiwga1xuICAgIHZhciBzZWdtZW50c1xuICAgIGlmIChza2lwUGF0KSB7XG4gICAgICBzZWdtZW50cyA9IFtdXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBibG9jID0gYmxvY2tzW2ldXG4gICAgICAgIGlmICh0eXBlb2YgYmxvYyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAvLyBUaGlzIGlzIGFuIG9iamVjdC5cbiAgICAgICAgICBzZWdtZW50cy5wdXNoKGJsb2MpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYmFzZSA9IDBcbiAgICAgICAgICBza2lwUGF0Lmxhc3RJbmRleCA9IDBcbiAgICAgICAgICBtYXRjaCA9IHNraXBQYXQuZXhlYyhibG9jKVxuICAgICAgICAgIHdoaWxlKG1hdGNoKSB7XG4gICAgICAgICAgICBzZWdtZW50cy5wdXNoKGJsb2Muc3Vic3RyaW5nKGJhc2UsIG1hdGNoLmluZGV4KSlcbiAgICAgICAgICAgIHNlZ21lbnRzLnB1c2goe3R5cGU6ICdza2lwJywgdmFsdWU6IG1hdGNoWzBdfSlcbiAgICAgICAgICAgIGJhc2UgPSBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aFxuICAgICAgICAgICAgbWF0Y2ggPSBza2lwUGF0LmV4ZWMoYmxvYylcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VnbWVudHMucHVzaChibG9jLnN1YnN0cmluZyhiYXNlKSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzZWdtZW50cyA9IGJsb2Nrc1xuICAgIH1cblxuICAgIHZhciBjaHVua3MgPSBbXVxuICAgIGZvciAoaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHNlZ21lbnQgPSBzZWdtZW50c1tpXVxuICAgICAgaWYgKHR5cGVvZiBzZWdtZW50ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAvLyBUaGlzIGlzIGFuIG9iamVjdC5cbiAgICAgICAgY2h1bmtzLnB1c2goc2VnbWVudClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh3c0NvbGxhcHNlKSB7XG4gICAgICAgICAgc2VnbWVudCA9IHNlZ21lbnQucmVwbGFjZShjb2xsYXBzZVBhdCwgJyAnKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHBhcnRzID0gc2VnbWVudC5zcGxpdChyZSksXG4gICAgICAgICAgYWNjID0gW11cblxuICAgICAgICBmb3IgKGogPSAwOyBqIDwgcGFydHMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICB2YXIgeCA9IHBhcnRzW2pdXG4gICAgICAgICAgaWYgKG1vZGUgPT09ICdoYXJkJykge1xuICAgICAgICAgICAgZm9yIChrID0gMDsgayA8IHgubGVuZ3RoOyBrICs9IHdyYXBMZW4pIHtcbiAgICAgICAgICAgICAgYWNjLnB1c2goeC5zbGljZShrLCBrICsgd3JhcExlbikpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHsgYWNjLnB1c2goeCk7IH1cbiAgICAgICAgfVxuICAgICAgICBjaHVua3MgPSBjaHVua3MuY29uY2F0KGFjYylcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgY3VyTGluZSA9IDAsXG4gICAgICBjdXJMaW5lTGVuZ3RoID0gc3RhcnQgKyBwcmVzZXJ2ZWRMaW5lUHJlZml4Lmxlbmd0aCxcbiAgICAgIGxpbmVzID0gWyBwcmVmaXggKyBwcmVzZXJ2ZWRMaW5lUHJlZml4IF0sXG4gICAgICAvLyBIb2xkcyB0aGUgXCJyZWFsIGxlbmd0aFwiIChleGNsdWRpbmcgdHJhaWxpbmcgd2hpdGVzcGFjZXMpIG9mIHRoZVxuICAgICAgLy8gY3VycmVudCBsaW5lIGlmIGl0IGV4Y2VlZHMgYHN0b3BgLCBvdGhlcndpc2UgMC5cbiAgICAgIC8vIE9OTFkgVVNFRCB3aGVuIGB3c0FsbGAgaXMgdHJ1ZSwgaW4gYGZpbmlzaE9mZkN1ckxpbmUoKWAuXG4gICAgICBidWxnZSA9IDAsXG4gICAgICAvLyBgY2xlYW5MaW5lYCBpcyB0cnVlIGlmZiB3ZSBhcmUgYXQgdGhlIGJlZ2lubmluZyBvZiBhbiBvdXRwdXQgbGluZS4gQnlcbiAgICAgIC8vIFwiYmVnaW5uaW5nXCIgd2UgbWVhbiBpdCBkb2Vzbid0IGNvbnRhaW4gYW55IG5vbi13aGl0ZXNwYWNlIGNoYXIgeWV0LlxuICAgICAgLy8gQnV0IGl0cyBgY3VyTGluZUxlbmd0aGAgY2FuIGJlIGdyZWF0ZXIgdGhhbiBgc3RhcnRgLCBvciBldmVuIHBvc3NpYmx5XG4gICAgICAvLyBiZSBncmVhdGVyIHRoYW4gYHN0b3BgLCBpZiBgd3NTdHJpcGAgaXMgZmFsc2UuXG4gICAgICAvL1xuICAgICAgLy8gTm90ZSB0aGF0IGEgXCJjbGVhblwiIGxpbmUgY2FuIHN0aWxsIGNvbnRhaW4gc2tpcCBzdHJpbmdzLCBpbiBhZGRpdGlvblxuICAgICAgLy8gdG8gd2hpdGVzcGFjZXMuXG4gICAgICAvL1xuICAgICAgLy8gVGhpcyB2YXJpYWJsZSBpcyB1c2VkIHRvIGFsbG93IHVzIHN0cmlwIHByZWNlZGluZyB3aGl0ZXNwYWNlcyB3aGVuXG4gICAgICAvLyBgd3NTdHJpcGAgaXMgdHJ1ZSwgb3IgYHdzTGluZWAgaXMgdHJ1ZSBhbmQgYHByZXNlcnZlZExpbmVgIGlzIGZhbHNlLlxuICAgICAgY2xlYW5MaW5lID0gdHJ1ZSxcbiAgICAgIC8vIGBwcmVzZXJ2ZWRMaW5lYCBpcyB0cnVlIGlmZiB3ZSBhcmUgaW4gYSBwcmVzZXJ2ZWQgaW5wdXQgbGluZS5cbiAgICAgIC8vXG4gICAgICAvLyBJdCdzIHVzZWQgd2hlbiBgd3NMaW5lYCBpcyB0cnVlIHRvIChjb21iaW5lZCB3aXRoIGBjbGVhbkxpbmVgKSBkZWNpZGVcbiAgICAgIC8vIHdoZXRoZXIgYSB3aGl0ZXNwYWNlIGlzIGF0IHRoZSBiZWdpbm5pbmcgb2YgYSBwcmVzZXJ2ZWQgaW5wdXQgbGluZSBhbmRcbiAgICAgIC8vIHNob3VsZCBub3QgYmUgc3RyaXBwZWQuXG4gICAgICBwcmVzZXJ2ZWRMaW5lID0gdHJ1ZSxcbiAgICAgIC8vIFRoZSBjdXJyZW50IGluZGVudCBwcmVmaXggZm9yIHdyYXBwZWQgbGluZXMuXG4gICAgICB3cmFwTGluZVByZWZpeCA9IHdyYXBMaW5lSW5pdFByZWZpeCxcbiAgICAgIHJlbW5hbnRcblxuICAgIC8vIEFsd2F5cyByZXR1cm5zICcnIGlmIGBiZWZvcmVIYXJkQnJlYWtgIGlzIHRydWUuXG4gICAgLy9cbiAgICAvLyBBc3N1bXB0aW9uOiBFYWNoIGNhbGwgb2YgdGhpcyBmdW5jdGlvbiBpcyBhbHdheXMgZm9sbG93ZWQgYnkgYSBgbGluZXMucHVzaCgpYCBjYWxsLlxuICAgIC8vXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBjYW4gY2hhbmdlIHRoZSBzdGF0dXMgb2YgYGNsZWFuTGluZWAsIGJ1dCB3ZSBkb24ndCBtb2RpZnkgdGhlIHZhbHVlIG9mXG4gICAgLy8gYGNsZWFuTGluZWAgaW4gdGhpcyBmdW5jdGlvbi4gSXQncyBmaW5lIGJlY2F1c2UgYGNsZWFuTGluZWAgd2lsbCBiZSBzZXQgdG8gdGhlIGNvcnJlY3RcbiAgICAvLyB2YWx1ZSBhZnRlciB0aGUgYGxpbmVzLnB1c2goKWAgY2FsbCBmb2xsb3dpbmcgdGhpcyBmdW5jdGlvbiBjYWxsLiBXZSBhbHNvIGRvbid0IHVwZGF0ZVxuICAgIC8vIGBjdXJMaW5lTGVuZ3RoYCB3aGVuIHB1c2hpbmcgYSBuZXcgbGluZSBhbmQgaXQncyBzYWZlIGZvciB0aGUgc2FtZSByZWFzb24uXG4gICAgZnVuY3Rpb24gZmluaXNoT2ZmQ3VyTGluZSAoYmVmb3JlSGFyZEJyZWFrKSB7XG4gICAgICB2YXIgc3RyID0gbGluZXNbY3VyTGluZV0sXG4gICAgICAgIGlkeCwgbG4sIHJCYXNlXG5cbiAgICAgIGlmICghd3NBbGwpIHtcbiAgICAgICAgLy8gU3RyaXAgYWxsIHRyYWlsaW5nIHdoaXRlc3BhY2VzIHBhc3QgYHN0YXJ0YC5cbiAgICAgICAgaWR4ID0gc3RyLmxlbmd0aCAtIDFcbiAgICAgICAgd2hpbGUgKGlkeCA+PSBzdGFydCAmJiBzdHJbaWR4XSA9PT0gJyAnKSB7IGlkeC0tOyB9XG4gICAgICAgIHdoaWxlIChpZHggPj0gc3RhcnQgJiYgd3NQYXQudGVzdChzdHJbaWR4XSkpIHsgaWR4LS07IH1cbiAgICAgICAgaWR4KytcblxuICAgICAgICBpZiAoaWR4ICE9PSBzdHIubGVuZ3RoKSB7XG4gICAgICAgICAgbGluZXNbY3VyTGluZV0gPSBzdHIuc3Vic3RyaW5nKDAsIGlkeClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcmVzZXJ2ZWRMaW5lICYmIGNsZWFuTGluZSAmJiB3c0xpbmUgJiYgY3VyTGluZUxlbmd0aCA+IHN0b3ApIHtcbiAgICAgICAgICAvLyBBZGQgdGhlIHJlbW5hbnRzIHRvIHRoZSBuZXh0IGxpbmUsIGp1c3QgbGlrZSB3aGVuIGB3c0FsbGAgaXMgdHJ1ZS5cbiAgICAgICAgICByQmFzZSA9IHN0ci5sZW5ndGggLSAoY3VyTGluZUxlbmd0aCAtIHN0b3ApXG4gICAgICAgICAgaWYgKHJCYXNlIDwgaWR4KSB7XG4gICAgICAgICAgICAvLyBXZSBkaWRuJ3QgcmVhY2ggYHN0b3BgIHdoZW4gc3RyaXBwaW5nIGR1ZSB0byBhIGJ1bGdlLlxuICAgICAgICAgICAgckJhc2UgPSBpZHhcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFN0cmlwIHRyYWlsaW5nIHdoaXRlc3BhY2VzIGV4Y2VlZGluZyBzdG9wLlxuICAgICAgICBpZiAoY3VyTGluZUxlbmd0aCA+IHN0b3ApIHtcbiAgICAgICAgICBidWxnZSA9IGJ1bGdlIHx8IHN0b3BcbiAgICAgICAgICByQmFzZSA9IHN0ci5sZW5ndGggLSAoY3VyTGluZUxlbmd0aCAtIGJ1bGdlKVxuICAgICAgICAgIGxpbmVzW2N1ckxpbmVdID0gc3RyLnN1YnN0cmluZygwLCByQmFzZSlcbiAgICAgICAgfVxuICAgICAgICBidWxnZSA9IDBcbiAgICAgIH1cblxuICAgICAgLy8gQnVnOiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvZiBgd3JhcExpbmVJbmRlbnRgIGlzIGJ1Z2d5OiB3ZSBhcmUgbm90XG4gICAgICAvLyB0YWtpbmcgdGhlIGV4dHJhIHNwYWNlIG9jY3VwaWVkIGJ5IHRoZSBhZGRpdGlvbmFsIGluZGVudGF0aW9uIGludG8gYWNjb3VudFxuICAgICAgLy8gd2hlbiB3cmFwcGluZyB0aGUgbGluZS4gRm9yIGV4YW1wbGUsIGluIFwiaGFyZFwiIG1vZGUsIHdlIHNob3VsZCBoYXJkLXdyYXBcbiAgICAgIC8vIGxvbmcgd29yZHMgYXQgYHdyYXBMZW4gLSB3cmFwTGluZVByZWZpeC5sZW5ndGhgIGluc3RlYWQgb2YgYHdyYXBMZW5gXG4gICAgICAvLyBhbmQgcmVtbmFudHMgc2hvdWxkIGFsc28gYmUgd3JhcHBlZCBhdCBgd3JhcExlbiAtIHdyYXBMaW5lUHJlZml4Lmxlbmd0aGAuXG4gICAgICBpZiAocHJlc2VydmVkTGluZSkge1xuICAgICAgICAvLyBUaGlzIGlzIGEgcHJlc2VydmVkIGxpbmUsIGFuZCB0aGUgbmV4dCBvdXRwdXQgbGluZSBpc24ndCBhXG4gICAgICAgIC8vIHByZXNlcnZlZCBsaW5lLlxuICAgICAgICBwcmVzZXJ2ZWRMaW5lID0gZmFsc2VcbiAgICAgICAgaWYgKHdyYXBMaW5lSW5kZW50UGF0KSB7XG4gICAgICAgICAgaWR4ID0gbGluZXNbY3VyTGluZV0uc3Vic3RyaW5nKHN0YXJ0KS5zZWFyY2god3JhcExpbmVJbmRlbnRQYXQpXG4gICAgICAgICAgaWYgKGlkeCA+PSAwICYmIGlkeCArIHdyYXBMaW5lSW5kZW50ID4gMCkge1xuICAgICAgICAgICAgd3JhcExpbmVQcmVmaXggPSBuZXcgQXJyYXkoaWR4ICsgd3JhcExpbmVJbmRlbnQgKyAxKS5qb2luKCcgJylcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3JhcExpbmVQcmVmaXggPSAnJ1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTb21lIHJlbW5hbnRzIGFyZSBsZWZ0IHRvIHRoZSBuZXh0IGxpbmUuXG4gICAgICBpZiAockJhc2UpIHtcbiAgICAgICAgd2hpbGUgKHJCYXNlICsgd3JhcExlbiA8IHN0ci5sZW5ndGgpIHtcbiAgICAgICAgICBpZiAod3NBbGwpIHtcbiAgICAgICAgICAgIGxuID0gc3RyLnN1YnN0cmluZyhyQmFzZSwgckJhc2UgKyB3cmFwTGVuKVxuICAgICAgICAgICAgbGluZXMucHVzaChwcmVmaXggKyB3cmFwTGluZVByZWZpeCArIGxuKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsaW5lcy5wdXNoKHByZWZpeCArIHdyYXBMaW5lUHJlZml4KVxuICAgICAgICAgIH1cbiAgICAgICAgICByQmFzZSArPSB3cmFwTGVuXG4gICAgICAgICAgY3VyTGluZSsrXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJlZm9yZUhhcmRCcmVhaykge1xuICAgICAgICAgIGlmICh3c0FsbCkge1xuICAgICAgICAgICAgbG4gPSBzdHIuc3Vic3RyaW5nKHJCYXNlKVxuICAgICAgICAgICAgbGluZXMucHVzaChwcmVmaXggKyB3cmFwTGluZVByZWZpeCArIGxuKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsaW5lcy5wdXNoKHByZWZpeCArIHdyYXBMaW5lUHJlZml4KVxuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJMaW5lKytcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsbiA9IHN0ci5zdWJzdHJpbmcockJhc2UpXG4gICAgICAgICAgcmV0dXJuIHdyYXBMaW5lUHJlZml4ICsgbG5cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gJydcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgY2h1bmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY2h1bmsgPSBjaHVua3NbaV1cblxuICAgICAgaWYgKGNodW5rID09PSAnJykgeyBjb250aW51ZTsgfVxuXG4gICAgICBpZiAodHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAoY2h1bmsudHlwZSA9PT0gJ2JyZWFrJykge1xuICAgICAgICAgIC8vIFRoaXMgaXMgb25lIG9yIG1vcmUgbGluZSBicmVha3MuXG4gICAgICAgICAgLy8gRWFjaCBlbnRyeSBpbiBgYnJlYWtzYCBpcyBqdXN0IHplcm8gb3IgbW9yZSB3aGl0ZXNwYWNlcy5cbiAgICAgICAgICBpZiAocmVzcGVjdExpbmVCcmVha3MgIT09ICdub25lJykge1xuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IGlmIGB3aGl0ZXNwYWNlYCBpcyBcImNvbGxhcHNlXCIsIHdlIHN0aWxsIG5lZWRcbiAgICAgICAgICAgIC8vIHRvIGNvbGxhcHNlIHdoaXRlc3BhY2VzIGluIGVudHJpZXMgb2YgYGJyZWFrc2AuXG4gICAgICAgICAgICB2YXIgYnJlYWtzID0gY2h1bmsuYnJlYWtzXG4gICAgICAgICAgICB2YXIgbnVtID0gYnJlYWtzLmxlbmd0aCAtIDFcblxuICAgICAgICAgICAgaWYgKHJlc3BlY3RMaW5lQnJlYWtzID09PSAncycpIHtcbiAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgbW9zdCBjb21wbGV4IHNjZW5hcmlvLiBXZSBoYXZlIHRvIGNoZWNrXG4gICAgICAgICAgICAgIC8vIHRoZSBsaW5lIGJyZWFrcyBvbmUgYnkgb25lLlxuICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbnVtOyBqKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoYnJlYWtzW2ogKyAxXS5sZW5ndGggPCByZXNwZWN0TnVtKSB7XG4gICAgICAgICAgICAgICAgICAvLyBUaGlzIGxpbmUgYnJlYWsgc2hvdWxkIGJlIHN0cmlwcGVkLlxuICAgICAgICAgICAgICAgICAgaWYgKHdzQ29sbGFwc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtzW2ogKyAxXSA9ICcgJ1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtzW2ogKyAxXSA9IGJyZWFrc1tqXSArIGJyZWFrc1tqICsgMV1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gVGhpcyBsaW5lIGJyZWFrIHNob3VsZCBiZSBwcmVzZXJ2ZWQuXG4gICAgICAgICAgICAgICAgICAvLyBGaXJzdCBmaW5pc2ggb2ZmIHRoZSBjdXJyZW50IGxpbmUuXG4gICAgICAgICAgICAgICAgICBpZiAod3NBbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbGluZXNbY3VyTGluZV0gKz0gYnJlYWtzW2pdXG4gICAgICAgICAgICAgICAgICAgIGN1ckxpbmVMZW5ndGggKz0gYnJlYWtzW2pdLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgZmluaXNoT2ZmQ3VyTGluZSh0cnVlKVxuXG4gICAgICAgICAgICAgICAgICBsaW5lcy5wdXNoKHByZWZpeCArIHByZXNlcnZlZExpbmVQcmVmaXgpXG4gICAgICAgICAgICAgICAgICBjdXJMaW5lKytcbiAgICAgICAgICAgICAgICAgIGN1ckxpbmVMZW5ndGggPSBzdGFydCArIHByZXNlcnZlZExpbmVQcmVmaXgubGVuZ3RoXG5cbiAgICAgICAgICAgICAgICAgIHByZXNlcnZlZExpbmUgPSBjbGVhbkxpbmUgPSB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIFdlIGFyZSBhZGRpbmcgdG8gZWl0aGVyIHRoZSBleGlzdGluZyBsaW5lIChpZiBubyBsaW5lIGJyZWFrXG4gICAgICAgICAgICAgIC8vIGlzIHF1YWxpZmllZCBmb3IgcHJlc2VydmFuY2UpIG9yIGEgXCJuZXdcIiBsaW5lLlxuICAgICAgICAgICAgICBpZiAoIWNsZWFuTGluZSB8fCB3c0FsbCB8fCAod3NMaW5lICYmIHByZXNlcnZlZExpbmUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHdzQ29sbGFwc2UgfHwgKCFjbGVhbkxpbmUgJiYgYnJlYWtzW251bV0gPT09ICcnKSkge1xuICAgICAgICAgICAgICAgICAgYnJlYWtzW251bV0gPSAnICdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGluZXNbY3VyTGluZV0gKz0gYnJlYWtzW251bV1cbiAgICAgICAgICAgICAgICBjdXJMaW5lTGVuZ3RoICs9IGJyZWFrc1tudW1dLmxlbmd0aFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3BlY3RMaW5lQnJlYWtzID09PSAnbScgJiYgbnVtIDwgcmVzcGVjdE51bSkge1xuICAgICAgICAgICAgICAvLyBUaGVzZSBsaW5lIGJyZWFrcyBzaG91bGQgYmUgc3RyaXBwZWQuXG4gICAgICAgICAgICAgIGlmICghY2xlYW5MaW5lIHx8IHdzQWxsIHx8ICh3c0xpbmUgJiYgcHJlc2VydmVkTGluZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAod3NDb2xsYXBzZSkge1xuICAgICAgICAgICAgICAgICAgY2h1bmsgPSAnICdcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgY2h1bmsgPSBicmVha3Muam9pbignJylcbiAgICAgICAgICAgICAgICAgIGlmICghY2xlYW5MaW5lICYmIGNodW5rID09PSAnJykge1xuICAgICAgICAgICAgICAgICAgICBjaHVuayA9ICcgJ1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaW5lc1tjdXJMaW5lXSArPSBjaHVua1xuICAgICAgICAgICAgICAgIGN1ckxpbmVMZW5ndGggKz0gY2h1bmsubGVuZ3RoXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7IC8vICdhbGwnIHx8ICgnbScgJiYgbnVtID49IHJlc3BlY3ROdW0pXG4gICAgICAgICAgICAgIC8vIFRoZXNlIGxpbmUgYnJlYWtzIHNob3VsZCBiZSBwcmVzZXJ2ZWQuXG4gICAgICAgICAgICAgIGlmICh3c1N0cmlwKSB7XG4gICAgICAgICAgICAgICAgLy8gRmluaXNoIG9mZiB0aGUgY3VycmVudCBsaW5lLlxuICAgICAgICAgICAgICAgIGZpbmlzaE9mZkN1ckxpbmUodHJ1ZSlcblxuICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBudW07IGorKykge1xuICAgICAgICAgICAgICAgICAgbGluZXMucHVzaChwcmVmaXggKyBwcmVzZXJ2ZWRMaW5lUHJlZml4KVxuICAgICAgICAgICAgICAgICAgY3VyTGluZSsrXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY3VyTGluZUxlbmd0aCA9IHN0YXJ0ICsgcHJlc2VydmVkTGluZVByZWZpeC5sZW5ndGhcbiAgICAgICAgICAgICAgICBwcmVzZXJ2ZWRMaW5lID0gY2xlYW5MaW5lID0gdHJ1ZVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh3c0FsbCB8fCAocHJlc2VydmVkTGluZSAmJiBjbGVhbkxpbmUpKSB7XG4gICAgICAgICAgICAgICAgICBsaW5lc1tjdXJMaW5lXSArPSBicmVha3NbMF1cbiAgICAgICAgICAgICAgICAgIGN1ckxpbmVMZW5ndGggKz0gYnJlYWtzWzBdLmxlbmd0aFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBudW07IGorKykge1xuICAgICAgICAgICAgICAgICAgLy8gRmluaXNoIG9mZiB0aGUgY3VycmVudCBsaW5lLlxuICAgICAgICAgICAgICAgICAgZmluaXNoT2ZmQ3VyTGluZSh0cnVlKVxuXG4gICAgICAgICAgICAgICAgICBsaW5lcy5wdXNoKHByZWZpeCArIHByZXNlcnZlZExpbmVQcmVmaXggKyBicmVha3NbaiArIDFdKVxuICAgICAgICAgICAgICAgICAgY3VyTGluZSsrXG4gICAgICAgICAgICAgICAgICBjdXJMaW5lTGVuZ3RoID0gc3RhcnQgKyBwcmVzZXJ2ZWRMaW5lUHJlZml4Lmxlbmd0aCArIGJyZWFrc1tqICsgMV0ubGVuZ3RoXG5cbiAgICAgICAgICAgICAgICAgIHByZXNlcnZlZExpbmUgPSBjbGVhbkxpbmUgPSB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoZXNlIGxpbmUgYnJlYWtzIHNob3VsZCBiZSBzdHJpcHBlZC5cbiAgICAgICAgICAgIGlmICghY2xlYW5MaW5lIHx8IHdzQWxsIHx8ICh3c0xpbmUgJiYgcHJlc2VydmVkTGluZSkpIHtcbiAgICAgICAgICAgICAgY2h1bmsgPSBjaHVuay5yZW1haW5pbmdcblxuICAgICAgICAgICAgICAvLyBCdWc6IElmIGB3c0FsbGAgaXMgdHJ1ZSwgYGNsZWFuTGluZWAgaXMgZmFsc2UsIGFuZCBgY2h1bmtgXG4gICAgICAgICAgICAgIC8vIGlzICcnLCB3ZSBpbnNlcnQgYSBzcGFjZSB0byByZXBsYWNlIHRoZSBsaW5lIGJyZWFrLiBUaGlzXG4gICAgICAgICAgICAgIC8vIHNwYWNlIHdpbGwgYmUgcHJlc2VydmVkIGV2ZW4gaWYgd2UgYXJlIGF0IHRoZSBlbmQgb2YgYW5cbiAgICAgICAgICAgICAgLy8gb3V0cHV0IGxpbmUsIHdoaWNoIGlzIHdyb25nIGJlaGF2aW9yLiBIb3dldmVyLCBJJ20gbm90XG4gICAgICAgICAgICAgIC8vIHN1cmUgaXQncyB3b3J0aCBpdCB0byBmaXggdGhpcyBlZGdlIGNhc2UuXG4gICAgICAgICAgICAgIGlmICh3c0NvbGxhcHNlIHx8ICghY2xlYW5MaW5lICYmIGNodW5rID09PSAnJykpIHtcbiAgICAgICAgICAgICAgICBjaHVuayA9ICcgJ1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGxpbmVzW2N1ckxpbmVdICs9IGNodW5rXG4gICAgICAgICAgICAgIGN1ckxpbmVMZW5ndGggKz0gY2h1bmsubGVuZ3RoXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGNodW5rLnR5cGUgPT09ICdza2lwJykge1xuICAgICAgICAgIC8vIFRoaXMgaXMgYSBza2lwIHN0cmluZy5cbiAgICAgICAgICAvLyBBc3N1bXB0aW9uOiBza2lwIHN0cmluZ3MgZG9uJ3QgZW5kIHdpdGggd2hpdGVzcGFjZXMuXG4gICAgICAgICAgaWYgKGN1ckxpbmVMZW5ndGggPiBzdG9wKSB7XG4gICAgICAgICAgICByZW1uYW50ID0gZmluaXNoT2ZmQ3VyTGluZShmYWxzZSlcblxuICAgICAgICAgICAgbGluZXMucHVzaChwcmVmaXggKyB3cmFwTGluZVByZWZpeClcbiAgICAgICAgICAgIGN1ckxpbmUrK1xuICAgICAgICAgICAgY3VyTGluZUxlbmd0aCA9IHN0YXJ0ICsgd3JhcExpbmVQcmVmaXgubGVuZ3RoXG5cbiAgICAgICAgICAgIGlmIChyZW1uYW50KSB7XG4gICAgICAgICAgICAgIGxpbmVzW2N1ckxpbmVdICs9IHJlbW5hbnRcbiAgICAgICAgICAgICAgY3VyTGluZUxlbmd0aCArPSByZW1uYW50Lmxlbmd0aFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjbGVhbkxpbmUgPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICAgIGxpbmVzW2N1ckxpbmVdICs9IGNodW5rLnZhbHVlXG4gICAgICAgIH1cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgdmFyIGNodW5rMlxuICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgY2h1bmsyID0gdW5kZWZpbmVkXG4gICAgICAgIGlmIChjdXJMaW5lTGVuZ3RoICsgY2h1bmsubGVuZ3RoID4gc3RvcCAmJlxuICAgICAgICAgIGN1ckxpbmVMZW5ndGggKyAoY2h1bmsyID0gY2h1bmsucmVwbGFjZSh0UGF0LCAnJykpLmxlbmd0aCA+IHN0b3AgJiZcbiAgICAgICAgICBjaHVuazIgIT09ICcnICYmXG4gICAgICAgICAgY3VyTGluZUxlbmd0aCA+IHN0YXJ0KSB7XG4gICAgICAgICAgLy8gVGhpcyBsaW5lIGlzIGZ1bGwsIGFkZCBgY2h1bmtgIHRvIHRoZSBuZXh0IGxpbmVcbiAgICAgICAgICByZW1uYW50ID0gZmluaXNoT2ZmQ3VyTGluZShmYWxzZSlcblxuICAgICAgICAgIGxpbmVzLnB1c2gocHJlZml4ICsgd3JhcExpbmVQcmVmaXgpXG4gICAgICAgICAgY3VyTGluZSsrXG4gICAgICAgICAgY3VyTGluZUxlbmd0aCA9IHN0YXJ0ICsgd3JhcExpbmVQcmVmaXgubGVuZ3RoXG5cbiAgICAgICAgICBpZiAocmVtbmFudCkge1xuICAgICAgICAgICAgbGluZXNbY3VyTGluZV0gKz0gcmVtbmFudFxuICAgICAgICAgICAgY3VyTGluZUxlbmd0aCArPSByZW1uYW50Lmxlbmd0aFxuICAgICAgICAgICAgY2xlYW5MaW5lID0gdHJ1ZVxuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAod3NTdHJpcCB8fCAod3NMaW5lICYmICEocHJlc2VydmVkTGluZSAmJiBjbGVhbkxpbmUpKSkge1xuICAgICAgICAgICAgY2h1bmsgPSBjaHVuay5yZXBsYWNlKHBQYXQsICcnKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjbGVhbkxpbmUgPSBmYWxzZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEFkZCBgY2h1bmtgIHRvIHRoaXMgbGluZVxuICAgICAgICAgIGlmIChjbGVhbkxpbmUpIHtcbiAgICAgICAgICAgIGlmICh3c1N0cmlwIHx8ICh3c0xpbmUgJiYgIShwcmVzZXJ2ZWRMaW5lICYmIGNsZWFuTGluZSkpKSB7XG4gICAgICAgICAgICAgIGNodW5rID0gY2h1bmsucmVwbGFjZShwUGF0LCAnJylcbiAgICAgICAgICAgICAgaWYgKGNodW5rICE9PSAnJykge1xuICAgICAgICAgICAgICAgIGNsZWFuTGluZSA9IGZhbHNlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChub25Xc1BhdC50ZXN0KGNodW5rKSkge1xuICAgICAgICAgICAgICAgIGNsZWFuTGluZSA9IGZhbHNlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGlmICh3c0FsbCAmJiBjaHVuazIgJiYgY3VyTGluZUxlbmd0aCArIGNodW5rMi5sZW5ndGggPiBzdG9wKSB7XG4gICAgICAgIGJ1bGdlID0gY3VyTGluZUxlbmd0aCArIGNodW5rMi5sZW5ndGhcbiAgICAgIH1cbiAgICAgIGxpbmVzW2N1ckxpbmVdICs9IGNodW5rXG4gICAgICBjdXJMaW5lTGVuZ3RoICs9IGNodW5rLmxlbmd0aFxuICAgIH1cbiAgICAvLyBGaW5hbGx5LCBmaW5pc2ggb2ZmIHRoZSBsYXN0IGxpbmUuXG4gICAgZmluaXNoT2ZmQ3VyTGluZSh0cnVlKVxuICAgIHJldHVybiBsaW5lcy5qb2luKGxpbmVCcmVha1N0cilcbiAgfVxufVxuXG5saW5ld3JhcC5zb2Z0ID0gbGluZXdyYXBcblxubGluZXdyYXAuaGFyZCA9IGZ1bmN0aW9uICggLypzdGFydCwgc3RvcCwgcGFyYW1zKi8pIHtcbiAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cylcbiAgdmFyIGxhc3QgPSBhcmdzLmxlbmd0aCAtIDFcbiAgaWYgKHR5cGVvZiBhcmdzW2xhc3RdID09PSAnb2JqZWN0Jykge1xuICAgIGFyZ3NbbGFzdF0ubW9kZSA9ICdoYXJkJ1xuICB9IGVsc2Uge1xuICAgIGFyZ3MucHVzaCh7IG1vZGU6ICdoYXJkJyB9KVxuICB9XG4gIHJldHVybiBsaW5ld3JhcC5hcHBseShudWxsLCBhcmdzKVxufVxuXG5saW5ld3JhcC53cmFwID0gZnVuY3Rpb24gKHRleHQgLyosIHN0YXJ0LCBzdG9wLCBwYXJhbXMqLykge1xuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKVxuICBhcmdzLnNoaWZ0KClcbiAgcmV0dXJuIGxpbmV3cmFwLmFwcGx5KG51bGwsIGFyZ3MpKHRleHQpXG59XG4iXX0=
\No newline at end of file