Commit graph

12535 commits

Author SHA1 Message Date
Linus Torvalds
52050fdc92 Save all dive computer nicknames - whether used or not
We used to save dive computer information only if that dive computer was
actually used in any of the dives we saved.  But we can simplify the
code if we just always save any dive computers we know about.  And it
does allow for some usage cases where you have nicknames for other
peoples computers that you may not actively use, but you want to see if
you end up loading multiple XML files in one go.

So there's just no compelling reason to not just save all the info we
have.  And this will make it less painful to remove the "use system
config for dive computer nicknames", because you can also use this to
continue to gather dive computer info in a separate XML file if you want
to.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-24 12:59:31 -08:00
Lubomir I. Ivanov
9acb52b9ee Store/Retrieve last entered webservice UID to/from config.
We use subsurface_set_conf() subsurface_get_conf() to store
and recall the prefered UID for the download.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-24 12:07:45 -08:00
Dirk Hohndel
100c400809 Merge branch 'webservice-import'
Update maxdepth / duration that have moved into the divecomputer
structure.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-24 12:05:16 -08:00
Henrik Brautaset Aronsen
d1262848d8 Fix compile error in planner.c
Linus seems to have been too eager in the dc refactoring: a diveplan
doesn't have a divecomputer.

Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-24 08:47:34 -08:00
Linus Torvalds
4982389ca7 Fix setting of the dive_table.preexisting logic
The 'preexisting' value is used for downloading dives: we want to add
new dives but, but then compare those new dives against the
preexisting ones before we start sorting things and possibly merging
them.

However, the value was only updated sporadically, resulting in it
having stale information in it.  Which would cause problems
particularly if you deleted dives, so that the preexisting value would
point past the actual existing values!

So just update it unconditionally in dive_list_update_dives(), which
anything that changes the dive list is supposed to call in order to
display the changes anyway.

Also, just for safety, when removing a dive, put NULL in the last dive
table location.  Nobody should ever access past the end anyway (this
is enforced by 'get_dive()') but there are places that access the dive
list table directly, and the libdivecomputer download was one of
those.  No reason to leave stale dive pointers possibly around for
uses like that.

Reported-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-23 13:37:02 -08:00
Linus Torvalds
413b9026dd Fix temperature rounding issues
Temperatures can actually be negative, which means that rounding by
adding 0.5 and casting to 'int' is not correct.

We could use '(int)(rint(val))' instead, but the only place we care
about might as well just print out the floating point representation
with a precision of two digits instead.  So if you have a dive computer
that gives you the precision, you might see '3.5˚C' as the temperature.

Remove the helper functions that nobody uses and that get the rounding
wrong anyway.

Reported-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-23 12:55:39 -08:00
Linus Torvalds
aac44f9b07 Remove XML parsing special case temperature code
We had various hacky historical artifacts in our XML parsing, partly
from our legacy of parsing integer and floating point data separately
(we used to recognize certain import format differences based on whether
the data was in a floating point or integer format).  And partly from
trying to do a good job of importing crap from other dive log software.

Anyway, that actually meant that we refused to parse negative numbers,
and we ignored temperatures of zero because some diving log would do
that for missing values.

Both of these actually bit us when parsing our native XML.  Of course,
only crazy ice divers would ever notice.

Noticed by Henrik Brautaset Aronsen.

Reported-acked-and-tested-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-23 12:55:37 -08:00
Linus Torvalds
b6c9301e58 Move more dive computer filled data to the divecomputer structure
This moves the fields 'duration', 'surfacetime', 'maxdepth',
'meandepth', 'airtemp', 'watertemp', 'salinity' and 'surface_pressure'
to the per-divecomputer data structure.  They are filled in by the dive
computer, and normally not edited.

