PHPIndex

This page lists files in the current directory. You can view content, get download/execute commands for Wget, Curl, or PowerShell, or filter the list using wildcards (e.g., `*.sh`).

email-decode.min.js
wget 'https://sme10.lists2.roe3.org/mdrone/timemymeeting/email-decode.min.js'
View Content
!function(){"use strict";function e(e){try{if("undefined"==typeof console)return;"error"in console?console.error(e):console.log(e)}catch(e){}}function t(e){return d.innerHTML='<a href="'+e.replace(/"/g,"&quot;")+'"></a>',d.childNodes[0].getAttribute("href")||""}function r(e,t){var r=e.substr(t,2);return parseInt(r,16)}function n(n,c){for(var o="",a=r(n,c),i=c+2;i<n.length;i+=2){var l=r(n,i)^a;o+=String.fromCharCode(l)}try{o=decodeURIComponent(escape(o))}catch(u){e(u)}return t(o)}function c(t){for(var r=t.querySelectorAll("a"),c=0;c<r.length;c++)try{var o=r[c],a=o.href.indexOf(l);a>-1&&(o.href="mailto:"+n(o.href,a+l.length))}catch(i){e(i)}}function o(t){for(var r=t.querySelectorAll(u),c=0;c<r.length;c++)try{var o=r[c],a=o.parentNode,i=o.getAttribute(f);if(i){var l=n(i,0),d=document.createTextNode(l);a.replaceChild(d,o)}}catch(h){e(h)}}function a(t){for(var r=t.querySelectorAll("template"),n=0;n<r.length;n++)try{i(r[n].content)}catch(c){e(c)}}function i(t){try{c(t),o(t),a(t)}catch(r){e(r)}}var l="/cdn-cgi/l/email-protection#",u=".__cf_email__",f="data-cfemail",d=document.createElement("div");i(document),function(){var e=document.currentScript||document.scripts[document.scripts.length-1];e.parentNode.removeChild(e)}()}();
index.html
wget 'https://sme10.lists2.roe3.org/mdrone/timemymeeting/index.html'
View Content
<!doctype html>
<html lang="en-US">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<link rel="profile" href="https://gmpg.org/xfn/11" />
		<meta name="referrer" content="always">
		<meta name="HandheldFriendly" content="True" />
		<meta name="MobileOptimized" content="320" />
		<meta name="mobile-web-app-capable" content="yes" />
		<meta name="apple-mobile-web-app-capable" content="yes" />
		<meta class="theme-color" name="theme-color" content="#f7f08b">
		<meta class="theme-color" name="msapplication-navbutton-color" content="#f7f08b">
		<meta class="theme-color" name="apple-mobile-web-app-status-bar-style" content="#f7f08b">
		<meta http-equiv="Accept-CH" content="Device-Memory">
		<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

		<title>TimeMyMeeting | Time your meetings with a fun twist!</title>
		<meta id="meta-description" name="description" content="Are your meetings as long as marathons, road trips, or feature films? Find out what other fun things your meeting is longer than!" />

		<link rel="manifest" href="manifest.json" />

		<link rel="icon" href="favicon.svg">
		<meta property="og:image" content="https://timemymeeting.com/img/meta/og-thumb.png" />
		<link rel="preconnect" href="https://fonts.googleapis.com">
		<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
		<link href="https://fonts.googleapis.com/css2?family=Patrick+Hand+SC" rel="stylesheet">

		<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" media="all" />
		<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.3/css/all.min.css" media="all" />
		<link type="text/css" rel="stylesheet" href="style.css" media="all" />

		<script type='application/ld+json'>
			{
				"@context": "http://www.schema.org",
				"@type": "WebSite",
				"name": "TimeMyMeeting",
				"alternateName": "Time My Meeting",
				"url": "https://timemymeeting.com"
			}
		</script>

		<script type="application/ld+json">
			{
				"@context": "https://schema.org",
				"@type": "Organization",
				"name": "TimeMyMeeting.com",
				"url": "https://timemymeeting.com",
				"logo": "https://timemymeeting.com/img/logo.svg",
				"alternateName": "Time My Meeting"
			}
		</script>

		<script type="application/ld+json">
			{
				"@context": "https://schema.org",
				"@id": "https://timemymeeting.com#webapp",
				"@type": "WebApplication",
				"author": {
			        "@id": "https://timemymeeting.com#identity"
			    },
			    "copyrightHolder": {
			        "@id": "https://timemymeeting.com#identity"
			    },
			    "copyrightYear": "2024",
			    "creator": {
			        "@id": "https://timemymeeting.com#creator"
			    },
				"name": "TimeMyMeeting",
				"url": "https://timemymeeting.com",
				"installUrl": "https://timemymeeting.com",
				"applicationCategory": "Utility",
				"applicationSubCategory": "Product Comparison",
				"about": "Are your meetings as long as marathons, road trips, or feature films? Find out what other fun things your meeting is longer than!",
				"description": "Are your meetings as long as marathons, road trips, or feature films? Find out what other fun things your meeting is longer than!",
			    "headline": "TimeMyMeeting.com",
			    "image": {
			        "@type": "ImageObject",
			        "url": "https://timemymeeting.com/img/screenshot.png"
			    },
				"browserRequirements": "Requires JavaScript. Requires HTML5.",
				"softwareVersion": "1.0.0",
				"screenshot": "https://timemymeeting.com/img/screenshot.png",
				"inLanguage":[{
					"@type": "Language",
					"name": "English",
					"alternateName": "en",
					"additionalType":"https://www.loc.gov/standards/iso639-2/php/code_list.php",
					"sameAs":"https://en.wikipedia.org/wiki/English_language"
				}],
				"operatingSystem": "Web Browser",
				"offers": {
					"@type": "Offer",
					"price": "0.00",
					"priceCurrency": "USD",
					"url": "https://timemymeeting.com"
				}
			}
		</script>

		<script type="application/ld+json">
			{
				"@context": "https://schema.org",
				"@type": "SoftwareApplication",
				"name": "TimeMyMeeting",
				"operatingSystem": "Web Browser",
				"applicationCategory": "BusinessApplication",
				"offers": {
					"@type": "Offer",
					"price": "0.00",
					"priceCurrency": "USD"
				}
			}
		</script>
		<script>
			window.started = false; //This should be an integer so no quotes
			//console.log( 'start time was:', window.started );
		</script>
	</head>
	<body class="">
		<div class="container">
			<div class="row">
				<div class="col">
					<div id="title">
						<h1>TimeMyMeeting</h1>
						<p>Time your meetings <em>with a fun twist</em>!</p>
					</div>
				</div>
			</div>
		</div>

		<div class="container">
			<div id="sticky-note">
				<div class="row">
					<div class="col">
						<div id="controls">
							<button id="start" class="btn btn-lg btn-success"><i class="fas fa-fw fa-stopwatch"></i> Start the Meeting!</button>
							<button id="pause" class="btn btn-lg btn-danger hidden"><i class="far fa-fw fa-pause-circle"></i> Pause</button>
							<button id="resume" class="btn btn-lg btn-success hidden"><i class="fas fa-fw fa-play-circle"></i> Resume</button>
							<button id="reset" class="btn btn-lg btn-outline-danger hidden"><i class="fas fa-fw fa-undo-alt"></i> Start Over</button>
						</div>
					</div><!--/col-->
				</div><!--/row-->

				<div class="row">
					<div class="col">
						<div id="main-content" class="post-it2">
							<div id="thing-container">
								<h1 id="longer-than" class="hidden">This meeting is longer than...</h1>
								<p id="intro-description">Click the start button to compare your meeting to durations of other things.</p>
							</div>

							<h2 id="the-thing"></h2>

							<div class="intensifies" style="animation-duration: 10000s;">
								<h3 id="going-on-for-text" class="hidden">It has been going on for...</h3>
								<h4 id="time-indicator" class="hidden"></h4>
								<h5 id="started-time" class="hidden">Started at...</h5>
							</div>

							<p id="next-milestone" class="hidden"></p>

						</div>
					</div><!--/col-->
				</div><!--/row-->
			</div>

			<div class="row">
				<div class="col">
					<div id="copyright">
						<p style="font-size: 14px;"><em>Use <a href="/?started=11:38am"><code>?started=11:38am</code></a> to track an earlier start time (or count down to a start time in the future).</em></p>
					</div>
				</div><!--/col-->
			</div><!--/row-->
		</div><!--/container-->

		<div id="constainer">
			<div id="stain"></div>
		</div>

<script data-cfasync="false" src="email-decode.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" defer></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.min.js" defer></script>
<script type="text/javascript" src="main.js" defer></script>

		<script>
			//Listen for window errors
			window.addEventListener('error', function(error){
				let errorMessage = error.message + ' at ' + error.lineno + ' of ' + error.filename;
				if ( error.message.toLowerCase().includes('script error') ){ //If it is a script error
					errorMessage = 'Script error (An error occurred in a script hosted on a different domain)'; //No additional information is available because of the browser's same-origin policy. Use CORS when possible to get additional information.
				}

				gtag('event', 'window_error', {
					description: errorMessage
				});
			}, {passive: true});
		</script>
	</body>
</html>
main.js
wget 'https://sme10.lists2.roe3.org/mdrone/timemymeeting/main.js'
View Content
jQuery(function(){
	init();

	//Automatically start if ?autostart exists in the URL (via body class)
	if ( jQuery('.autostart').length ){
		start();
	}

	jQuery('#start').on('click', function(){
		start();
		gtag('event', 'start_the_meeting');
		return false;
	});

	jQuery('#pause').on('click', function(){
		pause();
		let delta = Date.now()-startTime-totalPauseTime; // milliseconds elapsed since start
		gtag('event', 'pause_the_timer', {
			time:  msToTime(delta).replace('.0 seconds', ' seconds').replace(', 0 seconds', '').replace(/,(?=[^,]*$)/, ' and'),
			milestone: window.currentActive
		});

		return false;
	});

	jQuery('#resume').on('click', function(){
		resume();
		let delta = Date.now()-startTime-totalPauseTime; // milliseconds elapsed since start
		gtag('event', 'resume_timing', {
			time: msToTime(delta).replace('.0 seconds', ' seconds').replace(', 0 seconds', '').replace(/,(?=[^,]*$)/, ' and'),
			milestone: window.currentActive
		});

		return false;
	});

	jQuery('#reset').on('click', function(){
		init();
		gtag('event', 'reset_the_timer');
		return false;
	});

	jQuery('#social a').on('click', function(){
		gtag('event', 'social_share', {
			network: jQuery(this).attr('href')
		});
	});

	jQuery('#idea-form').on('submit', function(){
		logIdea();
		return false;
	});

	jQuery('#copyright a').on('click', function(){
		gtag('event', 'gearside_outbound_link_click');
	});
});

jQuery(window).on('load', function(){
	// Web Share API: https://caniuse.com/mdn-api_navigator_share
	if ( 'share' in navigator ) { // Chrome 61+
		jQuery(document).on('click', '#share', function(){
			let oThis = jQuery(this);
			let originalText = oThis.html();

			let shareText = 'Time your meetings in a fun way!';
			if ( window?.currentActive ){
				shareText = "I'm in a meeting that is longer than " + window.currentActive.toLowerCase() + "! Time yours here.";
			}

			navigator.share({
				title: 'TimeMyMeeting.com',
				text: shareText,
				url: 'https://timemymeeting.com?utm_source=share+api'
			}).then(function(){
				gtag('event', 'social_share', {
					network: 'Web Share API'
				});

				oThis.addClass('success');
			}).catch(function(error){ // This can happen on iOS when the user closes the drawer without sharing
				gtag('event', 'web_share_error', {
					description: error
				});

				oThis.addClass('error').html(originalText);
			});

			return false;
		});
	} else {
		jQuery('#share').addClass('hidden');
		jQuery('#social').removeClass('hidden');
	}

	// Register the Service Worker
	sw();
});

function init(){
	window.times = {
		//<10 seconds
		'A single frame of a film': 100,
		'It would take light to go around the Earth': 133,
		'A blink of an eye': 400,
		'The time it takes light to reach Earth from the moon': 1255,
		'The fastest Formula 1 pit stop': 1820,
		'The fastest 1/4 mile drag race time': 3580,
		'The fastest Rubik\'s cube solve': 4221,
		'The fastest 40-yard time at the NFL Combine': 4240,
		'The fastest 1 liter beer chug': 4370,
		'A skippable Youtube ad': 5000,
		'A full bull ride': 8000,
		'The fastest 100m sprint': 9580,

		//10 Seconds
		'The Wright Brothers first flight': 12000,
		'The fastest 200m sprint': 19190,
		'The fastest 50m freestyle swim lap': 21300,
		'The Westminster Kennel Club dog agility record': 28440,
		'A typical television ad': 30000,
		'The fastest NASCAR lap at Daytona': 40364,
		'The fastest 400m sprint': 43030,
		'The fastest NASCAR lap at Talladega': 44270,
		'The fastest 100m freestyle swim lap': 47050,

		//1 Minute
		'"Just a minute"': 60000,
		'The fastest Formula 1 lap at Monaco': 74260,
		'The fastest Formula 1 lap at Monza': 81046,
		'The fastest 800m sprint': 100910,
		'The fastest 200m freestyle swim lap': 102960,
		'The fastest Kentucky Derby time': 119400,
		'An NHL penalty box time for slashing, tripping, or holding': 120000,
		'How long it takes to drive across the Golden Gate Bridge (without traffic)': 135000,
		'The duration of the "Millenium Force" roller coaster': 140000,
		'The longest Super Bowl national anthem': 156000,
		'One round of a boxing match': 180000,
		'The average song length on Spotify': 183000,
		'The fastest 1,500m run': 206000,
		'The song "Never Gonna Give You Up" by Rick Astley': 215000,
		'The fastest 400m freestyle swim lap': 220140,
		'The fastest 1 mile run': 223130,
		'The duration of the "Steel Dragon" roller coaster': 240000,
		'The duration of "The Beast" roller coaster': 250000,
		'The song "4:33" by John Cage': 273000,
		'The longest sky diving freefall': 276000,
		'The Any% speedrun of Super Mario Bros for NES': 294948,

		//5 Minutes
		'An NHL penalty box time for fighting': 300000,
		'The average duration of a typical sky dive': 330000,
		'The average time for a drive-thru order': 356800,
		'The time it takes Jeff Bezos to make $1 million': 402000,
		'The fastest race car lap around the Nurburgring': 403300,
		'The time it takes light to reach Earth from the sun': 500000,
		'The time it takes a rocket ship to reach outer space': 510000,
		'A typical marching band show': 515000,

		//10 Minutes
		'The length of the first space walk': 600000,
		'The longest a human has held their breath (non-oxygen assisted)': 695000,
		'The average duration of popular Youtube videos': 702000,
		'The time it takes an average human to walk 1km': 710000,
		'The fastest 5K run': 757350,
		'The average time to bake a pizza': 810000,
		'1% of the entire day': 864000,

		//15 Minutes
		'A typical commute in the United States': 960000,
		'The fastest superbike lap of the Isle of Man TT': 1002778,
		"MLK's \"I Have A Dream\" Speech": 1020000,
		'An average baseball inning': 1200000,
		'The song "2112" by Rush': 1233000,
		'The first angels to appear in the movie "Angels in the Outfield" (1994)': 1275000,
		'An episode of The Office, Seinfeld, or Rick &amp; Morty': 1320000,
		'The time it takes to drive the entire Chesapeake Bay Bridge Tunnel': 1380000,
		'The song "Octavarium" by Dream Theater': 1440000,
		'A typical Super Bowl halftime show': 1500000,
		'The fastest 10K run': 1584000,
		'It takes for Bobby Boucher to get his first game snap in the movie "The Waterboy" (1998)': 1719000,

		//30 Minutes
		'The average time to bake a cake': 1950000,
		'The time it takes until the launch in the movie Apollo 13 (1995)': 2081000,
		'It takes WALL-E to arrive at the Axiom in the movie "WALL-E" (2008)': 2164000,
		'The shortest war in history (Anglo-Zanzibar War)': 2280000,
		'It takes Harry Potter to arrive at Hogwarts in "Harry Potter and the Sorcerer\'s Stone" (2001)': 2381000,
		'The album "Thriller" by Michael Jackson': 2539000,
		'The album "Dark Side of the Moon" by Pink Floyd': 2589000,
		'An episode of Breaking Bad, House, or Firefly': 2640000,
		'The boot camp sequence in the movie "Full Metal Jacket" (1987)': 2730000,
		'The album "Abbey Road" by The Beatles': 2823000,
		'It takes Simba to become an adult in the movie "The Lion King" (1994)': 2849000,
		'10% of a typical work day in the United States': 2880000,
		'The album "Kid A" by Radiohead': 2996000,
		'The time limit for the essay portion of the SATs': 3000000,
		'The time it takes a standard ice cube to melt at room temperature': 3150000,
		'0.01% of an entire year': 3155692,
		'A microcentury (one millionth of a centure)': 3155760,
		'The album "Fearless" by Taylor Swift': 3221000,
		'The time it takes for the basketball game to start in the movie "Space Jam"': 3222000,
		'An episode of Game of Thrones, True Detective, or The Sopranos': 3300000,
		'It takes Harry and Lloyd arrive in Aspen in the movie "Dumb and Dumber" (1994)': 3394000,
		'The album "Jagged Little Pill" by Alanis Morissette': 3443000,
		'The fastest half-marathon': 3451000,

		//1 Hour
		'An episode of Top Gear': 3600000,
		'The inception of Robert Fischer begins in the movie "Inception" (2010)': 3847000,
		'Riding the longest subway line in NYC from Queens to Inwood': 3900000,
		'The time it takes Jeff Bezos to make $10 million': 4017600,
		'It takes before Sean Connery says "Welcome to the Rock" in the movie "The Rock" (1996)': 4022000,
		'A flight from Syracuse to New York City': 4140000,
		'5% of the entire day': 4320000,
		'The album "Goodbye Yellow Brick Road" by Elton John': 4580000,
		'The album "Scenes From A Memory" by Dream Theater': 4626000,
		'The movie "Primer" (2004)': 4740000,
		'It takes to fully charge a Tesla (at 440V)': 4788000,
		'The ferry duration from Long Island, NY to  New London, CT': 4800000,
		'The movie "Toy Story" (1995)': 4860000,
		'A drive from Syracuse, NY to Rochester, NY (87.5 miles)': 4920000,
		'The movie "The Lion King" (1994)': 5280000,
		'The longest State of the Union address': 5280000, //Duplicate time...

		//1.5 Hours
		'The movie "Mony Python and the Holy Grail" (1975)': 5460000,
		'The movie "Monsters, Inc." (2001)': 5520000,
		'An average duration of a soccer game': 5700000,
		'The movie "Reservoir Dogs" (1992)': 5940000,
		'The longest Innaugural address': 6300000,
		'A drive from Orlando, FL to Tampa, FL (84.6 miles)': 6660000,
		'An SR-71 flight from New York City to London': 6896400,
		'The movie "Alien" (1979)': 7020000,

		//2 Hours
		//'25% of a typical work day in the United States': 7200000,
		'The average duration of an NCAA basketball game': 7200000,
		'The movie "Star Wars: A New Hope" (1977)': 7260000,
		'The fastest marathon time ever ran': 7299000,
		'The time it takes to listen to every studio album by Nirvana': 7667000,
		'The movie "Dogma" (1999)': 7680000,
		'The average duration of an NBA basketball game': 7860000,
		'The movie "The Matrix" (1999)': 8160000,
		'The movie "Fight Club" (1999)': 8340000,
		'The movie "The Shawshank Redemption" (1994)': 8520000,
		'The movie "Forrest Gump" (1994)': 8520000,
		'A drive from New York City to Philadelphia (94.6 miles)': 8520000,
		'10% of the entire day': 8640000,
		'The movie "Inception" (2010)': 8880000,
		'The movie "Avengers: Infinity War" (2018)': 8940000,
		'The movie "Pulp Fiction" (1994)': 9240000,
		'It takes Voyager 1 to travel 100,000 miles': 9360000,
		'The movie "Avatar" (2009)': 9720000,
		'The average duration of an NHL hockey game': 9750000,
		'The movie "Saving Private Ryan" (1998)': 10140000,
		'The movie "The Godfather" (1972)': 10500000,
		'The movie "Lord of the Rings: The Fellowship of the Ring" (2001)': 10680000,

		//3 Hours
		'The average duration of an NFL football game': 10800000,
		'The total time limit of the SATs': 10800000,
		'The movie "Avengers: Endgame" (2019)': 10860000,
		'The average duration of an MLB baseball game': 11280000,
		'The time it takes for a standard ice cube to freeze in a freezer': 11700000,
		'The movie "Titanic" (1997)': 12600000,
		'A drive from Boston to New York City (215.9 miles)': 13560000,
		'Alex Honnold\'s free solo climb of El Capitan': 14160000,

		//4 Hours
		'Half of a typical work day in the United States': 14400000,
		'The flight time from New York City to Los Angeles': 19800000,
		'The time limit of one session of the Bar exam': 21600000,
		'It takes Voyager 1 to travel 250,000 miles': 23400000,
		'The fastest swimmer to cross the English Channel': 24900000,

		//>8 Hours
		'A full typical work day in the United States': 28800000,
		'0.1% of an entire year': 31536000,
		'The time it takes Jeff Bezos to make $100 million': 40173000,
		'The time it takes to assemble a car': 57600000,
		'1% of an entire year': 315360000,
		'It takes for the Lōʻihi volcano to rise above the surface of the ocean becoming a new Hawaiian island': Number.MAX_SAFE_INTEGER //285,616 years
	};

	//Combine any user-inputted times
	window.userTimes = window.userTimes || {};
	Object.assign(times, window.userTimes);

	//Convert to array and sort by duration
	window.sortedTimes = Object.entries(times).sort((a, b) => a[1]-b[1]);

	jQuery('body').removeClass('paused timing');
	jQuery('#longer-than').addClass('hidden');
	jQuery('#the-thing').html('');
	jQuery('#time-indicator').html('');
	jQuery('#next-milestone').addClass('hidden');
	jQuery('#reset').addClass('hidden');
	jQuery('#resume').addClass('hidden');
	jQuery('#start').removeClass('hidden');
	jQuery('h3').addClass('hidden');
	jQuery('h5').html('').addClass('hidden');
	jQuery('#intro-description').removeClass('hidden');
	jQuery('.social-label').text('Share');
	document.title = 'TimeMyMeeting.com | Time your meetings with a fun twist!';
}

function start(){
	jQuery('body').removeClass('paused').addClass('timing');
	jQuery('#longer-than').removeClass('hidden');
	jQuery('#start').addClass('hidden');
	jQuery('#pause').removeClass('hidden');
	jQuery('#resume').addClass('hidden');
	jQuery('#intro-description').addClass('hidden');
	jQuery('#time-indicator').removeClass('hidden');
	jQuery('#next-milestone').removeClass('hidden');
	jQuery('h3').removeClass('hidden');
	jQuery('.social-label').text('Send for Help');

	//Note: you can use the query string ?started= in the url with an approved PHP strtotime() format to "start" at a previously denoted time

	//Prep an example start time in the query string
	let referenceStartHour = (new Date).getHours();
	let referenceStartMinute = (new Date).getMinutes();
	let referenceStartAmPm = ( referenceStartHour >= 12 )? 'pm' : 'am';
	referenceStartHour = ( referenceStartHour === 0 )? 12 : referenceStartHour; //Hour 0 should be 12
	let referenceStartTime = referenceStartHour + ':' + referenceStartMinute + referenceStartAmPm; //Ex: 10am
	let referenceStartedUrl = new URL(window.location.href);

	window.startTime = Date.now();
	if ( window.started ){ //If a pre-set time was used
		window.startTime = window.started; //Use the provided ?started= time
	} else {
		//Append the current time to the URL if the page is reloaded, it'll maintain the original meeting start time
		referenceStartedUrl.searchParams.set('started', referenceStartTime);
		window.history.replaceState(null, null, referenceStartedUrl.toString().replaceAll('%3A', ':'));
	}

	window.pauseTimes = [];
	window.totalPauseTime = 0;
	window.currentActive = '';
	window.slowerAfterMinute = false;

	nextMilestone();

	window.timer = setInterval(function(){
		timerDuties();
	}, 100);

	let startDate = new Date(window.startTime).toLocaleTimeString("en-US", {}).toLowerCase().replace(/:\d\d\s/, '');

	jQuery('h5').html('<a href="?started=' + window.startTime + '" title="Pre-set the start time here">(Started at ' + startDate + ')</a>').removeClass('hidden');

	//Slow the timer down after just over a minute to save some CPU (since we aren't showing milliseconds anymore)
	//Technically, if the timer is preset to a meeting time in the future, this will cause the timer to slow down too early... but whatever...
	setTimeout(function(){
		slowTimer(1000);
		slowerAfterMinute = true;
	}, 90_000);
}

function check(currentTime){
	//Loop through the sorted array
	for ( let time of sortedTimes ){
		if ( time[1] <= currentTime ){
			output(time[0], time[1]);
			sortedTimes.splice(time, 1);
		}

		break; //Exit the for loop
	}
}

function pause(){
	clearInterval(window.timer);

	pauseTimes.push([Date.now()]); //Add the time paused to the "pauses" array

	jQuery('body').removeClass('timing').addClass('paused');
	jQuery('#resume').removeClass('hidden');
	jQuery('#reset').removeClass('hidden');
	jQuery('#pause').addClass('hidden');
	jQuery('.intensifies').css('animation-duration', '0');
}

function resume(){
	pauseTimes[pauseTimes.length-1].push(Date.now()); //Add the time resumed to its associated pause timestamp

	totalPauseTime = 0; //Reset to 0 every time to add everything up again
	for ( let pause of pauseTimes ){
		totalPauseTime = totalPauseTime+(pause[1]-pause[0]); //The resumed time minutes the paused time gives us the duration of the pause
	}

	window.timer = setInterval(function(){
		timerDuties();
	}, 100);

	jQuery('body').removeClass('paused').addClass('timing');
	jQuery('#resume').addClass('hidden');
	jQuery('#reset').addClass('hidden');
	jQuery('#pause').removeClass('hidden');
}

function nextMilestone(){
	jQuery('#next-milestone').html('Next milestone:<br /><strong>' + sortedTimes[1][0] + '</strong><br /><small>at ' + msToTime(sortedTimes[1][1]).replace('.0 seconds', ' seconds').replace(', 0 seconds', '').replace(/,(?=[^,]*$)/, ' and') + '</small>');
}

function output(name, time){
	//console.log('Outputting:', name, time);

	let amountOfTime = msToTime(time).replace('.0 seconds', ' seconds').replace(', 0 seconds', '').replace(/,(?=[^,]*$)/, ' and'); //The regex replaces the last comma with the word "and"

	jQuery('#the-thing').html(name + '<br/><small>(' + amountOfTime + ')</small>');

	animate('#the-thing', 'tug'); //Animate it

	window.currentActive = name;

	if ( typeof gtag == 'function' ){ //Prevent an error that happened literally one time
		gtag('event', 'milestone', {
			milestone: name,
			time: amountOfTime
		});
	}

	jQuery('#meta-description').attr('content', "I'm in a meeting that is longer than " + window.currentActive.toLowerCase() + "! Time yours here."); //I don't think this will work the way I expect it to...

	nextMilestone();
}

//This happens inside of the setInterval() every 100ms-1000ms
function timerDuties(){
	let delta;

	if ( Date.now()-startTime > 0 ){
		delta = Date.now()-startTime-totalPauseTime; // milliseconds elapsed since start
	} else {
		delta = Date.now()-startTime; //Ignore pause times when the meeting starts in the future
	}

	check(delta);

	//If the meeting has not started yet (negative number delta)
	if ( delta < 0 ){
		jQuery('#thing-container').addClass('hidden');
		jQuery('#going-on-for-text').text('Your meeting begins in...');
		jQuery('#started-time').addClass('hidden');
		jQuery('#next-milestone').addClass('hidden');
	} else {
		jQuery('#thing-container').removeClass('hidden');
		jQuery('#going-on-for-text').text('It has been going on for...');
		jQuery('#started-time').removeClass('hidden');
		jQuery('#next-milestone').removeClass('hidden');
	}

	//Output the time
	jQuery('#time-indicator').text(msToTime(delta).replace(/,(?=[^,]*$)/, ' and')); //The regex replaces the last comma with the word "and");
	document.title = msToTime(delta).replaceAll(',', '').replace(/\shour(s)?/g, 'h').replace(/\sminute(s)?/g, 'm').replace(/\ssecond(s)?/g, 's').replace(' 0s', '') + ': Longer than ' + window.currentActive.charAt(0).toLowerCase() + window.currentActive.slice(1) + ' | TimeMyMeeting.com';

	//Intensify the duration timer
	let intensifiesDuration = 0;
	if ( delta > 7200000 ){ //2 Hours
		intensifiesDuration = 3;
	}
	jQuery('.intensifies').css('animation-duration', intensifiesDuration.toFixed(0) + 's');
}

//Increase the interval of the timer
function slowTimer(increment){
	clearInterval(window.timer);

	window.timer = setInterval(function(){
		timerDuties();
	}, increment);
}

//Log idea submissions to GA
function logIdea(){
	gtag('event', 'milestone_idea_submit', {
		idea: jQuery('#idea').val().trim(),
	});

	jQuery('#idea').val('');

	jQuery('#idea-submission-button').addClass('btn-success').removeClass('btn-primary').text('Thanks!');
	setTimeout(function(){
		jQuery('#idea-submission-button').addClass('btn-primary').removeClass('btn-success').text('Submit');
	}, 2000);
}

//Convert milliseconds to a human readable description
function msToTime(duration){
	duration = Math.abs(duration); //Ignore negative values

	let milliseconds = Math.floor((duration % 1000) / 100),
		seconds = Math.floor((duration / 1000) % 60),
		minutes = Math.floor((duration / (1000 * 60)) % 60),
		hours = Math.floor((duration / (1000 * 60 * 60)) % 24);

	let description = '';
	let label = '';

	if ( hours > 0 ){
		label = ( hours === 1 )? 'hour' : 'hours';
		description += hours + ' ' + label + ', ';
	}

	if ( minutes > 0 ){
		label = ( minutes === 1 )? 'minute' : 'minutes';
		description += minutes + ' ' + label + ', ';
	}

	if ( minutes < 1 && hours < 1 ){
		description += seconds + '.' + milliseconds + ' seconds';
	} else {
		label = ( seconds === 1 )? 'second' : 'seconds';
		description += seconds + ' ' + label;
	}

	return description;
}




//Trigger a reflow on an element.
//This is useful for repeating animations.
function reflow(selector){
	let element;
	if ( typeof selector === 'string' ){
		element = jQuery(selector);
	} else if ( typeof selector === 'object' ){
		element = selector;
	}

	element.width();
};

//Handle repeated animations in a single function.
function animate(selector, newAnimationClasses, oldAnimationClasses){
	let element;
	if ( typeof selector === 'string' ){
		element = jQuery(selector);
	} else if ( typeof selector === 'object' ){
		element = selector;
	}

	newAnimationClasses += ' animate';
	element.removeClass(newAnimationClasses); //Remove classes first so they can be re-added.

	if ( oldAnimationClasses ){
		element.removeClass(oldAnimationClasses); //Remove conflicting animation classes.
	}

	reflow(element); //Refresh the element so it can be animated again.
	element.addClass(newAnimationClasses); //Animate the element.
};







function sw(){
	if ( 'serviceWorker' in navigator ){ //If Service Worker is supported (Firefox 44+, Chrome 45+, Edge 17+, Safari 12+)
		//Dynamically import Workbox-Window
		import('https://cdn.jsdelivr.net/npm/workbox-window@6.1.5/build/workbox-window.prod.mjs').then(async function(module){
			const Workbox = module.Workbox;
			const workbox = new Workbox('/sw.js');

			//Listen for Service Worker installation (this is different than PWA installation)
			workbox.addEventListener('installed', function(event){
				//Skip waiting
				workbox.messageSkipWaiting(); //Will probably end up using this, but try it without if first- it was not in the tutorial
			});

			//Activate the service worker
			workbox.addEventListener('activated', async function(event){
				//Send the Workbox service worker router a list of resources to cache
				workbox.messageSW({
					type: 'CACHE_URLS', //This message type is handled in Workbox
					payload: {
						urlsToCache: [
							location.href, //Current page
							...performance.getEntriesByType('resource').map(function(resource){ //Get all of the resources used by this page
								return resource.name;
							}),
						]
					},
				});

				//Now we can send messages back and forth
			});

			//When the service worker begins controlling
			workbox.addEventListener('controlling', function(event){
				//Service worker is now controlling
			});

			//Register the service worker after above workbox event listeners have been added
			workbox.register().then(function(){
				//Whatever
			}).catch(function(error){
				gtag('event', 'service_worker_registration_error', {
					description: error,
				});
			});
		});

		pwa();
	}
}

//Progressive Web App functions (when the user installs the PWA onto their device)
function pwa(){
	let installPromptEvent; //Scope it to this level

	//Listen for ability to show SW install prompt
	window.addEventListener('beforeinstallprompt', function(event){
		event.preventDefault(); //Prevent Chrome <= 67 from automatically showing the prompt
		installPromptEvent = event; //Stash the event so it can be triggered later.
		//jQuery('.pwa-install-button').removeClass('inactive').addClass('ready'); //Show the install button if it is present.
	});

	//Trigger the SW install prompt and handle user choice
	jQuery(document).on('click', '.pwa-install-button', function(){
		if ( typeof installPromptEvent !== 'undefined' ){ //If the install event has been stashed for manual trigger
			jQuery('.pwa-install-button').removeClass('ready').addClass('prompted');

			installPromptEvent.prompt(); //Show the modal add to home screen dialog
			gtag('event', 'pwa_prompt_shown');

			//Wait for the user to respond to the prompt
			installPromptEvent.userChoice.then(function(result){
				jQuery('.pwa-install-button').removeClass('prompted').addClass('ready');

				gtag('event', 'pwa_user_choice', {
					description: result.outcome,
				});
			});
		} else {
			jQuery('.pwa-install-button').removeClass('ready').addClass('inactive');
		}

		return false;
	});

	//PWA installed to the device
	window.addEventListener('appinstalled', function(){
		jQuery('.pwa-install-button').removeClass('ready').addClass('success');
		gtag('event', 'pwa_installed');
	});
}
style.css
wget 'https://sme10.lists2.roe3.org/mdrone/timemymeeting/style.css'
View Content
html {font-size: 16px; background: #f2f2f2;}
body {height: 100vh; padding-top: 25px; background: #f2f2f2; background: linear-gradient(to bottom, #fff 0%, #f2f2f2 100%); overflow-x: hidden;}

@media ( min-width: 768px ){
	body {padding-top: 50px;}
}

a {transition: all 0.25s ease;}

.hidden {display: none;}

#controls {text-align: center;}

#main-content {text-align: center;}
	.paused #main-content {opacity: 0.6;}


#sticky-note {
	position: relative;
	background: linear-gradient(150deg, #f7f08b 60%, #f5f1b6 100%);
	/* background-image: url("../img/paper-fibers.png"), linear-gradient(150deg, #fbf050 60%, #f5f1b6 100%); */
	padding: 50px 40px;
	box-shadow: 12px 24px 50px 0 rgb(0 0 0 / 10%);
	transform: rotate(-2deg);
	z-index: 50;
}

/*
#sticky-note:before {content: ""; position: absolute; top: 50px; left: 0; width: 150px; height: 150px; background: url("../img/scribble.jpg") no-repeat center center / contain; mix-blend-mode: darken; opacity: 0.9;}
#sticky-note:after {content: ""; position: absolute; top: 50px; right: 50px; width: 100px; height: 100px; background: url("../img/scribble.jpg") no-repeat center center / contain; mix-blend-mode: darken; opacity: 0.9;}
*/

@media ( min-width: 768px ){
	#sticky-note {transform: rotate(-2deg); padding: 100px; padding-top: 50px;}
}


#share {margin-top: 75px;}
#social {margin-top: 75px; font-size: 18px;}
	#social .social-label:after {content: ":";}
	#social a {color: #212529;}
		#social a:hover,
		#social a:focus {color: #0d6efd;}

#title {margin-bottom: 50px; text-align: center;}
	#title h1 {font-size: 32px; margin-bottom: 0; font-weight: bold;}

#thing-container {margin-top: 50px;}
h1#longer-than {font-size: 24px; font-family: 'Patrick Hand SC', sans-serif;}
h2 {font-size: 32px; font-weight: bold;}
	h2 small {font-size: 24px; opacity: 0.6;}

h3 {margin-top: 50px; font-size: 18px; font-family: 'Patrick Hand SC', sans-serif;}
h4 {font-size: 24px; font-weight: bold;}
#started-time {font-size: 18px; opacity: 0.6;}
	#started-time a {color: #212529; text-decoration: none;}

@media ( min-width: 768px ){
	h2 {font-size: 42px;}
		h2 small {font-size: 32px;}

	h3 {margin-top: 100px; font-size: 24px;}
	h4 {font-size: 36px; font-weight: bold;}
}

#next-milestone {font-size: 14px; opacity: 0.6; font-style: italic; max-width: 300px; margin: 50px auto 0 auto;}

#feedback {position: relative; font-size: 16px; margin-top: 50px; color: #666; z-index: 45;}
@media ( min-width: 768px ){
	#feedback {margin-top: 150px;}
}
.my-input-group {align-items: flex-end;}

#copyright {font-size: 14px; text-align: center; margin-top: 50px; margin-bottom: 50px; color: #666;}
@media ( min-width: 768px ){
	#copyright {font-size: 12px; margin-top: 50px;}
}




#constainer {position: absolute; bottom: 0; right: 0; overflow: hidden; width: 100%; height: 100%; mix-blend-mode: darken; z-index: 1; pointer-events: none;}
	#stain {position: absolute; bottom: -100px; right: -350px; width: 700px; height: 700px; transform: rotate(180deg); background: url("../img/stain.jpg") no-repeat center center / cover; mix-blend-mode: darken; z-index: 1; opacity: 0.3;}











.tug.animate {animation: tug 0.5s cubic-bezier(0.445, 1.800, 0.360, 0.650);}
@keyframes tug {
	0% {transform: scale3d(1, 1, 1);}
	25% {transform: scale3d(1.2, 1.2, 1.2);}
}

@media ( prefers-reduced-motion: reduce ){
	.tug.animate {animation: none;}
}














.intensifies {animation: intensifies 3s infinite ease-out; transform-origin: bottom center; will-change:transform}
@keyframes intensifies {0%{transform:translate(5px, 2px)}1%{transform:translate(-3px, -1px)}2%{transform:translate(4px, 3px)}3%{transform:translate(-5px, -3px)}4%{transform:translate(4px, 2px)}5%{transform:translate(-4px, -1px)}6%{transform:translate(5px, 3px)}7%{transform:translate(-2px, -4px)}8%{transform:translate(2px, 2px)}9%{transform:translate(-4px, -4px)}10%{transform:translate(3px, 3px)}11%{transform:translate(-1px, -1px)}12%{transform:translate(3px, 3px)}13%{transform:translate(-3px, -1px)}14%{transform:translate(1px, 1px)}15%{transform:translate(-1px, -5px)}16%{transform:translate(1px, 3px)}17%{transform:translate(-4px, -2px)}18%{transform:translate(3px, 3px)}19%{transform:translate(-1px, -1px)}20%{transform:translate(5px, 2px)}21%{transform:translate(-2px, -3px)}22%{transform:translate(5px, 3px)}23%{transform:translate(-2px, -5px)}24%{transform:translate(5px, 4px)}25%{transform:translate(-2px, -3px)}26%{transform:translate(2px, 2px)}27%{transform:translate(-5px, -5px)}28%{transform:translate(2px, 2px)}29%{transform:translate(-4px, -5px)}30%{transform:translate(4px, 2px)}31%{transform:translate(-2px, -1px)}32%{transform:translate(3px, 2px)}33%{transform:translate(-4px, -3px)}34%{transform:translate(1px, 4px)}35%{transform:translate(-5px, -1px)}36%{transform:translate(2px, 5px)}37%{transform:translate(-5px, -2px)}38%{transform:translate(5px, 3px)}39%{transform:translate(-5px, -5px)}40%{transform:translate(2px, 3px)}41%{transform:translate(-5px, -4px)}42%{transform:translate(4px, 2px)}43%{transform:translate(-1px, -4px)}44%{transform:translate(1px, 4px)}45%{transform:translate(-4px, -3px)}46%{transform:translate(2px, 5px)}47%{transform:translate(-5px, -5px)}48%{transform:translate(4px, 4px)}49%{transform:translate(-3px, -5px)}50%{transform:translate(1px, 4px)}51%{transform:translate(-1px, -2px)}52%{transform:translate(3px, 3px)}53%{transform:translate(-4px, -3px)}54%{transform:translate(1px, 1px)}55%{transform:translate(-3px, -3px)}56%{transform:translate(5px, 4px)}57%{transform:translate(-3px, -4px)}58%{transform:translate(3px, 1px)}59%{transform:translate(-4px, -5px)}60%{transform:translate(4px, 5px)}61%{transform:translate(-5px, -1px)}62%{transform:translate(1px, 3px)}63%{transform:translate(-4px, -5px)}64%{transform:translate(2px, 4px)}65%{transform:translate(-4px, -5px)}66%{transform:translate(2px, 4px)}67%{transform:translate(-2px, -4px)}68%{transform:translate(4px, 1px)}69%{transform:translate(-1px, -1px)}70%{transform:translate(2px, 5px)}71%{transform:translate(-2px, -1px)}72%{transform:translate(2px, 3px)}73%{transform:translate(-5px, -2px)}74%{transform:translate(5px, 2px)}75%{transform:translate(-5px, -4px)}76%{transform:translate(3px, 3px)}77%{transform:translate(-1px, -1px)}78%{transform:translate(4px, 5px)}79%{transform:translate(-4px, -1px)}80%{transform:translate(4px, 5px)}81%{transform:translate(-1px, -1px)}82%{transform:translate(4px, 2px)}83%{transform:translate(-5px, -4px)}84%{transform:translate(2px, 5px)}85%{transform:translate(-1px, -5px)}86%{transform:translate(4px, 4px)}87%{transform:translate(-3px, -4px)}88%{transform:translate(5px, 5px)}89%{transform:translate(-4px, -4px)}90%{transform:translate(4px, 2px)}91%{transform:translate(-1px, -2px)}92%{transform:translate(1px, 2px)}93%{transform:translate(-1px, -2px)}94%{transform:translate(3px, 1px)}95%{transform:translate(-4px, -1px)}96%{transform:translate(3px, 3px)}97%{transform:translate(-4px, -1px)}98%{transform:translate(4px, 5px)}99%{transform:translate(-2px, -3px)}100%{transform:translate(0, 0) rotate(0deg)}}












.autostart {
	#longer-than {font-size: 72px;}
	#the-thing {font-size: 120px;
		small {display: none;}
	}

	#title {display: none;}
	#controls {display: none;}
	#next-milestone {display: none;}
	#social {display: none;}
	#feedback {display: none;}
	#copyright {display: none;}
}