| 'use strict'; | 
|   | 
| var isExtendable = require('is-extendable'); | 
| var forIn = require('for-in'); | 
|   | 
| function mixinDeep(target, objects) { | 
|   var len = arguments.length, i = 0; | 
|   while (++i < len) { | 
|     var obj = arguments[i]; | 
|     if (isObject(obj)) { | 
|       forIn(obj, copy, target); | 
|     } | 
|   } | 
|   return target; | 
| } | 
|   | 
| /** | 
|  * Copy properties from the source object to the | 
|  * target object. | 
|  * | 
|  * @param  {*} `val` | 
|  * @param  {String} `key` | 
|  */ | 
|   | 
| function copy(val, key) { | 
|   if (!isValidKey(key)) { | 
|     return; | 
|   } | 
|   | 
|   var obj = this[key]; | 
|   if (isObject(val) && isObject(obj)) { | 
|     mixinDeep(obj, val); | 
|   } else { | 
|     this[key] = val; | 
|   } | 
| } | 
|   | 
| /** | 
|  * Returns true if `val` is an object or function. | 
|  * | 
|  * @param  {any} val | 
|  * @return {Boolean} | 
|  */ | 
|   | 
| function isObject(val) { | 
|   return isExtendable(val) && !Array.isArray(val); | 
| } | 
|   | 
| /** | 
|  * Returns true if `key` is a valid key to use when extending objects. | 
|  * | 
|  * @param  {String} `key` | 
|  * @return {Boolean} | 
|  */ | 
|   | 
| function isValidKey(key) { | 
|   return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; | 
| }; | 
|   | 
| /** | 
|  * Expose `mixinDeep` | 
|  */ | 
|   | 
| module.exports = mixinDeep; |