1module.exports = exports = abbrev.abbrev = abbrev 2 3abbrev.monkeyPatch = monkeyPatch 4 5function monkeyPatch () { 6 Object.defineProperty(Array.prototype, 'abbrev', { 7 value: function () { return abbrev(this) }, 8 enumerable: false, configurable: true, writable: true 9 }) 10 11 Object.defineProperty(Object.prototype, 'abbrev', { 12 value: function () { return abbrev(Object.keys(this)) }, 13 enumerable: false, configurable: true, writable: true 14 }) 15} 16 17function abbrev (list) { 18 if (arguments.length !== 1 || !Array.isArray(list)) { 19 list = Array.prototype.slice.call(arguments, 0) 20 } 21 for (var i = 0, l = list.length, args = [] ; i < l ; i ++) { 22 args[i] = typeof list[i] === "string" ? list[i] : String(list[i]) 23 } 24 25 // sort them lexicographically, so that they're next to their nearest kin 26 args = args.sort(lexSort) 27 28 // walk through each, seeing how much it has in common with the next and previous 29 var abbrevs = {} 30 , prev = "" 31 for (var i = 0, l = args.length ; i < l ; i ++) { 32 var current = args[i] 33 , next = args[i + 1] || "" 34 , nextMatches = true 35 , prevMatches = true 36 if (current === next) continue 37 for (var j = 0, cl = current.length ; j < cl ; j ++) { 38 var curChar = current.charAt(j) 39 nextMatches = nextMatches && curChar === next.charAt(j) 40 prevMatches = prevMatches && curChar === prev.charAt(j) 41 if (!nextMatches && !prevMatches) { 42 j ++ 43 break 44 } 45 } 46 prev = current 47 if (j === cl) { 48 abbrevs[current] = current 49 continue 50 } 51 for (var a = current.substr(0, j) ; j <= cl ; j ++) { 52 abbrevs[a] = current 53 a += current.charAt(j) 54 } 55 } 56 return abbrevs 57} 58 59function lexSort (a, b) { 60 return a === b ? 0 : a > b ? 1 : -1 61} 62