Archive for the ‘iphone’ Category
iPhone ringtones flowchart
June 20th, 2008
I don’t convert songs to iPhone ringtones very often, so I made this flowchart to help me remember the process. And by posting it here, I’ll always know where it is. Oddly, I find that Googling “create iphone ringtone” or something like that often brings up out-of-date information. This flowchart works with iTunes 7.6.2 and iPhone 1.1.4 system software, I’ll try to keep it current as the versions change.
Here it is:
You can see a larger version by clicking on it.
This is a Mac-centric workflow, and it takes advantage of the software I own. I perform the actions in the yellow boxes using Rogue Amoeba’s Fission audio editor, but you could substitute any sound file editor, like Freeverse’s SoundStudio or the free Audacity or whatever’s popular on Windows.
Converting to AAC is done by choosing the Convert Selection to AAC command from iTunes’ Advanced menu. If you don’t see a Convert Selection to AAC item in that menu, it’s because your iTunes Importing Preference is set to use a different encoder. Change the encoder to AAC and the menu item will change, too.

A clip about 10-20 seconds long seems to work well. Once the clip is in the iTunes Ringtone Library, it will transfer to your iPhone the next time you sync.
New calculator for iPhone 2.0
June 9th, 2008
For me the hidden gem of the upcoming iPhone 2.0 software is the new scientific calculator application. I’ve been using Belfry’s SciCalc webapp, which is nice enough, but it doesn’t seem as responsive to key taps as the builtin calculator, probably because it’s not a native application.
Here’s what the new calculator looks like according to Apple’s calculator page.

It has the functions I use often, and may be hiding some more goodness behind that 2nd key in the upper left corner. Of course, I also have some complaints, even though I haven’t used it yet.
First, I think the calculator’s switch from basic to scientific when you turn the iPhone from portrait to landscape is a cute idea that will quickly wear out its welcome. Even though my favorite real-world calculator, the spectacular HP 15C, was landscape oriented, I don’t want my calculator switching back to basic mode just because I’ve turned it a bit. And I suspect people who just want the basic mode don’t want it shifting on them, either.
Next, Apple’s choice of some functions seems weird. The x3 key is a waste of space; in thirty years of calculator use, I’ve found cubing to be no more common than raising to any other power—the xy is sufficient. And while there’s a ex key to complement the ln, there’s no 10x key to complement the log. It wouldn’t bother me if there was no log button—calculators make base 10 logs much less useful than their continued presence in math handbooks would suggest—but if you’re going to have log, you really should have 10x. And percentage keys really have no business being on a scientific calculator; if you don’t know that percents are just decimals, you should stick to a basic calculator.
Finally, it looks like there’s just one memory location. One memory location!? On a computer with 8 or 16 gigabytes of memory? A computer with more power than what got Apollo 11 to the moon? Jesus!
Now, there are some good things about the calculator. The big = key is a nice touch. The pi key is something no scientific calculator should be without, but many keep it hidden behind a function key. And I like the idea of having a Rand key, even though I don’t know why you’d use a random number generator on a non-programmable calculator.
Speaking of which, why isn’t this a programmable calculator? Oh well, we’ll probably see a few of those in the App Store.
Another “best” weather webapp for the iPhone
June 3rd, 2008
Before writing this post about Weather Underground’s iPhone-specific site, I looked around on AccuWeather’s site to see if it had an iPhone page. I didn’t find one then, but I did today. It’s at http://apple.accuweather.com/widget/iphone1/iphone.html, and despite some user interface problems, it’s pretty good. Weather Underground gives more detail in current conditions; AccuWeather gives more detail in today’s forecast.
When you first load the AccuWeather page, you’ll probably see something like this:

The strip at the top of the page has icon that summarizes the current conditions (sunny, cloudy, rainy, etc.), and gives the time, temperature and location. At the upper right are two circular icons that act as buttons to control what’s displayed in center of the page (more about that later).
Along the bottom are rectangular buttons for quick access to three default locations. You can set these locations by first clicking on the button you want to set, then clicking the script “i” in the lower right corner. This brings up a form where you can enter the city name or zip code.

