text: // A modification of https://github.com/WebReflection/get-own-property-symbols
  // (C) Andrea Giammarchi - MIT Licensed
  
  (function (Object, GOPS, global) {
  	'use strict'; //so that ({}).toString.call(null) returns the correct [object Null] rather than [object Window]
  
  	var	setDescriptor;
  	var id = 0;
  	var random = '' + Math.random();
  	var prefix = '__\x01symbol:';
  	var prefixLength = prefix.length;
  	var internalSymbol = '__\x01symbol@@' + random;
  	var DP = 'defineProperty';
  	var DPies = 'defineProperties';
  	var GOPN = 'getOwnPropertyNames';
  	var GOPD = 'getOwnPropertyDescriptor';
  	var PIE = 'propertyIsEnumerable';
  	var ObjectProto = Object.prototype;
  	var hOP = ObjectProto.hasOwnProperty;
  	var pIE = ObjectProto[PIE];
  	var toString = ObjectProto.toString;
  	var concat = Array.prototype.concat;
  	var cachedWindowNames = Object.getOwnPropertyNames ? Object.getOwnPropertyNames(self) : [];
  	var nGOPN = Object[GOPN];
  	var gOPN = function getOwnPropertyNames (obj) {
  		if (toString.call(obj) === '[object Window]') {
  			try {
  				return nGOPN(obj);
  			} catch (e) {
  				// IE bug where layout engine calls userland gOPN for cross-domain `window` objects
  				return concat.call([], cachedWindowNames);
  			}
  		}
  		return nGOPN(obj);
  	};
  	var gOPD = Object[GOPD];
  	var create = Object.create;
  	var keys = Object.keys;
  	var freeze = Object.freeze || Object;
  	var defineProperty = Object[DP];
  	var $defineProperties = Object[DPies];
  	var descriptor = gOPD(Object, GOPN);
  	var addInternalIfNeeded = function (o, uid, enumerable) {
  		if (!hOP.call(o, internalSymbol)) {
  			try {
  				defineProperty(o, internalSymbol, {
  					enumerable: false,
  					configurable: false,
  					writable: false,
  					value: {}
  				});
  			} catch (e) {
  				o[internalSymbol] = {};
  			}
  		}
  		o[internalSymbol]['@@' + uid] = enumerable;
  	};
  	var createWithSymbols = function (proto, descriptors) {
  		var self = create(proto);
  		gOPN(descriptors).forEach(function (key) {
  			if (propertyIsEnumerable.call(descriptors, key)) {
  				$defineProperty(self, key, descriptors[key]);
  			}
  		});
  		return self;
  	};
  	var copyAsNonEnumerable = function (descriptor) {
  		var newDescriptor = create(descriptor);
  		newDescriptor.enumerable = false;
  		return newDescriptor;
  	};
  	var get = function get(){};
  	var onlyNonSymbols = function (name) {
  		return name != internalSymbol &&
  			!hOP.call(source, name);
  	};
  	var onlySymbols = function (name) {
  		return name != internalSymbol &&
  			hOP.call(source, name);
  	};
  	var propertyIsEnumerable = function propertyIsEnumerable(key) {
  		var uid = '' + key;
  		return onlySymbols(uid) ? (
  			hOP.call(this, uid) &&
  			this[internalSymbol]['@@' + uid]
  		) : pIE.call(this, key);
  	};
  	var setAndGetSymbol = function (uid) {
  		var descriptor = {
  			enumerable: false,
  			configurable: true,
  			get: get,
  			set: function (value) {
  			setDescriptor(this, uid, {
  				enumerable: false,
  				configurable: true,
  				writable: true,
  				value: value
  			});
  			addInternalIfNeeded(this, uid, true);
  			}
  		};
  		try {
  			defineProperty(ObjectProto, uid, descriptor);
  		} catch (e) {
  			ObjectProto[uid] = descriptor.value;
  		}
  		return freeze(source[uid] = defineProperty(
  			Object(uid),
  			'constructor',
  			sourceConstructor
  		));
  	};
  	var Symbol = function Symbol() {
  		var description = arguments[0];
  		if (this instanceof Symbol) {
  			throw new TypeError('Symbol is not a constructor');
  		}
  		return setAndGetSymbol(
  			prefix.concat(description || '', random, ++id)
  		);
  		};
  	var source = create(null);
  	var sourceConstructor = {value: Symbol};
  	var sourceMap = function (uid) {
  		return source[uid];
  		};
  	var $defineProperty = function defineProp(o, key, descriptor) {
  		var uid = '' + key;
  		if (onlySymbols(uid)) {
  			setDescriptor(o, uid, descriptor.enumerable ?
  				copyAsNonEnumerable(descriptor) : descriptor);
  			addInternalIfNeeded(o, uid, !!descriptor.enumerable);
  		} else {
  			defineProperty(o, key, descriptor);
  		}
  		return o;
  	};
  
  	var onlyInternalSymbols = function (obj) {
  		return function (name) {
  			return hOP.call(obj, internalSymbol) && hOP.call(obj[internalSymbol], '@@' + name);
  		};
  	};
  	var $getOwnPropertySymbols = function getOwnPropertySymbols(o) {
  		return gOPN(o).filter(o === ObjectProto ? onlyInternalSymbols(o) : onlySymbols).map(sourceMap);
  		}
  	;
  
  	descriptor.value = $defineProperty;
  	defineProperty(Object, DP, descriptor);
  
  	descriptor.value = $getOwnPropertySymbols;
  	defineProperty(Object, GOPS, descriptor);
  
  	descriptor.value = function getOwnPropertyNames(o) {
  		return gOPN(o).filter(onlyNonSymbols);
  	};
  	defineProperty(Object, GOPN, descriptor);
  
  	descriptor.value = function defineProperties(o, descriptors) {
  		var symbols = $getOwnPropertySymbols(descriptors);
  		if (symbols.length) {
  		keys(descriptors).concat(symbols).forEach(function (uid) {
  			if (propertyIsEnumerable.call(descriptors, uid)) {
  			$defineProperty(o, uid, descriptors[uid]);
  			}
  		});
  		} else {
  		$defineProperties(o, descriptors);
  		}
  		return o;
  	};
  	defineProperty(Object, DPies, descriptor);
  
  	descriptor.value = propertyIsEnumerable;
  	defineProperty(ObjectProto, PIE, descriptor);
  
  	descriptor.value = Symbol;
  	defineProperty(global, 'Symbol', descriptor);
  
  	// defining `Symbol.for(key)`
  	descriptor.value = function (key) {
  		var uid = prefix.concat(prefix, key, random);
  		return uid in ObjectProto ? source[uid] : setAndGetSymbol(uid);
  	};
  	defineProperty(Symbol, 'for', descriptor);
  
  	// defining `Symbol.keyFor(symbol)`
  	descriptor.value = function (symbol) {
  		if (onlyNonSymbols(symbol))
  		throw new TypeError(symbol + ' is not a symbol');
  		return hOP.call(source, symbol) ?
  		symbol.slice(prefixLength * 2, -random.length) :
  		void 0
  		;
  	};
  	defineProperty(Symbol, 'keyFor', descriptor);
  
  	descriptor.value = function getOwnPropertyDescriptor(o, key) {
  		var descriptor = gOPD(o, key);
  		if (descriptor && onlySymbols(key)) {
  		descriptor.enumerable = propertyIsEnumerable.call(o, key);
  		}
  		return descriptor;
  	};
  	defineProperty(Object, GOPD, descriptor);
  
  	descriptor.value = function (proto, descriptors) {
  		return arguments.length === 1 || typeof descriptors === "undefined" ?
  		create(proto) :
  		createWithSymbols(proto, descriptors);
  	};
  	defineProperty(Object, 'create', descriptor);
  
  	var strictModeSupported = (function(){ 'use strict'; return this; }).call(null) === null;
  	if (strictModeSupported) {
  		descriptor.value = function () {
  			var str = toString.call(this);
  			return (str === '[object String]' && onlySymbols(this)) ? '[object Symbol]' : str;
  		};
  	} else {
  		descriptor.value = function () {
  			// https://github.com/Financial-Times/polyfill-library/issues/164#issuecomment-486965300
  			// Polyfill.io this code is here for the situation where a browser does not
  			// support strict mode and is executing `Object.prototype.toString.call(null)`.
  			// This code ensures that we return the correct result in that situation however,
  			// this code also introduces a bug where it will return the incorrect result for
  			// `Object.prototype.toString.call(window)`. We can't have the correct result for
  			// both `window` and `null`, so we have opted for `null` as we believe this is the more 
  			// common situation. 
  			if (this === window) {
  				return '[object Null]';
  			}
  
  			var str = toString.call(this);
  			return (str === '[object String]' && onlySymbols(this)) ? '[object Symbol]' : str;
  		};
  	}
  	defineProperty(ObjectProto, 'toString', descriptor);
  
  	setDescriptor = function (o, key, descriptor) {
  		var protoDescriptor = gOPD(ObjectProto, key);
  		delete ObjectProto[key];
  		defineProperty(o, key, descriptor);
  		if (o !== ObjectProto) {
  			defineProperty(ObjectProto, key, protoDescriptor);
  		}
  	};
  
  }(Object, 'getOwnPropertySymbols', this));
  