sjl.js
function extend(o, p, deep) {
        // If `o` or `p` are not set bail
        if (!o || !p) {
            return o;
        }

        // Merge all props from `p` to `o`
        Object.keys(p).forEach(function (prop) { // For all props in p.
            // If property is present on target (o) and is not writable, skip iteration
            var propDescription = Object.getOwnPropertyDescriptor(o, prop);
            if (propDescription &&
                !(isset(propDescription.get) && isset(propDescription.set)) &&
                !propDescription.writable) {
                return;
            }
            if (deep === true) {
                if (isObject(p[prop]) && isObject(o[prop]) && !isEmptyObj(p[prop])) {
                    extend(o[prop], p[prop], deep);
                }
                else {
                    o[prop] = p[prop];
                }
            }
            else {
                o[prop] = p[prop];
            }
        });

        return o;
    }
function extend(o, p, deep) {
        // If `o` or `p` are not set bail
        if (!o || !p) {
            return o;
        }

        // Merge all props from `p` to `o`
        Object.keys(p).forEach(function (prop) { // For all props in p.
            // If property is present on target (o) and is not writable, skip iteration
            var propDescription = Object.getOwnPropertyDescriptor(o, prop);
            if (propDescription &&
                !(isset(propDescription.get) && isset(propDescription.set)) &&
                !propDescription.writable) {
                return;
            }
            if (deep === true) {
                if (isObject(p[prop]) && isObject(o[prop]) && !isEmptyObj(p[prop])) {
                    extend(o[prop], p[prop], deep);
                }
                else {
                    o[prop] = p[prop];
                }
            }
            else {
                o[prop] = p[prop];
            }
        });

        return o;
    }
Copy the enumerable properties of p to o, and return o.
If o and p have a property by the same name, o's property is overwritten.
@param o {*} - *object to extend
@param p {*} - *object to extend from
@param deep [Boolean=false] - Whether or not to do a deep extend (run extend on each prop if prop value is of type 'Object')
@todo rename these variables to be more readable.
@returns {*} - returns o