@speleotica/frcsdata 4.0.3 → 4.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/FrcsPlotFile.d.ts +1 -1
  2. package/FrcsPlotShot.d.ts +1 -1
  3. package/FrcsShot.d.ts +1 -1
  4. package/FrcsShot.js +2 -3
  5. package/FrcsSurveyFile.d.ts +1 -1
  6. package/FrcsTrip.d.ts +2 -2
  7. package/FrcsTripSummary.d.ts +1 -1
  8. package/FrcsTripSummaryFile.d.ts +1 -1
  9. package/formatFrcsShot.js +7 -6
  10. package/index.js +11 -11
  11. package/node/index.js +6 -9
  12. package/package.json +26 -124
  13. package/parseFrcsPlotFile.js +4 -3
  14. package/parseFrcsSurveyFile.js +13 -12
  15. package/parseFrcsTripSummaryFile.js +5 -4
  16. package/string/index.js +8 -11
  17. package/es/FrcsPlotFile.js +0 -6
  18. package/es/FrcsPlotShot.js +0 -6
  19. package/es/FrcsShot.js +0 -14
  20. package/es/FrcsSurveyFile.js +0 -6
  21. package/es/FrcsTrip.js +0 -6
  22. package/es/FrcsTripSummary.js +0 -6
  23. package/es/FrcsTripSummaryFile.js +0 -6
  24. package/es/formatFrcsShot.js +0 -75
  25. package/es/formatFrcsShot.spec.js +0 -141
  26. package/es/index.js +0 -96
  27. package/es/node/index.js +0 -20
  28. package/es/node/parseFrcsPlotFile.spec.js +0 -167
  29. package/es/node/parseFrcsSurveyFile.spec.js +0 -314
  30. package/es/node/parseFrcsTripSummaryFile.spec.js +0 -78
  31. package/es/parseFrcsPlotFile.js +0 -135
  32. package/es/parseFrcsSurveyFile.js +0 -503
  33. package/es/parseFrcsTripSummaryFile.js +0 -73
  34. package/es/string/index.js +0 -21
  35. package/es/string/parseFrcsPlotFile.spec.js +0 -179
  36. package/es/string/parseFrcsSurveyFile.spec.js +0 -646
  37. package/formatFrcsShot.spec.js +0 -139
  38. package/node/parseFrcsPlotFile.spec.js +0 -181
  39. package/node/parseFrcsSurveyFile.spec.js +0 -328
  40. package/node/parseFrcsTripSummaryFile.spec.js +0 -104
  41. package/string/parseFrcsPlotFile.spec.js +0 -182
  42. package/string/parseFrcsSurveyFile.spec.js +0 -673
  43. package/yarn.lock +0 -9542
