|  |  | 
|  | /** | 
|  | * This is the common logic for both the Node.js and web browser | 
|  | * implementations of `debug()`. | 
|  | */ | 
|  |  | 
|  | function setup(env) { | 
|  | createDebug.debug = createDebug; | 
|  | createDebug.default = createDebug; | 
|  | createDebug.coerce = coerce; | 
|  | createDebug.disable = disable; | 
|  | createDebug.enable = enable; | 
|  | createDebug.enabled = enabled; | 
|  | createDebug.humanize = require('ms'); | 
|  |  | 
|  | Object.keys(env).forEach(key => { | 
|  | createDebug[key] = env[key]; | 
|  | }); | 
|  |  | 
|  | /** | 
|  | * Active `debug` instances. | 
|  | */ | 
|  | createDebug.instances = []; | 
|  |  | 
|  | /** | 
|  | * The currently active debug mode names, and names to skip. | 
|  | */ | 
|  |  | 
|  | createDebug.names = []; | 
|  | createDebug.skips = []; | 
|  |  | 
|  | /** | 
|  | * Map of special "%n" handling functions, for the debug "format" argument. | 
|  | * | 
|  | * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". | 
|  | */ | 
|  | createDebug.formatters = {}; | 
|  |  | 
|  | /** | 
|  | * Selects a color for a debug namespace | 
|  | * @param {String} namespace The namespace string for the for the debug instance to be colored | 
|  | * @return {Number|String} An ANSI color code for the given namespace | 
|  | * @api private | 
|  | */ | 
|  | function selectColor(namespace) { | 
|  | let hash = 0; | 
|  |  | 
|  | for (let i = 0; i < namespace.length; i++) { | 
|  | hash = ((hash << 5) - hash) + namespace.charCodeAt(i); | 
|  | hash |= 0; // Convert to 32bit integer | 
|  | } | 
|  |  | 
|  | return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; | 
|  | } | 
|  | createDebug.selectColor = selectColor; | 
|  |  | 
|  | /** | 
|  | * Create a debugger with the given `namespace`. | 
|  | * | 
|  | * @param {String} namespace | 
|  | * @return {Function} | 
|  | * @api public | 
|  | */ | 
|  | function createDebug(namespace) { | 
|  | let prevTime; | 
|  |  | 
|  | function debug(...args) { | 
|  | // Disabled? | 
|  | if (!debug.enabled) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | const self = debug; | 
|  |  | 
|  | // Set `diff` timestamp | 
|  | const curr = Number(new Date()); | 
|  | const ms = curr - (prevTime || curr); | 
|  | self.diff = ms; | 
|  | self.prev = prevTime; | 
|  | self.curr = curr; | 
|  | prevTime = curr; | 
|  |  | 
|  | args[0] = createDebug.coerce(args[0]); | 
|  |  | 
|  | if (typeof args[0] !== 'string') { | 
|  | // Anything else let's inspect with %O | 
|  | args.unshift('%O'); | 
|  | } | 
|  |  | 
|  | // Apply any `formatters` transformations | 
|  | let index = 0; | 
|  | args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { | 
|  | // If we encounter an escaped % then don't increase the array index | 
|  | if (match === '%%') { | 
|  | return match; | 
|  | } | 
|  | index++; | 
|  | const formatter = createDebug.formatters[format]; | 
|  | if (typeof formatter === 'function') { | 
|  | const val = args[index]; | 
|  | match = formatter.call(self, val); | 
|  |  | 
|  | // Now we need to remove `args[index]` since it's inlined in the `format` | 
|  | args.splice(index, 1); | 
|  | index--; | 
|  | } | 
|  | return match; | 
|  | }); | 
|  |  | 
|  | // Apply env-specific formatting (colors, etc.) | 
|  | createDebug.formatArgs.call(self, args); | 
|  |  | 
|  | const logFn = self.log || createDebug.log; | 
|  | logFn.apply(self, args); | 
|  | } | 
|  |  | 
|  | debug.namespace = namespace; | 
|  | debug.enabled = createDebug.enabled(namespace); | 
|  | debug.useColors = createDebug.useColors(); | 
|  | debug.color = selectColor(namespace); | 
|  | debug.destroy = destroy; | 
|  | debug.extend = extend; | 
|  | // Debug.formatArgs = formatArgs; | 
|  | // debug.rawLog = rawLog; | 
|  |  | 
|  | // env-specific initialization logic for debug instances | 
|  | if (typeof createDebug.init === 'function') { | 
|  | createDebug.init(debug); | 
|  | } | 
|  |  | 
|  | createDebug.instances.push(debug); | 
|  |  | 
|  | return debug; | 
|  | } | 
|  |  | 
|  | function destroy() { | 
|  | const index = createDebug.instances.indexOf(this); | 
|  | if (index !== -1) { | 
|  | createDebug.instances.splice(index, 1); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | function extend(namespace, delimiter) { | 
|  | const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); | 
|  | newDebug.log = this.log; | 
|  | return newDebug; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Enables a debug mode by namespaces. This can include modes | 
|  | * separated by a colon and wildcards. | 
|  | * | 
|  | * @param {String} namespaces | 
|  | * @api public | 
|  | */ | 
|  | function enable(namespaces) { | 
|  | createDebug.save(namespaces); | 
|  |  | 
|  | createDebug.names = []; | 
|  | createDebug.skips = []; | 
|  |  | 
|  | let i; | 
|  | const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); | 
|  | const len = split.length; | 
|  |  | 
|  | for (i = 0; i < len; i++) { | 
|  | if (!split[i]) { | 
|  | // ignore empty strings | 
|  | continue; | 
|  | } | 
|  |  | 
|  | namespaces = split[i].replace(/\*/g, '.*?'); | 
|  |  | 
|  | if (namespaces[0] === '-') { | 
|  | createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); | 
|  | } else { | 
|  | createDebug.names.push(new RegExp('^' + namespaces + '$')); | 
|  | } | 
|  | } | 
|  |  | 
|  | for (i = 0; i < createDebug.instances.length; i++) { | 
|  | const instance = createDebug.instances[i]; | 
|  | instance.enabled = createDebug.enabled(instance.namespace); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Disable debug output. | 
|  | * | 
|  | * @return {String} namespaces | 
|  | * @api public | 
|  | */ | 
|  | function disable() { | 
|  | const namespaces = [ | 
|  | ...createDebug.names.map(toNamespace), | 
|  | ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace) | 
|  | ].join(','); | 
|  | createDebug.enable(''); | 
|  | return namespaces; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns true if the given mode name is enabled, false otherwise. | 
|  | * | 
|  | * @param {String} name | 
|  | * @return {Boolean} | 
|  | * @api public | 
|  | */ | 
|  | function enabled(name) { | 
|  | if (name[name.length - 1] === '*') { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | let i; | 
|  | let len; | 
|  |  | 
|  | for (i = 0, len = createDebug.skips.length; i < len; i++) { | 
|  | if (createDebug.skips[i].test(name)) { | 
|  | return false; | 
|  | } | 
|  | } | 
|  |  | 
|  | for (i = 0, len = createDebug.names.length; i < len; i++) { | 
|  | if (createDebug.names[i].test(name)) { | 
|  | return true; | 
|  | } | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Convert regexp to namespace | 
|  | * | 
|  | * @param {RegExp} regxep | 
|  | * @return {String} namespace | 
|  | * @api private | 
|  | */ | 
|  | function toNamespace(regexp) { | 
|  | return regexp.toString() | 
|  | .substring(2, regexp.toString().length - 2) | 
|  | .replace(/\.\*\?$/, '*'); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Coerce `val`. | 
|  | * | 
|  | * @param {Mixed} val | 
|  | * @return {Mixed} | 
|  | * @api private | 
|  | */ | 
|  | function coerce(val) { | 
|  | if (val instanceof Error) { | 
|  | return val.stack || val.message; | 
|  | } | 
|  | return val; | 
|  | } | 
|  |  | 
|  | createDebug.enable(createDebug.load()); | 
|  |  | 
|  | return createDebug; | 
|  | } | 
|  |  | 
|  | module.exports = setup; |