NOTE! All actual *use* of this data was then changed from dive->field to
dive->dc.field programmatically with a shell-script and sed, and the
result then edited for details.  So while the XML save and restore code
has been updated, all the displaying etc will currently always just show
the first dive computer entry.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-23 12:55:33 -08:00
Dirk Hohndel
3e5a508b15 Ensure each dive has its own copy of the location text (UEMIS importer)
Since multiple dives can reference the same divesite we need to do the
strdup when the value gets assigned, not when it gets passed into the
helper function.

This also validates the location string as on my divecomputer there is an
invalid divespot 0 that has a corrupted UTF8 string as location name.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-23 11:57:00 -08:00
Dirk Hohndel
c521aec884 Import and merge GPS data from the webservice
Dive locations marked (and named) via the companion app are downloaded
from the webservice, parsed and merged with the existing dives.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-23 11:53:42 -08:00
Lubomir I. Ivanov
b1db60ba47 divelist.c:icon_click_cb(): check if a GtkTreePath is found
In icon_click_cb() we need to check if a correct GtkTreePath is found
(using gtk_tree_view_get_path_at_pos()) before requesting a GtkTreeIter
for it.

Without this patch a bug is reproducible, where the user may click
outside of the GtkTreeView entries, but still in the GtkTreeView -
e.g. when only one entry is available.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-23 08:49:10 -08:00
Amit Chaudhuri
c149921df4 Fix crash when applying a non-edit of nicknames
As reported by Henrik, there was a crash lurking in edit_dc_nickname code.
Invoking the dialog and selecting apply without changes exposed it neatly.

This is a one line fix.

Signed off by Amit Chaudhuri <amit.k.chaudhuri@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-23 03:50:42 -08:00
Linus Torvalds
e618a245b9 Use proper helper functions for dive location and for_each_dive
This makes the code use the "dive_has_location()" function rather than
check the longitude and latitude directly.

It also uses "for_each_dive()" rather than open-coding it.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-22 22:26:12 -08:00
Linus Torvalds
1f3024152c Satellite icon diet
[Dirk Hohndel: converted to png and .h]

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-22 22:25:03 -08:00
Dirk Hohndel
714d5e2443 Fix crash when clicking on icon column in trip header entries
Silly oversight.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-22 20:44:27 -08:00
Linus Torvalds
9e0a316812 libdivecomputer: add air temperature fixups for Suunto
libdivecomputer doesn't actually seem to support air temperature
reporting at all, but at least for Suunto dive computers the air
temperature is recorded as the temperature for the first sample.

So since we already have vendor-specific libdivecomputer hacks, let's
just add that one as a rule.  It may be that other divecomputers do this
too, so this adds it as a generic concept - it's just that right now the
flag for "air temperature in first sample" is only set for Suunto dive
computers.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-22 20:15:10 -08:00
Linus Torvalds
acd6dff4a8 Improve on the "prefer downloaded" dive computer model
It used to be that when you checked the "Prefer downloaded" checkmark,
we'd throw away *any* old dive computer data.  That was good, because it
allowed us to start from a clean slate when you had some old subsurface
data with questionable dive computer data.

However, it was a bit extreme, and it's really not what you want if you
already have (good) dive computer data from other dive computers.

So this modifies the logic a bit.  Instead of throwing away all old dive
computer data, the "Prefer downloaded" checkmark now means:

 - the newly downloaded data becomes the "primary" dive computer data
   (ie the first in the list)

 - if there was old dive computer data that *could* have been from this
   new dive computer (ie it didn't have model information, or it had a
   matching model but no device ID data), we throw that away

 - but any existing dive computer data from other dive computers is left.

This seems to be much closer to what we really would want for a new
"preferred" download.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-22 20:15:06 -08:00
Linus Torvalds
20ad07d4ac Fix suunto serial number confusion in libdivecomputer
libdivecomputer has started giving the Suunto serial numbers in a
different format, which means that we have the same device with two
different serial numbers, and then we need two different ways of turning
the numerical entity into a string.