@@ -1,503 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = parseFrcsSurveyFile;
7
- var _parseSegment = require("parse-segment");
8
- var _unitized = require("@speleotica/unitized");
9
- var _FrcsShot = require("./FrcsShot");
10
- function parseNumber(s, unit) {
11
- const value = parseFloat(s);
12
- if (isNaN(value)) return null;
13
- return new _unitized.UnitizedNumber(value, unit);
14
- }
15
- function parseAzimuth(s, unit) {
16
- const parsed = parseNumber(s, unit);
17
- return (parsed === null || parsed === void 0 ? void 0 : parsed.get(_unitized.Angle.degrees)) === 360 ? _unitized.Unitize.degrees(0) : parsed;
18
- }
19
- function parseKind(kind) {
20
- switch (kind) {
21
- case 'H':
22
- return _FrcsShot.FrcsShotKind.Horizontal;
23
- case 'D':
24
- return _FrcsShot.FrcsShotKind.Diagonal;
25
- default:
26
- return _FrcsShot.FrcsShotKind.Normal;
27
- }
28
- }
29
- function parseLengthUnit(unit) {
30
- switch (unit) {
31
- case 'FI':
32
- return _unitized.Length.inches;
33
- case 'FF':
34
- case 'FT':
35
- return _unitized.Length.feet;
36
- case 'MT':
37
- case 'M ':
38
- return _unitized.Length.meters;
39
- }
40
- return null;
41
- }
42
- function parseAngleUnit(unit) {
43
- switch (unit) {
44
- case 'D':
45
- return _unitized.Angle.degrees;
46
- case 'G':
47
- return _unitized.Angle.gradians;
48
- case 'M':
49
- return _unitized.Angle.milsNATO;
50
- }
51
- return null;
52
- }
53
-
54
- // determines if a cell contains a valid station name.
55
- function isValidStation(s) {
56
- return /^\s*\S+\s*$/.test(s);
57
- }
58
- // determines if a cell contains a valid unsigned integer.
59
- function isValidUInt(s) {
60
- return /^\s*[0-9]+\s*$/.test(s);
61
- }
62
- // determines if a cell contains a valid float.
63
- function isValidFloat(s) {
64
- return /^\s*[-+]?([0-9]+(\.[0-9]*)?|\.[0-9]+)\s*$/.test(s);
65
- }
66
- // determines if a cell contains a valid unsigned float or whitespace.
67
- function isValidOptFloat(s) {
68
- return /^\s*[-+]?[0-9]*(\.[0-9]*)?\s*$/.test(s);
69
- }
70
- // determines if a cell contains a valid unsigned float or whitespace.
71
- function isValidOptUFloat(s) {
72
- return /^\s*[0-9]*(\.[0-9]*)?\s*$/.test(s);
73
- }
74
- // determines if a cell contains a valid unsigned float.
75
- function isValidUFloat(s) {
76
- return /^\s*([0-9]+(\.[0-9]*)?|\.[0-9]+)\s*$/.test(s);
77
- }
78
- // determines if a cell contains a valid inclination or whitespace.
79
- function isValidOptInclination(s) {
80
- return /^\s*[-+]?[0-9]*(\.[0-9]*)?\s*$/.test(s);
81
- }
82
- function parseLrud(s, unit) {
83
- const value = parseFloat(s);
84
- return !Number.isFinite(value) || value < 0 ? null : new _unitized.UnitizedNumber(value, unit);
85
- }
86
- function parseFromStationLruds(line, distanceUnit) {
87
- const fromStr = line.substring(0, 5);
88
- if (!/^\s*\S+$/.test(fromStr)) return undefined;
89
- const gap = line.substring(5, 40);
90
- if (gap.trim()) return undefined;
91
- const lrudStr = line.substring(40, 52);
92
- if (!/\d/.test(lrudStr)) return undefined;
93
- const lStr = line.substring(40, 43);
94
- const rStr = line.substring(43, 46);
95
- const uStr = line.substring(46, 49);
96
- const dStr = line.substring(49, 52);
97
- if (!isValidOptFloat(lStr) || !isValidOptFloat(rStr) || !isValidOptFloat(uStr) || !isValidOptFloat(dStr)) {
98
- return undefined;
99
- }
100
- const up = parseLrud(uStr, distanceUnit);
101
- const down = parseLrud(dStr, distanceUnit);
102
- const left = parseLrud(lStr, distanceUnit);
103
- const right = parseLrud(rStr, distanceUnit);
104
- return [fromStr.trim(), {
105
- left,
106
- right,
107
- up,
108
- down
109
- }];
110
- }
111
-
112
- /**
113
- * Parses a raw cdata.fr survey file. These look like so:
114
- *
115
- <pre> Fisher Ridge Cave System, Hart Co., KY
116
- ENTRANCE DROPS, JOE'S "I LOVE MY WIFE TRAVERSE", TRICKY TRAVERSE
117
- PETER QUICK, KEITH ORTIZ - 2-15-81
118
- This File has Crumps test connected. 11/20/12
119
- *
120
- FT C DD A
121
- AE20 0 1 3 0 2
122
- * %FS
123
- * AE20 0 0 0 Bug-can't put before so put after-so can't make 2 fixed 10/28/12
124
- AE19 AE20 9.3 60.0 60.0-36.0 2 12 0 20
125
- AE18 AE19 24.5 0.0 0.0-90.0 6 10 25 0
126
- AE17 AE18 8.0 350.5 350.5 17.0 3 5 0 0
127
- AE16 AE17 6.7 0.0 0.0-90.0 3 5 6 1
128
- AE15 AE16 12.6 70.5 71.0-18.0 4 0 2 1
129
- AE14 AE15 10.0 21.5 20.0 6.0 5 5 0 3
130
- AE13 AE14 26.8 288.0 286.0-50.0 0 7 20 5
131
- *
132
- *SHORT CANYON AT THE BASE OF THE SECOND DROP
133
- AE12 AE13 20.7 236.0 236.0 34.0 3 5 4 4
134
- AE11 AE12 12.4 210.0 210.0 35.0 7 4 5 1
135
- AE10 AE13 25.7 40.0 40.0 -9.0 2 2 3 6
136
- *
137
- *AE10 AT JOE'S " I LOVE MY WIFE TRAVERSE "
138
- AE9 AE10 17.8 32.5 31.0 23.0 4 5 20 15
139
- AE1 AE9 13.7 82.0 82.0-13.0
140
- A1 AE1 34.3 46.0 48.0-17.5
141
- *
142
- *SURVEY TO DOME NEAR THE ENTRANCE DOME (ABOVE THE SECOND DROP)
143
- AD1 AE15 8.0 200.0 200.0 0.0 3 1 1 1
144
- AD2 AD1 17.7 161.0 161.0 7.0 1 4 25 1
145
- AD3 AD2 10.4 180.0 180.0 50.0 4 1 15 5
146
- *
147
- TRICKY TRAVERSE AND THEN FIRST SURVEY IN UPPER CROWLWAY
148
- DAN CROWL, KEITH ORTIZ, CHIP HOPPER, PETER QUICK, LARRY BEAN 14 FEB 1981
149
- *
150
- FI B DD
151
- A2 A1 48 10 292.0 110.0-42.0 5 10 35 5
152
- A3 A2 12 5 333.5 153.5 35.0 3 1 15 5
153
- A4 A3 4 2 0.0 0.0 90.0 3 1 10 10
154
- ...</pre>
155
- *
156
- */
157
- async function parseFrcsSurveyFile(file,
158
- // eslint-disable-line @typescript-eslint/no-explicit-any
159
- lines) {
160
- let cave = null;
161
- let location = null;
162
- const trips = [];
163
- const errors = [];
164
- let tripName;
165
- let tripTeam;
166
- let tripDate;
167
- let inTripComment = true;
168
- let tripCommentStartLine = 1;
169
- let tripCommentEndLine = -1;
170
- let tripComment = [];
171
- let commentLines = null;
172
- let trip = null;
173
- let inBlockComment = false;
174
- let section;
175
- const commentFromStationLruds = new Map();
176
- function addCommentLine(comment) {
177
- if (trip) {
178
- const distanceUnit = trip.header.distanceUnit;
179
- const parsedFromStationLruds = parseFromStationLruds(comment, distanceUnit);
180
- if (parsedFromStationLruds) {
181
- commentFromStationLruds.set(parsedFromStationLruds[0], parsedFromStationLruds[1]);
182
- return;
183
- }
184
- }
185
- if (commentLines) {
186
- commentLines.push(comment);
187
- }
188
- }
189
- function getComment() {
190
- if (!commentLines) return null;
191
- const comment = commentLines.join('\n').trim();
192
- commentLines = null;
193
- return comment || null;
194
- }
195
- let lineNumber = 0;
196
- for await (const line of lines) {
197
- let errored = false;
198
- const thisLineNumber = lineNumber;
199
- const error = (message, startColumn, endColumn) => {
200
- errored = true;
201
- errors.push(new _parseSegment.SegmentParseError(message, new _parseSegment.Segment({
202
- value: line,
203
- source: file,
204
- startLine: thisLineNumber,
205
- startCol: 0
206
- }).substring(startColumn, endColumn)));
207
- };
208
- const validate = (startColumn, endColumn, fieldName, validator) => {
209
- const field = line.substring(startColumn, endColumn);
210
- if (!validator(field)) {
211
- error((field.trim() ? 'Invalid ' : 'Missing ') + fieldName, startColumn, endColumn);
212
- }
213
- return field;
214
- };
215
- lineNumber++;
216
- if (lineNumber === 1) {
217
- const match = /^\s*([^,]+)(,(.*))?/.exec(line);
218
- if (match) {
219
- cave = match[1].trim();
220
- if (match[3]) {
221
- location = match[3].trim();
222
- }
223
- }
224
- }
225
- if (line.charAt(0) === ' ' && line.charAt(1) === '*') {
226
- inTripComment = !inTripComment;
227
- if (inTripComment) {
228
- section = undefined;
229
- tripComment = [];
230
- tripCommentStartLine = lineNumber;
231
- } else {
232
- tripCommentEndLine = lineNumber;
233
- }
234
- } else if (inTripComment) {
235
- if (lineNumber === tripCommentStartLine + 1) {
236
- tripName = line && line.trim();
237
- } else if (lineNumber === tripCommentStartLine + 2) {
238
- const match = /^(.+?)\s*[-.]\s*(\d+)\/(\d+)\/(\d+)$/.exec(line && line.trim());
239
- if (match) {
240
- let k = 1;
241
- const team = match[k++];
242
- const month = parseInt(match[k++]);
243
- const day = parseInt(match[k++]);
244
- const year = parseInt(match[k++]);
245
- tripDate = new Date(year < 70 ? year + 2000 : year, month - 1, day);
246
- tripTeam = team.split(team.indexOf(';') >= 0 ? /\s*;\s*/g : /\s*,\s*/g);
247
- }
248
- } else if (lineNumber > 1) {
249
- tripComment.push(line);
250
- }
251
- const match = /^\*\*\*([^*])\*\*\*/.exec(line);
252
- if (match) {
253
- section = match[1].trim();
254
- }
255
- } else if (line.charAt(0) === '*') {
256
- inBlockComment = !inBlockComment;
257
- if (inBlockComment) commentLines = [];else {
258
- const part = line.substring(1);
259
- if (part) addCommentLine(part);
260
- }
261
- } else if (inBlockComment) {
262
- addCommentLine(line);
263
- } else if (lineNumber === tripCommentEndLine + 1) {
264
- // FT CC DD
265
- // 01234567
266
- let distanceUnit = parseLengthUnit(line.slice(0, 2));
267
- if (!distanceUnit) {
268
- distanceUnit = _unitized.Length.feet;
269
- error('Invalid distance unit', 0, 2);
270
- }
271
- let azimuthUnit = parseAngleUnit(line[6]);
272
- if (!azimuthUnit) {
273
- azimuthUnit = _unitized.Angle.degrees;
274
- error('Invalid azimuth unit', 6, 7);
275
- }
276
- let inclinationUnit = parseAngleUnit(line[7]);
277
- if (!inclinationUnit) {
278
- inclinationUnit = _unitized.Angle.degrees;
279
- error('Invalid inclination unit', 7, 8);
280
- }
281
- const backsightAzimuthCorrected = line[3] === 'C';
282
- const backsightInclinationCorrected = line[4] === 'C';
283
- const hasBacksightAzimuth = line[3] !== ' ' && line[3] !== '-';
284
- const hasBacksightInclination = line[4] !== ' ' && line[4] !== '-';
285
- if (!/[-CB ]/.test(line[3])) {
286
- error('Invalid backsight azimuth type', 3, 4);
287
- }
288
- if (!/[-CB ]/.test(line[4])) {
289
- error('Invalid backsight inclination type', 4, 5);
290
- }
291
- trip = {
292
- header: {
293
- name: tripName || '',
294
- comment: tripComment && tripComment.join('\n') || null,
295
- section,
296
- date: tripDate,
297
- team: tripTeam,
298
- distanceUnit,
299
- azimuthUnit,
300
- inclinationUnit,
301
- backsightAzimuthCorrected,
302
- backsightInclinationCorrected,
303
- hasBacksightAzimuth,
304
- hasBacksightInclination
305
- },
306
- shots: []
307
- };
308
- trips.push(trip);
309
- } else if (trip) {
310
- const {
311
- shots,
312
- header: {
313
- azimuthUnit,
314
- inclinationUnit
315
- }
316
- } = trip;
317
- let {
318
- distanceUnit
319
- } = trip.header;
320
- const inches = distanceUnit === _unitized.Length.inches;
321
- if (inches) distanceUnit = _unitized.Length.feet;
322
-
323
- // rigorously check the values in all the columns to make sure this
324
- // is really a survey shot line, just in case any stray comments are
325
- // not properly delimited.
326
-
327
- // from station name
328
- if (!/\S/.test(line.substring(5, 10))) continue;
329
- const fromStr = validate(5, 10, 'from station', isValidStation);
330
- const from = fromStr.trim();
331
-
332
- // Sadly I have found negative LRUD values in Chip's format and apparently
333
- // his program doesn't fail on them, so I have to accept them here
334
- // isValidOptFloat instead of isValidOptUFloat
335
- const lStr = validate(40, 43, 'left', isValidOptFloat);
336
- const rStr = validate(43, 46, 'right', isValidOptFloat);
337
- const uStr = validate(46, 49, 'up', isValidOptFloat);
338
- const dStr = validate(49, 52, 'down', isValidOptFloat);
339
- if (errored) continue;
340
- const up = parseLrud(uStr, distanceUnit);
341
- const down = parseLrud(dStr, distanceUnit);
342
- const left = parseLrud(lStr, distanceUnit);
343
- const right = parseLrud(rStr, distanceUnit);
344
-
345
- // to station name
346
- const toStr = line.substring(0, 5);
347
- if (!toStr.trim()) {
348
- const shot = {
349
- from,
350
- to: null,
351
- kind: _FrcsShot.FrcsShotKind.Normal,
352
- distance: new _unitized.UnitizedNumber(0, distanceUnit),
353
- frontsightAzimuth: null,
354
- backsightAzimuth: null,
355
- frontsightInclination: null,
356
- backsightInclination: null,
357
- fromLruds: {
358
- left,
359
- right,
360
- up,
361
- down
362
- },
363
- excludeDistance: true,
364
- comment: getComment()
365
- };
366
- shots.push(shot);
367
- continue;
368
- }
369
- if (!isValidStation(toStr)) {
370
- error('Invalid station name', 0, 5);
371
- }
372
- let fromLruds = commentFromStationLruds.get(from);
373
- if (fromLruds) {
374
- commentFromStationLruds.delete(from);
375
- } else {
376
- const fromLrudMatch = new RegExp(`^\\s+${fromStr.trim().replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}((\\s+(\\d+(\\.\\d*)?|\\.\\d+)){4})`).exec(line.substring(52));
377
- if (fromLrudMatch) {
378
- const [left, right, up, down] = fromLrudMatch[1].trim().split(/\s+/g).map(s => parseLrud(s, distanceUnit));
379
- fromLruds = {
380
- left,
381
- right,
382
- up,
383
- down
384
- };
385
- }
386
- }
387
- const comment = getComment();
388
-
389
- // azimuth and inclination
390
- const azmFsStr = validate(19, 25, 'azimuth', isValidOptUFloat);
391
- const azmBsStr = validate(25, 30, 'azimuth', isValidOptUFloat);
392
- const incFsStr = line.substring(30, 35);
393
- const incBsStr = line.substring(35, 40);
394
- if (errored) continue;
395
- let kind;
396
- let distance;
397
- let horizontalDistance;
398
- let verticalDistance;
399
- let frontsightInclination;
400
- let backsightInclination;
401
- let excludeDistance;
402
- let isSplay;
403
-
404
- // parse distance
405
- if (inches) {
406
- const feetStr = line.substring(10, 14);
407
- const inchesStr = line.substring(14, 17);
408
- // feet and inches are not both optional
409
- if (!isValidUInt(feetStr) && !isValidUInt(inchesStr)) {
410
- const invalid = feetStr.trim() || inchesStr.trim();
411
- error(invalid ? 'Invalid distance' : 'Missing distance', 10, 17);
412
- continue;
413
- }
414
-
415
- // sometimes inches are omitted, hence the || 0...I'm assuming it's possible
416
- // for feet to be omitted as well
417
- distance = _unitized.Unitize.inches(parseFloat(inchesStr) || 0).add(_unitized.Unitize.feet(parseFloat(feetStr) || 0));
418
- kind = parseKind(line[17]);
419
- // NOTE there are two columns around here that can contain a *.
420
- // I think they might represent different values, but thisis confused by
421
- // the fact that for ft/in shots, if there is a D or H flag it occupies the
422
- // first column that can contain a * for decimal feet shots
423
- excludeDistance = line[18] === '*' || line[18] === 's';
424
- isSplay = line[18] === 's';
425
- } else {
426
- // decimal feet are not optional
427
- const feetStr = validate(10, 16, 'distance', isValidUFloat);
428
- distance = new _unitized.UnitizedNumber(parseFloat(feetStr), distanceUnit);
429
- kind = parseKind(line[16]);
430
- excludeDistance = line[17] === '*' || line[17] === 's';
431
- isSplay = line[17] === 's';
432
- }
433
- if (kind !== _FrcsShot.FrcsShotKind.Normal) {
434
- validate(30, 35, 'vertical-distance', isValidFloat);
435
- }
436
-
437
- // convert horizontal and diagonal shots to standard
438
- // in this case incFs is the vertical offset between stations
439
- // fortunately it appears we can always count on incFs being specified
440
- // and incBs not being specified for these types of shots
441
- if (kind === _FrcsShot.FrcsShotKind.Horizontal) {
442
- // distance is horizontal offset and incFsStr is vertical offset
443
- horizontalDistance = distance;
444
- const h = horizontalDistance.get(distanceUnit);
445
- const v = parseFloat(incFsStr);
446
- verticalDistance = new _unitized.UnitizedNumber(v, distanceUnit);
447
- distance = new _unitized.UnitizedNumber(Math.sqrt(h * h + v * v), distanceUnit);
448
- frontsightInclination = _unitized.Angle.atan2(verticalDistance, horizontalDistance);
449
- backsightInclination = null;
450
- } else if (kind === _FrcsShot.FrcsShotKind.Diagonal) {
451
- // distance is as usual, but incFsStr is vertical offset
452
- const d = distance.get(distanceUnit);
453
- const v = parseFloat(incFsStr);
454
- verticalDistance = new _unitized.UnitizedNumber(v, distanceUnit);
455
- frontsightInclination = _unitized.Angle.asin(v / d);
456
- backsightInclination = null;
457
- } else {
458
- // frontsight inclination
459
- validate(30, 35, 'inclination', isValidOptInclination);
460
- // frontsight inclination
461
- validate(35, 40, 'inclination', isValidOptInclination);
462
- frontsightInclination = parseNumber(incFsStr, inclinationUnit);
463
- backsightInclination = parseNumber(incBsStr, inclinationUnit);
464
- }
465
- if (errored) continue;
466
- const frontsightAzimuth = parseAzimuth(azmFsStr, azimuthUnit);
467
- const backsightAzimuth = parseAzimuth(azmBsStr, azimuthUnit);
468
- if (!frontsightInclination && !backsightInclination) {
469
- frontsightInclination = _unitized.Unitize.degrees(0);
470
- }
471
- const shot = {
472
- from,
473
- to: toStr.trim(),
474
- kind,
475
- distance,
476
- frontsightAzimuth,
477
- backsightAzimuth,
478
- frontsightInclination,
479
- backsightInclination,
480
- toLruds: {
481
- left,
482
- right,
483
- up,
484
- down
485
- },
486
- excludeDistance,
487
- comment
488
- };
489
- if (isSplay) shot.isSplay = true;
490
- if (fromLruds) shot.fromLruds = fromLruds;
491
- if (horizontalDistance) shot.horizontalDistance = horizontalDistance;
492
- if (verticalDistance) shot.verticalDistance = verticalDistance;
493
- shots.push(shot);
494
- }
495
- }
496
- return {
497
- cave,
498
- location,
499
- trips,
500
- errors
501
- };
502
- }
503
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcGFyc2VTZWdtZW50IiwicmVxdWlyZSIsIl91bml0aXplZCIsIl9GcmNzU2hvdCIsInBhcnNlTnVtYmVyIiwicyIsInVuaXQiLCJ2YWx1ZSIsInBhcnNlRmxvYXQiLCJpc05hTiIsIlVuaXRpemVkTnVtYmVyIiwicGFyc2VBemltdXRoIiwicGFyc2VkIiwiZ2V0IiwiQW5nbGUiLCJkZWdyZWVzIiwiVW5pdGl6ZSIsInBhcnNlS2luZCIsImtpbmQiLCJGcmNzU2hvdEtpbmQiLCJIb3Jpem9udGFsIiwiRGlhZ29uYWwiLCJOb3JtYWwiLCJwYXJzZUxlbmd0aFVuaXQiLCJMZW5ndGgiLCJpbmNoZXMiLCJmZWV0IiwibWV0ZXJzIiwicGFyc2VBbmdsZVVuaXQiLCJncmFkaWFucyIsIm1pbHNOQVRPIiwiaXNWYWxpZFN0YXRpb24iLCJ0ZXN0IiwiaXNWYWxpZFVJbnQiLCJpc1ZhbGlkRmxvYXQiLCJpc1ZhbGlkT3B0RmxvYXQiLCJpc1ZhbGlkT3B0VUZsb2F0IiwiaXNWYWxpZFVGbG9hdCIsImlzVmFsaWRPcHRJbmNsaW5hdGlvbiIsInBhcnNlTHJ1ZCIsIk51bWJlciIsImlzRmluaXRlIiwicGFyc2VGcm9tU3RhdGlvbkxydWRzIiwibGluZSIsImRpc3RhbmNlVW5pdCIsImZyb21TdHIiLCJzdWJzdHJpbmciLCJ1bmRlZmluZWQiLCJnYXAiLCJ0cmltIiwibHJ1ZFN0ciIsImxTdHIiLCJyU3RyIiwidVN0ciIsImRTdHIiLCJ1cCIsImRvd24iLCJsZWZ0IiwicmlnaHQiLCJwYXJzZUZyY3NTdXJ2ZXlGaWxlIiwiZmlsZSIsImxpbmVzIiwiY2F2ZSIsImxvY2F0aW9uIiwidHJpcHMiLCJlcnJvcnMiLCJ0cmlwTmFtZSIsInRyaXBUZWFtIiwidHJpcERhdGUiLCJpblRyaXBDb21tZW50IiwidHJpcENvbW1lbnRTdGFydExpbmUiLCJ0cmlwQ29tbWVudEVuZExpbmUiLCJ0cmlwQ29tbWVudCIsImNvbW1lbnRMaW5lcyIsInRyaXAiLCJpbkJsb2NrQ29tbWVudCIsInNlY3Rpb24iLCJjb21tZW50RnJvbVN0YXRpb25McnVkcyIsIk1hcCIsImFkZENvbW1lbnRMaW5lIiwiY29tbWVudCIsImhlYWRlciIsInBhcnNlZEZyb21TdGF0aW9uTHJ1ZHMiLCJzZXQiLCJwdXNoIiwiZ2V0Q29tbWVudCIsImpvaW4iLCJsaW5lTnVtYmVyIiwiZXJyb3JlZCIsInRoaXNMaW5lTnVtYmVyIiwiZXJyb3IiLCJtZXNzYWdlIiwic3RhcnRDb2x1bW4iLCJlbmRDb2x1bW4iLCJTZWdtZW50UGFyc2VFcnJvciIsIlNlZ21lbnQiLCJzb3VyY2UiLCJzdGFydExpbmUiLCJzdGFydENvbCIsInZhbGlkYXRlIiwiZmllbGROYW1lIiwidmFsaWRhdG9yIiwiZmllbGQiLCJtYXRjaCIsImV4ZWMiLCJjaGFyQXQiLCJrIiwidGVhbSIsIm1vbnRoIiwicGFyc2VJbnQiLCJkYXkiLCJ5ZWFyIiwiRGF0ZSIsInNwbGl0IiwiaW5kZXhPZiIsInBhcnQiLCJzbGljZSIsImF6aW11dGhVbml0IiwiaW5jbGluYXRpb25Vbml0IiwiYmFja3NpZ2h0QXppbXV0aENvcnJlY3RlZCIsImJhY2tzaWdodEluY2xpbmF0aW9uQ29ycmVjdGVkIiwiaGFzQmFja3NpZ2h0QXppbXV0aCIsImhhc0JhY2tzaWdodEluY2xpbmF0aW9uIiwibmFtZSIsImRhdGUiLCJzaG90cyIsImZyb20iLCJ0b1N0ciIsInNob3QiLCJ0byIsImRpc3RhbmNlIiwiZnJvbnRzaWdodEF6aW11dGgiLCJiYWNrc2lnaHRBemltdXRoIiwiZnJvbnRzaWdodEluY2xpbmF0aW9uIiwiYmFja3NpZ2h0SW5jbGluYXRpb24iLCJmcm9tTHJ1ZHMiLCJleGNsdWRlRGlzdGFuY2UiLCJkZWxldGUiLCJmcm9tTHJ1ZE1hdGNoIiwiUmVnRXhwIiwicmVwbGFjZSIsIm1hcCIsImF6bUZzU3RyIiwiYXptQnNTdHIiLCJpbmNGc1N0ciIsImluY0JzU3RyIiwiaG9yaXpvbnRhbERpc3RhbmNlIiwidmVydGljYWxEaXN0YW5jZSIsImlzU3BsYXkiLCJmZWV0U3RyIiwiaW5jaGVzU3RyIiwiaW52YWxpZCIsImFkZCIsImgiLCJ2IiwiTWF0aCIsInNxcnQiLCJhdGFuMiIsImQiLCJhc2luIiwidG9McnVkcyJdLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXJzZUZyY3NTdXJ2ZXlGaWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEZyY3NTdXJ2ZXlGaWxlIH0gZnJvbSAnLi9GcmNzU3VydmV5RmlsZSdcbmltcG9ydCB7IEZyY3NUcmlwIH0gZnJvbSAnLi9GcmNzVHJpcCdcbmltcG9ydCB7IFNlZ21lbnQsIFNlZ21lbnRQYXJzZUVycm9yIH0gZnJvbSAncGFyc2Utc2VnbWVudCdcbmltcG9ydCB7XG4gIEFuZ2xlLFxuICBMZW5ndGgsXG4gIFVuaXQsXG4gIFVuaXRpemVkTnVtYmVyLFxuICBVbml0VHlwZSxcbiAgVW5pdGl6ZSxcbn0gZnJvbSAnQHNwZWxlb3RpY2EvdW5pdGl6ZWQnXG5pbXBvcnQgeyBGcmNzU2hvdCwgRnJjc1Nob3RLaW5kIH0gZnJvbSAnLi9GcmNzU2hvdCdcblxuZnVuY3Rpb24gcGFyc2VOdW1iZXI8VCBleHRlbmRzIFVuaXRUeXBlPFQ+PihcbiAgczogc3RyaW5nLFxuICB1bml0OiBVbml0PFQ+XG4pOiBVbml0aXplZE51bWJlcjxUPiB8IG51bGwge1xuICBjb25zdCB2YWx1ZSA9IHBhcnNlRmxvYXQocylcbiAgaWYgKGlzTmFOKHZhbHVlKSkgcmV0dXJuIG51bGxcbiAgcmV0dXJuIG5ldyBVbml0aXplZE51bWJlcih2YWx1ZSwgdW5pdClcbn1cblxuZnVuY3Rpb24gcGFyc2VBemltdXRoKFxuICBzOiBzdHJpbmcsXG4gIHVuaXQ6IFVuaXQ8QW5nbGU+XG4pOiBVbml0aXplZE51bWJlcjxBbmdsZT4gfCBudWxsIHtcbiAgY29uc3QgcGFyc2VkID0gcGFyc2VOdW1iZXIocywgdW5pdClcbiAgcmV0dXJuIHBhcnNlZD8uZ2V0KEFuZ2xlLmRlZ3JlZXMpID09PSAzNjAgPyBVbml0aXplLmRlZ3JlZXMoMCkgOiBwYXJzZWRcbn1cblxuZnVuY3Rpb24gcGFyc2VLaW5kKGtpbmQ6IHN0cmluZyk6IEZyY3NTaG90S2luZCB7XG4gIHN3aXRjaCAoa2luZCkge1xuICAgIGNhc2UgJ0gnOlxuICAgICAgcmV0dXJuIEZyY3NTaG90S2luZC5Ib3Jpem9udGFsXG4gICAgY2FzZSAnRCc6XG4gICAgICByZXR1cm4gRnJjc1Nob3RLaW5kLkRpYWdvbmFsXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBGcmNzU2hvdEtpbmQuTm9ybWFsXG4gIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VMZW5ndGhVbml0KHVuaXQ6IHN0cmluZyk6IFVuaXQ8TGVuZ3RoPiB8IG51bGwge1xuICBzd2l0Y2ggKHVuaXQpIHtcbiAgICBjYXNlICdGSSc6XG4gICAgICByZXR1cm4gTGVuZ3RoLmluY2hlc1xuICAgIGNhc2UgJ0ZGJzpcbiAgICBjYXNlICdGVCc6XG4gICAgICByZXR1cm4gTGVuZ3RoLmZlZXRcbiAgICBjYXNlICdNVCc6XG4gICAgY2FzZSAnTSAnOlxuICAgICAgcmV0dXJuIExlbmd0aC5tZXRlcnNcbiAgfVxuICByZXR1cm4gbnVsbFxufVxuZnVuY3Rpb24gcGFyc2VBbmdsZVVuaXQodW5pdDogc3RyaW5nKTogVW5pdDxBbmdsZT4gfCBudWxsIHtcbiAgc3dpdGNoICh1bml0KSB7XG4gICAgY2FzZSAnRCc6XG4gICAgICByZXR1cm4gQW5nbGUuZGVncmVlc1xuICAgIGNhc2UgJ0cnOlxuICAgICAgcmV0dXJuIEFuZ2xlLmdyYWRpYW5zXG4gICAgY2FzZSAnTSc6XG4gICAgICByZXR1cm4gQW5nbGUubWlsc05BVE9cbiAgfVxuICByZXR1cm4gbnVsbFxufVxuXG4vLyBkZXRlcm1pbmVzIGlmIGEgY2VsbCBjb250YWlucyBhIHZhbGlkIHN0YXRpb24gbmFtZS5cbmZ1bmN0aW9uIGlzVmFsaWRTdGF0aW9uKHM6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gL15cXHMqXFxTK1xccyokLy50ZXN0KHMpXG59XG4vLyBkZXRlcm1pbmVzIGlmIGEgY2VsbCBjb250YWlucyBhIHZhbGlkIHVuc2lnbmVkIGludGVnZXIuXG5mdW5jdGlvbiBpc1ZhbGlkVUludChzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9eXFxzKlswLTldK1xccyokLy50ZXN0KHMpXG59XG4vLyBkZXRlcm1pbmVzIGlmIGEgY2VsbCBjb250YWlucyBhIHZhbGlkIGZsb2F0LlxuZnVuY3Rpb24gaXNWYWxpZEZsb2F0KHM6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gL15cXHMqWy0rXT8oWzAtOV0rKFxcLlswLTldKik/fFxcLlswLTldKylcXHMqJC8udGVzdChzKVxufVxuLy8gZGV0ZXJtaW5lcyBpZiBhIGNlbGwgY29udGFpbnMgYSB2YWxpZCB1bnNpZ25lZCBmbG9hdCBvciB3aGl0ZXNwYWNlLlxuZnVuY3Rpb24gaXNWYWxpZE9wdEZsb2F0KHM6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gL15cXHMqWy0rXT9bMC05XSooXFwuWzAtOV0qKT9cXHMqJC8udGVzdChzKVxufVxuLy8gZGV0ZXJtaW5lcyBpZiBhIGNlbGwgY29udGFpbnMgYSB2YWxpZCB1bnNpZ25lZCBmbG9hdCBvciB3aGl0ZXNwYWNlLlxuZnVuY3Rpb24gaXNWYWxpZE9wdFVGbG9hdChzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9eXFxzKlswLTldKihcXC5bMC05XSopP1xccyokLy50ZXN0KHMpXG59XG4vLyBkZXRlcm1pbmVzIGlmIGEgY2VsbCBjb250YWlucyBhIHZhbGlkIHVuc2lnbmVkIGZsb2F0LlxuZnVuY3Rpb24gaXNWYWxpZFVGbG9hdChzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9eXFxzKihbMC05XSsoXFwuWzAtOV0qKT98XFwuWzAtOV0rKVxccyokLy50ZXN0KHMpXG59XG4vLyBkZXRlcm1pbmVzIGlmIGEgY2VsbCBjb250YWlucyBhIHZhbGlkIGluY2xpbmF0aW9uIG9yIHdoaXRlc3BhY2UuXG5mdW5jdGlvbiBpc1ZhbGlkT3B0SW5jbGluYXRpb24oczogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAvXlxccypbLStdP1swLTldKihcXC5bMC05XSopP1xccyokLy50ZXN0KHMpXG59XG5mdW5jdGlvbiBwYXJzZUxydWQ8VCBleHRlbmRzIFVuaXRUeXBlPFQ+PihcbiAgczogc3RyaW5nLFxuICB1bml0OiBVbml0PExlbmd0aD5cbik6IFVuaXRpemVkTnVtYmVyPExlbmd0aD4gfCBudWxsIHtcbiAgY29uc3QgdmFsdWUgPSBwYXJzZUZsb2F0KHMpXG4gIHJldHVybiAhTnVtYmVyLmlzRmluaXRlKHZhbHVlKSB8fCB2YWx1ZSA8IDBcbiAgICA/IG51bGxcbiAgICA6IG5ldyBVbml0aXplZE51bWJlcih2YWx1ZSwgdW5pdClcbn1cblxuZnVuY3Rpb24gcGFyc2VGcm9tU3RhdGlvbkxydWRzKFxuICBsaW5lOiBzdHJpbmcsXG4gIGRpc3RhbmNlVW5pdDogVW5pdDxMZW5ndGg+XG4pOiBbc3RyaW5nLCBOb25OdWxsYWJsZTxGcmNzU2hvdFsnZnJvbUxydWRzJ10+XSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGZyb21TdHIgPSBsaW5lLnN1YnN0cmluZygwLCA1KVxuICBpZiAoIS9eXFxzKlxcUyskLy50ZXN0KGZyb21TdHIpKSByZXR1cm4gdW5kZWZpbmVkXG4gIGNvbnN0IGdhcCA9IGxpbmUuc3Vic3RyaW5nKDUsIDQwKVxuICBpZiAoZ2FwLnRyaW0oKSkgcmV0dXJuIHVuZGVmaW5lZFxuICBjb25zdCBscnVkU3RyID0gbGluZS5zdWJzdHJpbmcoNDAsIDUyKVxuICBpZiAoIS9cXGQvLnRlc3QobHJ1ZFN0cikpIHJldHVybiB1bmRlZmluZWRcbiAgY29uc3QgbFN0ciA9IGxpbmUuc3Vic3RyaW5nKDQwLCA0MylcbiAgY29uc3QgclN0ciA9IGxpbmUuc3Vic3RyaW5nKDQzLCA0NilcbiAgY29uc3QgdVN0ciA9IGxpbmUuc3Vic3RyaW5nKDQ2LCA0OSlcbiAgY29uc3QgZFN0ciA9IGxpbmUuc3Vic3RyaW5nKDQ5LCA1MilcbiAgaWYgKFxuICAgICFpc1ZhbGlkT3B0RmxvYXQobFN0cikgfHxcbiAgICAhaXNWYWxpZE9wdEZsb2F0KHJTdHIpIHx8XG4gICAgIWlzVmFsaWRPcHRGbG9hdCh1U3RyKSB8fFxuICAgICFpc1ZhbGlkT3B0RmxvYXQoZFN0cilcbiAgKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG4gIGNvbnN0IHVwID0gcGFyc2VMcnVkKHVTdHIsIGRpc3RhbmNlVW5pdClcbiAgY29uc3QgZG93biA9IHBhcnNlTHJ1ZChkU3RyLCBkaXN0YW5jZVVuaXQpXG4gIGNvbnN0IGxlZnQgPSBwYXJzZUxydWQobFN0ciwgZGlzdGFuY2VVbml0KVxuICBjb25zdCByaWdodCA9IHBhcnNlTHJ1ZChyU3RyLCBkaXN0YW5jZVVuaXQpXG4gIHJldHVybiBbZnJvbVN0ci50cmltKCksIHsgbGVmdCwgcmlnaHQsIHVwLCBkb3duIH1dXG59XG5cbi8qKlxuICogUGFyc2VzIGEgcmF3IGNkYXRhLmZyIHN1cnZleSBmaWxlLiAgVGhlc2UgbG9vayBsaWtlIHNvOlxuICpcbjxwcmU+ICAgICAgRmlzaGVyIFJpZGdlIENhdmUgU3lzdGVtLCBIYXJ0IENvLiwgS1lcbkVOVFJBTkNFIERST1BTLCBKT0UnUyBcIkkgTE9WRSBNWSBXSUZFIFRSQVZFUlNFXCIsIFRSSUNLWSBUUkFWRVJTRVxuUEVURVIgUVVJQ0ssIEtFSVRIIE9SVElaICAgLSAgMi0xNS04MVxuVGhpcyBGaWxlIGhhcyBDcnVtcHMgdGVzdCBjb25uZWN0ZWQuICAxMS8yMC8xMlxuICpcbkZUIEMgIEREICAgIEFcbiAgICAgIEFFMjAgICAgIDAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgIDMgIDAgIDJcbiogICAgICAlRlNcbiogICAgIEFFMjAgICAgIDAgICAgICAgIDAgICAgICAgIDAgICAgICAgIEJ1Zy1jYW4ndCBwdXQgYmVmb3JlIHNvIHB1dCBhZnRlci1zbyBjYW4ndCBtYWtlIDIgZml4ZWQgMTAvMjgvMTJcbiBBRTE5IEFFMjAgICA5LjMgICAgNjAuMCAgNjAuMC0zNi4wICAgICAgIDIgMTIgIDAgMjBcbiBBRTE4IEFFMTkgIDI0LjUgICAgIDAuMCAgIDAuMC05MC4wICAgICAgIDYgMTAgMjUgIDBcbiBBRTE3IEFFMTggICA4LjAgICAzNTAuNSAzNTAuNSAxNy4wICAgICAgIDMgIDUgIDAgIDBcbiBBRTE2IEFFMTcgICA2LjcgICAgIDAuMCAgIDAuMC05MC4wICAgICAgIDMgIDUgIDYgIDFcbiBBRTE1IEFFMTYgIDEyLjYgICAgNzAuNSAgNzEuMC0xOC4wICAgICAgIDQgIDAgIDIgIDFcbiBBRTE0IEFFMTUgIDEwLjAgICAgMjEuNSAgMjAuMCAgNi4wICAgICAgIDUgIDUgIDAgIDNcbiBBRTEzIEFFMTQgIDI2LjggICAyODguMCAyODYuMC01MC4wICAgICAgIDAgIDcgMjAgIDVcbipcbipTSE9SVCBDQU5ZT04gQVQgVEhFIEJBU0UgT0YgVEhFIFNFQ09ORCBEUk9QXG4gQUUxMiBBRTEzICAyMC43ICAgMjM2LjAgMjM2LjAgMzQuMCAgICAgICAzICA1ICA0ICA0XG4gQUUxMSBBRTEyICAxMi40ICAgMjEwLjAgMjEwLjAgMzUuMCAgICAgICA3ICA0ICA1ICAxXG4gQUUxMCBBRTEzICAyNS43ICAgIDQwLjAgIDQwLjAgLTkuMCAgICAgICAyICAyICAzICA2XG4qXG4qQUUxMCBBVCBKT0UnUyBcIiBJIExPVkUgTVkgV0lGRSBUUkFWRVJTRSBcIlxuICBBRTkgQUUxMCAgMTcuOCAgICAzMi41ICAzMS4wIDIzLjAgICAgICAgNCAgNSAyMCAxNVxuICBBRTEgIEFFOSAgMTMuNyAgICA4Mi4wICA4Mi4wLTEzLjBcbiAgIEExICBBRTEgIDM0LjMgICAgNDYuMCAgNDguMC0xNy41XG4qXG4qU1VSVkVZIFRPIERPTUUgTkVBUiBUSEUgRU5UUkFOQ0UgRE9NRSAoQUJPVkUgVEhFIFNFQ09ORCBEUk9QKVxuICBBRDEgQUUxNSAgIDguMCAgIDIwMC4wIDIwMC4wICAwLjAgICAgICAgMyAgMSAgMSAgMVxuICBBRDIgIEFEMSAgMTcuNyAgIDE2MS4wIDE2MS4wICA3LjAgICAgICAgMSAgNCAyNSAgMVxuICBBRDMgIEFEMiAgMTAuNCAgIDE4MC4wIDE4MC4wIDUwLjAgICAgICAgNCAgMSAxNSAgNVxuICpcblRSSUNLWSBUUkFWRVJTRSBBTkQgVEhFTiBGSVJTVCBTVVJWRVkgSU4gVVBQRVIgQ1JPV0xXQVlcbkRBTiBDUk9XTCwgS0VJVEggT1JUSVosIENISVAgSE9QUEVSLCBQRVRFUiBRVUlDSywgTEFSUlkgQkVBTiAgICAxNCBGRUIgMTk4MVxuICpcbkZJIEIgIEREXG4gICBBMiAgIEExICA0OCAxMCAgMjkyLjAgMTEwLjAtNDIuMCAgICAgICA1IDEwIDM1ICA1XG4gICBBMyAgIEEyICAxMiAgNSAgMzMzLjUgMTUzLjUgMzUuMCAgICAgICAzICAxIDE1ICA1XG4gICBBNCAgIEEzICAgNCAgMiAgICAwLjAgICAwLjAgOTAuMCAgICAgICAzICAxIDEwIDEwXG4uLi48L3ByZT5cbiAqXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGFzeW5jIGZ1bmN0aW9uIHBhcnNlRnJjc1N1cnZleUZpbGUoXG4gIGZpbGU6IGFueSwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIGxpbmVzOiBBc3luY0l0ZXJhYmxlPHN0cmluZz5cbik6IFByb21pc2U8RnJjc1N1cnZleUZpbGU+IHtcbiAgbGV0IGNhdmU6IHN0cmluZyB8IG51bGwgPSBudWxsXG4gIGxldCBsb2NhdGlvbjogc3RyaW5nIHwgbnVsbCA9IG51bGxcbiAgY29uc3QgdHJpcHM6IEFycmF5PEZyY3NUcmlwPiA9IFtdXG4gIGNvbnN0IGVycm9yczogQXJyYXk8U2VnbWVudFBhcnNlRXJyb3I+ID0gW11cblxuICBsZXQgdHJpcE5hbWVcbiAgbGV0IHRyaXBUZWFtXG4gIGxldCB0cmlwRGF0ZVxuICBsZXQgaW5UcmlwQ29tbWVudCA9IHRydWVcbiAgbGV0IHRyaXBDb21tZW50U3RhcnRMaW5lID0gMVxuICBsZXQgdHJpcENvbW1lbnRFbmRMaW5lID0gLTFcbiAgbGV0IHRyaXBDb21tZW50OiBBcnJheTxzdHJpbmc+ID0gW11cbiAgbGV0IGNvbW1lbnRMaW5lczogQXJyYXk8c3RyaW5nPiB8IG51bGwgPSBudWxsXG4gIGxldCB0cmlwOiBGcmNzVHJpcCB8IG51bGwgPSBudWxsXG4gIGxldCBpbkJsb2NrQ29tbWVudCA9IGZhbHNlXG4gIGxldCBzZWN0aW9uXG4gIGNvbnN0IGNvbW1lbnRGcm9tU3RhdGlvbkxydWRzOiBNYXA8XG4gICAgc3RyaW5nLFxuICAgIE5vbk51bGxhYmxlPEZyY3NTaG90Wydmcm9tTHJ1ZHMnXT5cbiAgPiA9IG5ldyBNYXAoKVxuXG4gIGZ1bmN0aW9uIGFkZENvbW1lbnRMaW5lKGNvbW1lbnQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0cmlwKSB7XG4gICAgICBjb25zdCBkaXN0YW5jZVVuaXQgPSB0cmlwLmhlYWRlci5kaXN0YW5jZVVuaXRcbiAgICAgIGNvbnN0IHBhcnNlZEZyb21TdGF0aW9uTHJ1ZHMgPSBwYXJzZUZyb21TdGF0aW9uTHJ1ZHMoXG4gICAgICAgIGNvbW1lbnQsXG4gICAgICAgIGRpc3RhbmNlVW5pdFxuICAgICAgKVxuICAgICAgaWYgKHBhcnNlZEZyb21TdGF0aW9uTHJ1ZHMpIHtcbiAgICAgICAgY29tbWVudEZyb21TdGF0aW9uTHJ1ZHMuc2V0KFxuICAgICAgICAgIHBhcnNlZEZyb21TdGF0aW9uTHJ1ZHNbMF0sXG4gICAgICAgICAgcGFyc2VkRnJvbVN0YXRpb25McnVkc1sxXVxuICAgICAgICApXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoY29tbWVudExpbmVzKSB7XG4gICAgICBjb21tZW50TGluZXMucHVzaChjb21tZW50KVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGdldENvbW1lbnQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgaWYgKCFjb21tZW50TGluZXMpIHJldHVybiBudWxsXG4gICAgY29uc3QgY29tbWVudCA9IGNvbW1lbnRMaW5lcy5qb2luKCdcXG4nKS50cmltKClcbiAgICBjb21tZW50TGluZXMgPSBudWxsXG4gICAgcmV0dXJuIGNvbW1lbnQgfHwgbnVsbFxuICB9XG5cbiAgbGV0IGxpbmVOdW1iZXIgPSAwXG5cbiAgZm9yIGF3YWl0IChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgbGV0IGVycm9yZWQgPSBmYWxzZVxuXG4gICAgY29uc3QgdGhpc0xpbmVOdW1iZXIgPSBsaW5lTnVtYmVyXG5cbiAgICBjb25zdCBlcnJvciA9IChcbiAgICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICAgIHN0YXJ0Q29sdW1uOiBudW1iZXIsXG4gICAgICBlbmRDb2x1bW46IG51bWJlclxuICAgICk6IHZvaWQgPT4ge1xuICAgICAgZXJyb3JlZCA9IHRydWVcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBuZXcgU2VnbWVudFBhcnNlRXJyb3IoXG4gICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgICBuZXcgU2VnbWVudCh7XG4gICAgICAgICAgICB2YWx1ZTogbGluZSxcbiAgICAgICAgICAgIHNvdXJjZTogZmlsZSxcbiAgICAgICAgICAgIHN0YXJ0TGluZTogdGhpc0xpbmVOdW1iZXIsXG4gICAgICAgICAgICBzdGFydENvbDogMCxcbiAgICAgICAgICB9KS5zdWJzdHJpbmcoc3RhcnRDb2x1bW4sIGVuZENvbHVtbilcbiAgICAgICAgKVxuICAgICAgKVxuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkYXRlID0gKFxuICAgICAgc3RhcnRDb2x1bW46IG51bWJlcixcbiAgICAgIGVuZENvbHVtbjogbnVtYmVyLFxuICAgICAgZmllbGROYW1lOiBzdHJpbmcsXG4gICAgICB2YWxpZGF0b3I6ICh2YWx1ZTogc3RyaW5nKSA9PiBib29sZWFuXG4gICAgKTogc3RyaW5nID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkID0gbGluZS5zdWJzdHJpbmcoc3RhcnRDb2x1bW4sIGVuZENvbHVtbilcbiAgICAgIGlmICghdmFsaWRhdG9yKGZpZWxkKSkge1xuICAgICAgICBlcnJvcihcbiAgICAgICAgICAoZmllbGQudHJpbSgpID8gJ0ludmFsaWQgJyA6ICdNaXNzaW5nICcpICsgZmllbGROYW1lLFxuICAgICAgICAgIHN0YXJ0Q29sdW1uLFxuICAgICAgICAgIGVuZENvbHVtblxuICAgICAgICApXG4gICAgICB9XG4gICAgICByZXR1cm4gZmllbGRcbiAgICB9XG5cbiAgICBsaW5lTnVtYmVyKytcblxuICAgIGlmIChsaW5lTnVtYmVyID09PSAxKSB7XG4gICAgICBjb25zdCBtYXRjaCA9IC9eXFxzKihbXixdKykoLCguKikpPy8uZXhlYyhsaW5lKVxuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIGNhdmUgPSBtYXRjaFsxXS50cmltKClcbiAgICAgICAgaWYgKG1hdGNoWzNdKSB7XG4gICAgICAgICAgbG9jYXRpb24gPSBtYXRjaFszXS50cmltKClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChsaW5lLmNoYXJBdCgwKSA9PT0gJyAnICYmIGxpbmUuY2hhckF0KDEpID09PSAnKicpIHtcbiAgICAgIGluVHJpcENvbW1lbnQgPSAhaW5UcmlwQ29tbWVudFxuICAgICAgaWYgKGluVHJpcENvbW1lbnQpIHtcbiAgICAgICAgc2VjdGlvbiA9IHVuZGVmaW5lZFxuICAgICAgICB0cmlwQ29tbWVudCA9IFtdXG4gICAgICAgIHRyaXBDb21tZW50U3RhcnRMaW5lID0gbGluZU51bWJlclxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJpcENvbW1lbnRFbmRMaW5lID0gbGluZU51bWJlclxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaW5UcmlwQ29tbWVudCkge1xuICAgICAgaWYgKGxpbmVOdW1iZXIgPT09IHRyaXBDb21tZW50U3RhcnRMaW5lICsgMSkge1xuICAgICAgICB0cmlwTmFtZSA9IGxpbmUgJiYgbGluZS50cmltKClcbiAgICAgIH0gZWxzZSBpZiAobGluZU51bWJlciA9PT0gdHJpcENvbW1lbnRTdGFydExpbmUgKyAyKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gL14oLis/KVxccypbLS5dXFxzKihcXGQrKVxcLyhcXGQrKVxcLyhcXGQrKSQvLmV4ZWMoXG4gICAgICAgICAgbGluZSAmJiBsaW5lLnRyaW0oKVxuICAgICAgICApXG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgIGxldCBrID0gMVxuICAgICAgICAgIGNvbnN0IHRlYW0gPSBtYXRjaFtrKytdXG4gICAgICAgICAgY29uc3QgbW9udGggPSBwYXJzZUludChtYXRjaFtrKytdKVxuICAgICAgICAgIGNvbnN0IGRheSA9IHBhcnNlSW50KG1hdGNoW2srK10pXG4gICAgICAgICAgY29uc3QgeWVhciA9IHBhcnNlSW50KG1hdGNoW2srK10pXG4gICAgICAgICAgdHJpcERhdGUgPSBuZXcgRGF0ZSh5ZWFyIDwgNzAgPyB5ZWFyICsgMjAwMCA6IHllYXIsIG1vbnRoIC0gMSwgZGF5KVxuICAgICAgICAgIHRyaXBUZWFtID0gdGVhbS5zcGxpdChcbiAgICAgICAgICAgIHRlYW0uaW5kZXhPZignOycpID49IDAgPyAvXFxzKjtcXHMqL2cgOiAvXFxzKixcXHMqL2dcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobGluZU51bWJlciA+IDEpIHtcbiAgICAgICAgdHJpcENvbW1lbnQucHVzaChsaW5lKVxuICAgICAgfVxuICAgICAgY29uc3QgbWF0Y2ggPSAvXlxcKlxcKlxcKihbXipdKVxcKlxcKlxcKi8uZXhlYyhsaW5lKVxuICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgIHNlY3Rpb24gPSBtYXRjaFsxXS50cmltKClcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxpbmUuY2hhckF0KDApID09PSAnKicpIHtcbiAgICAgIGluQmxvY2tDb21tZW50ID0gIWluQmxvY2tDb21tZW50XG4gICAgICBpZiAoaW5CbG9ja0NvbW1lbnQpIGNvbW1lbnRMaW5lcyA9IFtdXG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc3QgcGFydCA9IGxpbmUuc3Vic3RyaW5nKDEpXG4gICAgICAgIGlmIChwYXJ0KSBhZGRDb21tZW50TGluZShwYXJ0KVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaW5CbG9ja0NvbW1lbnQpIHtcbiAgICAgIGFkZENvbW1lbnRMaW5lKGxpbmUpXG4gICAgfSBlbHNlIGlmIChsaW5lTnVtYmVyID09PSB0cmlwQ29tbWVudEVuZExpbmUgKyAxKSB7XG4gICAgICAvLyBGVCBDQyBERFxuICAgICAgLy8gMDEyMzQ1NjdcbiAgICAgIGxldCBkaXN0YW5jZVVuaXQgPSBwYXJzZUxlbmd0aFVuaXQobGluZS5zbGljZSgwLCAyKSlcbiAgICAgIGlmICghZGlzdGFuY2VVbml0KSB7XG4gICAgICAgIGRpc3RhbmNlVW5pdCA9IExlbmd0aC5mZWV0XG4gICAgICAgIGVycm9yKCdJbnZhbGlkIGRpc3RhbmNlIHVuaXQnLCAwLCAyKVxuICAgICAgfVxuICAgICAgbGV0IGF6aW11dGhVbml0ID0gcGFyc2VBbmdsZVVuaXQobGluZVs2XSlcbiAgICAgIGlmICghYXppbXV0aFVuaXQpIHtcbiAgICAgICAgYXppbXV0aFVuaXQgPSBBbmdsZS5kZWdyZWVzXG4gICAgICAgIGVycm9yKCdJbnZhbGlkIGF6aW11dGggdW5pdCcsIDYsIDcpXG4gICAgICB9XG4gICAgICBsZXQgaW5jbGluYXRpb25Vbml0ID0gcGFyc2VBbmdsZVVuaXQobGluZVs3XSlcbiAgICAgIGlmICghaW5jbGluYXRpb25Vbml0KSB7XG4gICAgICAgIGluY2xpbmF0aW9uVW5pdCA9IEFuZ2xlLmRlZ3JlZXNcbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgaW5jbGluYXRpb24gdW5pdCcsIDcsIDgpXG4gICAgICB9XG4gICAgICBjb25zdCBiYWNrc2lnaHRBemltdXRoQ29ycmVjdGVkID0gbGluZVszXSA9PT0gJ0MnXG4gICAgICBjb25zdCBiYWNrc2lnaHRJbmNsaW5hdGlvbkNvcnJlY3RlZCA9IGxpbmVbNF0gPT09ICdDJ1xuICAgICAgY29uc3QgaGFzQmFja3NpZ2h0QXppbXV0aCA9IGxpbmVbM10gIT09ICcgJyAmJiBsaW5lWzNdICE9PSAnLSdcbiAgICAgIGNvbnN0IGhhc0JhY2tzaWdodEluY2xpbmF0aW9uID0gbGluZVs0XSAhPT0gJyAnICYmIGxpbmVbNF0gIT09ICctJ1xuXG4gICAgICBpZiAoIS9bLUNCIF0vLnRlc3QobGluZVszXSkpIHtcbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgYmFja3NpZ2h0IGF6aW11dGggdHlwZScsIDMsIDQpXG4gICAgICB9XG4gICAgICBpZiAoIS9bLUNCIF0vLnRlc3QobGluZVs0XSkpIHtcbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgYmFja3NpZ2h0IGluY2xpbmF0aW9uIHR5cGUnLCA0LCA1KVxuICAgICAgfVxuXG4gICAgICB0cmlwID0ge1xuICAgICAgICBoZWFkZXI6IHtcbiAgICAgICAgICBuYW1lOiB0cmlwTmFtZSB8fCAnJyxcbiAgICAgICAgICBjb21tZW50OiAodHJpcENvbW1lbnQgJiYgdHJpcENvbW1lbnQuam9pbignXFxuJykpIHx8IG51bGwsXG4gICAgICAgICAgc2VjdGlvbixcbiAgICAgICAgICBkYXRlOiB0cmlwRGF0ZSxcbiAgICAgICAgICB0ZWFtOiB0cmlwVGVhbSxcbiAgICAgICAgICBkaXN0YW5jZVVuaXQsXG4gICAgICAgICAgYXppbXV0aFVuaXQsXG4gICAgICAgICAgaW5jbGluYXRpb25Vbml0LFxuICAgICAgICAgIGJhY2tzaWdodEF6aW11dGhDb3JyZWN0ZWQsXG4gICAgICAgICAgYmFja3NpZ2h0SW5jbGluYXRpb25Db3JyZWN0ZWQsXG4gICAgICAgICAgaGFzQmFja3NpZ2h0QXppbXV0aCxcbiAgICAgICAgICBoYXNCYWNrc2lnaHRJbmNsaW5hdGlvbixcbiAgICAgICAgfSxcbiAgICAgICAgc2hvdHM6IFtdLFxuICAgICAgfVxuICAgICAgdHJpcHMucHVzaCh0cmlwKVxuICAgIH0gZWxzZSBpZiAodHJpcCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBzaG90cyxcbiAgICAgICAgaGVhZGVyOiB7IGF6aW11dGhVbml0LCBpbmNsaW5hdGlvblVuaXQgfSxcbiAgICAgIH0gPSB0cmlwXG4gICAgICBsZXQgeyBkaXN0YW5jZVVuaXQgfSA9IHRyaXAuaGVhZGVyXG5cbiAgICAgIGNvbnN0IGluY2hlcyA9IGRpc3RhbmNlVW5pdCA9PT0gTGVuZ3RoLmluY2hlc1xuICAgICAgaWYgKGluY2hlcykgZGlzdGFuY2VVbml0ID0gTGVuZ3RoLmZlZXRcblxuICAgICAgLy8gcmlnb3JvdXNseSBjaGVjayB0aGUgdmFsdWVzIGluIGFsbCB0aGUgY29sdW1ucyB0byBtYWtlIHN1cmUgdGhpc1xuICAgICAgLy8gaXMgcmVhbGx5IGEgc3VydmV5IHNob3QgbGluZSwganVzdCBpbiBjYXNlIGFueSBzdHJheSBjb21tZW50cyBhcmVcbiAgICAgIC8vIG5vdCBwcm9wZXJseSBkZWxpbWl0ZWQuXG5cbiAgICAgIC8vIGZyb20gc3RhdGlvbiBuYW1lXG4gICAgICBpZiAoIS9cXFMvLnRlc3QobGluZS5zdWJzdHJpbmcoNSwgMTApKSkgY29udGludWVcbiAgICAgIGNvbnN0IGZyb21TdHIgPSB2YWxpZGF0ZSg1LCAxMCwgJ2Zyb20gc3RhdGlvbicsIGlzVmFsaWRTdGF0aW9uKVxuICAgICAgY29uc3QgZnJvbSA9IGZyb21TdHIudHJpbSgpXG5cbiAgICAgIC8vIFNhZGx5IEkgaGF2ZSBmb3VuZCBuZWdhdGl2ZSBMUlVEIHZhbHVlcyBpbiBDaGlwJ3MgZm9ybWF0IGFuZCBhcHBhcmVudGx5XG4gICAgICAvLyBoaXMgcHJvZ3JhbSBkb2Vzbid0IGZhaWwgb24gdGhlbSwgc28gSSBoYXZlIHRvIGFjY2VwdCB0aGVtIGhlcmVcbiAgICAgIC8vIGlzVmFsaWRPcHRGbG9hdCBpbnN0ZWFkIG9mIGlzVmFsaWRPcHRVRmxvYXRcbiAgICAgIGNvbnN0IGxTdHIgPSB2YWxpZGF0ZSg0MCwgNDMsICdsZWZ0JywgaXNWYWxpZE9wdEZsb2F0KVxuICAgICAgY29uc3QgclN0ciA9IHZhbGlkYXRlKDQzLCA0NiwgJ3JpZ2h0JywgaXNWYWxpZE9wdEZsb2F0KVxuICAgICAgY29uc3QgdVN0ciA9IHZhbGlkYXRlKDQ2LCA0OSwgJ3VwJywgaXNWYWxpZE9wdEZsb2F0KVxuICAgICAgY29uc3QgZFN0ciA9IHZhbGlkYXRlKDQ5LCA1MiwgJ2Rvd24nLCBpc1ZhbGlkT3B0RmxvYXQpXG5cbiAgICAgIGlmIChlcnJvcmVkKSBjb250aW51ZVxuXG4gICAgICBjb25zdCB1cCA9IHBhcnNlTHJ1ZCh1U3RyLCBkaXN0YW5jZVVuaXQpXG4gICAgICBjb25zdCBkb3duID0gcGFyc2VMcnVkKGRTdHIsIGRpc3RhbmNlVW5pdClcbiAgICAgIGNvbnN0IGxlZnQgPSBwYXJzZUxydWQobFN0ciwgZGlzdGFuY2VVbml0KVxuICAgICAgY29uc3QgcmlnaHQgPSBwYXJzZUxydWQoclN0ciwgZGlzdGFuY2VVbml0KVxuXG4gICAgICAvLyB0byBzdGF0aW9uIG5hbWVcbiAgICAgIGNvbnN0IHRvU3RyID0gbGluZS5zdWJzdHJpbmcoMCwgNSlcbiAgICAgIGlmICghdG9TdHIudHJpbSgpKSB7XG4gICAgICAgIGNvbnN0IHNob3Q6IEZyY3NTaG90ID0ge1xuICAgICAgICAgIGZyb20sXG4gICAgICAgICAgdG86IG51bGwsXG4gICAgICAgICAga2luZDogRnJjc1Nob3RLaW5kLk5vcm1hbCxcbiAgICAgICAgICBkaXN0YW5jZTogbmV3IFVuaXRpemVkTnVtYmVyKDAsIGRpc3RhbmNlVW5pdCksXG4gICAgICAgICAgZnJvbnRzaWdodEF6aW11dGg6IG51bGwsXG4gICAgICAgICAgYmFja3NpZ2h0QXppbXV0aDogbnVsbCxcbiAgICAgICAgICBmcm9udHNpZ2h0SW5jbGluYXRpb246IG51bGwsXG4gICAgICAgICAgYmFja3NpZ2h0SW5jbGluYXRpb246IG51bGwsXG4gICAgICAgICAgZnJvbUxydWRzOiB7XG4gICAgICAgICAgICBsZWZ0LFxuICAgICAgICAgICAgcmlnaHQsXG4gICAgICAgICAgICB1cCxcbiAgICAgICAgICAgIGRvd24sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBleGNsdWRlRGlzdGFuY2U6IHRydWUsXG4gICAgICAgICAgY29tbWVudDogZ2V0Q29tbWVudCgpLFxuICAgICAgICB9XG4gICAgICAgIHNob3RzLnB1c2goc2hvdClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGlmICghaXNWYWxpZFN0YXRpb24odG9TdHIpKSB7XG4gICAgICAgIGVycm9yKCdJbnZhbGlkIHN0YXRpb24gbmFtZScsIDAsIDUpXG4gICAgICB9XG5cbiAgICAgIGxldCBmcm9tTHJ1ZHMgPSBjb21tZW50RnJvbVN0YXRpb25McnVkcy5nZXQoZnJvbSlcbiAgICAgIGlmIChmcm9tTHJ1ZHMpIHtcbiAgICAgICAgY29tbWVudEZyb21TdGF0aW9uTHJ1ZHMuZGVsZXRlKGZyb20pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBmcm9tTHJ1ZE1hdGNoID0gbmV3IFJlZ0V4cChcbiAgICAgICAgICBgXlxcXFxzKyR7ZnJvbVN0clxuICAgICAgICAgICAgLnRyaW0oKVxuICAgICAgICAgICAgLnJlcGxhY2UoXG4gICAgICAgICAgICAgIC9bLiorP14ke30oKXxbXFxdXFxcXF0vZyxcbiAgICAgICAgICAgICAgJ1xcXFwkJidcbiAgICAgICAgICAgICl9KChcXFxccysoXFxcXGQrKFxcXFwuXFxcXGQqKT98XFxcXC5cXFxcZCspKXs0fSlgXG4gICAgICAgICkuZXhlYyhsaW5lLnN1YnN0cmluZyg1MikpXG4gICAgICAgIGlmIChmcm9tTHJ1ZE1hdGNoKSB7XG4gICAgICAgICAgY29uc3QgW2xlZnQsIHJpZ2h0LCB1cCwgZG93bl0gPSBmcm9tTHJ1ZE1hdGNoWzFdXG4gICAgICAgICAgICAudHJpbSgpXG4gICAgICAgICAgICAuc3BsaXQoL1xccysvZylcbiAgICAgICAgICAgIC5tYXAocyA9PiBwYXJzZUxydWQocywgZGlzdGFuY2VVbml0KSlcbiAgICAgICAgICBmcm9tTHJ1ZHMgPSB7IGxlZnQsIHJpZ2h0LCB1cCwgZG93biB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgY29tbWVudCA9IGdldENvbW1lbnQoKVxuXG4gICAgICAvLyBhemltdXRoIGFuZCBpbmNsaW5hdGlvblxuICAgICAgY29uc3QgYXptRnNTdHIgPSB2YWxpZGF0ZSgxOSwgMjUsICdhemltdXRoJywgaXNWYWxpZE9wdFVGbG9hdClcbiAgICAgIGNvbnN0IGF6bUJzU3RyID0gdmFsaWRhdGUoMjUsIDMwLCAnYXppbXV0aCcsIGlzVmFsaWRPcHRVRmxvYXQpXG4gICAgICBjb25zdCBpbmNGc1N0ciA9IGxpbmUuc3Vic3RyaW5nKDMwLCAzNSlcbiAgICAgIGNvbnN0IGluY0JzU3RyID0gbGluZS5zdWJzdHJpbmcoMzUsIDQwKVxuXG4gICAgICBpZiAoZXJyb3JlZCkgY29udGludWVcblxuICAgICAgbGV0IGtpbmQ6IEZyY3NTaG90S2luZFxuICAgICAgbGV0IGRpc3RhbmNlOiBVbml0aXplZE51bWJlcjxMZW5ndGg+XG4gICAgICBsZXQgaG9yaXpvbnRhbERpc3RhbmNlOiBVbml0aXplZE51bWJlcjxMZW5ndGg+IHwgdW5kZWZpbmVkXG4gICAgICBsZXQgdmVydGljYWxEaXN0YW5jZTogVW5pdGl6ZWROdW1iZXI8TGVuZ3RoPiB8IHVuZGVmaW5lZFxuICAgICAgbGV0IGZyb250c2lnaHRJbmNsaW5hdGlvbjogVW5pdGl6ZWROdW1iZXI8QW5nbGU+IHwgbnVsbFxuICAgICAgbGV0IGJhY2tzaWdodEluY2xpbmF0aW9uOiBVbml0aXplZE51bWJlcjxBbmdsZT4gfCBudWxsXG4gICAgICBsZXQgZXhjbHVkZURpc3RhbmNlOiBib29sZWFuXG4gICAgICBsZXQgaXNTcGxheTogYm9vbGVhblxuXG4gICAgICAvLyBwYXJzZSBkaXN0YW5jZVxuICAgICAgaWYgKGluY2hlcykge1xuICAgICAgICBjb25zdCBmZWV0U3RyID0gbGluZS5zdWJzdHJpbmcoMTAsIDE0KVxuICAgICAgICBjb25zdCBpbmNoZXNTdHIgPSBsaW5lLnN1YnN0cmluZygxNCwgMTcpXG4gICAgICAgIC8vIGZlZXQgYW5kIGluY2hlcyBhcmUgbm90IGJvdGggb3B0aW9uYWxcbiAgICAgICAgaWYgKCFpc1ZhbGlkVUludChmZWV0U3RyKSAmJiAhaXNWYWxpZFVJbnQoaW5jaGVzU3RyKSkge1xuICAgICAgICAgIGNvbnN0IGludmFsaWQgPSBmZWV0U3RyLnRyaW0oKSB8fCBpbmNoZXNTdHIudHJpbSgpXG4gICAgICAgICAgZXJyb3IoaW52YWxpZCA/ICdJbnZhbGlkIGRpc3RhbmNlJyA6ICdNaXNzaW5nIGRpc3RhbmNlJywgMTAsIDE3KVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyBzb21ldGltZXMgaW5jaGVzIGFyZSBvbWl0dGVkLCBoZW5jZSB0aGUgfHwgMC4uLkknbSBhc3N1bWluZyBpdCdzIHBvc3NpYmxlXG4gICAgICAgIC8vIGZvciBmZWV0IHRvIGJlIG9taXR0ZWQgYXMgd2VsbFxuICAgICAgICBkaXN0YW5jZSA9IFVuaXRpemUuaW5jaGVzKHBhcnNlRmxvYXQoaW5jaGVzU3RyKSB8fCAwKS5hZGQoXG4gICAgICAgICAgVW5pdGl6ZS5mZWV0KHBhcnNlRmxvYXQoZmVldFN0cikgfHwgMClcbiAgICAgICAgKVxuXG4gICAgICAgIGtpbmQgPSBwYXJzZUtpbmQobGluZVsxN10pXG4gICAgICAgIC8vIE5PVEUgdGhlcmUgYXJlIHR3byBjb2x1bW5zIGFyb3VuZCBoZXJlIHRoYXQgY2FuIGNvbnRhaW4gYSAqLlxuICAgICAgICAvLyBJIHRoaW5rIHRoZXkgbWlnaHQgcmVwcmVzZW50IGRpZmZlcmVudCB2YWx1ZXMsIGJ1dCB0aGlzaXMgY29uZnVzZWQgYnlcbiAgICAgICAgLy8gdGhlIGZhY3QgdGhhdCBmb3IgZnQvaW4gc2hvdHMsIGlmIHRoZXJlIGlzIGEgRCBvciBIIGZsYWcgaXQgb2NjdXBpZXMgdGhlXG4gICAgICAgIC8vIGZpcnN0IGNvbHVtbiB0aGF0IGNhbiBjb250YWluIGEgKiBmb3IgZGVjaW1hbCBmZWV0IHNob3RzXG4gICAgICAgIGV4Y2x1ZGVEaXN0YW5jZSA9IGxpbmVbMThdID09PSAnKicgfHwgbGluZVsxOF0gPT09ICdzJ1xuICAgICAgICBpc1NwbGF5ID0gbGluZVsxOF0gPT09ICdzJ1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZGVjaW1hbCBmZWV0IGFyZSBub3Qgb3B0aW9uYWxcbiAgICAgICAgY29uc3QgZmVldFN0ciA9IHZhbGlkYXRlKDEwLCAxNiwgJ2Rpc3RhbmNlJywgaXNWYWxpZFVGbG9hdClcbiAgICAgICAgZGlzdGFuY2UgPSBuZXcgVW5pdGl6ZWROdW1iZXIocGFyc2VGbG9hdChmZWV0U3RyKSwgZGlzdGFuY2VVbml0KVxuICAgICAgICBraW5kID0gcGFyc2VLaW5kKGxpbmVbMTZdKVxuICAgICAgICBleGNsdWRlRGlzdGFuY2UgPSBsaW5lWzE3XSA9PT0gJyonIHx8IGxpbmVbMTddID09PSAncydcbiAgICAgICAgaXNTcGxheSA9IGxpbmVbMTddID09PSAncydcbiAgICAgIH1cblxuICAgICAgaWYgKGtpbmQgIT09IEZyY3NTaG90S2luZC5Ob3JtYWwpIHtcbiAgICAgICAgdmFsaWRhdGUoMzAsIDM1LCAndmVydGljYWwtZGlzdGFuY2UnLCBpc1ZhbGlkRmxvYXQpXG4gICAgICB9XG5cbiAgICAgIC8vIGNvbnZlcnQgaG9yaXpvbnRhbCBhbmQgZGlhZ29uYWwgc2hvdHMgdG8gc3RhbmRhcmRcbiAgICAgIC8vIGluIHRoaXMgY2FzZSBpbmNGcyBpcyB0aGUgdmVydGljYWwgb2Zmc2V0IGJldHdlZW4gc3RhdGlvbnNcbiAgICAgIC8vIGZvcnR1bmF0ZWx5IGl0IGFwcGVhcnMgd2UgY2FuIGFsd2F5cyBjb3VudCBvbiBpbmNGcyBiZWluZyBzcGVjaWZpZWRcbiAgICAgIC8vIGFuZCBpbmNCcyBub3QgYmVpbmcgc3BlY2lmaWVkIGZvciB0aGVzZSB0eXBlcyBvZiBzaG90c1xuICAgICAgaWYgKGtpbmQgPT09IEZyY3NTaG90S2luZC5Ib3Jpem9udGFsKSB7XG4gICAgICAgIC8vIGRpc3RhbmNlIGlzIGhvcml6b250YWwgb2Zmc2V0IGFuZCBpbmNGc1N0ciBpcyB2ZXJ0aWNhbCBvZmZzZXRcbiAgICAgICAgaG9yaXpvbnRhbERpc3RhbmNlID0gZGlzdGFuY2VcbiAgICAgICAgY29uc3QgaCA9IGhvcml6b250YWxEaXN0YW5jZS5nZXQoZGlzdGFuY2VVbml0KVxuICAgICAgICBjb25zdCB2ID0gcGFyc2VGbG9hdChpbmNGc1N0cilcbiAgICAgICAgdmVydGljYWxEaXN0YW5jZSA9IG5ldyBVbml0aXplZE51bWJlcih2LCBkaXN0YW5jZVVuaXQpXG4gICAgICAgIGRpc3RhbmNlID0gbmV3IFVuaXRpemVkTnVtYmVyKE1hdGguc3FydChoICogaCArIHYgKiB2KSwgZGlzdGFuY2VVbml0KVxuICAgICAgICBmcm9udHNpZ2h0SW5jbGluYXRpb24gPSBBbmdsZS5hdGFuMihcbiAgICAgICAgICB2ZXJ0aWNhbERpc3RhbmNlLFxuICAgICAgICAgIGhvcml6b250YWxEaXN0YW5jZVxuICAgICAgICApXG4gICAgICAgIGJhY2tzaWdodEluY2xpbmF0aW9uID0gbnVsbFxuICAgICAgfSBlbHNlIGlmIChraW5kID09PSBGcmNzU2hvdEtpbmQuRGlhZ29uYWwpIHtcbiAgICAgICAgLy8gZGlzdGFuY2UgaXMgYXMgdXN1YWwsIGJ1dCBpbmNGc1N0ciBpcyB2ZXJ0aWNhbCBvZmZzZXRcbiAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlLmdldChkaXN0YW5jZVVuaXQpXG4gICAgICAgIGNvbnN0IHYgPSBwYXJzZUZsb2F0KGluY0ZzU3RyKVxuICAgICAgICB2ZXJ0aWNhbERpc3RhbmNlID0gbmV3IFVuaXRpemVkTnVtYmVyKHYsIGRpc3RhbmNlVW5pdClcbiAgICAgICAgZnJvbnRzaWdodEluY2xpbmF0aW9uID0gQW5nbGUuYXNpbih2IC8gZClcbiAgICAgICAgYmFja3NpZ2h0SW5jbGluYXRpb24gPSBudWxsXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBmcm9udHNpZ2h0IGluY2xpbmF0aW9uXG4gICAgICAgIHZhbGlkYXRlKDMwLCAzNSwgJ2luY2xpbmF0aW9uJywgaXNWYWxpZE9wdEluY2xpbmF0aW9uKVxuICAgICAgICAvLyBmcm9udHNpZ2h0IGluY2xpbmF0aW9uXG4gICAgICAgIHZhbGlkYXRlKDM1LCA0MCwgJ2luY2xpbmF0aW9uJywgaXNWYWxpZE9wdEluY2xpbmF0aW9uKVxuICAgICAgICBmcm9udHNpZ2h0SW5jbGluYXRpb24gPSBwYXJzZU51bWJlcihpbmNGc1N0ciwgaW5jbGluYXRpb25Vbml0KVxuICAgICAgICBiYWNrc2lnaHRJbmNsaW5hdGlvbiA9IHBhcnNlTnVtYmVyKGluY0JzU3RyLCBpbmNsaW5hdGlvblVuaXQpXG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JlZCkgY29udGludWVcblxuICAgICAgY29uc3QgZnJvbnRzaWdodEF6aW11dGggPSBwYXJzZUF6aW11dGgoYXptRnNTdHIsIGF6aW11dGhVbml0KVxuICAgICAgY29uc3QgYmFja3NpZ2h0QXppbXV0aCA9IHBhcnNlQXppbXV0aChhem1Cc1N0ciwgYXppbXV0aFVuaXQpXG5cbiAgICAgIGlmICghZnJvbnRzaWdodEluY2xpbmF0aW9uICYmICFiYWNrc2lnaHRJbmNsaW5hdGlvbikge1xuICAgICAgICBmcm9udHNpZ2h0SW5jbGluYXRpb24gPSBVbml0aXplLmRlZ3JlZXMoMClcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2hvdDogRnJjc1Nob3QgPSB7XG4gICAgICAgIGZyb20sXG4gICAgICAgIHRvOiB0b1N0ci50cmltKCksXG4gICAgICAgIGtpbmQsXG4gICAgICAgIGRpc3RhbmNlLFxuICAgICAgICBmcm9udHNpZ2h0QXppbXV0aCxcbiAgICAgICAgYmFja3NpZ2h0QXppbXV0aCxcbiAgICAgICAgZnJvbnRzaWdodEluY2xpbmF0aW9uLFxuICAgICAgICBiYWNrc2lnaHRJbmNsaW5hdGlvbixcbiAgICAgICAgdG9McnVkczoge1xuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgcmlnaHQsXG4gICAgICAgICAgdXAsXG4gICAgICAgICAgZG93bixcbiAgICAgICAgfSxcbiAgICAgICAgZXhjbHVkZURpc3RhbmNlLFxuICAgICAgICBjb21tZW50LFxuICAgICAgfVxuICAgICAgaWYgKGlzU3BsYXkpIHNob3QuaXNTcGxheSA9IHRydWVcbiAgICAgIGlmIChmcm9tTHJ1ZHMpIHNob3QuZnJvbUxydWRzID0gZnJvbUxydWRzXG4gICAgICBpZiAoaG9yaXpvbnRhbERpc3RhbmNlKSBzaG90Lmhvcml6b250YWxEaXN0YW5jZSA9IGhvcml6b250YWxEaXN0YW5jZVxuICAgICAgaWYgKHZlcnRpY2FsRGlzdGFuY2UpIHNob3QudmVydGljYWxEaXN0YW5jZSA9IHZlcnRpY2FsRGlzdGFuY2VcbiAgICAgIHNob3RzLnB1c2goc2hvdClcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNhdmUsXG4gICAgbG9jYXRpb24sXG4gICAgdHJpcHMsXG4gICAgZXJyb3JzLFxuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBLElBQUFBLGFBQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLFNBQUEsR0FBQUQsT0FBQTtBQVFBLElBQUFFLFNBQUEsR0FBQUYsT0FBQTtBQUVBLFNBQVNHLFdBQVdBLENBQ2xCQyxDQUFTLEVBQ1RDLElBQWEsRUFDYTtFQUMxQixNQUFNQyxLQUFLLEdBQUdDLFVBQVUsQ0FBQ0gsQ0FBQyxDQUFDO0VBQzNCLElBQUlJLEtBQUssQ0FBQ0YsS0FBSyxDQUFDLEVBQUUsT0FBTyxJQUFJO0VBQzdCLE9BQU8sSUFBSUcsd0JBQWMsQ0FBQ0gsS0FBSyxFQUFFRCxJQUFJLENBQUM7QUFDeEM7QUFFQSxTQUFTSyxZQUFZQSxDQUNuQk4sQ0FBUyxFQUNUQyxJQUFpQixFQUNhO0VBQzlCLE1BQU1NLE1BQU0sR0FBR1IsV0FBVyxDQUFDQyxDQUFDLEVBQUVDLElBQUksQ0FBQztFQUNuQyxPQUFPLENBQUFNLE1BQU0sYUFBTkEsTUFBTSx1QkFBTkEsTUFBTSxDQUFFQyxHQUFHLENBQUNDLGVBQUssQ0FBQ0MsT0FBTyxDQUFDLE1BQUssR0FBRyxHQUFHQyxpQkFBTyxDQUFDRCxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUdILE1BQU07QUFDekU7QUFFQSxT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