# Source: src/js/common/EntityUtils.js

    define(["jquery"], function ($) {
      return {
        /**
         * Read the first part of a file
         *
         * @param {File} file - A reference to a file
         * @param {Backbone.View} context - The View to bind `callback` to
         * @param {function} callback - A function to run after the read is
         *   complete. The function is bound to `context`.
         * @param {number} bytes - The number of bytes to read from the start of the
         *   file
         */
        readSlice: function (file, context, callback, bytes = 1024) {
          if (typeof callback !== "function") {
            return;
          }

          var reader = new FileReader(),
            blob = file.slice(0, bytes);

          reader.onloadend = callback.bind(context);
          reader.readAsBinaryString(blob);
        },
        /**
         * Attempt to parse the header/column names from a chunk of a CSV file
         *
         * Doesn't handle:
         * - UTF BOM (garbles first col name)
         * - Commas inside quoted headers
         *
         * @param {string} text - A chunk of a file
         * @return {Array} A list of names
         */
        tryParseCSVHeader: function (text) {
          // The order is important here
          var strategies = ["\r\\n", "\r", "\n"];

          var index = -1;

          for (var i = 1; i < strategies.length; i++) {
            var result = text.indexOf(strategies[i]);

            if (result >= 0) {
              index = result;

              break;
            }
          }

          if (index === -1) {
            return [];
          }

          var header_line = text.slice(0, index);
          var names = header_line.split(",");

          // Remove surrounding parens and double-quotes
          names = names.map(function(name) {
            return name.replaceAll(/^["']|["']$/gm, "");
          });

          // Filter out zero-length values (headers like a,b,c,,,,,)
          names = names.filter(function(name) {
            return name.length > 0;
          });

          return names;
        }
      };
    });