Look at the number pattern to see figure out which version of the format
it is that libdivecomputer is reporting, and turn it back into the
original format so that we can reliably give the right string for it.
This also mean sthat the device ID stays the same regardless of
libdivecomputer version.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-22 20:15:01 -08:00
Dirk Hohndel
713c845e5a Add GPS icon to the location column for dive sites where we have GPS data
This replaces the really lame "italics text" from commit abe810ca1a29
("Mark locations that have GPS location data attached") with a marginally
less lame GPS icon.There's a reason why I am not making a living as
graphics artist. But I think this is a huge step forward from what we had
before...

The satellite.svg file is very loosely based on a different icon that I
found as public domain here http://www.clker.com/clipart-30400.html.
From that I created the PNG and then that was converted into the
GdkPixdata via gdk-pixbuf-csource; a rule for that was added to
the Makefile but commented out as I don't know if this tool will always be
available in the path. Having this icon included in the sources avoids
locating yet another icon file.

Better icons are certainly welcome!

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-22 20:11:13 -08:00
Henrik Brautaset Aronsen
c02f1b88ab Add libsoup and osm-gps-map to Mac build instructions.
Also force py27-pygtk to use the quartz variant, since MacPorts
doesn't have variant dependency resolutions.

Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-21 09:52:03 -08:00
Dirk Hohndel
9e13655854 White space and coding style adjustments for gps.c
It's just nicer this way.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-20 20:28:37 -08:00
Dirk Hohndel
97ce7a3763 Fix map scrolling
The osm-gps-map default is to scroll-and-recenter around the mouse position.
That is BAT SHIT CRAZY. So this implements our own scroll handling instead.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-20 20:26:15 -08:00
Dirk Hohndel
3d248682ee Mark locations that have GPS location data attached
This is rather lame - we simply turn the location text into italics for those
dives where we have GPS location data. Underlining might be more natural, but
Gtk plays games with the underline attribute if the mouse hovers over text.

Ideally I would have prefered a little GPS logo next to the location text - but
I couldn't figure out how to do that without writing my own cell renderer which
seemed total overkill.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-20 17:32:55 -08:00
Dirk Hohndel
980ba9cb50 Reuse map windows
Instead of opening a new window / new map for every dive site we now have only
two windows / maps. One for the overview of all the dive sites, the other one
that is used to show the map for a specific dive site.

This also switches the position preference from CENTER to MOUSE - this way it's
less likely that the two map windows will be drawn exactly on top of each
other.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-20 17:07:07 -08:00
Dirk Hohndel
4ea90fcb0b Add modules file for building prerequisites on MacOS X
This should allow the user to build osm-gps-map with jhbuild (all other
required components are already build by the jhbuild default modules).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-19 16:19:11 -08:00
Dirk Hohndel
5c2d1af5ec Add CFLAGS to build rule for webservice.o
Otherwise it won't compile on MacOS X

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-19 16:06:24 -08:00
Dirk Hohndel
ed11851ae3 Improve handling for old XML files in Uemis downloader
In order to work in the most expected ways for people who have used
a version of Subsurface that didn't store the deviceid in the divecomputer
we relax the testing for when a divecomputer entry is assumed to match the
current divecomputer.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-18 13:01:08 -08:00
Dirk Hohndel
0a8038dba4 Consistently use uint32_t for deviceid
There were a handful of places that incorrectly used signed values for the
deviceid.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-18 12:58:45 -08:00
Dirk Hohndel
62c4ec20c7 Fix potential crash with old XML files
A file with no divecomputer section in a dive can trigger a SEGV as cur_dc
could be NULL.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-18 10:39:25 -08:00
Dirk Hohndel
edfdef1bbc Add libsoup to Windows installer
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-18 10:39:05 -08:00
Lubomir I. Ivanov
9fa6b224f7 Fixed some small issues in webservice.c
1) download_dialog_status_text() had some statements with no effect
due to missing return keywords. This fixes incorrect error reporting.

