text: /* This Source Code Form is subject to the terms of the Mozilla Public
   * License, v. 2.0. If a copy of the MPL was not distributed with this
   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
  var crypto = require('crypto');
  
  var defineProperty = Object.defineProperty;
  function next() {
    return "@@symbol:" + crypto.randomBytes(8).toString('hex');
  }
  
  
  function Symbol(desc) {
    if (!(this instanceof Symbol)) {
      return new Symbol(desc);
    }
    var _symbol = this._symbol = next();
    defineProperty(this, '_desc', {
      value: desc,
      enumerable: false,
      writable: false,
      configurable: false
    });
    defineProperty(Object.prototype, _symbol, {
      set: function(value) {
        defineProperty(this, _symbol, {
          value: value,
          enumerable: false,
          writable: true
        });
      }
    });
  }
  
  Symbol.prototype.toString = function toString() {
    return this._symbol;
  };
  
  var globalSymbolRegistry = {};
  Symbol.for = function symbolFor(key) {
    key = String(key);
    return globalSymbolRegistry[key] || (globalSymbolRegistry[key] = Symbol(key));
  };
  
  Symbol.keyFor = function keyFor(sym) {
    if (!(sym instanceof Symbol)) {
      throw new TypeError("Symbol.keyFor requires a Symbol argument");
    }
    for (var key in globalSymbolRegistry) {
      if (globalSymbolRegistry[key] === sym) {
        return key;
      }
    }
    return undefined;
  };
  
  module.exports = this.Symbol || Symbol;
  