text: var hiddenKeys = require('../internals/hidden-keys');
  var isObject = require('../internals/is-object');
  var has = require('../internals/has');
  var defineProperty = require('../internals/object-define-property').f;
  var uid = require('../internals/uid');
  var FREEZING = require('../internals/freezing');
  
  var METADATA = uid('meta');
  var id = 0;
  
  var isExtensible = Object.isExtensible || function() {
      return true;
  };
  
  var setMetadata = function(it) {
      defineProperty(it, METADATA, {
          value: {
              objectID: 'O' + ++id, // object ID
              weakData: {} // weak collections IDs
          }
      });
  };
  
  var fastKey = function(it, create) {
      // return a primitive with prefix
      if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
      if (!has(it, METADATA)) {
          // can't set metadata to uncaught frozen object
          if (!isExtensible(it)) return 'F';
          // not necessary to add metadata
          if (!create) return 'E';
          // add missing metadata
          setMetadata(it);
          // return object ID
      }
      return it[METADATA].objectID;
  };
  
  var getWeakData = function(it, create) {
      if (!has(it, METADATA)) {
          // can't set metadata to uncaught frozen object
          if (!isExtensible(it)) return true;
          // not necessary to add metadata
          if (!create) return false;
          // add missing metadata
          setMetadata(it);
          // return the store of weak collections IDs
      }
      return it[METADATA].weakData;
  };
  
  // add metadata on freeze-family methods calling
  var onFreeze = function(it) {
      if (FREEZING && meta.REQUIRED && isExtensible(it) && !has(it, METADATA)) setMetadata(it);
      return it;
  };
  
  var meta = module.exports = {
      REQUIRED: false,
      fastKey: fastKey,
      getWeakData: getWeakData,
      onFreeze: onFreeze
  };
  
  hiddenKeys[METADATA] = true;