The central section of the page is where most of the information is delivered. It’s split into an upper part, which is controlled by the leftmost of the two circular buttons, and a lower part, which is controlled by the rightmost of the two circular buttons. In the image above, the top part is showing a 15-day forecast calendar and the bottom part is showing a more detailed 4-day forecast calendar.
Clicking on the left circular button changes the upper part to an animated radar map.

Clicking the left circular button again changes the upper part to a hour-by-hour forecast for the rest of the day.

Clicking the left circular button again returns you to the 15-day forecast calendar.
Clicking the right circular button toggles the lower part between the 4-day forecast calendar shown above and a 5-hour forecast calendar.

The site loads pretty quickly, even over the EDGE connection; more quickly, it seems, than the Weather Underground site. It’s certainly not as well designed as the Weather Underground site, where the buttons look like buttons and have obvious labels like “Radar” and “Forecast.” In fact, I wrote these directions because I found the AccuWeather site confusing, with cryptic icon buttons. And don’t get me started on the ugly color choices.
Despite its user interface problems, I like the AccuWeather page because it’s more detailed in giving today’s forecast and because its radar images are time stamped so you have a sense of how fast a weather system is moving. I have buttons for both it and the Weather Underground page on my iPhone home screen.
Best weather webapp for the iPhone
May 5th, 2008
A few days ago, I wrote a post describing a little webapp I’d written that scraped a National Weather Service page to deliver a detailed text forecast to the iPhone. The next morning, I saw that @dsandler had Twittered that night about a Weather Underground service that did the same thing. And more.
The iPhone-optimized page is i.wund.com, and it provides
- Current conditions: temperature, wind, humidity, visibility
- Sun and moon rise and set times
- A radar image of your area
- Forecasts for the next several days
- Severe weather warnings
- A search field to get the weather for another city
Some of this is information that could be scraped from the NWS, and I had been thinking about improving my webapp by adding the current conditions and a search field. But there’s no reason for me to go any further; the Weather Underground page gives me everything I want in a compact, fast-loading package. I’ve bookmarked the page for Naperville and added an icon for it to my home screen. Had I known of i.wund.com earlier, I never would have bothered to develop my webapp. At least I learned a bit about Beautiful Soup.
You might wonder why I didn’t learn about the Weather Underground webapp before starting to develop my own. It is, after all, on Apple’s page for popular weather applications. Well, the sad fact is that I’ve been disappointed by so many of the webapps listed on Apple’s iPhone pages that I’ve gotten out of the habit of looking there first. I guess I should get back into the habit.
Better weather forecasts for the iPhone
May 2nd, 2008
I’ve come to hate the weather application built into the iPhone. The graphics are cute, but the information is limited: current temperature, highs and lows for today and the next five days, and a little icon that tries to describe the cloudiness/sunniness/raininess/snowiness/fogginess for each day. It’s the icon that gets to me. A spring day in the Midwest can seldom be described with just one picture, because the weather changes too quickly. What I want is something more granular—a forecast for this afternoon, overnight, tomorrow, and tomorrow night. Predictions beyond that are OK, but I don’t really believe them.
So I set about making a web app, geared to the iPhone, that would give me that information. Here’s what it looks like:

