function makeGlobalWrapper(local) {
  let globals = globalKeysSet; // will be copied only if modified
  /* Browsers may return [object Object] for Object.prototype.toString(window)
     on our `window` proxy so jQuery libs see it as a plain object and throw
     when trying to clone its recursive properties like `self` and `window`. */
  setOwnProp(local, toStringTagSym, () => 'Window', false, 'get');
  const events = createNullObj();
  const wrapper = new SafeProxy(local, {
    __proto__: null,
    defineProperty(_, name, desc) {
      if (name in local
      || !(_ = globalDesc[name] || updateGlobalDesc(name))
      || _.configurable) {
        /* It's up to caller to protect proto */// eslint-disable-next-line no-restricted-syntax
        return defineProperty(local, name, desc);
      }
    },
    deleteProperty(_, name) {
      if ((_ = delete local[name])
      && (_ = globalDesc[name] || updateGlobalDesc(name))
      && (_ = _.configurable)) {
        if (globals === globalKeysSet) {
          globals = globalKeysSet.clone();
        }
        globals.delete(name);
      }
      return !!_;
    },
    get: (_, name) => {
      if (name === 'undefined' || name === scopeSym) return;
      if ((_ = local[name]) !== undefined || name in local) return _;
      return proxyDescribe(local, name, wrapper, events, true);
    },
    getOwnPropertyDescriptor: (_, name) => describeProperty(local, name)
      || proxyDescribe(local, name, wrapper, events),
    has: (_, name) => name in globalDesc || name in local || updateGlobalDesc(name),
    ownKeys: () => makeOwnKeys(local, globals),
    preventExtensions() {},
    set(_, name, value) {
      if (!(name in local)) proxyDescribe(local, name, wrapper, events);
      local[name] = value;
      return true;
    },
  });
  return wrapper;
}
@desc Wrap helpers to prevent unexpected modifications.