2020-04-28 16:46:47 +02:00
/*istanbul ignore start*/
"use strict" ;
Object . defineProperty ( exports , "__esModule" , {
value : true
} ) ;
exports . createPatch = createPatch ;
2024-09-16 17:29:58 +00:00
exports . createTwoFilesPatch = createTwoFilesPatch ;
exports . formatPatch = formatPatch ;
exports . structuredPatch = structuredPatch ;
2020-04-28 16:46:47 +02:00
/*istanbul ignore end*/
var
/*istanbul ignore start*/
_line = require ( "../diff/line" )
/*istanbul ignore end*/
;
2024-09-16 17:29:58 +00:00
/*istanbul ignore start*/ function _typeof ( o ) { "@babel/helpers - typeof" ; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol . iterator ? function ( o ) { return typeof o ; } : function ( o ) { return o && "function" == typeof Symbol && o . constructor === Symbol && o !== Symbol . prototype ? "symbol" : typeof o ; } , _typeof ( o ) ; }
function _toConsumableArray ( arr ) { return _arrayWithoutHoles ( arr ) || _iterableToArray ( arr ) || _unsupportedIterableToArray ( arr ) || _nonIterableSpread ( ) ; }
2021-07-27 22:26:09 +00:00
function _nonIterableSpread ( ) { throw new TypeError ( "Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method." ) ; }
function _unsupportedIterableToArray ( o , minLen ) { if ( ! o ) return ; if ( typeof o === "string" ) return _arrayLikeToArray ( o , minLen ) ; var n = Object . prototype . toString . call ( o ) . slice ( 8 , - 1 ) ; if ( n === "Object" && o . constructor ) n = o . constructor . name ; if ( n === "Map" || n === "Set" ) return Array . from ( o ) ; if ( n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/ . test ( n ) ) return _arrayLikeToArray ( o , minLen ) ; }
2024-09-16 17:29:58 +00:00
function _iterableToArray ( iter ) { if ( typeof Symbol !== "undefined" && iter [ Symbol . iterator ] != null || iter [ "@@iterator" ] != null ) return Array . from ( iter ) ; }
2021-07-27 22:26:09 +00:00
function _arrayWithoutHoles ( arr ) { if ( Array . isArray ( arr ) ) return _arrayLikeToArray ( arr ) ; }
2024-09-16 17:29:58 +00:00
function _arrayLikeToArray ( arr , len ) { if ( len == null || len > arr . length ) len = arr . length ; for ( var i = 0 , arr2 = new Array ( len ) ; i < len ; i ++ ) arr2 [ i ] = arr [ i ] ; return arr2 ; }
function ownKeys ( e , r ) { var t = Object . keys ( e ) ; if ( Object . getOwnPropertySymbols ) { var o = Object . getOwnPropertySymbols ( e ) ; r && ( o = o . filter ( function ( r ) { return Object . getOwnPropertyDescriptor ( e , r ) . enumerable ; } ) ) , t . push . apply ( t , o ) ; } return t ; }
function _objectSpread ( e ) { for ( var r = 1 ; r < arguments . length ; r ++ ) { var t = null != arguments [ r ] ? arguments [ r ] : { } ; r % 2 ? ownKeys ( Object ( t ) , ! 0 ) . forEach ( function ( r ) { _defineProperty ( e , r , t [ r ] ) ; } ) : Object . getOwnPropertyDescriptors ? Object . defineProperties ( e , Object . getOwnPropertyDescriptors ( t ) ) : ownKeys ( Object ( t ) ) . forEach ( function ( r ) { Object . defineProperty ( e , r , Object . getOwnPropertyDescriptor ( t , r ) ) ; } ) ; } return e ; }
function _defineProperty ( obj , key , value ) { key = _toPropertyKey ( key ) ; if ( key in obj ) { Object . defineProperty ( obj , key , { value : value , enumerable : true , configurable : true , writable : true } ) ; } else { obj [ key ] = value ; } return obj ; }
function _toPropertyKey ( t ) { var i = _toPrimitive ( t , "string" ) ; return "symbol" == _typeof ( i ) ? i : i + "" ; }
function _toPrimitive ( t , r ) { if ( "object" != _typeof ( t ) || ! t ) return t ; var e = t [ Symbol . toPrimitive ] ; if ( void 0 !== e ) { var i = e . call ( t , r || "default" ) ; if ( "object" != _typeof ( i ) ) return i ; throw new TypeError ( "@@toPrimitive must return a primitive value." ) ; } return ( "string" === r ? String : Number ) ( t ) ; }
2020-04-28 16:46:47 +02:00
/*istanbul ignore end*/
function structuredPatch ( oldFileName , newFileName , oldStr , newStr , oldHeader , newHeader , options ) {
if ( ! options ) {
options = { } ;
}
2024-09-16 17:29:58 +00:00
if ( typeof options === 'function' ) {
options = {
callback : options
} ;
}
2020-04-28 16:46:47 +02:00
if ( typeof options . context === 'undefined' ) {
options . context = 4 ;
}
2024-09-16 17:29:58 +00:00
if ( options . newlineIsToken ) {
throw new Error ( 'newlineIsToken may not be used with patch-generation functions, only with diffing functions' ) ;
2020-04-28 16:46:47 +02:00
}
2024-09-16 17:29:58 +00:00
if ( ! options . callback ) {
return diffLinesResultToPatch (
/*istanbul ignore start*/
( 0 ,
/*istanbul ignore end*/
/*istanbul ignore start*/
_line
/*istanbul ignore end*/
.
/*istanbul ignore start*/
diffLines )
/*istanbul ignore end*/
( oldStr , newStr , options ) ) ;
} else {
var
2020-04-28 16:46:47 +02:00
/*istanbul ignore start*/
2024-09-16 17:29:58 +00:00
_options =
2020-04-28 16:46:47 +02:00
/*istanbul ignore end*/
2024-09-16 17:29:58 +00:00
options ,
2020-04-28 16:46:47 +02:00
/*istanbul ignore start*/
/*istanbul ignore end*/
2024-09-16 17:29:58 +00:00
_callback = _options . callback ;
/*istanbul ignore start*/
( 0 ,
/*istanbul ignore end*/
/*istanbul ignore start*/
_line
/*istanbul ignore end*/
.
/*istanbul ignore start*/
diffLines )
/*istanbul ignore end*/
( oldStr , newStr ,
/*istanbul ignore start*/
_objectSpread ( _objectSpread ( { } ,
/*istanbul ignore end*/
options ) , { } , {
callback : function
2020-04-28 16:46:47 +02:00
/*istanbul ignore start*/
2024-09-16 17:29:58 +00:00
callback
2020-04-28 16:46:47 +02:00
/*istanbul ignore end*/
2024-09-16 17:29:58 +00:00
( diff ) {
var patch = diffLinesResultToPatch ( diff ) ;
_callback ( patch ) ;
2020-04-28 16:46:47 +02:00
}
2024-09-16 17:29:58 +00:00
} ) ) ;
}
function diffLinesResultToPatch ( diff ) {
// STEP 1: Build up the patch with no "\ No newline at end of file" lines and with the arrays
// of lines containing trailing newline characters. We'll tidy up later...
2021-07-27 22:26:09 +00:00
2024-09-16 17:29:58 +00:00
if ( ! diff ) {
return ;
}
diff . push ( {
value : '' ,
lines : [ ]
} ) ; // Append an empty value to make cleanup easier
function contextLines ( lines ) {
return lines . map ( function ( entry ) {
return ' ' + entry ;
} ) ;
}
var hunks = [ ] ;
var oldRangeStart = 0 ,
newRangeStart = 0 ,
curRange = [ ] ,
oldLine = 1 ,
newLine = 1 ;
/*istanbul ignore start*/
var _loop = function _loop ( )
/*istanbul ignore end*/
{
var current = diff [ i ] ,
lines = current . lines || splitLines ( current . value ) ;
current . lines = lines ;
if ( current . added || current . removed ) {
/*istanbul ignore start*/
var _curRange ;
/*istanbul ignore end*/
// If we have previous context, start with that
if ( ! oldRangeStart ) {
var prev = diff [ i - 1 ] ;
oldRangeStart = oldLine ;
newRangeStart = newLine ;
if ( prev ) {
curRange = options . context > 0 ? contextLines ( prev . lines . slice ( - options . context ) ) : [ ] ;
oldRangeStart -= curRange . length ;
newRangeStart -= curRange . length ;
}
}
2021-07-27 22:26:09 +00:00
2024-09-16 17:29:58 +00:00
// Output our changes
/*istanbul ignore start*/
/*istanbul ignore end*/
/*istanbul ignore start*/
( _curRange =
/*istanbul ignore end*/
curRange ) . push . apply (
/*istanbul ignore start*/
_curRange
/*istanbul ignore end*/
,
/*istanbul ignore start*/
_toConsumableArray (
/*istanbul ignore end*/
lines . map ( function ( entry ) {
return ( current . added ? '+' : '-' ) + entry ;
} ) ) ) ;
// Track the updated file position
if ( current . added ) {
newLine += lines . length ;
2020-04-28 16:46:47 +02:00
} else {
2024-09-16 17:29:58 +00:00
oldLine += lines . length ;
}
} else {
// Identical context lines. Track line changes
if ( oldRangeStart ) {
// Close out any changes that have been output (or join overlapping)
if ( lines . length <= options . context * 2 && i < diff . length - 2 ) {
/*istanbul ignore start*/
var _curRange2 ;
/*istanbul ignore end*/
// Overlapping
/*istanbul ignore start*/
/*istanbul ignore end*/
/*istanbul ignore start*/
( _curRange2 =
/*istanbul ignore end*/
curRange ) . push . apply (
/*istanbul ignore start*/
_curRange2
/*istanbul ignore end*/
,
/*istanbul ignore start*/
_toConsumableArray (
/*istanbul ignore end*/
contextLines ( lines ) ) ) ;
} else {
/*istanbul ignore start*/
var _curRange3 ;
/*istanbul ignore end*/
// end the range and output
var contextSize = Math . min ( lines . length , options . context ) ;
/*istanbul ignore start*/
/*istanbul ignore end*/
/*istanbul ignore start*/
( _curRange3 =
/*istanbul ignore end*/
curRange ) . push . apply (
/*istanbul ignore start*/
_curRange3
/*istanbul ignore end*/
,
/*istanbul ignore start*/
_toConsumableArray (
/*istanbul ignore end*/
contextLines ( lines . slice ( 0 , contextSize ) ) ) ) ;
var _hunk = {
oldStart : oldRangeStart ,
oldLines : oldLine - oldRangeStart + contextSize ,
newStart : newRangeStart ,
newLines : newLine - newRangeStart + contextSize ,
lines : curRange
} ;
hunks . push ( _hunk ) ;
oldRangeStart = 0 ;
newRangeStart = 0 ;
curRange = [ ] ;
2020-04-28 16:46:47 +02:00
}
}
2024-09-16 17:29:58 +00:00
oldLine += lines . length ;
newLine += lines . length ;
2020-04-28 16:46:47 +02:00
}
2024-09-16 17:29:58 +00:00
} ;
for ( var i = 0 ; i < diff . length ; i ++ )
/*istanbul ignore start*/
{
_loop ( ) ;
2020-04-28 16:46:47 +02:00
}
2024-09-16 17:29:58 +00:00
// Step 2: eliminate the trailing `\n` from each line of each hunk, and, where needed, add
// "\ No newline at end of file".
/*istanbul ignore end*/
for (
/*istanbul ignore start*/
var _i = 0 , _hunks =
/*istanbul ignore end*/
hunks ;
/*istanbul ignore start*/
_i < _hunks . length
/*istanbul ignore end*/
;
2020-04-28 16:46:47 +02:00
/*istanbul ignore start*/
2024-09-16 17:29:58 +00:00
_i ++
2020-04-28 16:46:47 +02:00
/*istanbul ignore end*/
2024-09-16 17:29:58 +00:00
) {
var hunk =
/*istanbul ignore start*/
_hunks [ _i ]
/*istanbul ignore end*/
;
for ( var _i2 = 0 ; _i2 < hunk . lines . length ; _i2 ++ ) {
if ( hunk . lines [ _i2 ] . endsWith ( '\n' ) ) {
hunk . lines [ _i2 ] = hunk . lines [ _i2 ] . slice ( 0 , - 1 ) ;
} else {
hunk . lines . splice ( _i2 + 1 , 0 , '\\ No newline at end of file' ) ;
_i2 ++ ; // Skip the line we just added, then continue iterating
}
}
}
return {
oldFileName : oldFileName ,
newFileName : newFileName ,
oldHeader : oldHeader ,
newHeader : newHeader ,
hunks : hunks
} ;
2020-04-28 16:46:47 +02:00
}
}
2021-07-27 22:26:09 +00:00
function formatPatch ( diff ) {
2024-05-20 12:17:29 -07:00
if ( Array . isArray ( diff ) ) {
return diff . map ( formatPatch ) . join ( '\n' ) ;
}
2020-04-28 16:46:47 +02:00
var ret = [ ] ;
2021-07-27 22:26:09 +00:00
if ( diff . oldFileName == diff . newFileName ) {
ret . push ( 'Index: ' + diff . oldFileName ) ;
2020-04-28 16:46:47 +02:00
}
ret . push ( '===================================================================' ) ;
ret . push ( '--- ' + diff . oldFileName + ( typeof diff . oldHeader === 'undefined' ? '' : '\t' + diff . oldHeader ) ) ;
ret . push ( '+++ ' + diff . newFileName + ( typeof diff . newHeader === 'undefined' ? '' : '\t' + diff . newHeader ) ) ;
for ( var i = 0 ; i < diff . hunks . length ; i ++ ) {
2024-09-16 17:29:58 +00:00
var hunk = diff . hunks [ i ] ;
// Unified Diff Format quirk: If the chunk size is 0,
2021-07-27 22:26:09 +00:00
// the first number is one lower than one would expect.
// https://www.artima.com/weblogs/viewpost.jsp?thread=164293
if ( hunk . oldLines === 0 ) {
hunk . oldStart -= 1 ;
}
if ( hunk . newLines === 0 ) {
hunk . newStart -= 1 ;
}
2020-04-28 16:46:47 +02:00
ret . push ( '@@ -' + hunk . oldStart + ',' + hunk . oldLines + ' +' + hunk . newStart + ',' + hunk . newLines + ' @@' ) ;
ret . push . apply ( ret , hunk . lines ) ;
}
return ret . join ( '\n' ) + '\n' ;
}
2021-07-27 22:26:09 +00:00
function createTwoFilesPatch ( oldFileName , newFileName , oldStr , newStr , oldHeader , newHeader , options ) {
2024-09-16 17:29:58 +00:00
/*istanbul ignore start*/
var _options2 ;
/*istanbul ignore end*/
if ( typeof options === 'function' ) {
options = {
callback : options
} ;
}
if ( !
/*istanbul ignore start*/
( ( _options2 =
/*istanbul ignore end*/
options ) !== null && _options2 !== void 0 &&
/*istanbul ignore start*/
_options2
/*istanbul ignore end*/
. callback ) ) {
var patchObj = structuredPatch ( oldFileName , newFileName , oldStr , newStr , oldHeader , newHeader , options ) ;
if ( ! patchObj ) {
return ;
}
return formatPatch ( patchObj ) ;
} else {
var
/*istanbul ignore start*/
_options3 =
/*istanbul ignore end*/
options ,
/*istanbul ignore start*/
/*istanbul ignore end*/
_callback2 = _options3 . callback ;
structuredPatch ( oldFileName , newFileName , oldStr , newStr , oldHeader , newHeader ,
/*istanbul ignore start*/
_objectSpread ( _objectSpread ( { } ,
/*istanbul ignore end*/
options ) , { } , {
callback : function
/*istanbul ignore start*/
callback
/*istanbul ignore end*/
( patchObj ) {
if ( ! patchObj ) {
_callback2 ( ) ;
} else {
_callback2 ( formatPatch ( patchObj ) ) ;
}
}
} ) ) ;
}
2021-07-27 22:26:09 +00:00
}
2020-04-28 16:46:47 +02:00
function createPatch ( fileName , oldStr , newStr , oldHeader , newHeader , options ) {
return createTwoFilesPatch ( fileName , fileName , oldStr , newStr , oldHeader , newHeader , options ) ;
}
2024-09-16 17:29:58 +00:00
/**
* Split `text` into an array of lines, including the trailing newline character (where present)
*/
function splitLines ( text ) {
var hasTrailingNl = text . endsWith ( '\n' ) ;
var result = text . split ( '\n' ) . map ( function ( line )
/*istanbul ignore start*/
{
return (
/*istanbul ignore end*/
line + '\n'
) ;
} ) ;
if ( hasTrailingNl ) {
result . pop ( ) ;
} else {
result . push ( result . pop ( ) . slice ( 0 , - 1 ) ) ;
}
return result ;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbGluZSIsInJlcXVpcmUiLCJfdHlwZW9mIiwibyIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiY29uc3RydWN0b3IiLCJwcm90b3R5cGUiLCJfdG9Db25zdW1hYmxlQXJyYXkiLCJhcnIiLCJfYXJyYXlXaXRob3V0SG9sZXMiLCJfaXRlcmFibGVUb0FycmF5IiwiX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5IiwiX25vbkl0ZXJhYmxlU3ByZWFkIiwiVHlwZUVycm9yIiwibWluTGVuIiwiX2FycmF5TGlrZVRvQXJyYXkiLCJuIiwiT2JqZWN0IiwidG9TdHJpbmciLCJjYWxsIiwic2xpY2UiLCJuYW1lIiwiQXJyYXkiLCJmcm9tIiwidGVzdCIsIml0ZXIiLCJpc0FycmF5IiwibGVuIiwibGVuZ3RoIiwiaSIsImFycjIiLCJvd25LZXlzIiwiZSIsInIiLCJ0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZGVmaW5lUHJvcGVydHkiLCJvYmoiLCJrZXkiLCJ2YWx1ZSIsIl90b1Byb3BlcnR5S2V5IiwiY29uZmlndXJhYmxlIiwid3JpdGFibGUiLCJfdG9QcmltaXRpdmUiLCJ0b1ByaW1pdGl2ZSIsIlN0cmluZyIsIk51bWJlciIsInN0cnVjdHVyZWRQYXRjaCIsIm9sZEZpbGVOYW1lIiwibmV3RmlsZU5hbWUiLCJvbGRTdHIiLCJuZXdTdHIiLCJvbGRIZWFkZXIiLCJuZXdIZWFkZXIiLCJvcHRpb25zIiwiY2FsbGJhY2siLCJjb250ZXh0IiwibmV3bGluZUlzVG9rZW4iLCJFcnJvciIsImRpZmZMaW5lc1Jlc3VsdFRvUGF0Y2giLCJkaWZmTGluZXMiLCJfb3B0aW9ucyIsImRpZmYiLCJwYXRjaCIsImxpbmVzIiwiY29udGV4dExpbmVzIiwibWFwIiwiZW50cnkiLCJodW5rcyIsIm9sZFJhbmdlU3RhcnQiLCJuZXdSYW5nZVN0YXJ0IiwiY3VyUmFuZ2UiLCJvbGRMaW5lIiwibmV3TGluZSIsIl9sb29wIiwiY3VycmVudCIsInNwbGl0TGluZXMiLCJhZGRlZCIsInJlbW92ZWQiLCJfY3VyUmFuZ2UiLCJwcmV2IiwiX2N1clJhbmdlMiIsIl9jdXJSYW5nZTMiLCJjb250ZXh0U2l6ZSIsIk1hdGgiLCJtaW4iLCJodW5rIiwib2xkU3RhcnQiLCJvbGRMaW5lcyIsIm5ld1N0YXJ0IiwibmV3TGluZXMiLCJfaSIsIl9odW5rcyIsImVuZHNXaXRoIiwic3BsaWNlIiwiZm9ybWF0UGF0Y2giLCJqb2luIiwicmV0IiwiY3JlYXRlVHdvRmlsZXNQYXRjaCIsIl9vcHRpb25zMiIsInBhdGNoT2JqIiwiX29wdGlvbnMzIiwiY3JlYXRlUGF0Y2giLCJmaWxlTmFtZSIsInRleHQiLCJoYXNUcmFpbGluZ05sIiwicmVzdWx0Iiwic3BsaXQiLCJsaW5lIiwicG9wIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BhdGNoL2NyZWF0ZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2RpZmZMaW5lc30gZnJvbSAnLi4vZGlmZi9saW5lJztcblxuZXhwb3J0IGZ1bmN0aW9uIHN0cnVjdHVyZWRQYXRjaChvbGRGaWxlTmFtZSwgbmV3RmlsZU5hbWUsIG9sZFN0ciwgbmV3U3RyLCBvbGRIZWFkZXIsIG5ld0hlYWRlciwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0ge307XG4gIH1cbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgb3B0aW9ucyA9IHtjYWxsYmFjazogb3B0aW9uc307XG4gIH1cbiAgaWYgKHR5cGVvZiBvcHRpb25zLmNvbnRleHQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0aW9ucy5jb250ZXh0ID0gNDtcbiAgfVxuICBpZiAob3B0aW9ucy5uZXdsaW5lSXNUb2tlbikge1xuICAgIHRocm93IG5ldyBFcnJvcignbmV3bGluZUlzVG9rZW4gbWF5IG5vdCBiZSB1c2VkIHdpdGggcGF0Y2gtZ2VuZXJhdGlvbiBmdW5jdGlvbnMsIG9ubHkgd2l0aCBkaWZmaW5nIGZ1bmN0aW9ucycpO1xuICB9XG5cbiAgaWYgKCFvcHRpb25zLmNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGRpZmZMaW5lc1Jlc3VsdFRvUGF0Y2goZGlmZkxpbmVzKG9sZFN0ciwgbmV3U3RyLCBvcHRpb25zKSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qge2NhbGxiYWNrfSA9IG9wdGlvbnM7XG4gICAgZGlmZkxpbmVzKFxuICAgICAgb2xkU3RyLFxuICAgICAgbmV3U3RyLFxuICAgICAge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBjYWxsYmFjazogKGRpZmYpID0+IHtcbiAgICAgICAgICBjb25zdCBwYXRjaCA9IGRpZmZMaW5lc1Jlc3VsdFRvUGF0Y2goZGlmZik7XG4gICAgICAgICAgY2FsbGJhY2socGF0Y2gpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRpZmZMaW5lc1Jlc3VsdFRvUGF0Y2goZGlmZikge1xuICAgIC8vIFNURVAgMTogQnVpbGQgdXAgdGhlIHBhdGNoIHdpdGggbm8gXCJcXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlXCIgbGluZXMgYW5kIHdpdGggdGhlIGFycmF5c1xuICAgIC8vICAgICAgICAgb2YgbGluZXMgY29udGFpbmluZyB0cmFpbGluZyBuZXdsaW5lIGNoYXJhY3RlcnMuIFdlJ2xsIHRpZHkgdXAgbGF0ZXIuLi5cblxuICAgIGlmKCFkaWZmKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZGlmZi5wdXNoKHt2YWx1ZTogJycsIGxpbmVzOiBbXX0pOyAvLyBBcHBlbmQgYW4gZW1wdHkgdmFsdWUgdG8gbWFrZSBjbGVhbnVwIGVhc2llclxuXG4gICAgZnVuY3Rpb24gY29udGV4dExpbmVzKGxpbmVzKSB7XG4gICAgICByZXR1cm4gbGluZXMubWFwKGZ1bmN0aW9uKGVudHJ5KSB7IHJldHVybiAnICcgKyBlbnRyeTsgfSk7XG4gICAgfVxuXG4gICAgbGV0IGh1bmtzID0gW107XG4gICAgbGV0IG9sZFJhbmdlU3RhcnQgPSAwLCBuZXdSYW5nZVN0YXJ0ID0gMCwgY3VyUmFuZ2UgPSBbXSxcbiAgICAgICAgb2xkTGluZSA9IDEsIG5ld0xpbmUgPSAxO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGlmZi5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY3VycmVudCA9IGRpZmZbaV0sXG4gICAgICAgICA