text: "use strict";
  module.exports = fetch;
  
  var asPromise = require("@protobufjs/aspromise"),
      inquire   = require("@protobufjs/inquire");
  
  var fs = inquire("fs");
  
  /**
   * Node-style callback as used by {@link util.fetch}.
   * @typedef FetchCallback
   * @type {function}
   * @param {?Error} error Error, if any, otherwise `null`
   * @param {string} [contents] File contents, if there hasn't been an error
   * @returns {undefined}
   */
  
  /**
   * Options as used by {@link util.fetch}.
   * @interface IFetchOptions
   * @property {boolean} [binary=false] Whether expecting a binary response
   * @property {boolean} [xhr=false] If `true`, forces the use of XMLHttpRequest
   */
  
  /**
   * Fetches the contents of a file.
   * @memberof util
   * @param {string} filename File path or url
   * @param {IFetchOptions} options Fetch options
   * @param {FetchCallback} callback Callback function
   * @returns {undefined}
   */
  function fetch(filename, options, callback) {
      if (typeof options === "function") {
          callback = options;
          options = {};
      } else if (!options)
          options = {};
  
      if (!callback)
          return asPromise(fetch, this, filename, options); // eslint-disable-line no-invalid-this
  
      // if a node-like filesystem is present, try it first but fall back to XHR if nothing is found.
      if (!options.xhr && fs && fs.readFile)
          return fs.readFile(filename, function fetchReadFileCallback(err, contents) {
              return err && typeof XMLHttpRequest !== "undefined"
                  ? fetch.xhr(filename, options, callback)
                  : err
                  ? callback(err)
                  : callback(null, options.binary ? contents : contents.toString("utf8"));
          });
  
      // use the XHR version otherwise.
      return fetch.xhr(filename, options, callback);
  }
  
  /**
   * Fetches the contents of a file.
   * @name util.fetch
   * @function
   * @param {string} path File path or url
   * @param {FetchCallback} callback Callback function
   * @returns {undefined}
   * @variation 2
   */
  
  /**
   * Fetches the contents of a file.
   * @name util.fetch
   * @function
   * @param {string} path File path or url
   * @param {IFetchOptions} [options] Fetch options
   * @returns {Promise<string|Uint8Array>} Promise
   * @variation 3
   */
  
  /**/
  fetch.xhr = function fetch_xhr(filename, options, callback) {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange /* works everywhere */ = function fetchOnReadyStateChange() {
  
          if (xhr.readyState !== 4)
              return undefined;
  
          // local cors security errors return status 0 / empty string, too. afaik this cannot be
          // reliably distinguished from an actually empty file for security reasons. feel free
          // to send a pull request if you are aware of a solution.
          if (xhr.status !== 0 && xhr.status !== 200)
              return callback(Error("status " + xhr.status));
  
          // if binary data is expected, make sure that some sort of array is returned, even if
          // ArrayBuffers are not supported. the binary string fallback, however, is unsafe.
          if (options.binary) {
              var buffer = xhr.response;
              if (!buffer) {
                  buffer = [];
                  for (var i = 0; i < xhr.responseText.length; ++i)
                      buffer.push(xhr.responseText.charCodeAt(i) & 255);
              }
              return callback(null, typeof Uint8Array !== "undefined" ? new Uint8Array(buffer) : buffer);
          }
          return callback(null, xhr.responseText);
      };
  
      if (options.binary) {
          // ref: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Receiving_binary_data_in_older_browsers
          if ("overrideMimeType" in xhr)
              xhr.overrideMimeType("text/plain; charset=x-user-defined");
          xhr.responseType = "arraybuffer";
      }
  
      xhr.open("GET", filename);
      xhr.send();
  };
  