2) Optimize the traversion of the response XML. Assuming that the
status tag should be always under the root tag. We check if the
root tag has children and enter a loop until we find a the
"download" or "error" node names. If there are no children
we return a parser error.

3) Clamp the number of input characters to 30 in the user id
GtkEntry field.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-18 10:07:17 -08:00
Amit Chaudhuri
334e51988d Add facility to edit nicknames / remove nickname entry
This allows users to edit one or more nick name entries in a single
session. Entries can also be removed individually.

Based on mock up by Lubomir Ivanov and various conversations from Dirk.
Thanks to both.

[Dirk Hohndel: quite a bit of editing for coding style and whitespace]

Signed-off-by: Amit Chaudhuri <amit.k.chaudhuri@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-18 07:32:39 -08:00
Lubomir I. Ivanov
592c23cd9c Updated the Makefile to support libsoup and include webservice.[c|h]
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-17 22:29:41 -08:00
Lubomir I. Ivanov
a5ee2b66e1 Added client side communication to the Subsurface Web Service
A couple of new files webservice.c and webservice.h are added.

webservice.h exposes two methods at the moment:
- webservice_download_dialog():
this function creates the user interface for the download dialog
from the web service.
- webservice_request_user_xml()
this function is a direct call to retrieve XML for a specific
user identifier. the actual data, data length and error codes
are stored in passed pointers.

A menu entry is added in the Log menu:
"Download From Web Service"

The used backend for communication at the moment is provided
by libsoup.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-17 22:29:24 -08:00
Dirk Hohndel
d0d4bbece7 Hack Makefile, gtk-gui.c and divelist.c to allow building w/o osm-gps-map
While we are waiting for an autotools generated Makefile, this should allow
people to build that don't have osm-gps-map.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-17 11:17:48 -08:00
Dirk Hohndel
91d6d12416 Update gtk-osx-integration to version 2 of the API
In order to be able to work with Gtk3 introspection all the APIs had to be
renamed. Instead of quartz_application... and gtk_osxapplication... all the API
functions are now name gtkosx_application...

This will break the build for people who haven't upgraded to the latest - but
supporting both would be unspeakably ugly.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-17 11:14:47 -08:00
Dirk Hohndel
aa3eb364bc Add GFlow/GFhigh settings in dive planner
The planner interactively responds to changes to the GFlow and GFhigh in
the dialog and calculates an appropriate profile. If there is a previous
dive within the 48 hours prior to this dive then its saturation is
correctly taken into account if the gradient factors are changed - so if
they are aggressively lowered it is possible to start the dive with
already an existing ceiling (simply increase the surface interval to 'fix'
that).

