function exportKml(options) {
  options = options ?? Frozen.EMPTY_OBJECT;
  const entities = options.entities;
  const kmz = options.kmz ?? false;

  //>>includeStart('debug', pragmas.debug);
  if (!defined(entities)) {
    throw new DeveloperError("entities is required.");
  }
  //>>includeEnd('debug');

  // Get the state that is passed around during the recursion
  // This is separated out for testing.
  const state = exportKml._createState(options);

  // Filter EntityCollection so we only have top level entities
  const rootEntities = entities.values.filter(function (entity) {
    return !defined(entity.parent);
  });

  // Add the <Document>
  const kmlDoc = state.kmlDoc;
  const kmlElement = kmlDoc.documentElement;
  kmlElement.setAttributeNS(xmlnsNamespace, "xmlns:gx", gxNamespace);
  const kmlDocumentElement = kmlDoc.createElement("Document");
  kmlElement.appendChild(kmlDocumentElement);

  // Create the KML Hierarchy
  recurseEntities(state, kmlDocumentElement, rootEntities);

  // Write out the <Style> elements
  state.styleCache.save(kmlDocumentElement);

  // Once all the blobs have resolved return the KML string along with the blob collection
  const externalFileHandler = state.externalFileHandler;
  return externalFileHandler.promise.then(function () {
    const serializer = new XMLSerializer();
    const kmlString = serializer.serializeToString(state.kmlDoc);
    if (kmz) {
      return createKmz(kmlString, externalFileHandler.files);
    }

    return {
      kml: kmlString,
      externalFiles: externalFileHandler.files,
    };
  });
}
Exports an EntityCollection as a KML document. Only Point, Billboard, Model, Path, Polygon, Polyline geometries
will be exported. Note that there is not a 1 to 1 mapping of Entity properties to KML Feature properties. For
example, entity properties that are time dynamic but cannot be dynamic in KML are exported with their values at
options.time or the beginning of the EntityCollection's time interval if not specified. For time-dynamic properties
that are supported in KML, we use the samples if it is a {@link SampledProperty} otherwise we sample the value using
the options.sampleDuration. Point, Billboard, Model and Path geometries with time-dynamic positions will be exported
as gx:Track Features. Not all Materials are representable in KML, so for more advanced Materials just the primary
color is used. Canvas objects are exported as PNG images.

@function exportKml

@param {object} options An object with the following properties:
@param {EntityCollection} options.entities The EntityCollection to export as KML.
@param {Ellipsoid} [options.ellipsoid=Ellipsoid.default] The ellipsoid for the output file.
@param {exportKmlModelCallback} [options.modelCallback] A callback that will be called with a {@link ModelGraphics} instance and should return the URI to use in the KML. Required if a model exists in the entity collection.
@param {JulianDate} [options.time=entities.computeAvailability().start] The time value to use to get properties that are not time varying in KML.
@param {TimeInterval} [options.defaultAvailability=entities.computeAvailability()] The interval that will be sampled if an entity doesn't have an availability.
@param {number} [options.sampleDuration=60] The number of seconds to sample properties that are varying in KML.
@param {boolean} [options.kmz=false] If true KML and external files will be compressed into a kmz file.

@returns {Promise<exportKmlResultKml|exportKmlResultKmz>} A promise that resolved to an object containing the KML string and a dictionary of external file blobs, or a kmz file as a blob if options.kmz is true.
@demo {@link https://sandcastle.cesium.com/index.html?src=Export%20KML.html|Cesium Sandcastle KML Export Demo}
@example
Cesium.exportKml({
     entities: entityCollection
 })
  .then(function(result) {
    // The XML string is in result.kml

    const externalFiles = result.externalFiles
    for(const file in externalFiles) {
      // file is the name of the file used in the KML document as the href
      // externalFiles[file] is a blob with the contents of the file
    }
  });