docs: function computeStackTraceFromStackProp(ex) {
          if (!ex.stack) {
              return null;
          }
  
          var chrome = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,
              gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i,
              winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,
  
              // Used to additionally parse URL/line/column from eval frames
              isEval,
              geckoEval = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i,
              chromeEval = /\((\S*)(?::(\d+))(?::(\d+))\)/,
  
              lines = ex.stack.split('\n'),
              stack = [],
              submatch,
              parts,
              element,
              reference = /^(.*) is undefined$/.exec(ex.message);
  
          for (var i = 0, j = lines.length; i < j; ++i) {
              if ((parts = chrome.exec(lines[i]))) {
                  var isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line
                  isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
                  if (isEval && (submatch = chromeEval.exec(parts[2]))) {
                      // throw out eval line/column and use top-most line/column number
                      parts[2] = submatch[1]; // url
                      parts[3] = submatch[2]; // line
                      parts[4] = submatch[3]; // column
                  }
                  element = {
                      'url': !isNative ? parts[2] : null,
                      'func': parts[1] || UNKNOWN_FUNCTION,
                      'args': isNative ? [parts[2]] : [],
                      'line': parts[3] ? +parts[3] : null,
                      'column': parts[4] ? +parts[4] : null
                  };
              } else if ( parts = winjs.exec(lines[i]) ) {
                  element = {
                      'url': parts[2],
                      'func': parts[1] || UNKNOWN_FUNCTION,
                      'args': [],
                      'line': +parts[3],
                      'column': parts[4] ? +parts[4] : null
                  };
              } else if ((parts = gecko.exec(lines[i]))) {
                  isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
                  if (isEval && (submatch = geckoEval.exec(parts[3]))) {
                      // throw out eval line/column and use top-most line number
                      parts[3] = submatch[1];
                      parts[4] = submatch[2];
                      parts[5] = null; // no column when eval
                  } else if (i === 0 && !parts[5] && !_isUndefined(ex.columnNumber)) {
                      // FireFox uses this awesome columnNumber property for its top frame
                      // Also note, Firefox's column number is 0-based and everything else expects 1-based,
                      // so adding 1
                      // NOTE: this hack doesn't work if top-most frame is eval
                      stack[0].column = ex.columnNumber + 1;
                  }
                  element = {
                      'url': parts[3],
                      'func': parts[1] || UNKNOWN_FUNCTION,
                      'args': parts[2] ? parts[2].split(',') : [],
                      'line': parts[4] ? +parts[4] : null,
                      'column': parts[5] ? +parts[5] : null
                  };
              } else {
                  continue;
              }
  
              if (!element.func && element.line) {
                  element.func = guessFunctionName(element.url, element.line);
              }
  
              element.context = element.line ? gatherContext(element.url, element.line) : null;
              stack.push(element);
          }
  
          if (!stack.length) {
              return null;
          }
  
          if (stack[0] && stack[0].line && !stack[0].column && reference) {
              stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line);
          }
  
          return {
              'mode': 'stack',
              'name': ex.name,
              'message': ex.message,
              'stack': stack
          };
      }