helper = function(obj) {
    'use strict';
    const indentMultiline = function(output) {
      'use strict';
      return output.replace(/\n/g, '\n');
    };


    try {
      if (obj === undefined) {
        output.push('undefined');
      } else if (obj === null) {
        output.push('NULL');
      } else if (typeof obj === 'string') {
        output.push('"' + indentMultiline(obj) + '"');
      } else if (typeof obj === 'symbol') {
        output.push(obj.toString());
      } else if (typeof obj === 'bigint') {
        output.push(obj.toString(10) + 'n');
      } else if (typeof obj === 'function') {
        const funcName = goog.labs.mock.getFunctionName_(obj);
        output.push('<function ' + funcName + '>');
      } else if (goog.isObject(obj)) {
        if (goog.array.contains(previous, obj)) {
          if (id) {
            output.push(
                '<recursive/dupe obj_' + goog.labs.mock.getUid(obj) + '>');
          } else {
            output.push('<recursive/dupe>');
          }
        } else {
          previous.push(obj);
          output.push('{');
          for (let x in obj) {
            output.push(' ');
            output.push(
                '"' + x + '"' +
                ':');
            helper(obj[x]);
          }
          if (id) {
            output.push(' _id:' + goog.labs.mock.getUid(obj));
          }
          output.push('}');
        }
      } else {
        output.push(obj);
      }
    } catch (e) {
      output.push('*** ' + e + ' ***');
    }
  }
This is just another implementation of goog.debug.deepExpose with a more
compact format.
@private
@param {*} obj The object whose string representation will be returned.
@param {boolean=} opt_id Whether to include the id of objects or not.
    Defaults to true.
@return {string} The string representation of the object.