| 'use strict'; | 
|   | 
| const toString = Object.prototype.toString; | 
| const colors = require('ansi-colors'); | 
| let called = false; | 
| let fns = []; | 
|   | 
| const complements = { | 
|   'yellow': 'blue', | 
|   'cyan': 'red', | 
|   'green': 'magenta', | 
|   'black': 'white', | 
|   'blue': 'yellow', | 
|   'red': 'cyan', | 
|   'magenta': 'green', | 
|   'white': 'black' | 
| }; | 
|   | 
| exports.longest = (arr, prop) => { | 
|   return arr.reduce((a, v) => Math.max(a, prop ? v[prop].length : v.length), 0); | 
| }; | 
|   | 
| exports.hasColor = str => !!str && colors.hasColor(str); | 
|   | 
| const isObject = exports.isObject = val => { | 
|   return val !== null && typeof val === 'object' && !Array.isArray(val); | 
| }; | 
|   | 
| exports.nativeType = val => { | 
|   return toString.call(val).slice(8, -1).toLowerCase().replace(/\s/g, ''); | 
| }; | 
|   | 
| exports.isAsyncFn = val => { | 
|   return exports.nativeType(val) === 'asyncfunction'; | 
| }; | 
|   | 
| exports.isPrimitive = val => { | 
|   return val != null && typeof val !== 'object' && typeof val !== 'function'; | 
| }; | 
|   | 
| exports.resolve = (context, value, ...rest) => { | 
|   if (typeof value === 'function') { | 
|     return value.call(context, ...rest); | 
|   } | 
|   return value; | 
| }; | 
|   | 
| exports.scrollDown = (choices = []) => [...choices.slice(1), choices[0]]; | 
| exports.scrollUp = (choices = []) => [choices.pop(), ...choices]; | 
|   | 
| exports.reorder = (arr = []) => { | 
|   let res = arr.slice(); | 
|   res.sort((a, b) => { | 
|     if (a.index > b.index) return 1; | 
|     if (a.index < b.index) return -1; | 
|     return 0; | 
|   }); | 
|   return res; | 
| }; | 
|   | 
| exports.swap = (arr, index, pos) => { | 
|   let len = arr.length; | 
|   let idx = pos === len ? 0 : pos < 0 ? len - 1 : pos; | 
|   let choice = arr[index]; | 
|   arr[index] = arr[idx]; | 
|   arr[idx] = choice; | 
| }; | 
|   | 
| exports.width = (stream, fallback = 80) => { | 
|   let columns = (stream && stream.columns) ? stream.columns : fallback; | 
|   if (stream && typeof stream.getWindowSize === 'function') { | 
|     columns = stream.getWindowSize()[0]; | 
|   } | 
|   if (process.platform === 'win32') { | 
|     return columns - 1; | 
|   } | 
|   return columns; | 
| }; | 
|   | 
| exports.height = (stream, fallback = 20) => { | 
|   let rows = (stream && stream.rows) ? stream.rows : fallback; | 
|   if (stream && typeof stream.getWindowSize === 'function') { | 
|     rows = stream.getWindowSize()[1]; | 
|   } | 
|   return rows; | 
| }; | 
|   | 
| exports.wordWrap = (str, options = {}) => { | 
|   if (!str) return str; | 
|   | 
|   if (typeof options === 'number') { | 
|     options = { width: options }; | 
|   } | 
|   | 
|   let { indent = '', newline = ('\n' + indent), width = 80 } = options; | 
|   let spaces = (newline + indent).match(/[^\S\n]/g) || []; | 
|   width -= spaces.length; | 
|   let source = `.{1,${width}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`; | 
|   let output = str.trim(); | 
|   let regex = new RegExp(source, 'g'); | 
|   let lines = output.match(regex) || []; | 
|   lines = lines.map(line => line.replace(/\n$/, '')); | 
|   if (options.padEnd) lines = lines.map(line => line.padEnd(width, ' ')); | 
|   if (options.padStart) lines = lines.map(line => line.padStart(width, ' ')); | 
|   return indent + lines.join(newline); | 
| }; | 
|   | 
| exports.unmute = color => { | 
|   let name = color.stack.find(n => colors.keys.color.includes(n)); | 
|   if (name) { | 
|     return colors[name]; | 
|   } | 
|   let bg = color.stack.find(n => n.slice(2) === 'bg'); | 
|   if (bg) { | 
|     return colors[name.slice(2)]; | 
|   } | 
|   return str => str; | 
| }; | 
|   | 
| exports.pascal = str => str ? str[0].toUpperCase() + str.slice(1) : ''; | 
|   | 
| exports.inverse = color => { | 
|   if (!color || !color.stack) return color; | 
|   let name = color.stack.find(n => colors.keys.color.includes(n)); | 
|   if (name) { | 
|     let col = colors['bg' + exports.pascal(name)]; | 
|     return col ? col.black : color; | 
|   } | 
|   let bg = color.stack.find(n => n.slice(0, 2) === 'bg'); | 
|   if (bg) { | 
|     return colors[bg.slice(2).toLowerCase()] || color; | 
|   } | 
|   return colors.none; | 
| }; | 
|   | 
| exports.complement = color => { | 
|   if (!color || !color.stack) return color; | 
|   let name = color.stack.find(n => colors.keys.color.includes(n)); | 
|   let bg = color.stack.find(n => n.slice(0, 2) === 'bg'); | 
|   if (name && !bg) { | 
|     return colors[complements[name] || name]; | 
|   } | 
|   if (bg) { | 
|     let lower = bg.slice(2).toLowerCase(); | 
|     let comp = complements[lower]; | 
|     if (!comp) return color; | 
|     return colors['bg' + exports.pascal(comp)] || color; | 
|   } | 
|   return colors.none; | 
| }; | 
|   | 
| exports.meridiem = date => { | 
|   let hours = date.getHours(); | 
|   let minutes = date.getMinutes(); | 
|   let ampm = hours >= 12 ? 'pm' : 'am'; | 
|   hours = hours % 12; | 
|   let hrs = hours === 0 ? 12 : hours; | 
|   let min = minutes < 10 ? '0' + minutes : minutes; | 
|   return hrs + ':' + min + ' ' + ampm; | 
| }; | 
|   | 
| /** | 
|  * Set a value on the given object. | 
|  * @param {Object} obj | 
|  * @param {String} prop | 
|  * @param {any} value | 
|  */ | 
|   | 
| exports.set = (obj = {}, prop = '', val) => { | 
|   return prop.split('.').reduce((acc, k, i, arr) => { | 
|     let value = arr.length - 1 > i ? (acc[k] || {}) : val; | 
|     if (!exports.isObject(value) && i < arr.length - 1) value = {}; | 
|     return (acc[k] = value); | 
|   }, obj); | 
| }; | 
|   | 
| /** | 
|  * Get a value from the given object. | 
|  * @param {Object} obj | 
|  * @param {String} prop | 
|  */ | 
|   | 
| exports.get = (obj = {}, prop = '', fallback) => { | 
|   let value = obj[prop] == null | 
|     ? prop.split('.').reduce((acc, k) => acc && acc[k], obj) | 
|     : obj[prop]; | 
|   return value == null ? fallback : value; | 
| }; | 
|   | 
| exports.mixin = (target, b) => { | 
|   if (!isObject(target)) return b; | 
|   if (!isObject(b)) return target; | 
|   for (let key of Object.keys(b)) { | 
|     let desc = Object.getOwnPropertyDescriptor(b, key); | 
|     if (desc.hasOwnProperty('value')) { | 
|       if (target.hasOwnProperty(key) && isObject(desc.value)) { | 
|         let existing = Object.getOwnPropertyDescriptor(target, key); | 
|         if (isObject(existing.value)) { | 
|           target[key] = exports.merge({}, target[key], b[key]); | 
|         } else { | 
|           Reflect.defineProperty(target, key, desc); | 
|         } | 
|       } else { | 
|         Reflect.defineProperty(target, key, desc); | 
|       } | 
|     } else { | 
|       Reflect.defineProperty(target, key, desc); | 
|     } | 
|   } | 
|   return target; | 
| }; | 
|   | 
| exports.merge = (...args) => { | 
|   let target = {}; | 
|   for (let ele of args) exports.mixin(target, ele); | 
|   return target; | 
| }; | 
|   | 
| exports.mixinEmitter = (obj, emitter) => { | 
|   let proto = emitter.constructor.prototype; | 
|   for (let key of Object.keys(proto)) { | 
|     let val = proto[key]; | 
|     if (typeof val === 'function') { | 
|       exports.define(obj, key, val.bind(emitter)); | 
|     } else { | 
|       exports.define(obj, key, val); | 
|     } | 
|   } | 
| }; | 
|   | 
| exports.onExit = callback => { | 
|   const onExit = (quit, code) => { | 
|     if (called) return; | 
|   | 
|     called = true; | 
|     fns.forEach(fn => fn()); | 
|   | 
|     if (quit === true) { | 
|       process.exit(128 + code); | 
|     } | 
|   }; | 
|   | 
|   if (fns.length === 0) { | 
|     process.once('SIGTERM', onExit.bind(null, true, 15)); | 
|     process.once('SIGINT', onExit.bind(null, true, 2)); | 
|     process.once('exit', onExit); | 
|   } | 
|   | 
|   fns.push(callback); | 
| }; | 
|   | 
| exports.define = (obj, key, value) => { | 
|   Reflect.defineProperty(obj, key, { value }); | 
| }; | 
|   | 
| exports.defineExport = (obj, key, fn) => { | 
|   let custom; | 
|   Reflect.defineProperty(obj, key, { | 
|     enumerable: true, | 
|     configurable: true, | 
|     set(val) { | 
|       custom = val; | 
|     }, | 
|     get() { | 
|       return custom ? custom() : fn(); | 
|     } | 
|   }); | 
| }; |