| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 | 'use strict';var map        = require('es5-ext/object/map')  , isCallable = require('es5-ext/object/is-callable')  , validValue = require('es5-ext/object/valid-value')  , contains   = require('es5-ext/string/#/contains')  , call = Function.prototype.call  , defineProperty = Object.defineProperty  , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor  , getPrototypeOf = Object.getPrototypeOf  , hasOwnProperty = Object.prototype.hasOwnProperty  , cacheDesc = { configurable: false, enumerable: false, writable: false,		value: null }  , define;define = function (name, options) {	var value, dgs, cacheName, desc, writable = false, resolvable	  , flat;	options = Object(validValue(options));	cacheName = options.cacheName;	flat = options.flat;	if (cacheName == null) cacheName = name;	delete options.cacheName;	value = options.value;	resolvable = isCallable(value);	delete options.value;	dgs = { configurable: Boolean(options.configurable),		enumerable: Boolean(options.enumerable) };	if (name !== cacheName) {		dgs.get = function () {			if (hasOwnProperty.call(this, cacheName)) return this[cacheName];			cacheDesc.value = resolvable ? call.call(value, this, options) : value;			cacheDesc.writable = writable;			defineProperty(this, cacheName, cacheDesc);			cacheDesc.value = null;			if (desc) defineProperty(this, name, desc);			return this[cacheName];		};	} else if (!flat) {		dgs.get = function self() {			var ownDesc;			if (hasOwnProperty.call(this, name)) {				ownDesc = getOwnPropertyDescriptor(this, name);				// It happens in Safari, that getter is still called after property				// was defined with a value, following workarounds that				// While in IE11 it may happen that here ownDesc is undefined (go figure)				if (ownDesc) {					if (ownDesc.hasOwnProperty('value')) return ownDesc.value;					if ((typeof ownDesc.get === 'function') && (ownDesc.get !== self)) {						return ownDesc.get.call(this);					}					return value;				}			}			desc.value = resolvable ? call.call(value, this, options) : value;			defineProperty(this, name, desc);			desc.value = null;			return this[name];		};	} else {		dgs.get = function self() {			var base = this, ownDesc;			if (hasOwnProperty.call(this, name)) {				// It happens in Safari, that getter is still called after property				// was defined with a value, following workarounds that				ownDesc = getOwnPropertyDescriptor(this, name);				if (ownDesc.hasOwnProperty('value')) return ownDesc.value;				if ((typeof ownDesc.get === 'function') && (ownDesc.get !== self)) {					return ownDesc.get.call(this);				}			}			while (!hasOwnProperty.call(base, name)) base = getPrototypeOf(base);			desc.value = resolvable ? call.call(value, base, options) : value;			defineProperty(base, name, desc);			desc.value = null;			return base[name];		};	}	dgs.set = function (value) {		if (hasOwnProperty.call(this, name)) {			throw new TypeError("Cannot assign to lazy defined '" + name + "' property of " + this);		}		dgs.get.call(this);		this[cacheName] = value;	};	if (options.desc) {		desc = {			configurable: contains.call(options.desc, 'c'),			enumerable: contains.call(options.desc, 'e')		};		if (cacheName === name) {			desc.writable = contains.call(options.desc, 'w');			desc.value = null;		} else {			writable = contains.call(options.desc, 'w');			desc.get = dgs.get;			desc.set = dgs.set;		}		delete options.desc;	} else if (cacheName === name) {		desc = {			configurable: Boolean(options.configurable),			enumerable: Boolean(options.enumerable),			writable: Boolean(options.writable),			value: null		};	}	delete options.configurable;	delete options.enumerable;	delete options.writable;	return dgs;};module.exports = function (props) {	return map(props, function (desc, name) { return define(name, desc); });};
 |