It screen-scrapes a National Weather Service page that gives a detailed text forecast for the location of your choice. The full page looks like this:
I suppose I could have grabbed the part of the page that has the icons, but I like having the wind speed and other information that’s in the text forecast.
For my first go-round, I’ve hard-coded my home town into the CGI script, which I’ve called nws-naperville.cgi. It’s a Python program that uses the very cool Beautiful Soup library for scraping the NWS page.
1: #!/usr/bin/python
2:
3: from BeautifulSoup import BeautifulSoup
4: import urllib
5:
6: # Query the NWS site and get the page of results for Naperville.
7: f=urllib.urlopen('http://forecast.weather.gov/zipcity.php', urllib.urlencode({'inputstring' : '60565'}))
8: page = f.read()
9:
10: # Parse the HTML.
11: soup = BeautifulSoup(page)
12:
13: # Pluck the forecast from below the "Detailed 7-day Forecast" banner.
14: forecastItem = repr(soup.find('td', { 'width' : '50%', 'align' : 'left', 'valign' : 'top'}))
15: start = forecastItem.find('<b>')
16: forecast = forecastItem[start:-17]
17:
18: # Construct the page.
19: print "Content-type: text/html\n"
20:
21: print ''' <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html>
22: <html>
23: <head>
24: <title>Naperville Forecast</title>
25: <meta name="viewport" content="width = device-width" />
26: <style type="text/css">
27: body {
28: font-family: Sans-Serif;
29: font-size: large;
30: }
31: h1 {
32: font-size: x-large;
33: }
34: </style>
35: </head>
36: <body>
37: <h1>Naperville Forecast</h1>'''
38:
39: print forecast
40:
41: print '''</body>
42: </html>
43: '''
Lines 7 feeds one of Naperville’s zip codes to the PHP script that generates the NWS forecast page, and Line 8 gathers up the contents of that page. Beautiful Soup then parses the page on Line 11, and the detailed text forecast is pulled out of the page in Lines 14-16. From that point on, it’s just a matter of generating an HTML output page with the forecast embedded in it. Very simple after Beautiful Soup does the heavy lifting.
I’ve put the script in my cgi-bin directory, and I’ve added a link to it to my iPhone bookmarks. Maybe I’ll get around to creating an icon for the iPhone homepage later.
An obvious improvement to the script would be to generalize it to handle other cities. Fortunately, the NWS’s zipcity.php script can accept “City, State” input as well as zipcodes, which makes searching much easier with no additional work from me. Unfortunately, zipcity.php seems to call different servers depending on where the requested city is. If the requested city is in Arizona, California, Idaho, Montana, Nevada, New Mexico, Oregon, Utah, or Washington, the search is handled by the Western Region Headquarters server (wrh.noaa.gov), which seems to handle redirects and ambiguous city names in ways that are different (and, in my opinion, stupider) than the way the other regional servers work. I had to spend way more time learning about these differences and figuring out how to deal with them than I should have.
Here’s the HTML for simple web page that asks the user to enter a zipcode or city and state. I hope it’s clear from Line 22 that the city and state have to be separated by a comma and the state should be given as a two-letter abbreviation.
1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html>
2: <html>
3: <head>
4: <title>Get Forecast</title>
5: <meta name="viewport" content="width = device-width" />
6: <style type="text/css">
7: body {
8: font-family: Sans-Serif;
9: font-size: large;
10: }
11: h1 {
12: font-size: x-large;
13: }
14: input {
15: font-size: large;
16: }
17: </style>
18: </head>
19: <body>
20: <h1>Get Forecast</h1>
21: <form method="get" action="http://www.leancrew.com/cgi-bin/nws.cgi">
22: Zip code or City, ST:
23: <input type="text" name="inputstring" value="" /><br />
24: <input type="submit">
25: </form>
26: </body>
27: </html>
I call this page forecast.html and have bookmarked this link to it on my iPhone. As you can see on Line 21, it calls a CGI script called nws.cgi:
1: #!/usr/bin/python
2:
3: from BeautifulSoup import BeautifulSoup
4: import urllib, os
5:
6: def followPage(origPage):
7: "Recursively follow JavaScript redirects to the final page."
8: pos = origPage.find('<script>document.location.replace')
9: if pos == -1:
10: return origPage
11: else:
12: start = origPage.find("('", pos) + 2
13: stop = origPage.find("')", start)
14: newurl = 'http://www.wrh.noaa.gov' + origPage[start:stop]
15: f = urllib.urlopen(newurl)
16: newPage = f.read()
17: f.close()
18: return followPage(newPage)
19:
20: # Start the script.
21:
22: # Where are we getting the forecast from?
23: place = urllib.unquote_plus(os.environ['QUERY_STRING'].split('=')[1])
24:
25: # Query the NWS site and get the page of results.
26: f=urllib.urlopen('http://forecast.weather.gov/zipcity.php', urllib.urlencode({'inputstring' : place}))
27: page = f.read()
28: f.close()
29:
30: # If the above URL returns a JavaScript redirect instead of a forecast page,
31: # follow the redirect.
32: page = followPage(page)
33:
34: # If the search string is ambiguous, choose one of the possiblities presented.
35: if page.find('More than one match was found') != -1:
36: soup = BeautifulSoup(page)
37: # We'll use the first link if we can't find a better fit.
38: link = soup.h3.nextSibling['href']
39: linkTags = soup.h3.parent.findAll('a', href=True)
40: # print linkTags
41: # Look for an exact match of the city name.
42: for tag in linkTags:
43: if tag.string.split(',')[0].lower() == place.split(',')[0].lower():
44: link = tag['href']
45: # print tag.string
46: newurl = 'http://www.wrh.noaa.gov' + link
47: f = urllib.urlopen(newurl)
48: page = f.read()
49: f.close()
50: # If it's a JavaScript redirect, follow the redirect to get the forecast.
51: page = followPage(page)
52:
53:
54: # Parse the HTML.
55: soup = BeautifulSoup(page)
56:
57: # Pluck the city and state from the "Point Forcast" line.
58: cityItem = repr(soup.find('td', {'align' : 'left', 'valign' : 'center'}))
59: start = cityItem.find('Point Forecast:</b>') + 19
60: stop = cityItem.find('<br', start)
61: city = cityItem[start:stop].strip()
62:
63: # Pluck the forecast from below the "Detailed 7-day Forecast" banner.
64: forecastItem = repr(soup.find('td', { 'width' : '50%', 'align' : 'left', 'valign' : 'top'}))
65: start = forecastItem.find('<b>')
66: forecast = forecastItem[start:-17]
67:
68: # Construct the page.
69: print "Content-type: text/html\n"
70:
71: print '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html>
72: <html>
73: <head>
74: <title>%s Forecast</title>
75: <meta name="viewport" content="width = device-width" />
76: <style type="text/css">
77: body {
78: font-family: Sans-Serif;
79: font-size: large;
80: }
81: h1 {
82: font-size: x-large;
83: }
84: </style>
85: </head>
86: <body>
87: <h1>%s Forecast</h1>''' % (city, city)
88:
89: print forecast
90:
91: print '''</body>
92: </html>
93: '''
As you can see, it’s about twice as long as nws-naperville.cgi, and virtually all of the additional lines are the idiosyncrasies of the Western Region’s server. The followPage function on Lines 6-18 deals with the (sometimes repeated) JavaScript redirects, and Lines 35-51 deal with the stupid way that server handles ambiguous city names.
[Aside and rant: Here’s an example of the stupidity. If you ask for the forecast for “Phoenix, AZ,” you don’t get the forecast for Phoenix; you’re asked to be more specific. Do you want
- Phoenix, AZ;
- Phoenix Acres Trailer Park, AZ;
- Phoenix Mobile Home Park, AZ;
- Phoenix West Mobile Home Park, AZ;
- South Phoenix, AZ; or
- The Phoenix-Scottsdale Mobile Home Park, AZ
This result is, of course, a sad commentary on the Phoenix area, but it’s an even sadder commentary on whoever programmed the Western Region’s server. The other regional servers handle this ambiguity—which isn’t really an ambiguity, since you can’t get any more specific than “Phoenix,” but we’ll let that go—the right way. If you ask for “Chicago, IL,” for example, the Central Region’s server will give you (wait for it) the forecast for Chicago. Yes, it will give you the opportunity to change to Chicago Heights or Chicago Ridge, but only after it’s given you the forecast you asked for, which is almost certainly what you wanted. Really, if you wanted the forecast for South Phoenix, why the hell would you ask for Phoenix?]
I like having both bookmarks on my iPhone. Most of the time I’ll want the Naperville forecast, and it’s much more efficient to go there directly than through a query page. But when I’m out of town, or planning to go out of town, the query page is ready to give me a forecast for anywhere.
Feel free to adapt these scripts for your own use. If you live anywhere but in the Western Region, you should be able to customize the nws-naperville.cgi script by replacing the zipcode in Line 7. If you live in the Western Region and want a script that goes directly to your town’s forecast, you’ll have to customize nws.cgi by changing Line 23 to set place to either your zipcode or your city and state. For example, changing it to
23: place = '98039'
would be appropriate for Bill Gates.
Update
The Weather Underground has a great webapp for the iPhone at i.wund.com. It does everything my app does and more. I wrote a short description of it a few days after this post.
MIT courseware on the iPhone
April 13th, 2008
On Friday, I started downloading video lectures from MIT’s Open Courseware project, expecting to put them on my iPhone at the next sync. Today I learned that the videos were tagged as Movies instead of TV Shows, which made the iPhone syncing process a little goofy. So I wrote a quick little AppleScript to fix the tagging which I thought others might find useful. Unless you plan to download this exact course, you’ll have to make some changes to the AppleScript, but I think those changes will be obvious.
The course I chose to start with is Physics I, Classical Mechanics1. The MIT Open Courseware has a section in the iTunes Store, and that’s where I went to download the lectures. They came in their own little playlist and automatically generated an enclosing “MIT” folder in my iTunes sidebar.

Unfortunately, as I mentioned, the lecture videos were classified as Movies rather than TV Shows, so they had to be individually selected to be sync’d with my iPhone. I thought that a series of videos like this is more naturally thought of as a TV Show with many individual episodes. Recategorizing them as a TV Show would:
- Allow me to sync them with the iPhone with a single click.
- Automatically remove the lectures I had already watched (assuming my TV Show syncing is set to “all unwatched”).
I could, of course, recategorize all 36 videos by going to the Video tab of Info window and making the appropriate changes.
But I’d have to do it 37 times for this lecture series and then about as many times again for every other lecture series I download. Better to make up a quick script that will work for this course and can be easily edited to work for other courses.
1: set ep to 0
2: tell application "iTunes"
3: repeat with lecture in the selection
4: set video kind of lecture to TV show
5: set show of lecture to "MIT Physics I: Classical Mechanics"
6: set season number of lecture to 1999
7:
8: -- strip the "Lecture" prefix from the name
9: set epname to name of lecture
10: set colon to offset of ":" in epname
11: if colon > 0 then
12: set lastChar to length of epname
13: set epname to (characters (colon + 2) thru lastChar of epname) as text
14: end if
15:
16: set episode ID of lecture to epname
17: set episode number of lecture to ep
18: set ep to ep + 1
19: end repeat
20: end tell
I call the script “Convert Lectures,” and it’s saved in ~/Library/Scripts/Applications/iTunes, which is where FastScripts can find it and make it readily available to me when iTunes is the active application. (Since iTunes has its own AppleScript menu, I could have saved it in ~/Library/iTunes/Scripts, which is where iTunes looks for scripts. I’m just more in the FastScripts habit now.)
The script expects all the lecture videos to be downloaded, in order, and selected. It then goes through all the selected videos and makes the appropriate changes. Line 4 is the most important—it turns the video from a Movie to a TV Show. Line 5 gives the notional TV show a name, and Line 6 sets the season number—which for a real TV show would be 1 or 2 or whatever—to the year in which the lectured were recorded.
Lines 8-16 give each lecture a “episode” name. Each video in the lecture series comes with a name, and except for the introduction, each name is of the form “Lecture nn: Topics.” Lines 9-14 strip away the “Lecture nn: ” prefix—if it’s there—and Line 16 puts the result in the “episode ID” property of the track.
The “ep” variable keeps a running count of the lectures and puts it into the “episode number” property. The count starts at zero because first video, the course introduction, is only a few minutes long and isn’t considered a real lecture. Apparently, iTunes doesn’t consider zero to be a legitimate episode number, because after running the script, the episode number of the course introduction was still blank.
If you want to use this script as a template for your own script:
- You’ll need to change Line 5.
- You’ll need to change Line 6 unless your series was also recorded in 1999.
- You’ll need to change Lines 8-16 unless your track names follow the same format as mine.
- You’ll need to change the starting value of “ep” on Line 1 unless your series also starts with a short introduction.
Although the title of this post mentions the iPhone, you could, of course, transfer the lectures to any video-enabled iPod. It just so happens that the only experience I have with avideo-enabled iPod is with my iPhone. The 36 videos from this course take up about 3.6 GB, which may or may not a big deal depending on the capacity of your iPod and how much other stuff you carry on it. Right now, I have the entire course on my iPhone, but if I were short on space, I’d use the little checkboxes next to the tracks and the “Sync only checked songs and videos” option in the iPhone summary view to control how much of the course would get uploaded.
-
This is a topic with which I am quite familiar; I’m expecting to learn more about the usefulness of this form of education than I am about the topic itself. If I enjoy the form and see it as a nice way of learning, I’ll move on to topics I know less about. ↩
Train schedule for iPhone
March 27th, 2008
A commuter train schedule for my iPhone seemed like a good idea, so I made an iPhone-ready web page and uploaded it here. It’s highly specialized for my use: its for the Metra train that runs between my home town of Naperville and Chicago Union Station. Here’s a screenshot of it in a very narrow Safari window, a reasonable approximation of what it looks like on the iPhone.

As you might expect, Metra has a set of web pages with its schedule, but they include all the stations on the line (of course) and aren’t laid out for easy iPhone viewing. Look at the weekday inbound page:
The font is pretty lightweight (afternoon trains are shown in bold, which is more readable) and the choice of color gives little contrast. As you might guess from the monospace font, this isn’t an HTML table, it’s a table from the old typewriter days that’s been wrapped in <pre></pre> tags. Looking at this page on the iPhone requires a lot of zooming and scrolling.
What I wanted was a page that was quick to load, easy to navigate, and with text I could read without zooming. From the Metra pages, I extracted only the trains that stop at the Naperville station and only the times for Naperville and Union Station. I plugged these times into a table template and fiddled with the formatting until it looked OK.
Here’s the top of the HTML file:
1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2: <html>
3: <head>
4: <title>Metra Schedule</title>
5: <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6: <meta name="viewport" content="width = device-width" />
7: <link href="rr-158.png" rel="apple-touch-icon" />
8: <link rel="stylesheet" type="text/css" media="all" href="metra.css" />
9: </head>
10: <body>
11: <h1>Metra Schedule</h1>
12: <h2>Monday–Friday</h2>
13:
14: <div>
15: <a name="eastbound"></a>
16: <div class="schedlink"><a href="#westbound">to Westbound</a></div>
17: <h3>Eastbound</h3>
18: </div>
19: <table>
20: <thead>
21: <tr>
22: <th>Naperville</th>
23: <th>Union Sta</th>
24: <th></th>
25: </tr>
26: </thead>
27: <tbody>
28: <tr class="am">
29: <td class="time">4:43</td>
30: <td class="time">5:32</td>
31: <td class="x"> </td>
32: </tr>
The <tr></tr> stanza in Lines 28-32 is repeated again and again but with different times and, for afternoon and evening trains, a class of “pm.” The eastbound table ends like this:
164: <tr class="pm">
165: <td class="time">11:33</td>
166: <td class="time">12:29</td>
167: <td class="x"> </td>
168: </tr>
169: </tbody>
170: </table>
After the eastbound table is a westbound table with the same layout. The third column in the tables is either blank or has an “x” in it to denote express trains that have few if any stops between the two stations.
But for two lines, this is pretty generic HTML. Line 6 sets the viewport width to the width of the iPhone. Without this line, the iPhone thinks it’s looking at a page that’s 980 pixels wide and will start in a zoomed-out view that’s almost as hard to read as the Metra pages. Line 6 has no effect on other browsers.
For one-touch access to the schedule, I’ve added this page to my home screen. Line 7 sets the icon to this clip-art image:

There are two schools of thought on the size of the “apple-touch-icon”: Apple official docs say to use a 57x57 pixel PNG image, but others say to use a higher-resolution image to get a better looking icon when the iPhone adjusts it for a 3D look. Since Apple’s own icon is bigger than 57x57, I decided to go with a bigger icon, too. I’m happy with the result.
The CSS file sets the font sizes, borders, alignments, and background colors. It’s nothing special. I use a yellow background for the morning trains and a light purple for the afternoon and evening trains.
There’s no programming here, so this is is certainly not a “webapp.” In fact, I put it on the internet only because the iPhone currently doesn’t support local HTML files. But it’s the kind of information that’s very handy to have in my pocket, and I don’t have to remember to carry a paper train schedule with me.
Update
I now have three pages with Metra schedules, weekdays (updated), Saturdays, and Sundays. The CSS file has also been updated.