Once the plan is accepted the GF values are reset to the current
preferences. This can cause the ceiling in the plot to change and the deco
stops to no longer match the ceiling - but that's a logical consequence of
the ability to change a temporary copy of GFlow/GFhigh during the planning
process and not the actual preferences (which would be counter intuitive,
I think).

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-16 15:40:38 -08:00
Dirk Hohndel
2cee400ad1 Correctly mark divelist changed after accepting dive plan
Commit 293126257b20 ("Mark divelist as changed if user accepts planned
dive") had the correct commit message but an incorrect implementation.

This moves the mark_divelist_changed() call into the GTK_RESPONSE_ACCEPT
clause where it belongs.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-16 14:44:11 -08:00
Henrik Brautaset Aronsen
71c8234413 Update dive flag image.
The previous flag didn't work on Windows somehow.  I guess Photoshop
added some headers that GdkPixbuf didn't like.  I've reconverted it
with ImageMagick, which made the file less than half the size. Bonus!

Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-16 14:09:57 -08:00
Linus Torvalds
30d090cee2 Only offer to show dive on map if we have location information
This adds the "Show in map" menu entry to the divelist only if we
actually have a location to show.

Of course, having some way to visually see whether we have a GPS
location even before we show the menu would probably be good. Maybe a
marker in the "location" string or something. But in the meanwhile, at
least we don't have that menu entry if we have nothing to show.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-16 13:04:31 -08:00
Henrik Brautaset Aronsen
e9953fa5e6 Show single dives in map.
This adds a "Show in map" entry in the dive list context menu.  It will
zoom to the dive location if it exists, otherwise the full map will be
displayed.

I've also switched map tiles from OpenStreetMap to Google Maps just to
show off that we can.

Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 17:41:57 -08:00
Salvador Cuñat
3fb80bcaeb Clean up null pointer printout in weightsystem description
If there's no weightsystem description, as in most imported
dives, print a literal "unknown" instead of null pointer
or blank.

Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 17:37:42 -08:00
Dirk Hohndel
348c590ac6 Mark divelist as changed if user accepts planned dive
When the user clicks OK in the dive planner and the dive is added to the
divelist the divelist needs to be marked as changed so Subsurface prompts
the user to save the file before quitting.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 17:35:29 -08:00
Dirk Hohndel
db8de4233d Calculate the gas used during the planned dive
This works on the assumption that the diver uses the deco SAC rate while
on a calculated deco stop and the bottom SAC rate during the rest of the
dive (including the time they move from deco stop to deco stop).

This is making the planning function mostly useful for open circuit
diving.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 17:35:14 -08:00
Dirk Hohndel
c3a08ff056 Add diveplan to the dive notes
This makes it easy to print out a dive plan - it's simply stored in the
notes of the simulated dive we create.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 17:34:51 -08:00
Dirk Hohndel
189cba7fd2 Add code to enter SAC rates for dive planning
This just provides the infrastructure to enter the data, nothing is
calculated, yet.

This adds a new get_thousandths() helper function so we can enter
information of the 'mili-' type as decimal values. So things like
"14.5 l/min" or "0.75 cuft/min" are parsed correctly and converted
into a ml value.

In the process of implementing that I also fixed a bug introduced in
commit ab7aecf16e ("Simplify dive planning code") which broke the
get_tenth() function.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 17:31:27 -08:00
Dirk Hohndel
417391a801 Add small helper function to make planner gui function easier to read
This is just preparation for the next set of changes.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 17:31:03 -08:00
Jan Schubert
322410a845 Trivial pressure related fixes
This patch removes the need for the "string" pressurebuf in planner.c.

It also adds a unit to the partial pressures displayed in the mouse
overlay which are always displayed in bar.

BTW: Has anyone seen a pO2 shown in PSI?

Signed-off-by: Jan Schubert <Jan.Schubert@GMX.li>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 10:13:33 -08:00
Dirk Hohndel
3b7d68c091 Correct the start time of planned dives
Subsurface follows the lead of most divecomputers to use times without
timezone - so all times are implicitly assumed to be local time of the
dive location; so in order to give the current time in that way we
actually need to add the timezone offset.

Instead of relying on OS specific members of struct tm we use the glib
timezone functions to get the timezone offset for us. Of course, the
function used to do this is only in glib 2.26 or newer, which once again
means that Debian stable won't be supported. But since that doesn't build
other parts of Subsurface, either, I think I'll live with that.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 10:09:42 -08:00
Lubomir I. Ivanov
2fb7aa1172 Attempt to override the URI handler in the about dialog
The previous patch in this series adds the function
subsurface_launch_for_uri(), which has to be called from the about
dialog instead of the default function for the URI calls to work
on Windows - i.e. opening links from the dialog.

gtk_about_dialog_set_url_hook() is a deprecated method, but seems
to be the only reasonable way to make the override between GTK 2.20 -
2.24 possible. The "activate-link" signal is recomended instead,
but is not portable for GTK bellow 2.24.

An alternative would be to somehow hack into the GtkAboutDialog
and override the callback for each clickable link.

Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-01-15 08:52:18 -08:00