code: function _replaceMediaSources( xmlDoc, mediaMap ) {
      if ( !mediaMap ) {
          return xmlDoc;
      }
  
      // iterate through each element with a src attribute
      xmlDoc.find( '//*[@src] | //a[@href]' ).forEach( mediaEl => {
          const attribute = ( mediaEl.name().toLowerCase() === 'a' ) ? 'href' : 'src';
          const src = mediaEl.attr( attribute ).value();
          const matches = src ? src.match( /jr:\/\/[\w-]+\/(.+)/ ) : null;
          const filename = matches && matches.length ? matches[ 1 ] : null;
          const replacement = filename ? mediaMap[ filename ] : null;
          if ( replacement ) {
              mediaEl.attr( attribute, replacement );
          }
      } );
  
      // add form logo <img> element if applicable
      const formLogo = mediaMap[ 'form_logo.png' ];
      const formLogoEl = xmlDoc.get( '//*[@class="form-logo"]' );
      if ( formLogo && formLogoEl ) {
          formLogoEl
              .node( 'img' )
              .attr( 'src', formLogo )
              .attr( 'alt', 'form logo' );
      }
  
      return xmlDoc;
  }
docs: Replaces xformManifest urls with URLs according to an internal Enketo Express url format
  
  @param  {[type]} xmlDoc   libxmljs object
  @param  {*} manifest      json representation of XForm manifest
  @return {Promise}         libxmljs object