UNPKG

53 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.renderRoute = undefined;
7
8var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
9
10var _defineProperty3 = _interopRequireDefault(_defineProperty2);
11
12var _keys = require('babel-runtime/core-js/object/keys');
13
14var _keys2 = _interopRequireDefault(_keys);
15
16var _promise = require('babel-runtime/core-js/promise');
17
18var _promise2 = _interopRequireDefault(_promise);
19
20var _extends2 = require('babel-runtime/helpers/extends');
21
22var _extends3 = _interopRequireDefault(_extends2);
23
24var _regenerator = require('babel-runtime/regenerator');
25
26var _regenerator2 = _interopRequireDefault(_regenerator);
27
28var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
29
30var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
31
32/**
33 * Render route into JS.
34 */
35
36var renderRoute = exports.renderRoute = function () {
37 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(route, options) {
38 var _options$publicPath, publicPath, node;
39
40 return _regenerator2.default.wrap(function _callee$(_context) {
41 while (1) {
42 switch (_context.prev = _context.next) {
43 case 0:
44 (0, _bluebird.promisifyAll)(options.fs);
45 _options$publicPath = options.publicPath;
46 publicPath = _options$publicPath === undefined ? '/' : _options$publicPath;
47 _context.next = 5;
48 return renderRoutePage(route, publicPath, [''], options);
49
50 case 5:
51 node = _context.sent;
52 return _context.abrupt('return', node);
53
54 case 7:
55 case 'end':
56 return _context.stop();
57 }
58 }
59 }, _callee, this);
60 }));
61 return function renderRoute(_x, _x2) {
62 return ref.apply(this, arguments);
63 };
64}();
65
66var renderRoutePage = function () {
67 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(route, path, trace, options) {
68 var indexRoute, childRoutes, key, getComponent, _getComponent;
69
70 return _regenerator2.default.wrap(function _callee2$(_context2) {
71 while (1) {
72 switch (_context2.prev = _context2.next) {
73 case 0:
74 if (!route.route) {
75 _context2.next = 23;
76 break;
77 }
78
79 indexRoute = void 0;
80 childRoutes = [];
81 _context2.t0 = _regenerator2.default.keys(route.route);
82
83 case 4:
84 if ((_context2.t1 = _context2.t0()).done) {
85 _context2.next = 19;
86 break;
87 }
88
89 key = _context2.t1.value;
90
91 if (!(key === 'index')) {
92 _context2.next = 12;
93 break;
94 }
95
96 _context2.next = 9;
97 return renderRoutePage(route.route[key], null, trace, options);
98
99 case 9:
100 indexRoute = _context2.sent;
101 _context2.next = 17;
102 break;
103
104 case 12:
105 _context2.t2 = childRoutes;
106 _context2.next = 15;
107 return renderRoutePage(route.route[key], key, trace.concat(key), options);
108
109 case 15:
110 _context2.t3 = _context2.sent;
111
112 _context2.t2.push.call(_context2.t2, _context2.t3);
113
114 case 17:
115 _context2.next = 4;
116 break;
117
118 case 19:
119 getComponent = renderGetComponent(route.page, {
120 split: options.split !== undefined ? options.split : route.split,
121 chunkName: trace.join('/')
122 });
123 return _context2.abrupt('return', renderRouteSpec({
124 path: path,
125 getComponent: getComponent,
126 indexRoute: indexRoute,
127 childRoutes: childRoutes
128 }));
129
130 case 23:
131 if (!route.collection) {
132 _context2.next = 27;
133 break;
134 }
135
136 return _context2.abrupt('return', renderRouteCollection(route, path, trace, options));
137
138 case 27:
139 _getComponent = renderGetComponent(route.page, {
140 split: options.split !== undefined ? options.split : route.split,
141 chunkName: trace.join('/')
142 });
143 return _context2.abrupt('return', renderRouteSpec({
144 path: path,
145 getComponent: _getComponent
146 }));
147
148 case 29:
149 case 'end':
150 return _context2.stop();
151 }
152 }
153 }, _callee2, this);
154 }));
155 return function renderRoutePage(_x3, _x4, _x5, _x6) {
156 return ref.apply(this, arguments);
157 };
158}();
159
160var renderRouteCollection = function () {
161 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(route, path, trace, options) {
162 var _route$collection, _route$collection$pag, directory, match, paginate, chunkName, name, items, chunks, childRoutes, getComponent, pageParam;
163
164 return _regenerator2.default.wrap(function _callee3$(_context3) {
165 while (1) {
166 switch (_context3.prev = _context3.next) {
167 case 0:
168 _route$collection = route.collection;
169 _route$collection$pag = _route$collection.page;
170 directory = _route$collection$pag.directory;
171 match = _route$collection$pag.match;
172 paginate = _route$collection.paginate;
173 chunkName = trace.join('/');
174 name = chunkName;
175 _context3.next = 9;
176 return walkDirectory(options.fs, directory);
177
178 case 9:
179 _context3.t0 = function (filename) {
180 return match(filename);
181 };
182
183 _context3.t1 = function (filename) {
184 return {
185 filename: filename,
186 path: stripExtension((0, _path.relative)(directory, filename))
187 };
188 };
189
190 items = _context3.sent.filter(_context3.t0).map(_context3.t1);
191 chunks = [items];
192
193 if (paginate) {
194 chunks = (0, _lodash.chunk)(items, paginate.size);
195 }
196
197 chunks = chunks.map(function (chunk, idx) {
198 return renderGetCollectionChunk(chunk, {
199 page: route.page,
200 chunkNumber: idx,
201 chunkCount: chunks.length,
202 loader: META_LOADER,
203 chunkName: trace.concat('@page', idx + 1).join('/'),
204 split: options.split !== undefined ? options.split : true
205 });
206 });
207
208 childRoutes = items.map(function (item) {
209 return renderRouteSpec({
210 path: item.path,
211 getComponent: renderGetComponent(item.filename, {
212 split: options.split !== undefined ? options.split : true,
213 chunkName: trace.concat(item.path).join('/')
214 })
215 });
216 });
217
218 getComponent = function (_param) {
219 return {
220 "type": "FunctionExpression",
221 "id": {
222 "type": "Identifier",
223 "name": "getComponent"
224 },
225 "generator": false,
226 "expression": false,
227 "async": false,
228 "params": [{
229 "type": "Identifier",
230 "name": "nextState"
231 }, {
232 "type": "Identifier",
233 "name": "cb"
234 }],
235 "body": {
236 "type": "BlockStatement",
237 "body": [{
238 "type": "VariableDeclaration",
239 "declarations": [{
240 "type": "VariableDeclarator",
241 "id": {
242 "type": "Identifier",
243 "name": "pageNumber"
244 },
245 "init": {
246 "type": "CallExpression",
247 "callee": {
248 "type": "Identifier",
249 "name": "parseInt"
250 },
251 "arguments": [{
252 "type": "LogicalExpression",
253 "left": {
254 "type": "MemberExpression",
255 "object": {
256 "type": "MemberExpression",
257 "object": {
258 "type": "Identifier",
259 "name": "nextState"
260 },
261 "property": {
262 "type": "Identifier",
263 "name": "params"
264 },
265 "computed": false
266 },
267 "property": {
268 "type": "Identifier",
269 "name": "page"
270 },
271 "computed": false
272 },
273 "operator": "||",
274 "right": {
275 "type": "NumericLiteral",
276 "extra": {
277 "rawValue": 1,
278 "raw": "1"
279 },
280 "value": 1
281 }
282 }, {
283 "type": "NumericLiteral",
284 "extra": {
285 "rawValue": 10,
286 "raw": "10"
287 },
288 "value": 10
289 }]
290 }
291 }],
292 "kind": "var"
293 }, {
294 "type": "VariableDeclaration",
295 "declarations": [{
296 "type": "VariableDeclarator",
297 "id": {
298 "type": "Identifier",
299 "name": "chunkList"
300 },
301 "init": _param
302 }],
303 "kind": "var"
304 }, {
305 "type": "VariableDeclaration",
306 "declarations": [{
307 "type": "VariableDeclarator",
308 "id": {
309 "type": "Identifier",
310 "name": "getCollectionChunk"
311 },
312 "init": {
313 "type": "MemberExpression",
314 "object": {
315 "type": "Identifier",
316 "name": "chunkList"
317 },
318 "property": {
319 "type": "BinaryExpression",
320 "left": {
321 "type": "Identifier",
322 "name": "pageNumber"
323 },
324 "operator": "-",
325 "right": {
326 "type": "NumericLiteral",
327 "extra": {
328 "rawValue": 1,
329 "raw": "1"
330 },
331 "value": 1
332 }
333 },
334 "computed": true
335 }
336 }],
337 "kind": "var"
338 }, {
339 "type": "ExpressionStatement",
340 "expression": {
341 "type": "CallExpression",
342 "callee": {
343 "type": "Identifier",
344 "name": "getCollectionChunk"
345 },
346 "arguments": [{
347 "type": "Identifier",
348 "name": "nextState"
349 }, {
350 "type": "Identifier",
351 "name": "cb"
352 }]
353 }
354 }],
355 "directives": []
356 },
357 "extra": {
358 "parenthesized": true,
359 "parenStart": 0
360 }
361 };
362 }(types.arrayExpression(chunks));
363
364 pageParam = types.arrayExpression(chunks.map(function (_, idx) {
365 return types.numericLiteral(idx + 1);
366 }));
367
368 childRoutes = childRoutes.concat(renderRouteSpec({
369 path: '@page/:page',
370 name: name,
371 params: function (_param2) {
372 return {
373 "type": "ObjectExpression",
374 "properties": [{
375 "type": "ObjectProperty",
376 "method": false,
377 "shorthand": false,
378 "computed": false,
379 "key": {
380 "type": "Identifier",
381 "name": "page"
382 },
383 "value": _param2
384 }],
385 "extra": {
386 "parenthesized": true,
387 "parenStart": 0
388 }
389 };
390 }(pageParam)
391 }));
392
393 return _context3.abrupt('return', renderRouteSpec({
394 path: path,
395 getComponent: getComponent,
396 childRoutes: childRoutes,
397 name: name
398 }));
399
400 case 20:
401 case 'end':
402 return _context3.stop();
403 }
404 }
405 }, _callee3, this);
406 }));
407 return function renderRouteCollection(_x7, _x8, _x9, _x10) {
408 return ref.apply(this, arguments);
409 };
410}();
411
412/**
413 * Render a fetcher for a collection chunk.
414 */
415
416
417var walkDirectory = function () {
418 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee5(fs, directory) {
419 var _this = this;
420
421 var files;
422 return _regenerator2.default.wrap(function _callee5$(_context5) {
423 while (1) {
424 switch (_context5.prev = _context5.next) {
425 case 0:
426 _context5.next = 2;
427 return fs.readdirAsync(directory).then(function (segments) {
428 return _promise2.default.all(segments.map(function () {
429 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4(segment) {
430 var filename, stat;
431 return _regenerator2.default.wrap(function _callee4$(_context4) {
432 while (1) {
433 switch (_context4.prev = _context4.next) {
434 case 0:
435 filename = (0, _path.join)(directory, segment);
436 _context4.next = 3;
437 return fs.statAsync(filename);
438
439 case 3:
440 stat = _context4.sent;
441
442 if (!stat.isDirectory()) {
443 _context4.next = 8;
444 break;
445 }
446
447 return _context4.abrupt('return', walkDirectory(fs, filename));
448
449 case 8:
450 return _context4.abrupt('return', [filename]);
451
452 case 9:
453 case 'end':
454 return _context4.stop();
455 }
456 }
457 }, _callee4, _this);
458 }));
459 return function (_x13) {
460 return ref.apply(this, arguments);
461 };
462 }()));
463 });
464
465 case 2:
466 files = _context5.sent;
467 return _context5.abrupt('return', (0, _lodash.flatten)(files));
468
469 case 4:
470 case 'end':
471 return _context5.stop();
472 }
473 }
474 }, _callee5, this);
475 }));
476 return function walkDirectory(_x11, _x12) {
477 return ref.apply(this, arguments);
478 };
479}();
480
481exports.forEach = forEach;
482exports.validate = validate;
483exports.forEachPath = forEachPath;
484
485var _path = require('path');
486
487var _bluebird = require('bluebird');
488
489var _minimatch = require('minimatch');
490
491var _minimatch2 = _interopRequireDefault(_minimatch);
492
493var _lodash = require('lodash');
494
495var _schema = require('validated/schema');
496
497var _object = require('validated/object');
498
499var _babelTypes = require('babel-types');
500
501var types = _interopRequireWildcard(_babelTypes);
502
503var _config = require('./config');
504
505function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
506
507function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
508
509/**
510 * @copyright 2016-present, Sitegen team
511 */
512
513var META_LOADER = require.resolve('./loader/meta');
514var CHUNK_LOADER = require.resolve('./loader/chunk');
515var REACT_HOT_LOADER = require.resolve('react-hot-loader/webpack');
516
517function forEach(route, func) {
518 func(route);
519 if (route.route) {
520 for (var k in route.route) {
521 forEach(route.route[k], func);
522 }
523 }
524}
525
526/**
527 * Validate route.
528 */
529function validate(route, _ref) {
530 var basedir = _ref.basedir;
531
532 var pattern = _schema.string.andThen(function (val) {
533 return parsePattern(val, { basedir: basedir });
534 });
535 var pageShortcut = _schema.string.andThen(function (page) {
536 return { page: page };
537 });
538 var collectionShortcut = pattern.andThen(function (page) {
539 return { page: page };
540 });
541 var schema = (0, _schema.ref)();
542
543 var routePage = (0, _schema.oneOf)(pageShortcut, (0, _schema.object)({
544 page: _schema.string,
545 split: (0, _schema.maybe)(_schema.boolean),
546 route: (0, _schema.maybe)((0, _schema.mapping)(schema)),
547 collection: (0, _schema.maybe)((0, _schema.oneOf)(collectionShortcut, (0, _schema.object)({
548 page: pattern,
549 paginate: (0, _schema.maybe)((0, _schema.object)({ size: _schema.number }))
550 })))
551 })).andThen(function (route, error) {
552 if (route.route && route.collection) {
553 error('Route cannot have both "route" and "collection" defined');
554 }
555 return route;
556 });
557
558 schema.set(routePage);
559
560 return (0, _object.validate)(schema, route);
561}function renderGetCollectionChunk(chunk, options) {
562 options = (0, _extends3.default)({
563 loader: META_LOADER,
564 chunkName: 'collectionPage',
565 split: false
566 }, options);
567
568 var query = {
569 chunk: chunk,
570 loader: options.loader,
571 chunkNumber: options.chunkNumber,
572 chunkCount: options.chunkCount
573 };
574
575 var req = (0, _config.moduleRequest)(options.page, { loader: CHUNK_LOADER, query: query },
576 // TODO: we don't really want to leak configuration here, think of a better
577 // way to inject this
578 REACT_HOT_LOADER);
579 return renderGetComponent(req, {
580 split: options.split,
581 chunkName: options.chunkName
582 });
583}
584
585/**
586 * Render React Router route spec.
587 */
588function renderRouteSpec(_ref2) {
589 var path = _ref2.path;
590 var getComponent = _ref2.getComponent;
591 var indexRoute = _ref2.indexRoute;
592 var childRoutes = _ref2.childRoutes;
593 var name = _ref2.name;
594 var params = _ref2.params;
595
596 path = path == null ? function () {
597 return {
598 "type": "Identifier",
599 "name": "undefined",
600 "extra": {
601 "parenthesized": true,
602 "parenStart": 0
603 }
604 };
605 }() : types.stringLiteral(path);
606 getComponent = getComponent == null ? function () {
607 return {
608 "type": "Identifier",
609 "name": "undefined",
610 "extra": {
611 "parenthesized": true,
612 "parenStart": 0
613 }
614 };
615 }() : getComponent;
616 indexRoute = indexRoute == null ? function () {
617 return {
618 "type": "Identifier",
619 "name": "undefined",
620 "extra": {
621 "parenthesized": true,
622 "parenStart": 0
623 }
624 };
625 }() : indexRoute;
626 childRoutes = types.arrayExpression(childRoutes || []);
627 name = name == null ? function () {
628 return {
629 "type": "Identifier",
630 "name": "undefined",
631 "extra": {
632 "parenthesized": true,
633 "parenStart": 0
634 }
635 };
636 }() : types.stringLiteral(name);
637 params = params == null ? function () {
638 return {
639 "type": "Identifier",
640 "name": "undefined",
641 "extra": {
642 "parenthesized": true,
643 "parenStart": 0
644 }
645 };
646 }() : params;
647 return function (_param3, _param4, _param5, _param6, _param7, _param8) {
648 return {
649 "type": "ObjectExpression",
650 "properties": [{
651 "type": "ObjectProperty",
652 "method": false,
653 "shorthand": false,
654 "computed": false,
655 "key": {
656 "type": "Identifier",
657 "name": "path"
658 },
659 "value": _param3
660 }, {
661 "type": "ObjectProperty",
662 "method": false,
663 "shorthand": false,
664 "computed": false,
665 "key": {
666 "type": "Identifier",
667 "name": "getComponent"
668 },
669 "value": _param4
670 }, {
671 "type": "ObjectProperty",
672 "method": false,
673 "shorthand": false,
674 "computed": false,
675 "key": {
676 "type": "Identifier",
677 "name": "indexRoute"
678 },
679 "value": _param5
680 }, {
681 "type": "ObjectProperty",
682 "method": false,
683 "shorthand": false,
684 "computed": false,
685 "key": {
686 "type": "Identifier",
687 "name": "childRoutes"
688 },
689 "value": _param6
690 }, {
691 "type": "ObjectProperty",
692 "method": false,
693 "shorthand": false,
694 "computed": false,
695 "key": {
696 "type": "Identifier",
697 "name": "name"
698 },
699 "value": _param7
700 }, {
701 "type": "ObjectProperty",
702 "method": false,
703 "shorthand": false,
704 "computed": false,
705 "key": {
706 "type": "Identifier",
707 "name": "params"
708 },
709 "value": _param8
710 }],
711 "extra": {
712 "parenthesized": true,
713 "parenStart": 0
714 }
715 };
716 }(path, getComponent, indexRoute, childRoutes, name, params);
717}
718
719/**
720 * Render component loader to load component from a given module.
721 */
722function renderGetComponent(id, options) {
723 options = (0, _extends3.default)({
724 split: false,
725 chunkName: 'component'
726 }, options);
727
728 var req = types.stringLiteral(id);
729
730 if (options.split) {
731 return function (_param9, _param10) {
732 return {
733 "type": "FunctionExpression",
734 "id": {
735 "type": "Identifier",
736 "name": "getComponentAsync"
737 },
738 "generator": false,
739 "expression": false,
740 "async": false,
741 "params": [{
742 "type": "Identifier",
743 "name": "_nextState"
744 }, {
745 "type": "Identifier",
746 "name": "cb"
747 }],
748 "body": {
749 "type": "BlockStatement",
750 "body": [{
751 "type": "ExpressionStatement",
752 "expression": {
753 "type": "CallExpression",
754 "callee": {
755 "type": "MemberExpression",
756 "object": {
757 "type": "Identifier",
758 "name": "require"
759 },
760 "property": {
761 "type": "Identifier",
762 "name": "ensure"
763 },
764 "computed": false
765 },
766 "arguments": [{
767 "type": "ArrayExpression",
768 "elements": []
769 }, {
770 "type": "FunctionExpression",
771 "id": null,
772 "generator": false,
773 "expression": false,
774 "async": false,
775 "params": [{
776 "type": "Identifier",
777 "name": "require"
778 }],
779 "body": {
780 "type": "BlockStatement",
781 "body": [{
782 "type": "ExpressionStatement",
783 "expression": {
784 "type": "CallExpression",
785 "callee": {
786 "type": "Identifier",
787 "name": "cb"
788 },
789 "arguments": [{
790 "type": "NullLiteral"
791 }, {
792 "type": "MemberExpression",
793 "object": {
794 "type": "CallExpression",
795 "callee": {
796 "type": "Identifier",
797 "name": "require"
798 },
799 "arguments": [_param9]
800 },
801 "property": {
802 "type": "Identifier",
803 "name": "default"
804 },
805 "computed": false
806 }]
807 }
808 }],
809 "directives": []
810 }
811 }, _param10]
812 }
813 }],
814 "directives": []
815 },
816 "extra": {
817 "parenthesized": true,
818 "parenStart": 0
819 }
820 };
821 }(req, types.stringLiteral(options.chunkName));
822 } else {
823 return function (_param11) {
824 return {
825 "type": "FunctionExpression",
826 "id": {
827 "type": "Identifier",
828 "name": "getComponentSync"
829 },
830 "generator": false,
831 "expression": false,
832 "async": false,
833 "params": [{
834 "type": "Identifier",
835 "name": "_nextState"
836 }, {
837 "type": "Identifier",
838 "name": "cb"
839 }],
840 "body": {
841 "type": "BlockStatement",
842 "body": [{
843 "type": "ExpressionStatement",
844 "expression": {
845 "type": "CallExpression",
846 "callee": {
847 "type": "Identifier",
848 "name": "cb"
849 },
850 "arguments": [{
851 "type": "NullLiteral"
852 }, {
853 "type": "MemberExpression",
854 "object": {
855 "type": "CallExpression",
856 "callee": {
857 "type": "Identifier",
858 "name": "require"
859 },
860 "arguments": [_param11]
861 },
862 "property": {
863 "type": "Identifier",
864 "name": "default"
865 },
866 "computed": false
867 }]
868 }
869 }],
870 "directives": []
871 },
872 "extra": {
873 "parenthesized": true,
874 "parenStart": 0
875 }
876 };
877 }(req);
878 }
879}
880
881function parsePattern(pattern, _ref3) {
882 var basedir = _ref3.basedir;
883
884 pattern = (0, _path.join)(basedir, pattern);
885 var matcher = new _minimatch2.default.Minimatch(pattern);
886 var directory = [];
887 for (var i = 0; i < matcher.set[0].length; i++) {
888 if (typeof matcher.set[0][i] === 'string') {
889 directory.push(matcher.set[0][i]);
890 } else {
891 break;
892 }
893 }
894 if (directory.length > 1) {
895 directory = directory.join('/');
896 }
897 return {
898 directory: directory,
899 match: matcher.match.bind(matcher)
900 };
901}
902
903function stripExtension(filename) {
904 return filename.substring(0, filename.length - (0, _path.extname)(filename).length);
905}
906
907function forEachPath(route, func) {
908 var trace = arguments.length <= 2 || arguments[2] === undefined ? [''] : arguments[2];
909
910 var path = '/' + trace.filter(Boolean).join('/');
911 if (route.params) {
912 (0, _keys2.default)(route.params).forEach(function (key) {
913 route.params[key].forEach(function (value) {
914 func(interpolateParams(path, (0, _defineProperty3.default)({}, key, value)));
915 });
916 });
917 } else {
918 func(path);
919 }
920 if (route.childRoutes) {
921 route.childRoutes.forEach(function (route) {
922 return forEachPath(route, func, trace.concat(route.path));
923 });
924 }
925}
926
927function interpolateParams(path, params) {
928 return path.replace(/:([a-zA-Z_\-]+)/g, function (_, key) {
929 return params[key];
930 });
931}
932//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9hbmRyZXlwb3BwL1dvcmtzcGFjZS9zaXRlZ2VuL3NyYy9yb3V0ZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7dUVBa0VPLGlCQUEyQixLQUEzQixFQUFrQyxPQUFsQztBQUFBLDZCQUVBLFVBRkEsRUFHRCxJQUhDOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0wsd0NBQWEsUUFBUSxFQUFyQjtBQURLLGtDQUVvQixPQUZwQixDQUVBLFVBRkE7QUFFQSxzQkFGQSx1Q0FFYSxHQUZiO0FBQUE7QUFBQSxtQkFHWSxnQkFBZ0IsS0FBaEIsRUFBdUIsVUFBdkIsRUFBbUMsQ0FBQyxFQUFELENBQW5DLEVBQXlDLE9BQXpDLENBSFo7O0FBQUE7QUFHRCxnQkFIQztBQUFBLDZDQUlFLElBSkY7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRztrQkFBZSxXOzs7Ozs7dUVBT3RCLGtCQUErQixLQUEvQixFQUFzQyxJQUF0QyxFQUE0QyxLQUE1QyxFQUFtRCxPQUFuRDtBQUFBLFFBRVEsVUFGUixFQUdRLFdBSFIsRUFJYSxHQUpiLEVBY1EsWUFkUixFQTJCUSxhQTNCUjs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGlCQUNNLE1BQU0sS0FEWjtBQUFBO0FBQUE7QUFBQTs7QUFFUSxzQkFGUjtBQUdRLHVCQUhSLEdBR3NCLEVBSHRCO0FBQUEsc0RBSW9CLE1BQU0sS0FKMUI7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFJYSxlQUpiOztBQUFBLGtCQUtVLFFBQVEsT0FMbEI7QUFBQTtBQUFBO0FBQUE7O0FBQUE7QUFBQSxtQkFNMkIsZ0JBQWdCLE1BQU0sS0FBTixDQUFZLEdBQVosQ0FBaEIsRUFBa0MsSUFBbEMsRUFBd0MsS0FBeEMsRUFBK0MsT0FBL0MsQ0FOM0I7O0FBQUE7QUFNUSxzQkFOUjtBQUFBO0FBQUE7O0FBQUE7QUFBQSwyQkFRUSxXQVJSO0FBQUE7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QUFKO0FBQUEsV0FBWSxPQUFPLEdBQVAsQ0FBWjtBQUFBLEdBQWpDLENBQVA7QUFDRCIsImZpbGUiOiJyb3V0ZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNvcHlyaWdodCAyMDE2LXByZXNlbnQsIFNpdGVnZW4gdGVhbVxuICovXG5cbmltcG9ydCB7am9pbiwgZXh0bmFtZSwgcmVsYXRpdmV9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHtwcm9taXNpZnlBbGx9IGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBtaW5pbWF0Y2ggZnJvbSAnbWluaW1hdGNoJztcbmltcG9ydCB7ZmxhdHRlbiwgY2h1bmt9IGZyb20gJ2xvZGFzaCc7XG5cbmltcG9ydCB7c3RyaW5nLCBudW1iZXIsIHJlZiwgbWF5YmUsIG9iamVjdCwgbWFwcGluZywgb25lT2YsIGJvb2xlYW59IGZyb20gJ3ZhbGlkYXRlZC9zY2hlbWEnO1xuaW1wb3J0IHt2YWxpZGF0ZSBhcyB2YWxpZGF0ZU9iamVjdH0gZnJvbSAndmFsaWRhdGVkL29iamVjdCc7XG5cbmltcG9ydCAqIGFzIHR5cGVzIGZyb20gJ2JhYmVsLXR5cGVzJztcbmltcG9ydCB7bW9kdWxlUmVxdWVzdH0gZnJvbSAnLi9jb25maWcnO1xuXG5jb25zdCBNRVRBX0xPQURFUiA9IHJlcXVpcmUucmVzb2x2ZSgnLi9sb2FkZXIvbWV0YScpO1xuY29uc3QgQ0hVTktfTE9BREVSID0gcmVxdWlyZS5yZXNvbHZlKCcuL2xvYWRlci9jaHVuaycpO1xuY29uc3QgUkVBQ1RfSE9UX0xPQURFUiA9IHJlcXVpcmUucmVzb2x2ZSgncmVhY3QtaG90LWxvYWRlci93ZWJwYWNrJyk7XG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JFYWNoKHJvdXRlLCBmdW5jKSB7XG4gIGZ1bmMocm91dGUpO1xuICBpZiAocm91dGUucm91dGUpIHtcbiAgICBmb3IgKGxldCBrIGluIHJvdXRlLnJvdXRlKSB7XG4gICAgICBmb3JFYWNoKHJvdXRlLnJvdXRlW2tdLCBmdW5jKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSByb3V0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlKHJvdXRlLCB7YmFzZWRpcn0pIHtcbiAgbGV0IHBhdHRlcm4gPSBzdHJpbmcuYW5kVGhlbih2YWwgPT4gcGFyc2VQYXR0ZXJuKHZhbCwge2Jhc2VkaXJ9KSk7XG4gIGxldCBwYWdlU2hvcnRjdXQgPSBzdHJpbmcuYW5kVGhlbihwYWdlID0+ICh7cGFnZX0pKTtcbiAgbGV0IGNvbGxlY3Rpb25TaG9ydGN1dCA9IHBhdHRlcm4uYW5kVGhlbihwYWdlID0+ICh7cGFnZX0pKTtcbiAgbGV0IHNjaGVtYSA9IHJlZigpO1xuXG4gIGxldCByb3V0ZVBhZ2UgPSBvbmVPZihcbiAgICBwYWdlU2hvcnRjdXQsXG4gICAgb2JqZWN0KHtcbiAgICAgIHBhZ2U6IHN0cmluZyxcbiAgICAgIHNwbGl0OiBtYXliZShib29sZWFuKSxcbiAgICAgIHJvdXRlOiBtYXliZShtYXBwaW5nKHNjaGVtYSkpLFxuICAgICAgY29sbGVjdGlvbjogbWF5YmUob25lT2YoXG4gICAgICAgIGNvbGxlY3Rpb25TaG9ydGN1dCxcbiAgICAgICAgb2JqZWN0KHtcbiAgICAgICAgICBwYWdlOiBwYXR0ZXJuLFxuICAgICAgICAgIHBhZ2luYXRlOiBtYXliZShvYmplY3Qoe3NpemU6IG51bWJlcn0pKSxcbiAgICAgICAgfSlcbiAgICAgICkpLFxuICAgIH0pXG4gICkuYW5kVGhlbigocm91dGUsIGVycm9yKSA9PiB7XG4gICAgaWYgKHJvdXRlLnJvdXRlICYmIHJvdXRlLmNvbGxlY3Rpb24pIHtcbiAgICAgIGVycm9yKCdSb3V0ZSBjYW5ub3QgaGF2ZSBib3RoIFwicm91dGVcIiBhbmQgXCJjb2xsZWN0aW9uXCIgZGVmaW5lZCcpO1xuICAgIH1cbiAgICByZXR1cm4gcm91dGU7XG4gIH0pO1xuXG4gIHNjaGVtYS5zZXQocm91dGVQYWdlKTtcblxuICByZXR1cm4gdmFsaWRhdGVPYmplY3Qoc2NoZW1hLCByb3V0ZSk7XG59XG5cbi8qKlxuICogUmVuZGVyIHJvdXRlIGludG8gSlMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW5kZXJSb3V0ZShyb3V0ZSwgb3B0aW9ucykge1xuICBwcm9taXNpZnlBbGwob3B0aW9ucy5mcyk7XG4gIGxldCB7cHVibGljUGF0aCA9ICcvJ30gPSBvcHRpb25zO1xuICBsZXQgbm9kZSA9IGF3YWl0IHJlbmRlclJvdXRlUGFnZShyb3V0ZSwgcHVibGljUGF0aCwgWycnXSwgb3B0aW9ucyk7XG4gIHJldHVybiBub2RlO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZW5kZXJSb3V0ZVBhZ2Uocm91dGUsIHBhdGgsIHRyYWNlLCBvcHRpb25zKSB7XG4gIGlmIChyb3V0ZS5yb3V0ZSkge1xuICAgIGxldCBpbmRleFJvdXRlO1xuICAgIGxldCBjaGlsZFJvdXRlcyA9IFtdO1xuICAgIGZvciAobGV0IGtleSBpbiByb3V0ZS5yb3V0ZSkge1xuICAgICAgaWYgKGtleSA9PT0gJ2luZGV4Jykge1xuICAgICAgICBpbmRleFJvdXRlID0gYXdhaXQgcmVuZGVyUm91dGVQYWdlKHJvdXRlLnJvdXRlW2tleV0sIG51bGwsIHRyYWNlLCBvcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoaWxkUm91dGVzLnB1c2goXG4gICAgICAgICAgYXdhaXQgcmVuZGVyUm91dGVQYWdlKHJvdXRlLnJvdXRlW2tleV0sIGtleSwgdHJhY2UuY29uY2F0KGtleSksIG9wdGlvbnMpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGdldENvbXBvbmVudCA9IHJlbmRlckdldENvbXBvbmVudChyb3V0ZS5wYWdlLCB7XG4gICAgICBzcGxpdDogb3B0aW9ucy5zcGxpdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zcGxpdCA6IHJvdXRlLnNwbGl0LFxuICAgICAgY2h1bmtOYW1lOiB0cmFjZS5qb2luKCcvJyksXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlbmRlclJvdXRlU3BlYyh7XG4gICAgICBwYXRoLFxuICAgICAgZ2V0Q29tcG9uZW50LFxuICAgICAgaW5kZXhSb3V0ZSxcbiAgICAgIGNoaWxkUm91dGVzXG4gICAgfSk7XG4gIH0gZWxzZSBpZiAocm91dGUuY29sbGVjdGlvbikge1xuICAgIHJldHVybiByZW5kZXJSb3V0ZUNvbGxlY3Rpb24ocm91dGUsIHBhdGgsIHRyYWNlLCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgZ2V0Q29tcG9uZW50ID0gcmVuZGVyR2V0Q29tcG9uZW50KHJvdXRlLnBhZ2UsIHtcbiAgICAgIHNwbGl0OiBvcHRpb25zLnNwbGl0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnNwbGl0IDogcm91dGUuc3BsaXQsXG4gICAgICBjaHVua05hbWU6IHRyYWNlLmpvaW4oJy8nKSxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVuZGVyUm91dGVTcGVjKHtcbiAgICAgIHBhdGgsXG4gICAgICBnZXRDb21wb25lbnQsXG4gICAgfSk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVuZGVyUm91dGVDb2xsZWN0aW9uKHJvdXRlLCBwYXRoLCB0cmFjZSwgb3B0aW9ucykge1xuICBsZXQge3BhZ2U6IHtkaXJlY3RvcnksIG1hdGNofSwgcGFnaW5hdGV9ID0gcm91dGUuY29sbGVjdGlvbjtcblxuICBsZXQgY2h1bmtOYW1lID0gdHJhY2Uuam9pbignLycpO1xuICBsZXQgbmFtZSA9IGNodW5rTmFtZTtcblxuICBsZXQgaXRlbXMgPSAoYXdhaXQgd2Fsa0RpcmVjdG9yeShvcHRpb25zLmZzLCBkaXJlY3RvcnkpKVxuICAgIC5maWx0ZXIoZmlsZW5hbWUgPT4gbWF0Y2goZmlsZW5hbWUpKVxuICAgIC5tYXAoZmlsZW5hbWUgPT4gKHtcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgcGF0aDogc3RyaXBFeHRlbnNpb24ocmVsYXRpdmUoZGlyZWN0b3J5LCBmaWxlbmFtZSkpXG4gICAgfSkpO1xuXG4gIGxldCBjaHVua3MgPSBbaXRlbXNdO1xuICBpZiAocGFnaW5hdGUpIHtcbiAgICBjaHVua3MgPSBjaHVuayhpdGVtcywgcGFnaW5hdGUuc2l6ZSk7XG4gIH1cblxuICBjaHVua3MgPSBjaHVua3MubWFwKChjaHVuaywgaWR4KSA9PiByZW5kZXJHZXRDb2xsZWN0aW9uQ2h1bmsoY2h1bmssIHtcbiAgICBwYWdlOiByb3V0ZS5wYWdlLFxuICAgIGNodW5rTnVtYmVyOiBpZHgsXG4gICAgY2h1bmtDb3VudDogY2h1bmtzLmxlbmd0aCxcbiAgICBsb2FkZXI6IE1FVEFfTE9BREVSLFxuICAgIGNodW5rTmFtZTogdHJhY2UuY29uY2F0KCdAcGFnZScsIGlkeCArIDEpLmpvaW4oJy8nKSxcbiAgICBzcGxpdDogb3B0aW9ucy5zcGxpdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zcGxpdCA6IHRydWUsXG4gIH0pKTtcblxuICBsZXQgY2hpbGRSb3V0ZXMgPSBpdGVtcy5tYXAoaXRlbSA9PiByZW5kZXJSb3V0ZVNwZWMoe1xuICAgIHBhdGg6IGl0ZW0ucGF0aCxcbiAgICBnZXRDb21wb25lbnQ6IHJlbmRlckdldENvbXBvbmVudChpdGVtLmZpbGVuYW1lLCB7XG4gICAgICBzcGxpdDogb3B0aW9ucy5zcGxpdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zcGxpdCA6IHRydWUsXG4gICAgICBjaHVua05hbWU6IHRyYWNlLmNvbmNhdChpdGVtLnBhdGgpLmpvaW4oJy8nKSxcbiAgICB9KSxcbiAgfSkpO1xuXG4gIGxldCBnZXRDb21wb25lbnQgPSBleHByYGZ1bmN0aW9uIGdldENvbXBvbmVudChuZXh0U3RhdGUsIGNiKSB7XG4gICAgdmFyIHBhZ2VOdW1iZXIgPSBwYXJzZUludChuZXh0U3RhdGUucGFyYW1zLnBhZ2UgfHwgMSwgMTApO1xuICAgIHZhciBjaHVua0xpc3QgPSAke3R5cGVzLmFycmF5RXhwcmVzc2lvbihjaHVua3MpfTtcbiAgICB2YXIgZ2V0Q29sbGVjdGlvbkNodW5rID0gY2h1bmtMaXN0W3BhZ2VOdW1iZXIgLSAxXTtcbiAgICBnZXRDb2xsZWN0aW9uQ2h1bmsobmV4dFN0YXRlLCBjYik7XG4gIH1gO1xuXG4gIGxldCBwYWdlUGFyYW0gPSB0eXBlcy5hcnJheUV4cHJlc3Npb24oY2h1bmtzLm1hcCgoXywgaWR4KSA9PiB0eXBlcy5udW1lcmljTGl0ZXJhbChpZHggKyAxKSkpO1xuICBjaGlsZFJvdXRlcyA9IGNoaWxkUm91dGVzLmNvbmNhdChyZW5kZXJSb3V0ZVNwZWMoe1xuICAgIHBhdGg6ICdAcGFnZS86cGFnZScsXG4gICAgbmFtZSxcbiAgICBwYXJhbXM6IGV4cHJge3BhZ2U6ICR7cGFnZVBhcmFtfX1gLFxuICB9KSk7XG5cbiAgcmV0dXJuIHJlbmRlclJvdXRlU3BlYyh7XG4gICAgcGF0aCxcbiAgICBnZXRDb21wb25lbnQsXG4gICAgY2hpbGRSb3V0ZXMsXG4gICAgbmFtZSxcbiAgfSk7XG59XG5cbi8qKlxuICogUmVuZGVyIGEgZmV0Y2hlciBmb3IgYSBjb2xsZWN0aW9uIGNodW5rLlxuICovXG5mdW5jdGlvbiByZW5kZXJHZXRDb2xsZWN0aW9uQ2h1bmsoY2h1bmssIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IHtcbiAgICBsb2FkZXI6IE1FVEFfTE9BREVSLFxuICAgIGNodW5rTmFtZTogJ2NvbGxlY3Rpb25QYWdlJyxcbiAgICBzcGxpdDogZmFsc2UsXG4gICAgLi4ub3B0aW9ucyxcbiAgfTtcblxuICBsZXQgcXVlcnkgPSB7XG4gICAgY2h1bmssXG4gICAgbG9hZGVyOiBvcHRpb25zLmxvYWRlcixcbiAgICBjaHVua051bWJlcjogb3B0aW9ucy5jaHVua051bWJlcixcbiAgICBjaHVua0NvdW50OiBvcHRpb25zLmNodW5rQ291bnQsXG4gIH07XG5cbiAgbGV0IHJlcSA9IG1vZHVsZVJlcXVlc3QoXG4gICAgb3B0aW9ucy5wYWdlLFxuICAgIHtsb2FkZXI6IENIVU5LX0xPQURFUiwgcXVlcnl9LFxuICAgIC8vIFRPRE86IHdlIGRvbid0IHJlYWxseSB3YW50IHRvIGxlYWsgY29uZmlndXJhdGlvbiBoZXJlLCB0aGluayBvZiBhIGJldHRlclxuICAgIC8vIHdheSB0byBpbmplY3QgdGhpc1xuICAgIFJFQUNUX0hPVF9MT0FERVJcbiAgKTtcbiAgcmV0dXJuIHJlbmRlckdldENvbXBvbmVudChyZXEsIHtcbiAgICBzcGxpdDogb3B0aW9ucy5zcGxpdCxcbiAgICBjaHVua05hbWU6IG9wdGlvbnMuY2h1bmtOYW1lLFxuICB9KTtcbn1cblxuLyoqXG4gKiBSZW5kZXIgUmVhY3QgUm91dGVyIHJvdXRlIHNwZWMuXG4gKi9cbmZ1bmN0aW9uIHJlbmRlclJvdXRlU3BlYyh7cGF0aCwgZ2V0Q29tcG9uZW50LCBpbmRleFJvdXRlLCBjaGlsZFJvdXRlcywgbmFtZSwgcGFyYW1zfSkge1xuICBwYXRoID0gcGF0aCA9PSBudWxsID8gZXhwcmB1bmRlZmluZWRgIDogdHlwZXMuc3RyaW5nTGl0ZXJhbChwYXRoKTtcbiAgZ2V0Q29tcG9uZW50ID0gZ2V0Q29tcG9uZW50ID09IG51bGwgPyBleHByYHVuZGVmaW5lZGAgOiBnZXRDb21wb25lbnQ7XG4gIGluZGV4Um91dGUgPSBpbmRleFJvdXRlID09IG51bGwgPyBleHByYHVuZGVmaW5lZGAgOiBpbmRleFJvdXRlO1xuICBjaGlsZFJvdXRlcyA9IHR5cGVzLmFycmF5RXhwcmVzc2lvbihjaGlsZFJvdXRlcyB8fCBbXSk7XG4gIG5hbWUgPSBuYW1lID09IG51bGwgPyBleHByYHVuZGVmaW5lZGAgOiB0eXBlcy5zdHJpbmdMaXRlcmFsKG5hbWUpO1xuICBwYXJhbXMgPSBwYXJhbXMgPT0gbnVsbCA/IGV4cHJgdW5kZWZpbmVkYCA6IHBhcmFtcztcbiAgcmV0dXJuIGV4cHJge1xuICAgIHBhdGg6ICR7cGF0aH0sXG4gICAgZ2V0Q29tcG9uZW50OiAke2dldENvbXBvbmVudH0sXG4gICAgaW5kZXhSb3V0ZTogJHtpbmRleFJvdXRlfSxcbiAgICBjaGlsZFJvdXRlczogJHtjaGlsZFJvdXRlc30sXG4gICAgbmFtZTogJHtuYW1lfSxcbiAgICBwYXJhbXM6ICR7cGFyYW1zfSxcbiAgfWA7XG59XG5cbi8qKlxuICogUmVuZGVyIGNvbXBvbmVudCBsb2FkZXIgdG8gbG9hZCBjb21wb25lbnQgZnJvbSBhIGdpdmVuIG1vZHVsZS5cbiAqL1xuZnVuY3Rpb24gcmVuZGVyR2V0Q29tcG9uZW50KGlkLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSB7XG4gICAgc3BsaXQ6IGZhbHNlLFxuICAgIGNodW5rTmFtZTogJ2NvbXBvbmVudCcsXG4gICAgLi4ub3B0aW9ucyxcbiAgfTtcblxuICBsZXQgcmVxID0gdHlwZXMuc3RyaW5nTGl0ZXJhbChpZCk7XG5cbiAgaWYgKG9wdGlvbnMuc3BsaXQpIHtcbiAgICByZXR1cm4gZXhwcmBcbiAgICAgIGZ1bmN0aW9uIGdldENvbXBvbmVudEFzeW5jKF9uZXh0U3RhdGUsIGNiKSB7XG4gICAgICAgIHJlcXVpcmUuZW5zdXJlKFtdLCBmdW5jdGlvbihyZXF1aXJlKSB7XG4gICAgICAgICAgY2IobnVsbCwgcmVxdWlyZSgke3JlcX0pLmRlZmF1bHQpO1xuICAgICAgICB9LCAke3R5cGVzLnN0cmluZ0xpdGVyYWwob3B0aW9ucy5jaHVua05hbWUpfSk7XG4gICAgICB9XG4gICAgYDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZXhwcmBcbiAgICAgIGZ1bmN0aW9uIGdldENvbXBvbmVudFN5bmMoX25leHRTdGF0ZSwgY2IpIHtcbiAgICAgICAgY2IobnVsbCwgcmVxdWlyZShcIiR7cmVxfVwiKS5kZWZhdWx0KTtcbiAgICAgIH1cbiAgICBgO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlUGF0dGVybihwYXR0ZXJuLCB7YmFzZWRpcn0pIHtcbiAgcGF0dGVybiA9IGpvaW4oYmFzZWRpciwgcGF0dGVybik7XG4gIGxldCBtYXRjaGVyID0gbmV3IG1pbmltYXRjaC5NaW5pbWF0Y2gocGF0dGVybik7XG4gIGxldCBkaXJlY3RvcnkgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaGVyLnNldFswXS5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0eXBlb2YgbWF0Y2hlci5zZXRbMF1baV0gPT09ICdzdHJpbmcnKSB7XG4gICAgICBkaXJlY3RvcnkucHVzaChtYXRjaGVyLnNldFswXVtpXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoZGlyZWN0b3J5Lmxlbmd0aCA+IDEpIHtcbiAgICBkaXJlY3RvcnkgPSBkaXJlY3Rvcnkuam9pbignLycpO1xuICB9XG4gIHJldHVybiB7XG4gICAgZGlyZWN0b3J5LFxuICAgIG1hdGNoOiBtYXRjaGVyLm1hdGNoLmJpbmQobWF0Y2hlciksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHN0cmlwRXh0ZW5zaW9uKGZpbGVuYW1lKSB7XG4gIHJldHVybiBmaWxlbmFtZS5zdWJzdHJpbmcoMCwgZmlsZW5hbWUubGVuZ3RoIC0gZXh0bmFtZShmaWxlbmFtZSkubGVuZ3RoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gd2Fsa0RpcmVjdG9yeShmcywgZGlyZWN0b3J5KSB7XG4gIGxldCBmaWxlcyA9IGF3YWl0IGZzLnJlYWRkaXJBc3luYyhkaXJlY3RvcnkpLnRoZW4oc2VnbWVudHMgPT5cbiAgICBQcm9taXNlLmFsbChzZWdtZW50cy5tYXAoYXN5bmMgc2VnbWVudCA9PiB7XG4gICAgICBsZXQgZmlsZW5hbWUgPSBqb2luKGRpcmVjdG9yeSwgc2VnbWVudCk7XG4gICAgICBsZXQgc3RhdCA9IGF3YWl0IGZzLnN0YXRBc3luYyhmaWxlbmFtZSk7XG4gICAgICBpZiAoc3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIHJldHVybiB3YWxrRGlyZWN0b3J5KGZzLCBmaWxlbmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gW2ZpbGVuYW1lXTtcbiAgICAgIH1cbiAgICB9KSlcbiAgKTtcbiAgcmV0dXJuIGZsYXR0ZW4oZmlsZXMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZm9yRWFjaFBhdGgocm91dGUsIGZ1bmMsIHRyYWNlID0gWycnXSkge1xuICBsZXQgcGF0aCA9ICcvJyArIHRyYWNlLmZpbHRlcihCb29sZWFuKS5qb2luKCcvJyk7XG4gIGlmIChyb3V0ZS5wYXJhbXMpIHtcbiAgICBPYmplY3Qua2V5cyhyb3V0ZS5wYXJhbXMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIHJvdXRlLnBhcmFtc1trZXldLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgICBmdW5jKGludGVycG9sYXRlUGFyYW1zKHBhdGgsIHtba2V5XTogdmFsdWV9KSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBmdW5jKHBhdGgpO1xuICB9XG4gIGlmIChyb3V0ZS5jaGlsZFJvdXRlcykge1xuICAgIHJvdXRlLmNoaWxkUm91dGVzLmZvckVhY2gocm91dGUgPT5cbiAgICAgIGZvckVhY2hQYXRoKHJvdXRlLCBmdW5jLCB0cmFjZS5jb25jYXQocm91dGUucGF0aCkpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZVBhcmFtcyhwYXRoLCBwYXJhbXMpIHtcbiAgcmV0dXJuIHBhdGgucmVwbGFjZSgvOihbYS16QS1aX1xcLV0rKS9nLCAoXywga2V5KSA9PiBwYXJhbXNba2V5XSk7XG59XG4iXX0=
\No newline at end of file