text: // Copyright © 2020 MUSC Foundation for Research Development~
  // All rights reserved.~
  
  // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:~
  
  // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.~
  
  // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following~
  // disclaimer in the documentation and/or other materials provided with the distribution.~
  
  // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products~
  // derived from this software without specific prior written permission.~
  
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,~
  // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT~
  // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL~
  // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS~
  // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR~
  // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.~
  
  define([
  	"../core",
  	"../core/init",
  	"../deferred"
  ], function( jQuery ) {
  
  // The deferred used on DOM ready
  var readyList;
  
  jQuery.fn.ready = function( fn ) {
  	// Add the callback
  	jQuery.ready.promise().done( fn );
  
  	return this;
  };
  
  jQuery.extend({
  	// Is the DOM ready to be used? Set to true once it occurs.
  	isReady: false,
  
  	// A counter to track how many items to wait for before
  	// the ready event fires. See #6781
  	readyWait: 1,
  
  	// Hold (or release) the ready event
  	holdReady: function( hold ) {
  		if ( hold ) {
  			jQuery.readyWait++;
  		} else {
  			jQuery.ready( true );
  		}
  	},
  
  	// Handle when the DOM is ready
  	ready: function( wait ) {
  
  		// Abort if there are pending holds or we're already ready
  		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
  			return;
  		}
  
  		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
  		if ( !document.body ) {
  			return setTimeout( jQuery.ready );
  		}
  
  		// Remember that the DOM is ready
  		jQuery.isReady = true;
  
  		// If a normal DOM Ready event fired, decrement, and wait if need be
  		if ( wait !== true && --jQuery.readyWait > 0 ) {
  			return;
  		}
  
  		// If there are functions bound, to execute
  		readyList.resolveWith( document, [ jQuery ] );
  
  		// Trigger any bound ready events
  		if ( jQuery.fn.triggerHandler ) {
  			jQuery( document ).triggerHandler( "ready" );
  			jQuery( document ).off( "ready" );
  		}
  	}
  });
  
  /**
   * Clean-up method for dom ready events
   */
  function detach() {
  	if ( document.addEventListener ) {
  		document.removeEventListener( "DOMContentLoaded", completed, false );
  		window.removeEventListener( "load", completed, false );
  
  	} else {
  		document.detachEvent( "onreadystatechange", completed );
  		window.detachEvent( "onload", completed );
  	}
  }
  
  /**
   * The ready event handler and self cleanup method
   */
  function completed() {
  	// readyState === "complete" is good enough for us to call the dom ready in oldIE
  	if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
  		detach();
  		jQuery.ready();
  	}
  }
  
  jQuery.ready.promise = function( obj ) {
  	if ( !readyList ) {
  
  		readyList = jQuery.Deferred();
  
  		// Catch cases where $(document).ready() is called after the browser event has already occurred.
  		// we once tried to use readyState "interactive" here, but it caused issues like the one
  		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
  		if ( document.readyState === "complete" ) {
  			// Handle it asynchronously to allow scripts the opportunity to delay ready
  			setTimeout( jQuery.ready );
  
  		// Standards-based browsers support DOMContentLoaded
  		} else if ( document.addEventListener ) {
  			// Use the handy event callback
  			document.addEventListener( "DOMContentLoaded", completed, false );
  
  			// A fallback to window.onload, that will always work
  			window.addEventListener( "load", completed, false );
  
  		// If IE event model is used
  		} else {
  			// Ensure firing before onload, maybe late but safe also for iframes
  			document.attachEvent( "onreadystatechange", completed );
  
  			// A fallback to window.onload, that will always work
  			window.attachEvent( "onload", completed );
  
  			// If IE and not a frame
  			// continually check to see if the document is ready
  			var top = false;
  
  			try {
  				top = window.frameElement == null && document.documentElement;
  			} catch(e) {}
  
  			if ( top && top.doScroll ) {
  				(function doScrollCheck() {
  					if ( !jQuery.isReady ) {
  
  						try {
  							// Use the trick by Diego Perini
  							// http://javascript.nwbox.com/IEContentLoaded/
  							top.doScroll("left");
  						} catch(e) {
  							return setTimeout( doScrollCheck, 50 );
  						}
  
  						// detach all dom ready events
  						detach();
  
  						// and execute any waiting functions
  						jQuery.ready();
  					}
  				})();
  			}
  		}
  	}
  	return readyList.promise( obj );
  };
  
  });
  