MDL-40874 Retire MyMobile as a standard theme
authorJerome Mouneyrac <jerome@mouneyrac.com>
Mon, 4 Nov 2013 03:11:46 +0000 (14:11 +1100)
committerMarina Glancy <marina@moodle.com>
Mon, 4 Nov 2013 03:18:41 +0000 (14:18 +1100)
186 files changed:
lib/classes/plugin_manager.php
lib/db/upgrade.php
theme/mymobile/config.php [deleted file]
theme/mymobile/jquery/custom131.js [deleted file]
theme/mymobile/jquery/jquery.mobile-1.3.1.js [deleted file]
theme/mymobile/jquery/plugins.php [deleted file]
theme/mymobile/lang/en/theme_mymobile.php [deleted file]
theme/mymobile/layout/embedded.php [deleted file]
theme/mymobile/layout/general.php [deleted file]
theme/mymobile/lib.php [deleted file]
theme/mymobile/pix/07-map-marker.png [deleted file]
theme/mymobile/pix/41-picture-frame.png [deleted file]
theme/mymobile/pix/83-calendar.png [deleted file]
theme/mymobile/pix/ajax-loader.png [deleted file]
theme/mymobile/pix/ajax-loader2.gif [deleted file]
theme/mymobile/pix/ajax-loader2.png [deleted file]
theme/mymobile/pix/clip.png [deleted file]
theme/mymobile/pix/empty.gif [deleted file]
theme/mymobile/pix/favicon.ico [deleted file]
theme/mymobile/pix/form-check-off.png [deleted file]
theme/mymobile/pix/form-check-on.png [deleted file]
theme/mymobile/pix/form-radio-off.png [deleted file]
theme/mymobile/pix/form-radio-on.png [deleted file]
theme/mymobile/pix/header.png [deleted file]
theme/mymobile/pix/ibulb.png [deleted file]
theme/mymobile/pix/icalendar.png [deleted file]
theme/mymobile/pix/icalendarI4.png [deleted file]
theme/mymobile/pix/icon-arrow-white-down.png [deleted file]
theme/mymobile/pix/icon-arrow-white-left.png [deleted file]
theme/mymobile/pix/icon-arrow-white-right.png [deleted file]
theme/mymobile/pix/icon-arrow-white-up.png [deleted file]
theme/mymobile/pix/icon-delete.png [deleted file]
theme/mymobile/pix/icon-minus-white.png [deleted file]
theme/mymobile/pix/icon-plus-white.png [deleted file]
theme/mymobile/pix/icon-search-black.png [deleted file]
theme/mymobile/pix/icons-18-black.png [deleted file]
theme/mymobile/pix/icons-18-white.png [deleted file]
theme/mymobile/pix/icons-36-black.png [deleted file]
theme/mymobile/pix/icons-36-white.png [deleted file]
theme/mymobile/pix/imessage.png [deleted file]
theme/mymobile/pix/imessageI4.png [deleted file]
theme/mymobile/pix/iuser.png [deleted file]
theme/mymobile/pix/iuserI4.png [deleted file]
theme/mymobile/pix/linevert.png [deleted file]
theme/mymobile/pix/m2m.png [deleted file]
theme/mymobile/pix/m2m2x.png [deleted file]
theme/mymobile/pix/m2ms.png [deleted file]
theme/mymobile/pix/navs.png [deleted file]
theme/mymobile/pix/navsI4.png [deleted file]
theme/mymobile/pix/newnav.png [deleted file]
theme/mymobile/pix/newnav_s.png [deleted file]
theme/mymobile/pix/photos.png [deleted file]
theme/mymobile/pix/pinstripes.png [deleted file]
theme/mymobile/pix/power.png [deleted file]
theme/mymobile/pix/req.png [deleted file]
theme/mymobile/pix/screenshot.png [deleted file]
theme/mymobile/pix/texture_05.png [deleted file]
theme/mymobile/pix/texture_075.png [deleted file]
theme/mymobile/pix_core/a/help.png [deleted file]
theme/mymobile/pix_core/a/refresh.png [deleted file]
theme/mymobile/pix_core/a/search.png [deleted file]
theme/mymobile/pix_core/a/setting.png [deleted file]
theme/mymobile/pix_core/c/event.png [deleted file]
theme/mymobile/pix_core/docs.png [deleted file]
theme/mymobile/pix_core/f/audio.png [deleted file]
theme/mymobile/pix_core/f/avi.png [deleted file]
theme/mymobile/pix_core/f/dmg.png [deleted file]
theme/mymobile/pix_core/f/docm.png [deleted file]
theme/mymobile/pix_core/f/docx.png [deleted file]
theme/mymobile/pix_core/f/excel.png [deleted file]
theme/mymobile/pix_core/f/image.png [deleted file]
theme/mymobile/pix_core/f/text.png [deleted file]
theme/mymobile/pix_core/f/video.png [deleted file]
theme/mymobile/pix_core/f/web.png [deleted file]
theme/mymobile/pix_core/help.png [deleted file]
theme/mymobile/pix_core/i/admin.png [deleted file]
theme/mymobile/pix_core/i/backup.png [deleted file]
theme/mymobile/pix_core/i/calc.png [deleted file]
theme/mymobile/pix_core/i/checkpermissions.png [deleted file]
theme/mymobile/pix_core/i/closed.png [deleted file]
theme/mymobile/pix_core/i/cohort.png [deleted file]
theme/mymobile/pix_core/i/completion-auto-n.png [deleted file]
theme/mymobile/pix_core/i/completion-auto-y.png [deleted file]
theme/mymobile/pix_core/i/completion-manual-n.png [deleted file]
theme/mymobile/pix_core/i/completion-manual-y.png [deleted file]
theme/mymobile/pix_core/i/course.png [deleted file]
theme/mymobile/pix_core/i/courseevent.png [deleted file]
theme/mymobile/pix_core/i/db.png [deleted file]
theme/mymobile/pix_core/i/edit.png [deleted file]
theme/mymobile/pix_core/i/email.png [deleted file]
theme/mymobile/pix_core/i/files.png [deleted file]
theme/mymobile/pix_core/i/filter.png [deleted file]
theme/mymobile/pix_core/i/flagged.png [deleted file]
theme/mymobile/pix_core/i/grades.png [deleted file]
theme/mymobile/pix_core/i/group.png [deleted file]
theme/mymobile/pix_core/i/groupevent.png [deleted file]
theme/mymobile/pix_core/i/guest.png [deleted file]
theme/mymobile/pix_core/i/info.png [deleted file]
theme/mymobile/pix_core/i/item.png [deleted file]
theme/mymobile/pix_core/i/lock.png [deleted file]
theme/mymobile/pix_core/i/log.png [deleted file]
theme/mymobile/pix_core/i/mail.png [deleted file]
theme/mymobile/pix_core/i/menu.png [deleted file]
theme/mymobile/pix_core/i/navigationitem.png [deleted file]
theme/mymobile/pix_core/i/new.png [deleted file]
theme/mymobile/pix_core/i/news.png [deleted file]
theme/mymobile/pix_core/i/open.png [deleted file]
theme/mymobile/pix_core/i/payment.png [deleted file]
theme/mymobile/pix_core/i/publish.png [deleted file]
theme/mymobile/pix_core/i/reload.png [deleted file]
theme/mymobile/pix_core/i/report.png [deleted file]
theme/mymobile/pix_core/i/return.png [deleted file]
theme/mymobile/pix_core/i/rss.png [deleted file]
theme/mymobile/pix_core/i/search.png [deleted file]
theme/mymobile/pix_core/i/siteevent.png [deleted file]
theme/mymobile/pix_core/i/stats.png [deleted file]
theme/mymobile/pix_core/i/switch.png [deleted file]
theme/mymobile/pix_core/i/unflagged.png [deleted file]
theme/mymobile/pix_core/i/unlock.png [deleted file]
theme/mymobile/pix_core/i/user.png [deleted file]
theme/mymobile/pix_core/i/userevent.png [deleted file]
theme/mymobile/pix_core/i/users.png [deleted file]
theme/mymobile/pix_core/req.png [deleted file]
theme/mymobile/pix_core/t/add.png [deleted file]
theme/mymobile/pix_core/t/adddir.png [deleted file]
theme/mymobile/pix_core/t/addfile.png [deleted file]
theme/mymobile/pix_core/t/approve.png [deleted file]
theme/mymobile/pix_core/t/check.png [deleted file]
theme/mymobile/pix_core/t/collapsed.png [deleted file]
theme/mymobile/pix_core/t/delete.png [deleted file]
theme/mymobile/pix_core/t/down.png [deleted file]
theme/mymobile/pix_core/t/edit.png [deleted file]
theme/mymobile/pix_core/t/email.png [deleted file]
theme/mymobile/pix_core/t/expanded.png [deleted file]
theme/mymobile/pix_core/t/groupn.png [deleted file]
theme/mymobile/pix_core/t/hiddenuntil.png [deleted file]
theme/mymobile/pix_core/t/hideuntil.png [deleted file]
theme/mymobile/pix_core/t/left.png [deleted file]
theme/mymobile/pix_core/t/lock.png [deleted file]
theme/mymobile/pix_core/t/log.png [deleted file]
theme/mymobile/pix_core/t/message.png [deleted file]
theme/mymobile/pix_core/t/move.png [deleted file]
theme/mymobile/pix_core/t/portfolioadd.png [deleted file]
theme/mymobile/pix_core/t/preview.png [deleted file]
theme/mymobile/pix_core/t/ranges.png [deleted file]
theme/mymobile/pix_core/t/reload.png [deleted file]
theme/mymobile/pix_core/t/restore.png [deleted file]
theme/mymobile/pix_core/t/right.png [deleted file]
theme/mymobile/pix_core/t/unlock.png [deleted file]
theme/mymobile/pix_core/t/up.png [deleted file]
theme/mymobile/pix_core/t/user.png [deleted file]
theme/mymobile/pix_core/u/f1.png [deleted file]
theme/mymobile/pix_core/u/f2.png [deleted file]
theme/mymobile/pix_core/u/user100.png [deleted file]
theme/mymobile/pix_core/u/user35.png [deleted file]
theme/mymobile/pix_plugins/mod/assignment/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/book/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/chat/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/choice/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/data/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/feedback/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/folder/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/forum/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/glossary/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/glossary/print.png [deleted file]
theme/mymobile/pix_plugins/mod/label/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/lams/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/lesson/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/mail/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/page/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/quiz/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/resource/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/scorm/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/survey/icon.png [deleted file]
theme/mymobile/pix_plugins/mod/wiki/icon.png [deleted file]
theme/mymobile/readme_moodle.txt [deleted file]
theme/mymobile/renderers.php [deleted file]
theme/mymobile/renderers/mod_choice_renderer.php [deleted file]
theme/mymobile/settings.php [deleted file]
theme/mymobile/style/core.css [deleted file]
theme/mymobile/style/jmobile131.css [deleted file]
theme/mymobile/style/jmobile131_rtl.css [deleted file]
theme/mymobile/style/media.css [deleted file]
theme/mymobile/version.php [deleted file]
theme/upgrade.txt
version.php

index 05b72ef..35bf4c1 100644 (file)
@@ -1103,7 +1103,7 @@ class core_plugin_manager {
             'theme' => array(
                 'afterburner', 'anomaly', 'arialist', 'base', 'binarius', 'bootstrapbase',
                 'boxxie', 'brick', 'canvas', 'clean', 'formal_white', 'formfactor',
-                'fusion', 'leatherbound', 'magazine', 'mymobile', 'nimble',
+                'fusion', 'leatherbound', 'magazine', 'nimble',
                 'nonzero', 'overlay', 'serenity', 'sky_high', 'splash',
                 'standard', 'standardold'
             ),
index edf21a9..7604f3e 100644 (file)
@@ -2774,5 +2774,38 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2013102500.01);
     }
 
+    if ($oldversion < 2013110400.00) {
+
+        if (!check_dir_exists($CFG->dirroot . '/theme/mymobile', false)) {
+            // Delete from config_plugins.
+            $DB->delete_records('config_plugins', array('plugin' => 'theme_mymobile'));
+            // Delete the config logs.
+            $DB->delete_records('config_log', array('plugin' => 'theme_mymobile'));
+
+            // Replace the mymobile settings.
+            $DB->set_field('course', 'theme', 'clean', array('theme' => 'mymobile'));
+            $DB->set_field('course_categories', 'theme', 'clean', array('theme' => 'mymobile'));
+            $DB->set_field('user', 'theme', 'clean', array('theme' => 'mymobile'));
+            $DB->set_field('mnet_host', 'theme', 'clean', array('theme' => 'mymobile'));
+
+            // Replace the theme configs.
+            if (get_config('core', 'theme') == 'mymobile') {
+                set_config('theme', 'clean');
+            }
+            if (get_config('core', 'thememobile') == 'mymobile') {
+                set_config('thememobile', 'clean');
+            }
+            if (get_config('core', 'themelegacy') == 'mymobile') {
+                set_config('themelegacy', 'clean');
+            }
+            if (get_config('core', 'themetablet') == 'mymobile') {
+                set_config('themetablet', 'clean');
+            }
+        }
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2013110400.00);
+    }
+
     return true;
 }
diff --git a/theme/mymobile/config.php b/theme/mymobile/config.php
deleted file mode 100644 (file)
index c162766..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Config file for mymobile theme
- *
- * @package    theme_mymobile
- * @copyright  John Stabinger
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-// The name of the theme
-$THEME->name = 'mymobile';
-
-// This theme relies on canvas and of course base themes
-$THEME->parents = array(
-    'canvas',
-    'base',
-);
-
-// Set the stylesheets that we want to include for this theme
-$THEME->sheets = array(
-    'jmobile131',
-    'jmobile131_rtl',
-    'core',
-    'media'
-);
-
-// Exclude parent sheets that we don't want
-$THEME->parents_exclude_sheets = array(
-    'base' => array(
-        'pagelayout',
-        'dock',
-        'editor',
-    ),
-    'canvas' => array(
-        'pagelayout',
-        'tabs',
-        'editor',
-    ),
-);
-
-// Disable the dock - this theme does not support it.
-$THEME->enable_dock = false;
-
-// Set up the default layout options. Note that none of these have block
-// regions. See the code below this for where and when block regions are added.
-$THEME->layouts = array(
-    'base' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-    ),
-    'standard' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-    ),
-    'course' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-    ),
-    'coursecategory' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-    ),
-    'incourse' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-    ),
-    'frontpage' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-    ),
-    'admin' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-    ),
-    'mydashboard' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-        'options' => array('nonavbar' => true),
-    ),
-    'mypublic' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-    ),
-    'login' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-        'options' => array('langmenu'=>true, 'nonavbar'=>true),
-    ),
-    'popup' => array(
-        'file' => 'embedded.php',
-        'regions' => array(),
-        'options' => array('nofooter'=>true, 'noblocks'=>true, 'nonavbar'=>true, 'nocourseheaderfooter'=>true),
-    ),
-    'frametop' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-        'options' => array('nofooter'=>true, 'nocoursefooter'=>true),
-    ),
-    'maintenance' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-        'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocourseheaderfooter'=>true),
-    ),
-    'embedded' => array(
-        'file' => 'embedded.php',
-        'regions' => array(),
-        'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocourseheaderfooter'=>true),
-    ),
-    // Should display the content and basic headers only.
-    'print' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-        'options' => array('nofooter'=>true, 'nonavbar'=>false, 'noblocks'=>true, 'nocourseheaderfooter'=>true),
-    ),
-     // The pagelayout used when a redirection is occuring.
-    'redirect' => array(
-        'file' => 'embedded.php',
-        'regions' => array(),
-        'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocustommenu'=>true, 'nocourseheaderfooter'=>true),
-    ),
-     // The pagelayout used for reports
-    'report' => array(
-        'file' => 'general.php',
-        'regions' => array(),
-        'options' => array('nofooter'=>true, 'nonavbar'=>false, 'noblocks'=>true),
-    ),
-);
-
-// Get whether to show blocks and use appropriate pagelayout
-// this is necessary for block JS errors and other block problems.
-$thisdevice = core_useragent::get_device_type();
-if ($thisdevice === core_useragent::DEVICETYPE_DEFAULT || $thisdevice === core_useragent::DEVICETYPE_TABLET ||
-    optional_param('mymobile_blocks', false, PARAM_BOOL)) {
-    // These are layouts with blocks.
-    $blocklayouts = array('course', 'incourse', 'frontpage', 'mydashboard', 'mypublic');
-    foreach ($blocklayouts as $layout) {
-        $THEME->layouts[$layout]['regions'] = array('myblocks');
-        $THEME->layouts[$layout]['defaultregion'] = 'myblocks';
-    }
-}
-
-// Sets a custom render factory to use with the theme, used when working with custom renderers.
-$THEME->rendererfactory = 'theme_overridden_renderer_factory';
-$THEME->csspostprocess = 'mymobile_user_settings';
-
-// Disables CSS Optimiser for MyMobile theme.
-$THEME->supportscssoptimisation = false;
diff --git a/theme/mymobile/jquery/custom131.js b/theme/mymobile/jquery/custom131.js
deleted file mode 100644 (file)
index 5d4b0ad..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-$(document).bind("mobileinit", function(){
-//mobile init stuff 11/12/10
-//turn off ajax forms...
-$.mobile.defaultPageTransition = "slide";
-});
-
-$(document).ready(function() {
-    //get some vars to start
-    var siteurl = $('.mobilesiteurl').attr("id");
-    var mytheme = $(".datatheme").attr("id");
-    var mythemeb = $(".datathemeb").attr("id");
-
-
-    //function below does generic stuff before creating all pages...
-    $('div').live('pagebeforecreate', function(event, ui) {
-        //turn off ajax on all forms for now as of beta1
-        $('form').attr("data-ajax", "false");
-        //lesson
-        $('.lessonbutton.standardbutton a').attr("data-role", "button");
-        $('#page-mod-lesson-viewPAGE div.fitemtitle label').addClass("afirst");
-
-        //tablet column removal switch
-        $('.slider').live("change",function() {
-            var slids = $(this).val();
-            M.util.set_user_preference('theme_mymobile_chosen_colpos', slids);
-            if (slids == "off") {
-                $('.ui-page-active').removeClass("has-myblocks");
-            } else {
-                $('.ui-page-active').addClass("has-myblocks");
-            }
-        });
-
-        //tabs- links set to external to fix forms
-        $('div.tabtree ul.tabrow0').attr("data-role", "controlgroup");
-        $('div.tabtree ul.tabrow12').attr("data-role", "controlgroup");
-        $('div.tabtree li a').attr("data-role", "button").attr("data-ajax", "false");
-
-        //jump to current or bottom
-        $('a.jumptocurrent').live('tap', function() {
-            var position = $(".ui-page-active .section.current").position();
-            if (!position) {
-                var position = $(".ui-page-active .mobilefooter").position();
-            }
-            $.mobile.silentScroll(position.top);
-            $(this).removeClass("ui-btn-active");
-            return false;
-        });
-
-        //scroll to top
-        $('a#uptotop').live('tap', function() {
-            var position = $(".ui-page-active").position();
-            $.mobile.silentScroll(position.top);
-            $(this).removeClass("ui-btn-active");
-            return false;
-        });
-
-        //remove message notifcation overlay on tap 6/21/11
-        $('a#notificationno').live('tap', function() {
-            $('#newmessageoverlay').remove();
-            return false;
-        });
-
-        //calendar and other links that need to be external
-        $('.maincalendar .filters a, li.activity.scorm a, div.files a, #page-user-filesPAGE li div a, .maincalendar .bottom a, .section li.url.modtype_url a, .resourcecontent .resourcemediaplugin a, #underfooter .noajax a, .block_mnet_hosts .content a, .block_private_files .content a, a.portfolio-add-link, #attempts td a, .settingsul li a, .foldertree li a').attr("data-ajax", "false");
-
-        //add blank to open in window for some
-        $('#page-mod-url-viewPAGE div.urlworkaround a, #page-mod-resource-viewPAGE div.resourceworkaround a, .mediaplugin a.mediafallbacklink, #page-mod-resource-viewPAGE .resourcemp3 a, .foldertree li a').attr("target", "_blank").attr("data-role", "button").attr("data-icon", "plus");
-
-        //// **** general stuff *** ////
-        $('form fieldset').attr("data-role", "fieldcontain");
-        $('form .fitem').attr("data-role", "fieldcontain");
-
-        //submit button for forum
-        $('#page-mod-url-viewPAGE div.urlworkaround a').attr("data-role", "button");
-
-        //survey form fix
-        $('#surveyform').attr("action", siteurl + '/mod/survey/save.php');
-
-        //nav select navigtation NEW
-        $("#navselect").live("change",function() {
-            var meb = encodeURI($(this).val());
-            $(this).val("-1");
-            if (meb != "" && meb != "-1") {
-                $.mobile.changePage(meb);
-            }
-       });
-
-    });
-
-
-    //course page only js
-    $('div.path-site, div.path-course-view, .path-course-view div.generalpage').live('pagebeforecreate', function(event, ui) {
-        //course listing
-        $('.section li img.activityicon').addClass("ui-li-icon");
-        $('.course-content ul.section, .sitetopic ul.section').attr("data-role", "listview").attr("data-inset", "true").attr("data-theme", mythemeb);
-        $('.topics div.left.side').addClass("ui-bar-" + mytheme);
-        $('.section.hidden div.headingwrap').attr("data-theme", mythemeb);
-        //$('.topics #section-0 div.left.side').removeClass("ui-li ui-li-divider ui-btn ui-bar-a");
-        $('.section .resource.modtype_resource a, .section .modtype_survey a').attr("data-ajax", "false");
-
-        //toggle completion checkmarks and form fixes
-        $('.togglecompletion input[type="image"]').attr("data-role", "none");
-        $('.togglecompletion input[type="image"]').click(function() {
-            $(".section .togglecompletion").attr("action", '');
-            var mylocc = siteurl + "/course/togglecompletion.php";
-            $(".section .togglecompletion").attr("action", mylocc);
-            this.form.submit();
-            return false;
-        });
-
-        // Force the class ui-li-desc on non-detected elements.
-        $('ul.section div.availabilityinfo, ul.section div.contentafterlink').addClass('ui-li-desc');
-
-        // Force some classes on dimmed elements.
-        $('ul.section div.dimmed_text > span').addClass('instancename');
-    });
-
-    //forum listing only stuff
-    $('div#page-mod-forum-viewPAGE, #page-mod-forum-view div.generalpage').live('pagebeforecreate',function(event, ui){
-        //forums listing change theme for other theme
-        $('table.forumheaderlist').attr("data-role", "controlgroup");
-        $('table.forumheaderlist thead tr').attr("data-role", "button").attr("data-theme", mythemeb);
-        $('table.forumheaderlist td.topic a').attr("data-role", "button").attr("data-icon", "arrow-r").attr("data-iconpos", "right").attr("data-theme", mythemeb);
-    });
-
-    $('div#page-mod-forum-viewPAGE').live('pageinit',function(event, ui){
-        $('.forumheaderlist td.topic').each(function(index) {
-            var ggg = $(this).nextAll("td.replies").text();
-            $(this).find('a').append('<span class="ui-li-count ui-btn-up-a ui-btn-corner-all"> ' + ggg + '</span>');
-         });
-    });
-
-    //forum discussion page only stuff
-    $('div#page-mod-forum-discussPAGE, #page-mod-forum-discuss div.generalpage, div.forumtype-single, .forumtype-single div.generalpage, div#page-mod-forum-postPAGE').live('pagebeforecreate',function(event, ui){
-        //actual forum posting
-        $('.forumpost div.row.header').addClass("ui-li ui-li-divider ui-btn ui-bar-" + mytheme);
-        $('.options div.commands').attr("data-role", "controlgroup").attr("data-type", "horizontal");
-        $('.options div.commands a').attr("data-role", "button").attr("data-ajax", "false").attr("data-inline", "true");
-        $('.forumpost div.author a').attr("data-inline", "true");
-        $('.options div.commands').contents().filter(function() {
-            return this.nodeType == 3; //Node.TEXT_NODE
-        }).remove();
-        //function above removes | in div.commands
-    });
-
-    //frontpage only stuff
-    $('div#page-site-indexPAGE, div.pagelayout-coursecategory').live('pagebeforecreate',function(event, ui){
-        //course boxes on category pages and front page stuff
-        //forum posts on front page only
-        $('.forumpost div.row.header').addClass("ui-li ui-li-divider ui-btn ui-bar-" + mytheme);
-        $('div.subscribelink a').attr("data-role", "button").attr("data-inline", "true");
-        $('.unlist').attr("data-role", "controlgroup");
-        $('div.coursebox a').attr("data-role", "button").attr("data-icon", "arrow-r").attr("data-iconpos", "right").attr("data-theme", mythemeb);
-        $('.box.categorybox').attr("data-role", "controlgroup");
-        $('div.categorylist div.category a').attr("data-role", "button").attr("data-theme", mythemeb);
-        $('#shortsearchbox, #coursesearch2 #shortsearchbox').attr("data-type", "search");
-    });
-
-    $('div#page-site-indexPAGE').live('pageinit',function(event, ui){
-        $('div.categorylist div.category').each(function(index) {
-            var ggb = $(this).find("span.numberofcourse").text().replace('(','').replace(')','');
-            if (ggb != "") {
-                $(this).find('a').append('<span class="ui-li-count ui-btn-up-a ui-btn-corner-all">' + ggb + '</span>');
-            }
-        });
-    });
-
-    //chat only stuff
-    $('div#chatpage, div.path-mod-chat').live('pagebeforecreate',function(event, ui){
-        $('#input-message, #button-send').attr("data-role", "none");
-        $('#enterlink a').attr("data-role", "button").attr("data-ajax", "false").attr("data-icon", "plus");
-        $('form, input, button').attr("data-ajax", "false");
-    });
-
-    //login page only stuff
-    $('div#page-login-indexPAGE').live('pagebeforecreate',function(event, ui){
-        //signup form fix
-        $('.path-login .signupform #signup').attr("action", siteurl + '/login/signup.php');
-        $('.path-login #guestlogin').attr("action", siteurl + '/login/index.php');
-    });
-
-    //messaging only stuff
-    $('div#page-message-indexPAGE').live('pagebeforecreate',function(event, ui){
-        //below to fix form actions here and there
-        $("#usergroupform").attr("action", '');
-        //if (userform == "") {
-        var myloc = siteurl + "/message/index.php";
-        $("#usergroupform").attr("action", myloc);
-        //messaging links
-        $('.path-message td.link').attr("data-role", "controlgroup").attr("data-type", "horizontal");
-        $('.path-message td.link a').attr("data-role", "button").attr("data-inline", "true");
-    });
-
-    //database and glossary only stuff
-    $('div#page-mod-data-viewPAGE, div#page-mod-glossary-viewPAGE').live('pagebeforecreate',function(event, ui){
-        $('.defaulttemplate td a').attr("data-role", "button").attr("data-ajax", "false").attr("data-inline", "true");
-        $('#options select, .aliases select').attr("data-native-menu", "true");
-        $('#pref_search, .glossarysearchbox input[type="text"]').attr("data-type", "search");
-        $('#options').attr("action", siteurl + '/mod/data/view.php');
-        $('#page-mod-glossary-viewPAGE form').each(function(index) {
-            var glossform = $(this).attr("action");
-            if (glossform == "view.php") {
-                $(this).attr("action", siteurl + '/mod/glossary/view.php');
-            }
-        });
-    });
-
-    //mymoodle only stuff
-    $('div#page-my-indexPAGE').live('pagebeforecreate',function(event, ui){
-        //my moodle page fixes
-        //block_course_overview
-        $('.block_course_overview div.headingwrap').attr("data-role", "none");
-        $('.block_course_overview h3 a').attr("data-theme", mytheme);
-    });
-
-    //resource only stuff to help embedded PDFs, provides link to open in new window
-    $('div#page-mod-resource-viewPAGE').live('pagebeforecreate',function(event, ui){
-        $('div.resourcepdf').each(function(index) {
-            var thisopen = $(this).find('#resourceobject').attr("data");
-            $(this).append('<a class="mobileresource" href="' +thisopen+ '" target="_blank"></a>');
-        });
-    });
-
-    //quiz page only js
-    $('div#page-mod-quiz-viewPAGE, div#page-mod-quiz-attemptPAGE, div#page-mod-quiz-summaryPAGE, div#page-mod-quiz-reviewPAGE, #page-mod-quiz-attempt #content2').live('pagebeforecreate',function(event, ui){
-        //add quiz timer into quiz page
-        $('#quiz-timer').remove();
-        $('.mymobilecontent').prepend('<div id="quiz-timer" > <span id="quiz-time-left"></span></div>');
-        $('.que .info').addClass("ui-bar-" + mytheme);
-        $('.que input.submit').attr("data-role", "none");
-        $('div.submitbtns a, div.quizattemptcounts a').attr("data-role", "button").attr("data-ajax", "false");
-        $('#page-mod-quiz-attemptPAGE .questionflag input, .path-mod-quiz .questionflag input').attr("data-role", "none");
-    });
-
-    //assignment page only stuff
-    $('#page-mod-assignment-viewPAGE').live('pagebeforecreate',function(event, ui){
-         //below fixes the advanced upload edit notes button
-         $('#page-mod-assignment-viewPAGE div[rel="upload.php"]').parent().attr("action", siteurl + '/mod/assignment/upload.php');
-    });
-
-    //hotpot page only stuff
-    $('div.path-mod-hotpot').live('pagebeforecreate',function(event, ui){
-        $('.path-mod-hotpot button').attr("data-role", "none");
-    });
-
-    ///// functions below does stuff after creating page for some cleaning...
-    $('div').live('pageinit',function(event, ui){
-        $('.path-calendar div.ui-radio label:first-child, .path-mod-lesson div.ui-radio label:first-child, #page-mod-wiki-createPAGE div.ui-radio label:first-child').addClass("afirst");
-        $('.forumpost div.author a').removeAttr('data-role');
-        //$('.questionflagimage2').removeClass("ui-btn-hidden");a#notificationyes
-        //image replacement
-        $(this).find(".ithumb .course-content .summary img, .ithumb .course-content .activity.label img, .ithumb .sitetopic .no-overflow img").click(function() {
-            var turl = $(this).attr("src");
-            window.open(turl);
-        });
-    });
-});
\ No newline at end of file
diff --git a/theme/mymobile/jquery/jquery.mobile-1.3.1.js b/theme/mymobile/jquery/jquery.mobile-1.3.1.js
deleted file mode 100644 (file)
index 692e96d..0000000
+++ /dev/null
@@ -1,11199 +0,0 @@
-/*
-* jQuery Mobile 1.3.1
-* Git HEAD hash: 74b4bec049fd93e4fe40205e6157de16eb64eb46 <> Date: Mon Apr 8 2013 19:41:28 UTC
-* http://jquerymobile.com
-*
-* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors
-* Released under the MIT license.
-* http://jquery.org/license
-*
-*/
-
-
-(function ( root, doc, factory ) {
-       if ( typeof define === "function" && define.amd ) {
-               // AMD. Register as an anonymous module.
-               define( [ "jquery" ], function ( $ ) {
-                       factory( $, root, doc );
-                       return $.mobile;
-               });
-       } else {
-               // Browser globals
-               factory( root.jQuery, root, doc );
-       }
-}( this, document, function ( jQuery, window, document, undefined ) {
-(function( $ ) {
-       $.mobile = {};
-}( jQuery ));
-(function( $, window, undefined ) {
-       var nsNormalizeDict = {};
-
-       // jQuery.mobile configurable options
-       $.mobile = $.extend($.mobile, {
-
-               // Version of the jQuery Mobile Framework
-               version: "1.3.1",
-
-               // Namespace used framework-wide for data-attrs. Default is no namespace
-               ns: "",
-
-               // Define the url parameter used for referencing widget-generated sub-pages.
-               // Translates to to example.html&ui-page=subpageIdentifier
-               // hash segment before &ui-page= is used to make Ajax request
-               subPageUrlKey: "ui-page",
-
-               // Class assigned to page currently in view, and during transitions
-               activePageClass: "ui-page-active",
-
-               // Class used for "active" button state, from CSS framework
-               activeBtnClass: "ui-btn-active",
-
-               // Class used for "focus" form element state, from CSS framework
-               focusClass: "ui-focus",
-
-               // Automatically handle clicks and form submissions through Ajax, when same-domain
-               ajaxEnabled: true,
-
-               // Automatically load and show pages based on location.hash
-               hashListeningEnabled: true,
-
-               // disable to prevent jquery from bothering with links
-               linkBindingEnabled: true,
-
-               // Set default page transition - 'none' for no transitions
-               defaultPageTransition: "fade",
-
-               // Set maximum window width for transitions to apply - 'false' for no limit
-               maxTransitionWidth: false,
-
-               // Minimum scroll distance that will be remembered when returning to a page
-               minScrollBack: 250,
-
-               // DEPRECATED: the following property is no longer in use, but defined until 2.0 to prevent conflicts
-               touchOverflowEnabled: false,
-
-               // Set default dialog transition - 'none' for no transitions
-               defaultDialogTransition: "pop",
-
-               // Error response message - appears when an Ajax page request fails
-               pageLoadErrorMessage: "Error Loading Page",
-
-               // For error messages, which theme does the box uses?
-               pageLoadErrorMessageTheme: "e",
-
-               // replace calls to window.history.back with phonegaps navigation helper
-               // where it is provided on the window object
-               phonegapNavigationEnabled: false,
-
-               //automatically initialize the DOM when it's ready
-               autoInitializePage: true,
-
-               pushStateEnabled: true,
-
-               // allows users to opt in to ignoring content by marking a parent element as
-               // data-ignored
-               ignoreContentEnabled: false,
-
-               // turn of binding to the native orientationchange due to android orientation behavior
-               orientationChangeEnabled: true,
-
-               buttonMarkup: {
-                       hoverDelay: 200
-               },
-
-               // define the window and the document objects
-               window: $( window ),
-               document: $( document ),
-
-               // TODO might be useful upstream in jquery itself ?
-               keyCode: {
-                       ALT: 18,
-                       BACKSPACE: 8,
-                       CAPS_LOCK: 20,
-                       COMMA: 188,
-                       COMMAND: 91,
-                       COMMAND_LEFT: 91, // COMMAND
-                       COMMAND_RIGHT: 93,
-                       CONTROL: 17,
-                       DELETE: 46,
-                       DOWN: 40,
-                       END: 35,
-                       ENTER: 13,
-                       ESCAPE: 27,
-                       HOME: 36,
-                       INSERT: 45,
-                       LEFT: 37,
-                       MENU: 93, // COMMAND_RIGHT
-                       NUMPAD_ADD: 107,
-                       NUMPAD_DECIMAL: 110,
-                       NUMPAD_DIVIDE: 111,
-                       NUMPAD_ENTER: 108,
-                       NUMPAD_MULTIPLY: 106,
-                       NUMPAD_SUBTRACT: 109,
-                       PAGE_DOWN: 34,
-                       PAGE_UP: 33,
-                       PERIOD: 190,
-                       RIGHT: 39,
-                       SHIFT: 16,
-                       SPACE: 32,
-                       TAB: 9,
-                       UP: 38,
-                       WINDOWS: 91 // COMMAND
-               },
-
-               // Place to store various widget extensions
-               behaviors: {},
-
-               // Scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value
-               silentScroll: function( ypos ) {
-                       if ( $.type( ypos ) !== "number" ) {
-                               ypos = $.mobile.defaultHomeScroll;
-                       }
-
-                       // prevent scrollstart and scrollstop events
-                       $.event.special.scrollstart.enabled = false;
-
-                       setTimeout( function() {
-                               window.scrollTo( 0, ypos );
-                               $.mobile.document.trigger( "silentscroll", { x: 0, y: ypos });
-                       }, 20 );
-
-                       setTimeout( function() {
-                               $.event.special.scrollstart.enabled = true;
-                       }, 150 );
-               },
-
-               // Expose our cache for testing purposes.
-               nsNormalizeDict: nsNormalizeDict,
-
-               // Take a data attribute property, prepend the namespace
-               // and then camel case the attribute string. Add the result
-               // to our nsNormalizeDict so we don't have to do this again.
-               nsNormalize: function( prop ) {
-                       if ( !prop ) {
-                               return;
-                       }
-
-                       return nsNormalizeDict[ prop ] || ( nsNormalizeDict[ prop ] = $.camelCase( $.mobile.ns + prop ) );
-               },
-
-               // Find the closest parent with a theme class on it. Note that
-               // we are not using $.fn.closest() on purpose here because this
-               // method gets called quite a bit and we need it to be as fast
-               // as possible.
-               getInheritedTheme: function( el, defaultTheme ) {
-                       var e = el[ 0 ],
-                               ltr = "",
-                               re = /ui-(bar|body|overlay)-([a-z])\b/,
-                               c, m;
-
-                       while ( e ) {
-                               c = e.className || "";
-                               if ( c && ( m = re.exec( c ) ) && ( ltr = m[ 2 ] ) ) {
-                                       // We found a parent with a theme class
-                                       // on it so bail from this loop.
-                                       break;
-                               }
-
-                               e = e.parentNode;
-                       }
-
-                       // Return the theme letter we found, if none, return the
-                       // specified default.
-
-                       return ltr || defaultTheme || "a";
-               },
-
-               // TODO the following $ and $.fn extensions can/probably should be moved into jquery.mobile.core.helpers
-               //
-               // Find the closest javascript page element to gather settings data jsperf test
-               // http://jsperf.com/single-complex-selector-vs-many-complex-selectors/edit
-               // possibly naive, but it shows that the parsing overhead for *just* the page selector vs
-               // the page and dialog selector is negligable. This could probably be speed up by
-               // doing a similar parent node traversal to the one found in the inherited theme code above
-               closestPageData: function( $target ) {
-                       return $target
-                               .closest( ':jqmData(role="page"), :jqmData(role="dialog")' )
-                               .data( "mobile-page" );
-               },
-
-               enhanceable: function( $set ) {
-                       return this.haveParents( $set, "enhance" );
-               },
-
-               hijackable: function( $set ) {
-                       return this.haveParents( $set, "ajax" );
-               },
-
-               haveParents: function( $set, attr ) {
-                       if ( !$.mobile.ignoreContentEnabled ) {
-                               return $set;
-                       }
-
-                       var count = $set.length,
-                               $newSet = $(),
-                               e, $element, excluded;
-
-                       for ( var i = 0; i < count; i++ ) {
-                               $element = $set.eq( i );
-                               excluded = false;
-                               e = $set[ i ];
-
-                               while ( e ) {
-                                       var c = e.getAttribute ? e.getAttribute( "data-" + $.mobile.ns + attr ) : "";
-
-                                       if ( c === "false" ) {
-                                               excluded = true;
-                                               break;
-                                       }
-
-                                       e = e.parentNode;
-                               }
-
-                               if ( !excluded ) {
-                                       $newSet = $newSet.add( $element );
-                               }
-                       }
-
-                       return $newSet;
-               },
-
-               getScreenHeight: function() {
-                       // Native innerHeight returns more accurate value for this across platforms,
-                       // jQuery version is here as a normalized fallback for platforms like Symbian
-                       return window.innerHeight || $.mobile.window.height();
-               }
-       }, $.mobile );
-
-       // Mobile version of data and removeData and hasData methods
-       // ensures all data is set and retrieved using jQuery Mobile's data namespace
-       $.fn.jqmData = function( prop, value ) {
-               var result;
-               if ( typeof prop !== "undefined" ) {
-                       if ( prop ) {
-                               prop = $.mobile.nsNormalize( prop );
-                       }
-
-                       // undefined is permitted as an explicit input for the second param
-                       // in this case it returns the value and does not set it to undefined
-                       if( arguments.length < 2 || value === undefined ){
-                               result = this.data( prop );
-                       } else {
-                               result = this.data( prop, value );
-                       }
-               }
-               return result;
-       };
-
-       $.jqmData = function( elem, prop, value ) {
-               var result;
-               if ( typeof prop !== "undefined" ) {
-                       result = $.data( elem, prop ? $.mobile.nsNormalize( prop ) : prop, value );
-               }
-               return result;
-       };
-
-       $.fn.jqmRemoveData = function( prop ) {
-               return this.removeData( $.mobile.nsNormalize( prop ) );
-       };
-
-       $.jqmRemoveData = function( elem, prop ) {
-               return $.removeData( elem, $.mobile.nsNormalize( prop ) );
-       };
-
-       $.fn.removeWithDependents = function() {
-               $.removeWithDependents( this );
-       };
-
-       $.removeWithDependents = function( elem ) {
-               var $elem = $( elem );
-
-               ( $elem.jqmData( 'dependents' ) || $() ).remove();
-               $elem.remove();
-       };
-
-       $.fn.addDependents = function( newDependents ) {
-               $.addDependents( $( this ), newDependents );
-       };
-
-       $.addDependents = function( elem, newDependents ) {
-               var dependents = $( elem ).jqmData( 'dependents' ) || $();
-
-               $( elem ).jqmData( 'dependents', $.merge( dependents, newDependents ) );
-       };
-
-       // note that this helper doesn't attempt to handle the callback
-       // or setting of an html element's text, its only purpose is
-       // to return the html encoded version of the text in all cases. (thus the name)
-       $.fn.getEncodedText = function() {
-               return $( "<div/>" ).text( $( this ).text() ).html();
-       };
-
-       // fluent helper function for the mobile namespaced equivalent
-       $.fn.jqmEnhanceable = function() {
-               return $.mobile.enhanceable( this );
-       };
-
-       $.fn.jqmHijackable = function() {
-               return $.mobile.hijackable( this );
-       };
-
-       // Monkey-patching Sizzle to filter the :jqmData selector
-       var oldFind = $.find,
-               jqmDataRE = /:jqmData\(([^)]*)\)/g;
-
-       $.find = function( selector, context, ret, extra ) {
-               selector = selector.replace( jqmDataRE, "[data-" + ( $.mobile.ns || "" ) + "$1]" );
-
-               return oldFind.call( this, selector, context, ret, extra );
-       };
-
-       $.extend( $.find, oldFind );
-
-       $.find.matches = function( expr, set ) {
-               return $.find( expr, null, null, set );
-       };
-
-       $.find.matchesSelector = function( node, expr ) {
-               return $.find( expr, null, null, [ node ] ).length > 0;
-       };
-})( jQuery, this );
-
-
-/*!
- * jQuery UI Widget v1.10.0pre - 2012-11-13 (ff055a0c353c3c8ce6e5bfa07ad7cb03e8885bc5)
- * http://jqueryui.com
- *
- * Copyright 2010, 2013 jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- *
- * http://api.jqueryui.com/jQuery.widget/
- */
-(function( $, undefined ) {
-
-var uuid = 0,
-       slice = Array.prototype.slice,
-       _cleanData = $.cleanData;
-$.cleanData = function( elems ) {
-       for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
-               try {
-                       $( elem ).triggerHandler( "remove" );
-               // http://bugs.jquery.com/ticket/8235
-               } catch( e ) {}
-       }
-       _cleanData( elems );
-};
-
-$.widget = function( name, base, prototype ) {
-       var fullName, existingConstructor, constructor, basePrototype,
-               namespace = name.split( "." )[ 0 ];
-
-       name = name.split( "." )[ 1 ];
-       fullName = namespace + "-" + name;
-
-       if ( !prototype ) {
-               prototype = base;
-               base = $.Widget;
-       }
-
-       // create selector for plugin
-       $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
-               return !!$.data( elem, fullName );
-       };
-
-       $[ namespace ] = $[ namespace ] || {};
-       existingConstructor = $[ namespace ][ name ];
-       constructor = $[ namespace ][ name ] = function( options, element ) {
-               // allow instantiation without "new" keyword
-               if ( !this._createWidget ) {
-                       return new constructor( options, element );
-               }
-
-               // allow instantiation without initializing for simple inheritance
-               // must use "new" keyword (the code above always passes args)
-               if ( arguments.length ) {
-                       this._createWidget( options, element );
-               }
-       };
-       // extend with the existing constructor to carry over any static properties
-       $.extend( constructor, existingConstructor, {
-               version: prototype.version,
-               // copy the object used to create the prototype in case we need to
-               // redefine the widget later
-               _proto: $.extend( {}, prototype ),
-               // track widgets that inherit from this widget in case this widget is
-               // redefined after a widget inherits from it
-               _childConstructors: []
-       });
-
-       basePrototype = new base();
-       // we need to make the options hash a property directly on the new instance
-       // otherwise we'll modify the options hash on the prototype that we're
-       // inheriting from
-       basePrototype.options = $.widget.extend( {}, basePrototype.options );
-       $.each( prototype, function( prop, value ) {
-               if ( $.isFunction( value ) ) {
-                       prototype[ prop ] = (function() {
-                               var _super = function() {
-                                               return base.prototype[ prop ].apply( this, arguments );
-                                       },
-                                       _superApply = function( args ) {
-                                               return base.prototype[ prop ].apply( this, args );
-                                       };
-                               return function() {
-                                       var __super = this._super,
-                                               __superApply = this._superApply,
-                                               returnValue;
-
-                                       this._super = _super;
-                                       this._superApply = _superApply;
-
-                                       returnValue = value.apply( this, arguments );
-
-                                       this._super = __super;
-                                       this._superApply = __superApply;
-
-                                       return returnValue;
-                               };
-                       })();
-               }
-       });
-       constructor.prototype = $.widget.extend( basePrototype, {
-               // TODO: remove support for widgetEventPrefix
-               // always use the name + a colon as the prefix, e.g., draggable:start
-               // don't prefix for widgets that aren't DOM-based
-               widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
-       }, prototype, {
-               constructor: constructor,
-               namespace: namespace,
-               widgetName: name,
-               widgetFullName: fullName
-       });
-
-       // If this widget is being redefined then we need to find all widgets that
-       // are inheriting from it and redefine all of them so that they inherit from
-       // the new version of this widget. We're essentially trying to replace one
-       // level in the prototype chain.
-       if ( existingConstructor ) {
-               $.each( existingConstructor._childConstructors, function( i, child ) {
-                       var childPrototype = child.prototype;
-
-                       // redefine the child widget using the same prototype that was
-                       // originally used, but inherit from the new version of the base
-                       $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
-               });
-               // remove the list of existing child constructors from the old constructor
-               // so the old child constructors can be garbage collected
-               delete existingConstructor._childConstructors;
-       } else {
-               base._childConstructors.push( constructor );
-       }
-
-       $.widget.bridge( name, constructor );
-};
-
-$.widget.extend = function( target ) {
-       var input = slice.call( arguments, 1 ),
-               inputIndex = 0,
-               inputLength = input.length,
-               key,
-               value;
-       for ( ; inputIndex < inputLength; inputIndex++ ) {
-               for ( key in input[ inputIndex ] ) {
-                       value = input[ inputIndex ][ key ];
-                       if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
-                               // Clone objects
-                               if ( $.isPlainObject( value ) ) {
-                                       target[ key ] = $.isPlainObject( target[ key ] ) ?
-                                               $.widget.extend( {}, target[ key ], value ) :
-                                               // Don't extend strings, arrays, etc. with objects
-                                               $.widget.extend( {}, value );
-                               // Copy everything else by reference
-                               } else {
-                                       target[ key ] = value;
-                               }
-                       }
-               }
-       }
-       return target;
-};
-
-$.widget.bridge = function( name, object ) {
-       var fullName = object.prototype.widgetFullName || name;
-       $.fn[ name ] = function( options ) {
-               var isMethodCall = typeof options === "string",
-                       args = slice.call( arguments, 1 ),
-                       returnValue = this;
-
-               // allow multiple hashes to be passed on init
-               options = !isMethodCall && args.length ?
-                       $.widget.extend.apply( null, [ options ].concat(args) ) :
-                       options;
-
-               if ( isMethodCall ) {
-                       this.each(function() {
-                               var methodValue,
-                                       instance = $.data( this, fullName );
-                               if ( !instance ) {
-                                       return $.error( "cannot call methods on " + name + " prior to initialization; " +
-                                               "attempted to call method '" + options + "'" );
-                               }
-                               if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
-                                       return $.error( "no such method '" + options + "' for " + name + " widget instance" );
-                               }
-                               methodValue = instance[ options ].apply( instance, args );
-                               if ( methodValue !== instance && methodValue !== undefined ) {
-                                       returnValue = methodValue && methodValue.jquery ?
-                                               returnValue.pushStack( methodValue.get() ) :
-                                               methodValue;
-                                       return false;
-                               }
-                       });
-               } else {
-                       this.each(function() {
-                               var instance = $.data( this, fullName );
-                               if ( instance ) {
-                                       instance.option( options || {} )._init();
-                               } else {
-                                       $.data( this, fullName, new object( options, this ) );
-                               }
-                       });
-               }
-
-               return returnValue;
-       };
-};
-
-$.Widget = function( /* options, element */ ) {};
-$.Widget._childConstructors = [];
-
-$.Widget.prototype = {
-       widgetName: "widget",
-       widgetEventPrefix: "",
-       defaultElement: "<div>",
-       options: {
-               disabled: false,
-
-               // callbacks
-               create: null
-       },
-       _createWidget: function( options, element ) {
-               element = $( element || this.defaultElement || this )[ 0 ];
-               this.element = $( element );
-               this.uuid = uuid++;
-               this.eventNamespace = "." + this.widgetName + this.uuid;
-               this.options = $.widget.extend( {},
-                       this.options,
-                       this._getCreateOptions(),
-                       options );
-
-               this.bindings = $();
-               this.hoverable = $();
-               this.focusable = $();
-
-               if ( element !== this ) {
-                       $.data( element, this.widgetFullName, this );
-                       this._on( true, this.element, {
-                               remove: function( event ) {
-                                       if ( event.target === element ) {
-                                               this.destroy();
-                                       }
-                               }
-                       });
-                       this.document = $( element.style ?
-                               // element within the document
-                               element.ownerDocument :
-                               // element is window or document
-                               element.document || element );
-                       this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
-               }
-
-               this._create();
-               this._trigger( "create", null, this._getCreateEventData() );
-               this._init();
-       },
-       _getCreateOptions: $.noop,
-       _getCreateEventData: $.noop,
-       _create: $.noop,
-       _init: $.noop,
-
-       destroy: function() {
-               this._destroy();
-               // we can probably remove the unbind calls in 2.0
-               // all event bindings should go through this._on()
-               this.element
-                       .unbind( this.eventNamespace )
-                       // 1.9 BC for #7810
-                       // TODO remove dual storage
-                       .removeData( this.widgetName )
-                       .removeData( this.widgetFullName )
-                       // support: jquery <1.6.3
-                       // http://bugs.jquery.com/ticket/9413
-                       .removeData( $.camelCase( this.widgetFullName ) );
-               this.widget()
-                       .unbind( this.eventNamespace )
-                       .removeAttr( "aria-disabled" )
-                       .removeClass(
-                               this.widgetFullName + "-disabled " +
-                               "ui-state-disabled" );
-
-               // clean up events and states
-               this.bindings.unbind( this.eventNamespace );
-               this.hoverable.removeClass( "ui-state-hover" );
-               this.focusable.removeClass( "ui-state-focus" );
-       },
-       _destroy: $.noop,
-
-       widget: function() {
-               return this.element;
-       },
-
-       option: function( key, value ) {
-               var options = key,
-                       parts,
-                       curOption,
-                       i;
-
-               if ( arguments.length === 0 ) {
-                       // don't return a reference to the internal hash
-                       return $.widget.extend( {}, this.options );
-               }
-
-               if ( typeof key === "string" ) {
-                       // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
-                       options = {};
-                       parts = key.split( "." );
-                       key = parts.shift();
-                       if ( parts.length ) {
-                               curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
-                               for ( i = 0; i < parts.length - 1; i++ ) {
-                                       curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
-                                       curOption = curOption[ parts[ i ] ];
-                               }
-                               key = parts.pop();
-                               if ( value === undefined ) {
-                                       return curOption[ key ] === undefined ? null : curOption[ key ];
-                               }
-                               curOption[ key ] = value;
-                       } else {
-                               if ( value === undefined ) {
-                                       return this.options[ key ] === undefined ? null : this.options[ key ];
-                               }
-                               options[ key ] = value;
-                       }
-               }
-
-               this._setOptions( options );
-
-               return this;
-       },
-       _setOptions: function( options ) {
-               var key;
-
-               for ( key in options ) {
-                       this._setOption( key, options[ key ] );
-               }
-
-               return this;
-       },
-       _setOption: function( key, value ) {
-               this.options[ key ] = value;
-
-               if ( key === "disabled" ) {
-                       this.widget()
-                               .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
-                               .attr( "aria-disabled", value );
-                       this.hoverable.removeClass( "ui-state-hover" );
-                       this.focusable.removeClass( "ui-state-focus" );
-               }
-
-               return this;
-       },
-
-       enable: function() {
-               return this._setOption( "disabled", false );
-       },
-       disable: function() {
-               return this._setOption( "disabled", true );
-       },
-
-       _on: function( suppressDisabledCheck, element, handlers ) {
-               var delegateElement,
-                       instance = this;
-
-               // no suppressDisabledCheck flag, shuffle arguments
-               if ( typeof suppressDisabledCheck !== "boolean" ) {
-                       handlers = element;
-                       element = suppressDisabledCheck;
-                       suppressDisabledCheck = false;
-               }
-
-               // no element argument, shuffle and use this.element
-               if ( !handlers ) {
-                       handlers = element;
-                       element = this.element;
-                       delegateElement = this.widget();
-               } else {
-                       // accept selectors, DOM elements
-                       element = delegateElement = $( element );
-                       this.bindings = this.bindings.add( element );
-               }
-
-               $.each( handlers, function( event, handler ) {
-                       function handlerProxy() {
-                               // allow widgets to customize the disabled handling
-                               // - disabled as an array instead of boolean
-                               // - disabled class as method for disabling individual parts
-                               if ( !suppressDisabledCheck &&
-                                               ( instance.options.disabled === true ||
-                                                       $( this ).hasClass( "ui-state-disabled" ) ) ) {
-                                       return;
-                               }
-                               return ( typeof handler === "string" ? instance[ handler ] : handler )
-                                       .apply( instance, arguments );
-                       }
-
-                       // copy the guid so direct unbinding works
-                       if ( typeof handler !== "string" ) {
-                               handlerProxy.guid = handler.guid =
-                                       handler.guid || handlerProxy.guid || $.guid++;
-                       }
-
-                       var match = event.match( /^(\w+)\s*(.*)$/ ),
-                               eventName = match[1] + instance.eventNamespace,
-                               selector = match[2];
-                       if ( selector ) {
-                               delegateElement.delegate( selector, eventName, handlerProxy );
-                       } else {
-                               element.bind( eventName, handlerProxy );
-                       }
-               });
-       },
-
-       _off: function( element, eventName ) {
-               eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
-               element.unbind( eventName ).undelegate( eventName );
-       },
-
-       _delay: function( handler, delay ) {
-               function handlerProxy() {
-                       return ( typeof handler === "string" ? instance[ handler ] : handler )
-                               .apply( instance, arguments );
-               }
-               var instance = this;
-               return setTimeout( handlerProxy, delay || 0 );
-       },
-
-       _hoverable: function( element ) {
-               this.hoverable = this.hoverable.add( element );
-               this._on( element, {
-                       mouseenter: function( event ) {
-                               $( event.currentTarget ).addClass( "ui-state-hover" );
-                       },
-                       mouseleave: function( event ) {
-                               $( event.currentTarget ).removeClass( "ui-state-hover" );
-                       }
-               });
-       },
-
-       _focusable: function( element ) {
-               this.focusable = this.focusable.add( element );
-               this._on( element, {
-                       focusin: function( event ) {
-                               $( event.currentTarget ).addClass( "ui-state-focus" );
-                       },
-                       focusout: function( event ) {
-                               $( event.currentTarget ).removeClass( "ui-state-focus" );
-                       }
-               });
-       },
-
-       _trigger: function( type, event, data ) {
-               var prop, orig,
-                       callback = this.options[ type ];
-
-               data = data || {};
-               event = $.Event( event );
-               event.type = ( type === this.widgetEventPrefix ?
-                       type :
-                       this.widgetEventPrefix + type ).toLowerCase();
-               // the original event may come from any element
-               // so we need to reset the target on the new event
-               event.target = this.element[ 0 ];
-
-               // copy original event properties over to the new event
-               orig = event.originalEvent;
-               if ( orig ) {
-                       for ( prop in orig ) {
-                               if ( !( prop in event ) ) {
-                                       event[ prop ] = orig[ prop ];
-                               }
-                       }
-               }
-
-               this.element.trigger( event, data );
-               return !( $.isFunction( callback ) &&
-                       callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
-                       event.isDefaultPrevented() );
-       }
-};
-
-$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
-       $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
-               if ( typeof options === "string" ) {
-                       options = { effect: options };
-               }
-               var hasOptions,
-                       effectName = !options ?
-                               method :
-                               options === true || typeof options === "number" ?
-                                       defaultEffect :
-                                       options.effect || defaultEffect;
-               options = options || {};
-               if ( typeof options === "number" ) {
-                       options = { duration: options };
-               }
-               hasOptions = !$.isEmptyObject( options );
-               options.complete = callback;
-               if ( options.delay ) {
-                       element.delay( options.delay );
-               }
-               if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
-                       element[ method ]( options );
-               } else if ( effectName !== method && element[ effectName ] ) {
-                       element[ effectName ]( options.duration, options.easing, callback );
-               } else {
-                       element.queue(function( next ) {
-                               $( this )[ method ]();
-                               if ( callback ) {
-                                       callback.call( element[ 0 ] );
-                               }
-                               next();
-                       });
-               }
-       };
-});
-
-})( jQuery );
-
-(function( $, undefined ) {
-
-$.widget( "mobile.widget", {
-       // decorate the parent _createWidget to trigger `widgetinit` for users
-       // who wish to do post post `widgetcreate` alterations/additions
-       //
-       // TODO create a pull request for jquery ui to trigger this event
-       // in the original _createWidget
-       _createWidget: function() {
-               $.Widget.prototype._createWidget.apply( this, arguments );
-               this._trigger( 'init' );
-       },
-
-       _getCreateOptions: function() {
-
-               var elem = this.element,
-                       options = {};
-
-               $.each( this.options, function( option ) {
-
-                       var value = elem.jqmData( option.replace( /[A-Z]/g, function( c ) {
-                                                       return "-" + c.toLowerCase();
-                                               })
-                                       );
-
-                       if ( value !== undefined ) {
-                               options[ option ] = value;
-                       }
-               });
-
-               return options;
-       },
-
-       enhanceWithin: function( target, useKeepNative ) {
-               this.enhance( $( this.options.initSelector, $( target )), useKeepNative );
-       },
-
-       enhance: function( targets, useKeepNative ) {
-               var page, keepNative, $widgetElements = $( targets ), self = this;
-
-               // if ignoreContentEnabled is set to true the framework should
-               // only enhance the selected elements when they do NOT have a
-               // parent with the data-namespace-ignore attribute
-               $widgetElements = $.mobile.enhanceable( $widgetElements );
-
-               if ( useKeepNative && $widgetElements.length ) {
-                       // TODO remove dependency on the page widget for the keepNative.
-                       // Currently the keepNative value is defined on the page prototype so
-                       // the method is as well
-                       page = $.mobile.closestPageData( $widgetElements );
-                       keepNative = ( page && page.keepNativeSelector()) || "";
-
-                       $widgetElements = $widgetElements.not( keepNative );
-               }
-
-               $widgetElements[ this.widgetName ]();
-       },
-
-       raise: function( msg ) {
-               throw "Widget [" + this.widgetName + "]: " + msg;
-       }
-});
-
-})( jQuery );
-
-
-(function( $, window ) {
-       // DEPRECATED
-       // NOTE global mobile object settings
-       $.extend( $.mobile, {
-               // DEPRECATED Should the text be visble in the loading message?
-               loadingMessageTextVisible: undefined,
-
-               // DEPRECATED When the text is visible, what theme does the loading box use?
-               loadingMessageTheme: undefined,
-
-               // DEPRECATED default message setting
-               loadingMessage: undefined,
-
-               // DEPRECATED
-               // Turn on/off page loading message. Theme doubles as an object argument
-               // with the following shape: { theme: '', text: '', html: '', textVisible: '' }
-               // NOTE that the $.mobile.loading* settings and params past the first are deprecated
-               showPageLoadingMsg: function( theme, msgText, textonly ) {
-                       $.mobile.loading( 'show', theme, msgText, textonly );
-               },
-
-               // DEPRECATED
-               hidePageLoadingMsg: function() {
-                       $.mobile.loading( 'hide' );
-               },
-
-               loading: function() {
-                       this.loaderWidget.loader.apply( this.loaderWidget, arguments );
-               }
-       });
-
-       // TODO move loader class down into the widget settings
-       var loaderClass = "ui-loader", $html = $( "html" ), $window = $.mobile.window;
-
-       $.widget( "mobile.loader", {
-               // NOTE if the global config settings are defined they will override these
-               //      options
-               options: {
-                       // the theme for the loading message
-                       theme: "a",
-
-                       // whether the text in the loading message is shown
-                       textVisible: false,
-
-                       // custom html for the inner content of the loading message
-                       html: "",
-
-                       // the text to be displayed when the popup is shown
-                       text: "loading"
-               },
-
-               defaultHtml: "<div class='" + loaderClass + "'>" +
-                       "<span class='ui-icon ui-icon-loading'></span>" +
-                       "<h1></h1>" +
-                       "</div>",
-
-               // For non-fixed supportin browsers. Position at y center (if scrollTop supported), above the activeBtn (if defined), or just 100px from top
-               fakeFixLoader: function() {
-                       var activeBtn = $( "." + $.mobile.activeBtnClass ).first();
-
-                       this.element
-                               .css({
-                                       top: $.support.scrollTop && $window.scrollTop() + $window.height() / 2 ||
-                                               activeBtn.length && activeBtn.offset().top || 100
-                               });
-               },
-
-               // check position of loader to see if it appears to be "fixed" to center
-               // if not, use abs positioning
-               checkLoaderPosition: function() {
-                       var offset = this.element.offset(),
-                               scrollTop = $window.scrollTop(),
-                               screenHeight = $.mobile.getScreenHeight();
-
-                       if ( offset.top < scrollTop || ( offset.top - scrollTop ) > screenHeight ) {
-                               this.element.addClass( "ui-loader-fakefix" );
-                               this.fakeFixLoader();
-                               $window
-                                       .unbind( "scroll", this.checkLoaderPosition )
-                                       .bind( "scroll", $.proxy( this.fakeFixLoader, this ) );
-                       }
-               },
-
-               resetHtml: function() {
-                       this.element.html( $( this.defaultHtml ).html() );
-               },
-
-               // Turn on/off page loading message. Theme doubles as an object argument
-               // with the following shape: { theme: '', text: '', html: '', textVisible: '' }
-               // NOTE that the $.mobile.loading* settings and params past the first are deprecated
-               // TODO sweet jesus we need to break some of this out
-               show: function( theme, msgText, textonly ) {
-                       var textVisible, message, $header, loadSettings;
-
-                       this.resetHtml();
-
-                       // use the prototype options so that people can set them globally at
-                       // mobile init. Consistency, it's what's for dinner
-                       if ( $.type(theme) === "object" ) {
-                               loadSettings = $.extend( {}, this.options, theme );
-
-                               // prefer object property from the param then the old theme setting
-                               theme = loadSettings.theme || $.mobile.loadingMessageTheme;
-                       } else {
-                               loadSettings = this.options;
-
-                               // here we prefer the them value passed as a string argument, then
-                               // we prefer the global option because we can't use undefined default
-                               // prototype options, then the prototype option
-                               theme = theme || $.mobile.loadingMessageTheme || loadSettings.theme;
-                       }
-
-                       // set the message text, prefer the param, then the settings object
-                       // then loading message
-                       message = msgText || $.mobile.loadingMessage || loadSettings.text;
-
-                       // prepare the dom
-                       $html.addClass( "ui-loading" );
-
-                       if ( $.mobile.loadingMessage !== false || loadSettings.html ) {
-                               // boolean values require a bit more work :P, supports object properties
-                               // and old settings
-                               if ( $.mobile.loadingMessageTextVisible !== undefined ) {
-                                       textVisible = $.mobile.loadingMessageTextVisible;
-                               } else {
-                                       textVisible = loadSettings.textVisible;
-                               }
-
-                               // add the proper css given the options (theme, text, etc)
-                               // Force text visibility if the second argument was supplied, or
-                               // if the text was explicitly set in the object args
-                               this.element.attr("class", loaderClass +
-                                       " ui-corner-all ui-body-" + theme +
-                                       " ui-loader-" + ( textVisible || msgText || theme.text ? "verbose" : "default" ) +
-                                       ( loadSettings.textonly || textonly ? " ui-loader-textonly" : "" ) );
-
-                               // TODO verify that jquery.fn.html is ok to use in both cases here
-                               //      this might be overly defensive in preventing unknowing xss
-                               // if the html attribute is defined on the loading settings, use that
-                               // otherwise use the fallbacks from above
-                               if ( loadSettings.html ) {
-                                       this.element.html( loadSettings.html );
-                               } else {
-                                       this.element.find( "h1" ).text( message );
-                               }
-
-                               // attach the loader to the DOM
-                               this.element.appendTo( $.mobile.pageContainer );
-
-                               // check that the loader is visible
-                               this.checkLoaderPosition();
-
-                               // on scroll check the loader position
-                               $window.bind( "scroll", $.proxy( this.checkLoaderPosition, this ) );
-                       }
-               },
-
-               hide: function() {
-                       $html.removeClass( "ui-loading" );
-
-                       if ( $.mobile.loadingMessage ) {
-                               this.element.removeClass( "ui-loader-fakefix" );
-                       }
-
-                       $.mobile.window.unbind( "scroll", this.fakeFixLoader );
-                       $.mobile.window.unbind( "scroll", this.checkLoaderPosition );
-               }
-       });
-
-       $window.bind( 'pagecontainercreate', function() {
-               $.mobile.loaderWidget = $.mobile.loaderWidget || $( $.mobile.loader.prototype.defaultHtml ).loader();
-       });
-})(jQuery, this);
-
-
-// Script: jQuery hashchange event
-// 
-// *Version: 1.3, Last updated: 7/21/2010*
-// 
-// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
-// GitHub       - http://github.com/cowboy/jquery-hashchange/
-// Source       - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
-// (Minified)   - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped)
-// 
-// About: License
-// 
-// Copyright (c) 2010 "Cowboy" Ben Alman,
-// Dual licensed under the MIT and GPL licenses.
-// http://benalman.com/about/license/
-// 
-// About: Examples
-// 
-// These working examples, complete with fully commented code, illustrate a few
-// ways in which this plugin can be used.
-// 
-// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
-// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/
-// 
-// About: Support and Testing
-// 
-// Information about what version or versions of jQuery this plugin has been
-// tested with, what browsers it has been tested in, and where the unit tests
-// reside (so you can test it yourself).
-// 
-// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
-// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
-//                   Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
-// Unit Tests      - http://benalman.com/code/projects/jquery-hashchange/unit/
-// 
-// About: Known issues
-// 
-// While this jQuery hashchange event implementation is quite stable and
-// robust, there are a few unfortunate browser bugs surrounding expected
-// hashchange event-based behaviors, independent of any JavaScript
-// window.onhashchange abstraction. See the following examples for more
-// information:
-// 
-// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
-// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
-// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
-// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
-// 
-// Also note that should a browser natively support the window.onhashchange 
-// event, but not report that it does, the fallback polling loop will be used.
-// 
-// About: Release History
-// 
-// 1.3   - (7/21/2010) Reorganized IE6/7 Iframe code to make it more
-//         "removable" for mobile-only development. Added IE6/7 document.title
-//         support. Attempted to make Iframe as hidden as possible by using
-//         techniques from http://www.paciellogroup.com/blog/?p=604. Added 
-//         support for the "shortcut" format $(window).hashchange( fn ) and
-//         $(window).hashchange() like jQuery provides for built-in events.
-//         Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and
-//         lowered its default value to 50. Added <jQuery.fn.hashchange.domain>
-//         and <jQuery.fn.hashchange.src> properties plus document-domain.html
-//         file to address access denied issues when setting document.domain in
-//         IE6/7.
-// 1.2   - (2/11/2010) Fixed a bug where coming back to a page using this plugin
-//         from a page on another domain would cause an error in Safari 4. Also,
-//         IE6/7 Iframe is now inserted after the body (this actually works),
-//         which prevents the page from scrolling when the event is first bound.
-//         Event can also now be bound before DOM ready, but it won't be usable
-//         before then in IE6/7.
-// 1.1   - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
-//         where browser version is incorrectly reported as 8.0, despite
-//         inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
-// 1.0   - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
-//         window.onhashchange functionality into a separate plugin for users
-//         who want just the basic event & back button support, without all the
-//         extra awesomeness that BBQ provides. This plugin will be included as
-//         part of jQuery BBQ, but also be available separately.
-
-(function( $, window, undefined ) {
-  // Reused string.
-  var str_hashchange = 'hashchange',
-    
-    // Method / object references.
-    doc = document,
-    fake_onhashchange,
-    special = $.event.special,
-    
-    // Does the browser support window.onhashchange? Note that IE8 running in
-    // IE7 compatibility mode reports true for 'onhashchange' in window, even
-    // though the event isn't supported, so also test document.documentMode.
-    doc_mode = doc.documentMode,
-    supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );
-  
-  // Get location.hash (or what you'd expect location.hash to be) sans any
-  // leading #. Thanks for making this necessary, Firefox!
-  function get_fragment( url ) {
-    url = url || location.href;
-    return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
-  };
-  
-  // Method: jQuery.fn.hashchange
-  // 
-  // Bind a handler to the window.onhashchange event or trigger all bound
-  // window.onhashchange event handlers. This behavior is consistent with
-  // jQuery's built-in event handlers.
-  // 
-  // Usage:
-  // 
-  // > jQuery(window).hashchange( [ handler ] );
-  // 
-  // Arguments:
-  // 
-  //  handler - (Function) Optional handler to be bound to the hashchange
-  //    event. This is a "shortcut" for the more verbose form:
-  //    jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
-  //    all bound window.onhashchange event handlers will be triggered. This
-  //    is a shortcut for the more verbose
-  //    jQuery(window).trigger( 'hashchange' ). These forms are described in
-  //    the <hashchange event> section.
-  // 
-  // Returns:
-  // 
-  //  (jQuery) The initial jQuery collection of elements.
-  
-  // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and
-  // $(elem).hashchange() for triggering, like jQuery does for built-in events.
-  $.fn[ str_hashchange ] = function( fn ) {
-    return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
-  };
-  
-  // Property: jQuery.fn.hashchange.delay
-  // 
-  // The numeric interval (in milliseconds) at which the <hashchange event>
-  // polling loop executes. Defaults to 50.
-  
-  // Property: jQuery.fn.hashchange.domain
-  // 
-  // If you're setting document.domain in your JavaScript, and you want hash
-  // history to work in IE6/7, not only must this property be set, but you must
-  // also set document.domain BEFORE jQuery is loaded into the page. This
-  // property is only applicable if you are supporting IE6/7 (or IE8 operating
-  // in "IE7 compatibility" mode).
-  // 
-  // In addition, the <jQuery.fn.hashchange.src> property must be set to the
-  // path of the included "document-domain.html" file, which can be renamed or
-  // modified if necessary (note that the document.domain specified must be the
-  // same in both your main JavaScript as well as in this file).
-  // 
-  // Usage:
-  // 
-  // jQuery.fn.hashchange.domain = document.domain;
-  
-  // Property: jQuery.fn.hashchange.src
-  // 
-  // If, for some reason, you need to specify an Iframe src file (for example,
-  // when setting document.domain as in <jQuery.fn.hashchange.domain>), you can
-  // do so using this property. Note that when using this property, history
-  // won't be recorded in IE6/7 until the Iframe src file loads. This property
-  // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7
-  // compatibility" mode).
-  // 
-  // Usage:
-  // 
-  // jQuery.fn.hashchange.src = 'path/to/file.html';
-  
-  $.fn[ str_hashchange ].delay = 50;
-  /*
-  $.fn[ str_hashchange ].domain = null;
-  $.fn[ str_hashchange ].src = null;
-  */
-  
-  // Event: hashchange event
-  // 
-  // Fired when location.hash changes. In browsers that support it, the native
-  // HTML5 window.onhashchange event is used, otherwise a polling loop is
-  // initialized, running every <jQuery.fn.hashchange.delay> milliseconds to
-  // see if the hash has changed. In IE6/7 (and IE8 operating in "IE7
-  // compatibility" mode), a hidden Iframe is created to allow the back button
-  // and hash-based history to work.
-  // 
-  // Usage as described in <jQuery.fn.hashchange>:
-  // 
-  // > // Bind an event handler.
-  // > jQuery(window).hashchange( function(e) {
-  // >   var hash = location.hash;
-  // >   ...
-  // > });
-  // > 
-  // > // Manually trigger the event handler.
-  // > jQuery(window).hashchange();
-  // 
-  // A more verbose usage that allows for event namespacing:
-  // 
-  // > // Bind an event handler.
-  // > jQuery(window).bind( 'hashchange', function(e) {
-  // >   var hash = location.hash;
-  // >   ...
-  // > });
-  // > 
-  // > // Manually trigger the event handler.
-  // > jQuery(window).trigger( 'hashchange' );
-  // 
-  // Additional Notes:
-  // 
-  // * The polling loop and Iframe are not created until at least one handler
-  //   is actually bound to the 'hashchange' event.
-  // * If you need the bound handler(s) to execute immediately, in cases where
-  //   a location.hash exists on page load, via bookmark or page refresh for
-  //   example, use jQuery(window).hashchange() or the more verbose 
-  //   jQuery(window).trigger( 'hashchange' ).
-  // * The event can be bound before DOM ready, but since it won't be usable
-  //   before then in IE6/7 (due to the necessary Iframe), recommended usage is
-  //   to bind it inside a DOM ready handler.
-  
-  // Override existing $.event.special.hashchange methods (allowing this plugin
-  // to be defined after jQuery BBQ in BBQ's source code).
-  special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
-    
-    // Called only when the first 'hashchange' event is bound to window.
-    setup: function() {
-      // If window.onhashchange is supported natively, there's nothing to do..
-      if ( supports_onhashchange ) { return false; }
-      
-      // Otherwise, we need to create our own. And we don't want to call this
-      // until the user binds to the event, just in case they never do, since it
-      // will create a polling loop and possibly even a hidden Iframe.
-      $( fake_onhashchange.start );
-    },
-    
-    // Called only when the last 'hashchange' event is unbound from window.
-    teardown: function() {
-      // If window.onhashchange is supported natively, there's nothing to do..
-      if ( supports_onhashchange ) { return false; }
-      
-      // Otherwise, we need to stop ours (if possible).
-      $( fake_onhashchange.stop );
-    }
-    
-  });
-  
-  // fake_onhashchange does all the work of triggering the window.onhashchange
-  // event for browsers that don't natively support it, including creating a
-  // polling loop to watch for hash changes and in IE 6/7 creating a hidden
-  // Iframe to enable back and forward.
-  fake_onhashchange = (function() {
-    var self = {},
-      timeout_id,
-      
-      // Remember the initial hash so it doesn't get triggered immediately.
-      last_hash = get_fragment(),
-      
-      fn_retval = function( val ) { return val; },
-      history_set = fn_retval,
-      history_get = fn_retval;
-    
-    // Start the polling loop.
-    self.start = function() {
-      timeout_id || poll();
-    };
-    
-    // Stop the polling loop.
-    self.stop = function() {
-      timeout_id && clearTimeout( timeout_id );
-      timeout_id = undefined;
-    };
-    
-    // This polling loop checks every $.fn.hashchange.delay milliseconds to see
-    // if location.hash has changed, and triggers the 'hashchange' event on
-    // window when necessary.
-    function poll() {
-      var hash = get_fragment(),
-        history_hash = history_get( last_hash );
-      
-      if ( hash !== last_hash ) {
-        history_set( last_hash = hash, history_hash );
-        
-        $(window).trigger( str_hashchange );
-        
-      } else if ( history_hash !== last_hash ) {
-        location.href = location.href.replace( /#.*/, '' ) + history_hash;
-      }
-      
-      timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
-    };
-    
-    // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
-    // vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv
-    // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
-    window.attachEvent && !window.addEventListener && !supports_onhashchange && (function() {
-      // Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8
-      // when running in "IE7 compatibility" mode.
-      
-      var iframe,
-        iframe_src;
-      
-      // When the event is bound and polling starts in IE 6/7, create a hidden
-      // Iframe for history handling.
-      self.start = function() {
-        if ( !iframe ) {
-          iframe_src = $.fn[ str_hashchange ].src;
-          iframe_src = iframe_src && iframe_src + get_fragment();
-          
-          // Create hidden Iframe. Attempt to make Iframe as hidden as possible
-          // by using techniques from http://www.paciellogroup.com/blog/?p=604.
-          iframe = $('<iframe tabindex="-1" title="empty"/>').hide()
-            
-            // When Iframe has completely loaded, initialize the history and
-            // start polling.
-            .one( 'load', function() {
-              iframe_src || history_set( get_fragment() );
-              poll();
-            })
-            
-            // Load Iframe src if specified, otherwise nothing.
-            .attr( 'src', iframe_src || 'javascript:0' )
-            
-            // Append Iframe after the end of the body to prevent unnecessary
-            // initial page scrolling (yes, this works).
-            .insertAfter( 'body' )[0].contentWindow;
-          
-          // Whenever `document.title` changes, update the Iframe's title to
-          // prettify the back/next history menu entries. Since IE sometimes
-          // errors with "Unspecified error" the very first time this is set
-          // (yes, very useful) wrap this with a try/catch block.
-          doc.onpropertychange = function() {
-            try {
-              if ( event.propertyName === 'title' ) {
-                iframe.document.title = doc.title;
-              }
-            } catch(e) {}
-          };
-          
-        }
-      };
-      
-      // Override the "stop" method since an IE6/7 Iframe was created. Even
-      // if there are no longer any bound event handlers, the polling loop
-      // is still necessary for back/next to work at all!
-      self.stop = fn_retval;
-      
-      // Get history by looking at the hidden Iframe's location.hash.
-      history_get = function() {
-        return get_fragment( iframe.location.href );
-      };
-      
-      // Set a new history item by opening and then closing the Iframe
-      // document, *then* setting its location.hash. If document.domain has
-      // been set, update that as well.
-      history_set = function( hash, history_hash ) {
-        var iframe_doc = iframe.document,
-          domain = $.fn[ str_hashchange ].domain;
-        
-        if ( hash !== history_hash ) {
-          // Update Iframe with any initial `document.title` that might be set.
-          iframe_doc.title = doc.title;
-          
-          // Opening the Iframe's document after it has been closed is what
-          // actually adds a history entry.
-          iframe_doc.open();
-          
-          // Set document.domain for the Iframe document as well, if necessary.
-          domain && iframe_doc.write( '<script>document.domain="' + domain + '"</script>' );
-          
-          iframe_doc.close();
-          
-          // Update the Iframe's hash, for great justice.
-          iframe.location.hash = hash;
-        }
-      };
-      
-    })();
-    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-    // ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^
-    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-    
-    return self;
-  })();
-  
-})(jQuery,this);
-
-(function( $, undefined ) {
-
-       /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
-       window.matchMedia = window.matchMedia || (function( doc, undefined ) {
-
-               
-
-               var bool,
-                       docElem = doc.documentElement,
-                       refNode = docElem.firstElementChild || docElem.firstChild,
-                       // fakeBody required for <FF4 when executed in <head>
-                       fakeBody = doc.createElement( "body" ),
-                       div = doc.createElement( "div" );
-
-               div.id = "mq-test-1";
-               div.style.cssText = "position:absolute;top:-100em";
-               fakeBody.style.background = "none";
-               fakeBody.appendChild(div);
-
-               return function(q){
-
-                       div.innerHTML = "&shy;<style media=\"" + q + "\"> #mq-test-1 { width: 42px; }</style>";
-
-                       docElem.insertBefore( fakeBody, refNode );
-                       bool = div.offsetWidth === 42;
-                       docElem.removeChild( fakeBody );
-
-                       return {
-                               matches: bool,
-                               media: q
-                       };
-
-               };
-
-       }( document ));
-
-       // $.mobile.media uses matchMedia to return a boolean.
-       $.mobile.media = function( q ) {
-               return window.matchMedia( q ).matches;
-       };
-
-})(jQuery);
-
-       (function( $, undefined ) {
-               var support = {
-                       touch: "ontouchend" in document
-               };
-
-               $.mobile.support = $.mobile.support || {};
-               $.extend( $.support, support );
-               $.extend( $.mobile.support, support );
-       }( jQuery ));
-
-       (function( $, undefined ) {
-               $.extend( $.support, {
-                       orientation: "orientation" in window && "onorientationchange" in window
-               });
-       }( jQuery ));
-
-(function( $, undefined ) {
-
-// thx Modernizr
-function propExists( prop ) {
-       var uc_prop = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ),
-               props = ( prop + " " + vendors.join( uc_prop + " " ) + uc_prop ).split( " " );
-
-       for ( var v in props ) {
-               if ( fbCSS[ props[ v ] ] !== undefined ) {
-                       return true;
-               }
-       }
-}
-
-var fakeBody = $( "<body>" ).prependTo( "html" ),
-       fbCSS = fakeBody[ 0 ].style,
-       vendors = [ "Webkit", "Moz", "O" ],
-       webos = "palmGetResource" in window, //only used to rule out scrollTop
-       opera = window.opera,
-       operamini = window.operamini && ({}).toString.call( window.operamini ) === "[object OperaMini]",
-       bb = window.blackberry && !propExists( "-webkit-transform" ); //only used to rule out box shadow, as it's filled opaque on BB 5 and lower
-
-
-function validStyle( prop, value, check_vend ) {
-       var div = document.createElement( 'div' ),
-               uc = function( txt ) {
-                       return txt.charAt( 0 ).toUpperCase() + txt.substr( 1 );
-               },
-               vend_pref = function( vend ) {
-                       if( vend === "" ) {
-                               return "";
-                       } else {
-                               return  "-" + vend.charAt( 0 ).toLowerCase() + vend.substr( 1 ) + "-";
-                       }
-               },
-               check_style = function( vend ) {
-                       var vend_prop = vend_pref( vend ) + prop + ": " + value + ";",
-                               uc_vend = uc( vend ),
-                               propStyle = uc_vend + ( uc_vend === "" ? prop : uc( prop ) );
-
-                       div.setAttribute( "style", vend_prop );
-
-                       if ( !!div.style[ propStyle ] ) {
-                               ret = true;
-                       }
-               },
-               check_vends = check_vend ? check_vend : vendors,
-               ret;
-
-       for( var i = 0; i < check_vends.length; i++ ) {
-               check_style( check_vends[i] );
-       }
-       return !!ret;
-}
-
-function transform3dTest() {
-       var mqProp = "transform-3d",
-               // Because the `translate3d` test below throws false positives in Android:
-               ret = $.mobile.media( "(-" + vendors.join( "-" + mqProp + "),(-" ) + "-" + mqProp + "),(" + mqProp + ")" );
-
-       if( ret ) {
-               return !!ret;
-       }
-
-       var el = document.createElement( "div" ),
-               transforms = {
-                       // We’re omitting Opera for the time being; MS uses unprefixed.
-                       'MozTransform':'-moz-transform',
-                       'transform':'transform'
-               };
-
-       fakeBody.append( el );
-
-       for ( var t in transforms ) {
-               if( el.style[ t ] !== undefined ){
-                       el.style[ t ] = 'translate3d( 100px, 1px, 1px )';
-                       ret = window.getComputedStyle( el ).getPropertyValue( transforms[ t ] );
-               }
-       }
-       return ( !!ret && ret !== "none" );
-}
-
-// Test for dynamic-updating base tag support ( allows us to avoid href,src attr rewriting )
-function baseTagTest() {
-       var fauxBase = location.protocol + "//" + location.host + location.pathname + "ui-dir/",
-               base = $( "head base" ),
-               fauxEle = null,
-               href = "",
-               link, rebase;
-
-       if ( !base.length ) {
-               base = fauxEle = $( "<base>", { "href": fauxBase }).appendTo( "head" );
-       } else {
-               href = base.attr( "href" );
-       }
-
-       link = $( "<a href='testurl' />" ).prependTo( fakeBody );
-       rebase = link[ 0 ].href;
-       base[ 0 ].href = href || location.pathname;
-
-       if ( fauxEle ) {
-               fauxEle.remove();
-       }
-       return rebase.indexOf( fauxBase ) === 0;
-}
-
-// Thanks Modernizr
-function cssPointerEventsTest() {
-       var element = document.createElement( 'x' ),
-               documentElement = document.documentElement,
-               getComputedStyle = window.getComputedStyle,
-               supports;
-
-       if ( !( 'pointerEvents' in element.style ) ) {
-               return false;
-       }
-
-       element.style.pointerEvents = 'auto';
-       element.style.pointerEvents = 'x';
-       documentElement.appendChild( element );
-       supports = getComputedStyle &&
-       getComputedStyle( element, '' ).pointerEvents === 'auto';
-       documentElement.removeChild( element );
-       return !!supports;
-}
-
-function boundingRect() {
-       var div = document.createElement( "div" );
-       return typeof div.getBoundingClientRect !== "undefined";
-}
-
-// non-UA-based IE version check by James Padolsey, modified by jdalton - from http://gist.github.com/527683
-// allows for inclusion of IE 6+, including Windows Mobile 7
-$.extend( $.mobile, { browser: {} } );
-$.mobile.browser.oldIE = (function() {
-       var v = 3,
-               div = document.createElement( "div" ),
-               a = div.all || [];
-
-       do {
-               div.innerHTML = "<!--[if gt IE " + ( ++v ) + "]><br><![endif]-->";
-       } while( a[0] );
-
-       return v > 4 ? v : !v;
-})();
-
-function fixedPosition() {
-       var w = window,
-               ua = navigator.userAgent,
-               platform = navigator.platform,
-               // Rendering engine is Webkit, and capture major version
-               wkmatch = ua.match( /AppleWebKit\/([0-9]+)/ ),
-               wkversion = !!wkmatch && wkmatch[ 1 ],
-               ffmatch = ua.match( /Fennec\/([0-9]+)/ ),
-               ffversion = !!ffmatch && ffmatch[ 1 ],
-               operammobilematch = ua.match( /Opera Mobi\/([0-9]+)/ ),
-               omversion = !!operammobilematch && operammobilematch[ 1 ];
-
-       if(
-               // iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5)
-               ( ( platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1  || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534 ) ||
-               // Opera Mini
-               ( w.operamini && ({}).toString.call( w.operamini ) === "[object OperaMini]" ) ||
-               ( operammobilematch && omversion < 7458 )       ||
-               //Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2)
-               ( ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533 ) ||
-               // Firefox Mobile before 6.0 -
-               ( ffversion && ffversion < 6 ) ||
-               // WebOS less than 3
-               ( "palmGetResource" in window && wkversion && wkversion < 534 ) ||
-               // MeeGo
-               ( ua.indexOf( "MeeGo" ) > -1 && ua.indexOf( "NokiaBrowser/8.5.0" ) > -1 ) ) {
-               return false;
-       }
-
-       return true;
-}
-
-$.extend( $.support, {
-       cssTransitions: "WebKitTransitionEvent" in window ||
-               validStyle( 'transition', 'height 100ms linear', [ "Webkit", "Moz", "" ] ) &&
-               !$.mobile.browser.oldIE && !opera,
-
-       // Note, Chrome for iOS has an extremely quirky implementation of popstate.
-       // We've chosen to take the shortest path to a bug fix here for issue #5426
-       // See the following link for information about the regex chosen
-       // https://developers.google.com/chrome/mobile/docs/user-agent#chrome_for_ios_user-agent
-       pushState: "pushState" in history &&
-               "replaceState" in history &&
-               // When running inside a FF iframe, calling replaceState causes an error
-               !( window.navigator.userAgent.indexOf( "Firefox" ) >= 0 && window.top !== window ) &&
-               ( window.navigator.userAgent.search(/CriOS/) === -1 ),
-
-       mediaquery: $.mobile.media( "only all" ),
-       cssPseudoElement: !!propExists( "content" ),
-       touchOverflow: !!propExists( "overflowScrolling" ),
-       cssTransform3d: transform3dTest(),
-       boxShadow: !!propExists( "boxShadow" ) && !bb,
-       fixedPosition: fixedPosition(),
-       scrollTop: ("pageXOffset" in window ||
-               "scrollTop" in document.documentElement ||
-               "scrollTop" in fakeBody[ 0 ]) && !webos && !operamini,
-
-       dynamicBaseTag: baseTagTest(),
-       cssPointerEvents: cssPointerEventsTest(),
-       boundingRect: boundingRect()
-});
-
-fakeBody.remove();
-
-
-// $.mobile.ajaxBlacklist is used to override ajaxEnabled on platforms that have known conflicts with hash history updates (BB5, Symbian)
-// or that generally work better browsing in regular http for full page refreshes (Opera Mini)
-// Note: This detection below is used as a last resort.
-// We recommend only using these detection methods when all other more reliable/forward-looking approaches are not possible
-var nokiaLTE7_3 = (function() {
-
-       var ua = window.navigator.userAgent;
-
-       //The following is an attempt to match Nokia browsers that are running Symbian/s60, with webkit, version 7.3 or older
-       return ua.indexOf( "Nokia" ) > -1 &&
-                       ( ua.indexOf( "Symbian/3" ) > -1 || ua.indexOf( "Series60/5" ) > -1 ) &&
-                       ua.indexOf( "AppleWebKit" ) > -1 &&
-                       ua.match( /(BrowserNG|NokiaBrowser)\/7\.[0-3]/ );
-})();
-
-// Support conditions that must be met in order to proceed
-// default enhanced qualifications are media query support OR IE 7+
-
-$.mobile.gradeA = function() {
-       return ( $.support.mediaquery || $.mobile.browser.oldIE && $.mobile.browser.oldIE >= 7 ) && ( $.support.boundingRect || $.fn.jquery.match(/1\.[0-7+]\.[0-9+]?/) !== null );
-};
-
-$.mobile.ajaxBlacklist =
-                       // BlackBerry browsers, pre-webkit
-                       window.blackberry && !window.WebKitPoint ||
-                       // Opera Mini
-                       operamini ||
-                       // Symbian webkits pre 7.3
-                       nokiaLTE7_3;
-
-// Lastly, this workaround is the only way we've found so far to get pre 7.3 Symbian webkit devices
-// to render the stylesheets when they're referenced before this script, as we'd recommend doing.
-// This simply reappends the CSS in place, which for some reason makes it apply
-if ( nokiaLTE7_3 ) {
-       $(function() {
-               $( "head link[rel='stylesheet']" ).attr( "rel", "alternate stylesheet" ).attr( "rel", "stylesheet" );
-       });
-}
-
-// For ruling out shadows via css
-if ( !$.support.boxShadow ) {
-       $( "html" ).addClass( "ui-mobile-nosupport-boxshadow" );
-}
-
-})( jQuery );
-
-
-(function( $, undefined ) {
-       var $win = $.mobile.window, self, history;
-
-       $.event.special.navigate = self = {
-               bound: false,
-
-               pushStateEnabled: true,
-
-               originalEventName: undefined,
-
-               // If pushstate support is present and push state support is defined to
-               // be true on the mobile namespace.
-               isPushStateEnabled: function() {
-                       return $.support.pushState &&
-                               $.mobile.pushStateEnabled === true &&
-                               this.isHashChangeEnabled();
-               },
-
-               // !! assumes mobile namespace is present
-               isHashChangeEnabled: function() {
-                       return $.mobile.hashListeningEnabled === true;
-               },
-
-               // TODO a lot of duplication between popstate and hashchange
-               popstate: function( event ) {
-                       var newEvent = new $.Event( "navigate" ),
-                               beforeNavigate = new $.Event( "beforenavigate" ),
-                               state = event.originalEvent.state || {},
-                               href = location.href;
-
-                       $win.trigger( beforeNavigate );
-
-                       if( beforeNavigate.isDefaultPrevented() ){
-                               return;
-                       }
-
-                       if( event.historyState ){
-                               $.extend(state, event.historyState);
-                       }
-
-                       // Make sure the original event is tracked for the end
-                       // user to inspect incase they want to do something special
-                       newEvent.originalEvent = event;
-
-                       // NOTE we let the current stack unwind because any assignment to
-                       //      location.hash will stop the world and run this event handler. By
-                       //      doing this we create a similar behavior to hashchange on hash
-                       //      assignment
-                       setTimeout(function() {
-                               $win.trigger( newEvent, {
-                                       state: state
-                               });
-                       }, 0);
-               },
-
-               hashchange: function( event, data ) {
-                       var newEvent = new $.Event( "navigate" ),
-                               beforeNavigate = new $.Event( "beforenavigate" );
-
-                       $win.trigger( beforeNavigate );
-
-                       if( beforeNavigate.isDefaultPrevented() ){
-                               return;
-                       }
-
-                       // Make sure the original event is tracked for the end
-                       // user to inspect incase they want to do something special
-                       newEvent.originalEvent = event;
-
-                       // Trigger the hashchange with state provided by the user
-                       // that altered the hash
-                       $win.trigger( newEvent, {
-                               // Users that want to fully normalize the two events
-                               // will need to do history management down the stack and
-                               // add the state to the event before this binding is fired
-                               // TODO consider allowing for the explicit addition of callbacks
-                               //      to be fired before this value is set to avoid event timing issues
-                               state: event.hashchangeState || {}
-                       });
-               },
-
-               // TODO We really only want to set this up once
-               //      but I'm not clear if there's a beter way to achieve
-               //      this with the jQuery special event structure
-               setup: function( data, namespaces ) {
-                       if( self.bound ) {
-                               return;
-                       }
-
-                       self.bound = true;
-
-                       if( self.isPushStateEnabled() ) {
-                               self.originalEventName = "popstate";
-                               $win.bind( "popstate.navigate", self.popstate );
-                       } else if ( self.isHashChangeEnabled() ){
-                               self.originalEventName = "hashchange";
-                               $win.bind( "hashchange.navigate", self.hashchange );
-                       }
-               }
-       };
-})( jQuery );
-
-
-
-(function( $, undefined ) {
-               var path, documentBase, $base, dialogHashKey = "&ui-state=dialog";
-
-               $.mobile.path = path = {
-                       uiStateKey: "&ui-state",
-
-                       // This scary looking regular expression parses an absolute URL or its relative
-                       // variants (protocol, site, document, query, and hash), into the various
-                       // components (protocol, host, path, query, fragment, etc that make up the
-                       // URL as well as some other commonly used sub-parts. When used with RegExp.exec()
-                       // or String.match, it parses the URL into a results array that looks like this:
-                       //
-                       //     [0]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content
-                       //     [1]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread
-                       //     [2]: http://jblas:password@mycompany.com:8080/mail/inbox
-                       //     [3]: http://jblas:password@mycompany.com:8080
-                       //     [4]: http:
-                       //     [5]: //
-                       //     [6]: jblas:password@mycompany.com:8080
-                       //     [7]: jblas:password
-                       //     [8]: jblas
-                       //     [9]: password
-                       //    [10]: mycompany.com:8080
-                       //    [11]: mycompany.com
-                       //    [12]: 8080
-                       //    [13]: /mail/inbox
-                       //    [14]: /mail/
-                       //    [15]: inbox
-                       //    [16]: ?msg=1234&type=unread
-                       //    [17]: #msg-content
-                       //
-                       urlParseRE: /^\s*(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,
-
-                       // Abstraction to address xss (Issue #4787) by removing the authority in
-                       // browsers that auto   decode it. All references to location.href should be
-                       // replaced with a call to this method so that it can be dealt with properly here
-                       getLocation: function( url ) {
-                               var uri = url ? this.parseUrl( url ) : location,
-                                       hash = this.parseUrl( url || location.href ).hash;
-
-                               // mimic the browser with an empty string when the hash is empty
-                               hash = hash === "#" ? "" : hash;
-
-                               // Make sure to parse the url or the location object for the hash because using location.hash
-                               // is autodecoded in firefox, the rest of the url should be from the object (location unless
-                               // we're testing) to avoid the inclusion of the authority
-                               return uri.protocol + "//" + uri.host + uri.pathname + uri.search + hash;
-                       },
-
-                       parseLocation: function() {
-                               return this.parseUrl( this.getLocation() );
-                       },
-
-                       //Parse a URL into a structure that allows easy access to
-                       //all of the URL components by name.
-                       parseUrl: function( url ) {
-                               // If we're passed an object, we'll assume that it is
-                               // a parsed url object and just return it back to the caller.
-                               if ( $.type( url ) === "object" ) {
-                                       return url;
-                               }
-
-                               var matches = path.urlParseRE.exec( url || "" ) || [];
-
-                                       // Create an object that allows the caller to access the sub-matches
-                                       // by name. Note that IE returns an empty string instead of undefined,
-                                       // like all other browsers do, so we normalize everything so its consistent
-                                       // no matter what browser we're running on.
-                                       return {
-                                               href:         matches[  0 ] || "",
-                                               hrefNoHash:   matches[  1 ] || "",
-                                               hrefNoSearch: matches[  2 ] || "",
-                                               domain:       matches[  3 ] || "",
-                                               protocol:     matches[  4 ] || "",
-                                               doubleSlash:  matches[  5 ] || "",
-                                               authority:    matches[  6 ] || "",
-                                               username:     matches[  8 ] || "",
-                                               password:     matches[  9 ] || "",
-                                               host:         matches[ 10 ] || "",
-                                               hostname:     matches[ 11 ] || "",
-                                               port:         matches[ 12 ] || "",
-                                               pathname:     matches[ 13 ] || "",
-                                               directory:    matches[ 14 ] || "",
-                                               filename:     matches[ 15 ] || "",
-                                               search:       matches[ 16 ] || "",
-                                               hash:         matches[ 17 ] || ""
-                                       };
-                       },
-
-                       //Turn relPath into an asbolute path. absPath is
-                       //an optional absolute path which describes what
-                       //relPath is relative to.
-                       makePathAbsolute: function( relPath, absPath ) {
-                               if ( relPath && relPath.charAt( 0 ) === "/" ) {
-                                       return relPath;
-                               }
-
-                               relPath = relPath || "";
-                               absPath = absPath ? absPath.replace( /^\/|(\/[^\/]*|[^\/]+)$/g, "" ) : "";
-
-                               var absStack = absPath ? absPath.split( "/" ) : [],
-                                       relStack = relPath.split( "/" );
-                               for ( var i = 0; i < relStack.length; i++ ) {
-                                       var d = relStack[ i ];
-                                       switch ( d ) {
-                                               case ".":
-                                                       break;
-                                               case "..":
-                                                       if ( absStack.length ) {
-                                                               absStack.pop();
-                                                       }
-                                                       break;
-                                               default:
-                                                       absStack.push( d );
-                                                       break;
-                                       }
-                               }
-                               return "/" + absStack.join( "/" );
-                       },
-
-                       //Returns true if both urls have the same domain.
-                       isSameDomain: function( absUrl1, absUrl2 ) {
-                               return path.parseUrl( absUrl1 ).domain === path.parseUrl( absUrl2 ).domain;
-                       },
-
-                       //Returns true for any relative variant.
-                       isRelativeUrl: function( url ) {
-                               // All relative Url variants have one thing in common, no protocol.
-                               return path.parseUrl( url ).protocol === "";
-                       },
-
-                       //Returns true for an absolute url.
-                       isAbsoluteUrl: function( url ) {
-                               return path.parseUrl( url ).protocol !== "";
-                       },
-
-                       //Turn the specified realtive URL into an absolute one. This function
-                       //can handle all relative variants (protocol, site, document, query, fragment).
-                       makeUrlAbsolute: function( relUrl, absUrl ) {
-                               if ( !path.isRelativeUrl( relUrl ) ) {
-                                       return relUrl;
-                               }
-
-                               if ( absUrl === undefined ) {
-                                       absUrl = this.documentBase;
-                               }
-
-                               var relObj = path.parseUrl( relUrl ),
-                                       absObj = path.parseUrl( absUrl ),
-                                       protocol = relObj.protocol || absObj.protocol,
-                                       doubleSlash = relObj.protocol ? relObj.doubleSlash : ( relObj.doubleSlash || absObj.doubleSlash ),
-                                       authority = relObj.authority || absObj.authority,
-                                       hasPath = relObj.pathname !== "",
-                                       pathname = path.makePathAbsolute( relObj.pathname || absObj.filename, absObj.pathname ),
-                                       search = relObj.search || ( !hasPath && absObj.search ) || "",
-                                       hash = relObj.hash;
-
-                               return protocol + doubleSlash + authority + pathname + search + hash;
-                       },
-
-                       //Add search (aka query) params to the specified url.
-                       addSearchParams: function( url, params ) {
-                               var u = path.parseUrl( url ),
-                                       p = ( typeof params === "object" ) ? $.param( params ) : params,
-                                       s = u.search || "?";
-                               return u.hrefNoSearch + s + ( s.charAt( s.length - 1 ) !== "?" ? "&" : "" ) + p + ( u.hash || "" );
-                       },
-
-                       convertUrlToDataUrl: function( absUrl ) {
-                               var u = path.parseUrl( absUrl );
-                               if ( path.isEmbeddedPage( u ) ) {
-                                       // For embedded pages, remove the dialog hash key as in getFilePath(),
-                                       // and remove otherwise the Data Url won't match the id of the embedded Page.
-                                       return u.hash
-                                               .split( dialogHashKey )[0]
-                                               .replace( /^#/, "" )
-                                               .replace( /\?.*$/, "" );
-                               } else if ( path.isSameDomain( u, this.documentBase ) ) {
-                                       return u.hrefNoHash.replace( this.documentBase.domain, "" ).split( dialogHashKey )[0];
-                               }
-
-                               return window.decodeURIComponent(absUrl);
-                       },
-
-                       //get path from current hash, or from a file path
-                       get: function( newPath ) {
-                               if ( newPath === undefined ) {
-                                       newPath = path.parseLocation().hash;
-                               }
-                               return path.stripHash( newPath ).replace( /[^\/]*\.[^\/*]+$/, '' );
-                       },
-
-                       //set location hash to path
-                       set: function( path ) {
-                               location.hash = path;
-                       },
-
-                       //test if a given url (string) is a path
-                       //NOTE might be exceptionally naive
-                       isPath: function( url ) {
-                               return ( /\// ).test( url );
-                       },
-
-                       //return a url path with the window's location protocol/hostname/pathname removed
-                       clean: function( url ) {
-                               return url.replace( this.documentBase.domain, "" );
-                       },
-
-                       //just return the url without an initial #
-                       stripHash: function( url ) {
-                               return url.replace( /^#/, "" );
-                       },
-
-                       stripQueryParams: function( url ) {
-                               return url.replace( /\?.*$/, "" );
-                       },
-
-                       //remove the preceding hash, any query params, and dialog notations
-                       cleanHash: function( hash ) {
-                               return path.stripHash( hash.replace( /\?.*$/, "" ).replace( dialogHashKey, "" ) );
-                       },
-
-                       isHashValid: function( hash ) {
-                               return ( /^#[^#]+$/ ).test( hash );
-                       },
-
-                       //check whether a url is referencing the same domain, or an external domain or different protocol
-                       //could be mailto, etc
-                       isExternal: function( url ) {
-                               var u = path.parseUrl( url );
-                               return u.protocol && u.domain !== this.documentUrl.domain ? true : false;
-                       },
-
-                       hasProtocol: function( url ) {
-                               return ( /^(:?\w+:)/ ).test( url );
-                       },
-
-                       isEmbeddedPage: function( url ) {
-                               var u = path.parseUrl( url );
-
-                               //if the path is absolute, then we need to compare the url against
-                               //both the this.documentUrl and the documentBase. The main reason for this
-                               //is that links embedded within external documents will refer to the
-                               //application document, whereas links embedded within the application
-                               //document will be resolved against the document base.
-                               if ( u.protocol !== "" ) {
-                                       return ( !this.isPath(u.hash) && u.hash && ( u.hrefNoHash === this.documentUrl.hrefNoHash || ( this.documentBaseDiffers && u.hrefNoHash === this.documentBase.hrefNoHash ) ) );
-                               }
-                               return ( /^#/ ).test( u.href );
-                       },
-
-                       squash: function( url, resolutionUrl ) {
-                               var state, href, cleanedUrl, search, stateIndex,
-                                       isPath = this.isPath( url ),
-                                       uri = this.parseUrl( url ),
-                                       preservedHash = uri.hash,
-                                       uiState = "";
-
-                               // produce a url against which we can resole the provided path
-                               resolutionUrl = resolutionUrl || (path.isPath(url) ? path.getLocation() : path.getDocumentUrl());
-
-                               // If the url is anything but a simple string, remove any preceding hash
-                               // eg #foo/bar -> foo/bar
-                               //    #foo -> #foo
-                               cleanedUrl = isPath ? path.stripHash( url ) : url;
-
-                               // If the url is a full url with a hash check if the parsed hash is a path
-                               // if it is, strip the #, and use it otherwise continue without change
-                               cleanedUrl = path.isPath( uri.hash ) ? path.stripHash( uri.hash ) : cleanedUrl;
-
-                               // Split the UI State keys off the href
-                               stateIndex = cleanedUrl.indexOf( this.uiStateKey );
-
-                               // store the ui state keys for use
-                               if( stateIndex > -1 ){
-                                       uiState = cleanedUrl.slice( stateIndex );
-                                       cleanedUrl = cleanedUrl.slice( 0, stateIndex );
-                               }
-
-                               // make the cleanedUrl absolute relative to the resolution url
-                               href = path.makeUrlAbsolute( cleanedUrl, resolutionUrl );
-
-                               // grab the search from the resolved url since parsing from
-                               // the passed url may not yield the correct result
-                               search = this.parseUrl( href ).search;
-
-                               // TODO all this crap is terrible, clean it up
-                               if ( isPath ) {
-                                       // reject the hash if it's a path or it's just a dialog key
-                                       if( path.isPath( preservedHash ) || preservedHash.replace("#", "").indexOf( this.uiStateKey ) === 0) {
-                                               preservedHash = "";
-                                       }
-
-                                       // Append the UI State keys where it exists and it's been removed
-                                       // from the url
-                                       if( uiState && preservedHash.indexOf( this.uiStateKey ) === -1){
-                                               preservedHash += uiState;
-                                       }
-
-                                       // make sure that pound is on the front of the hash
-                                       if( preservedHash.indexOf( "#" ) === -1 && preservedHash !== "" ){
-                                               preservedHash = "#" + preservedHash;
-                                       }
-
-                                       // reconstruct each of the pieces with the new search string and hash
-                                       href = path.parseUrl( href );
-                                       href = href.protocol + "//" + href.host + href.pathname + search + preservedHash;
-                               } else {
-                                       href += href.indexOf( "#" ) > -1 ? uiState : "#" + uiState;
-                               }
-
-                               return href;
-                       },
-
-                       isPreservableHash: function( hash ) {
-                               return hash.replace( "#", "" ).indexOf( this.uiStateKey ) === 0;
-                       }
-               };
-
-               path.documentUrl = path.parseLocation();
-
-               $base = $( "head" ).find( "base" );
-
-               path.documentBase = $base.length ?
-                       path.parseUrl( path.makeUrlAbsolute( $base.attr( "href" ), path.documentUrl.href ) ) :
-                       path.documentUrl;
-
-               path.documentBaseDiffers = (path.documentUrl.hrefNoHash !== path.documentBase.hrefNoHash);
-
-               //return the original document url
-               path.getDocumentUrl = function( asParsedObject ) {
-                       return asParsedObject ? $.extend( {}, path.documentUrl ) : path.documentUrl.href;
-               };
-
-               //return the original document base url
-               path.getDocumentBase = function( asParsedObject ) {
-                       return asParsedObject ? $.extend( {}, path.documentBase ) : path.documentBase.href;
-               };
-})( jQuery );
-
-
-
-(function( $, undefined ) {
-       var path = $.mobile.path;
-
-       $.mobile.History = function( stack, index ) {
-               this.stack = stack || [];
-               this.activeIndex = index || 0;
-       };
-
-       $.extend($.mobile.History.prototype, {
-               getActive: function() {
-                       return this.stack[ this.activeIndex ];
-               },
-
-               getLast: function() {
-                       return this.stack[ this.previousIndex ];
-               },
-
-               getNext: function() {
-                       return this.stack[ this.activeIndex + 1 ];
-               },
-
-               getPrev: function() {
-                       return this.stack[ this.activeIndex - 1 ];
-               },
-
-               // addNew is used whenever a new page is added
-               add: function( url, data ){
-                       data = data || {};
-
-                       //if there's forward history, wipe it
-                       if ( this.getNext() ) {
-                               this.clearForward();
-                       }
-
-                       // if the hash is included in the data make sure the shape
-                       // is consistent for comparison
-                       if( data.hash && data.hash.indexOf( "#" ) === -1) {
-                               data.hash = "#" + data.hash;
-                       }
-
-                       data.url = url;
-                       this.stack.push( data );
-                       this.activeIndex = this.stack.length - 1;
-               },
-
-               //wipe urls ahead of active index
-               clearForward: function() {
-                       this.stack = this.stack.slice( 0, this.activeIndex + 1 );
-               },
-
-               find: function( url, stack, earlyReturn ) {
-                       stack = stack || this.stack;
-
-                       var entry, i, length = stack.length, index;
-
-                       for ( i = 0; i < length; i++ ) {
-                               entry = stack[i];
-
-                               if ( decodeURIComponent(url) === decodeURIComponent(entry.url) ||
-                                       decodeURIComponent(url) === decodeURIComponent(entry.hash) ) {
-                                       index = i;
-
-                                       if( earlyReturn ) {
-                                               return index;
-                                       }
-                               }
-                       }
-
-                       return index;
-               },
-
-               closest: function( url ) {
-                       var closest, a = this.activeIndex;
-
-                       // First, take the slice of the history stack before the current index and search
-                       // for a url match. If one is found, we'll avoid avoid looking through forward history
-                       // NOTE the preference for backward history movement is driven by the fact that
-                       //      most mobile browsers only have a dedicated back button, and users rarely use
-                       //      the forward button in desktop browser anyhow
-                       closest = this.find( url, this.stack.slice(0, a) );
-
-                       // If nothing was found in backward history check forward. The `true`
-                       // value passed as the third parameter causes the find method to break
-                       // on the first match in the forward history slice. The starting index
-                       // of the slice must then be added to the result to get the element index
-                       // in the original history stack :( :(
-                       //
-                       // TODO this is hyper confusing and should be cleaned up (ugh so bad)
-                       if( closest === undefined ) {
-                               closest = this.find( url, this.stack.slice(a), true );
-                               closest = closest === undefined ? closest : closest + a;
-                       }
-
-                       return closest;
-               },
-
-               direct: function( opts ) {
-                       var newActiveIndex = this.closest( opts.url ), a = this.activeIndex;
-
-                       // save new page index, null check to prevent falsey 0 result
-                       // record the previous index for reference
-                       if( newActiveIndex !== undefined ) {
-                               this.activeIndex = newActiveIndex;
-                               this.previousIndex = a;
-                       }
-
-                       // invoke callbacks where appropriate
-                       //
-                       // TODO this is also convoluted and confusing
-                       if ( newActiveIndex < a ) {
-                               ( opts.present || opts.back || $.noop )( this.getActive(), 'back' );
-                       } else if ( newActiveIndex > a ) {
-                               ( opts.present || opts.forward || $.noop )( this.getActive(), 'forward' );
-                       } else if ( newActiveIndex === undefined && opts.missing ){
-                               opts.missing( this.getActive() );
-                       }
-               }
-       });
-})( jQuery );
-
-
-(function( $, undefined ) {
-       var path = $.mobile.path,
-               initialHref = location.href;
-
-       $.mobile.Navigator = function( history ) {
-               this.history = history;
-               this.ignoreInitialHashChange = true;
-
-               $.mobile.window.bind({
-                       "popstate.history": $.proxy( this.popstate, this ),
-                       "hashchange.history": $.proxy( this.hashchange, this )
-               });
-       };
-
-       $.extend($.mobile.Navigator.prototype, {
-               squash: function( url, data ) {
-                       var state, href, hash = path.isPath(url) ? path.stripHash(url) : url;
-
-                       href = path.squash( url );
-
-                       // make sure to provide this information when it isn't explicitly set in the
-                       // data object that was passed to the squash method
-                       state = $.extend({
-                               hash: hash,
-                               url: href
-                       }, data);
-
-                       // replace the current url with the new href and store the state
-                       // Note that in some cases we might be replacing an url with the
-                       // same url. We do this anyways because we need to make sure that
-                       // all of our history entries have a state object associated with
-                       // them. This allows us to work around the case where $.mobile.back()
-                       // is called to transition from an external page to an embedded page.
-                       // In that particular case, a hashchange event is *NOT* generated by the browser.
-                       // Ensuring each history entry has a state object means that onPopState()
-                       // will always trigger our hashchange callback even when a hashchange event
-                       // is not fired.
-                       window.history.replaceState( state, state.title || document.title, href );
-
-                       return state;
-               },
-
-               hash: function( url, href ) {
-                       var parsed, loc, hash;
-
-                       // Grab the hash for recording. If the passed url is a path
-                       // we used the parsed version of the squashed url to reconstruct,
-                       // otherwise we assume it's a hash and store it directly
-                       parsed = path.parseUrl( url );
-                       loc = path.parseLocation();
-
-                       if( loc.pathname + loc.search === parsed.pathname + parsed.search ) {
-                               // If the pathname and search of the passed url is identical to the current loc
-                               // then we must use the hash. Otherwise there will be no event
-                               // eg, url = "/foo/bar?baz#bang", location.href = "http://example.com/foo/bar?baz"
-                               hash = parsed.hash ? parsed.hash : parsed.pathname + parsed.search;
-                       } else if ( path.isPath(url) ) {
-                               var resolved = path.parseUrl( href );
-                               // If the passed url is a path, make it domain relative and remove any trailing hash
-                               hash = resolved.pathname + resolved.search + (path.isPreservableHash( resolved.hash )? resolved.hash.replace( "#", "" ) : "");
-                       } else {
-                               hash = url;
-                       }
-
-                       return hash;
-               },
-
-               // TODO reconsider name
-               go: function( url, data, noEvents ) {
-                       var state, href, hash, popstateEvent,
-                               isPopStateEvent = $.event.special.navigate.isPushStateEnabled();
-
-                       // Get the url as it would look squashed on to the current resolution url
-                       href = path.squash( url );
-
-                       // sort out what the hash sould be from the url
-                       hash = this.hash( url, href );
-
-                       // Here we prevent the next hash change or popstate event from doing any
-                       // history management. In the case of hashchange we don't swallow it
-                       // if there will be no hashchange fired (since that won't reset the value)
-                       // and will swallow the following hashchange
-                       if( noEvents && hash !== path.stripHash(path.parseLocation().hash) ) {
-                               this.preventNextHashChange = noEvents;
-                       }
-
-                       // IMPORTANT in the case where popstate is supported the event will be triggered
-                       //      directly, stopping further execution - ie, interupting the flow of this
-                       //      method call to fire bindings at this expression. Below the navigate method
-                       //      there is a binding to catch this event and stop its propagation.
-                       //
-                       //      We then trigger a new popstate event on the window with a null state
-                       //      so that the navigate events can conclude their work properly
-                       //
-                       // if the url is a path we want to preserve the query params that are available on
-                       // the current url.
-                       this.preventHashAssignPopState = true;
-                       window.location.hash = hash;
-
-                       // If popstate is enabled and the browser triggers `popstate` events when the hash
-                       // is set (this often happens immediately in browsers like Chrome), then the
-                       // this flag will be set to false already. If it's a browser that does not trigger
-                       // a `popstate` on hash assignement or `replaceState` then we need avoid the branch
-                       // that swallows the event created by the popstate generated by the hash assignment
-                       // At the time of this writing this happens with Opera 12 and some version of IE
-                       this.preventHashAssignPopState = false;
-
-                       state = $.extend({
-                               url: href,
-                               hash: hash,
-                               title: document.title
-                       }, data);
-
-                       if( isPopStateEvent ) {
-                               popstateEvent = new $.Event( "popstate" );
-                               popstateEvent.originalEvent = {
-                                       type: "popstate",
-                                       state: null
-                               };
-
-                               this.squash( url, state );
-
-                               // Trigger a new faux popstate event to replace the one that we
-                               // caught that was triggered by the hash setting above.
-                               if( !noEvents ) {
-                                       this.ignorePopState = true;
-                                       $.mobile.window.trigger( popstateEvent );
-                               }
-                       }
-
-                       // record the history entry so that the information can be included
-                       // in hashchange event driven navigate events in a similar fashion to
-                       // the state that's provided by popstate
-                       this.history.add( state.url, state );
-               },
-
-
-               // This binding is intended to catch the popstate events that are fired
-               // when execution of the `$.navigate` method stops at window.location.hash = url;
-               // and completely prevent them from propagating. The popstate event will then be
-               // retriggered after execution resumes
-               //
-               // TODO grab the original event here and use it for the synthetic event in the
-               //      second half of the navigate execution that will follow this binding
-               popstate: function( event ) {
-                       var active, hash, state, closestIndex;
-
-                       // Partly to support our test suite which manually alters the support
-                       // value to test hashchange. Partly to prevent all around weirdness
-                       if( !$.event.special.navigate.isPushStateEnabled() ){
-                               return;
-                       }
-
-                       // If this is the popstate triggered by the actual alteration of the hash
-                       // prevent it completely. History is tracked manually
-                       if( this.preventHashAssignPopState ) {
-                               this.preventHashAssignPopState = false;
-                               event.stopImmediatePropagation();
-                               return;
-                       }
-
-                       // if this is the popstate triggered after the `replaceState` call in the go
-                       // method, then simply ignore it. The history entry has already been captured
-                       if( this.ignorePopState ) {
-                               this.ignorePopState = false;
-                               return;
-                       }
-
-                       // If there is no state, and the history stack length is one were
-                       // probably getting the page load popstate fired by browsers like chrome
-                       // avoid it and set the one time flag to false.
-                       // TODO: Do we really need all these conditions? Comparing location hrefs
-                       // should be sufficient.
-                       if( !event.originalEvent.state &&
-                               this.history.stack.length === 1 &&
-                               this.ignoreInitialHashChange ) {
-                               this.ignoreInitialHashChange = false;
-
-                               if ( location.href === initialHref ) {
-                                       event.preventDefault();
-                                       return;
-                               }
-                       }
-
-                       // account for direct manipulation of the hash. That is, we will receive a popstate
-                       // when the hash is changed by assignment, and it won't have a state associated. We
-                       // then need to squash the hash. See below for handling of hash assignment that
-                       // matches an existing history entry
-                       // TODO it might be better to only add to the history stack
-                       //      when the hash is adjacent to the active history entry
-                       hash = path.parseLocation().hash;
-                       if( !event.originalEvent.state && hash ) {
-                               // squash the hash that's been assigned on the URL with replaceState
-                               // also grab the resulting state object for storage
-                               state = this.squash( hash );
-
-                               // record the new hash as an additional history entry
-                               // to match the browser's treatment of hash assignment
-                               this.history.add( state.url, state );
-
-                               // pass the newly created state information
-                               // along with the event
-                               event.historyState = state;
-
-                               // do not alter history, we've added a new history entry
-                               // so we know where we are
-                               return;
-                       }
-
-                       // If all else fails this is a popstate that comes from the back or forward buttons
-                       // make sure to set the state of our history stack properly, and record the directionality
-                       this.history.direct({
-                               url: (event.originalEvent.state || {}).url || hash,
-
-                               // When the url is either forward or backward in history include the entry
-                               // as data on the event object for merging as data in the navigate event
-                               present: function( historyEntry, direction ) {
-                                       // make sure to create a new object to pass down as the navigate event data
-                                       event.historyState = $.extend({}, historyEntry);
-                                       event.historyState.direction = direction;
-                               }
-                       });
-               },
-
-               // NOTE must bind before `navigate` special event hashchange binding otherwise the
-               //      navigation data won't be attached to the hashchange event in time for those
-               //      bindings to attach it to the `navigate` special event
-               // TODO add a check here that `hashchange.navigate` is bound already otherwise it's
-               //      broken (exception?)
-               hashchange: function( event ) {
-                       var history, hash;
-
-                       // If hashchange listening is explicitly disabled or pushstate is supported
-                       // avoid making use of the hashchange handler.
-                       if(!$.event.special.navigate.isHashChangeEnabled() ||
-                               $.event.special.navigate.isPushStateEnabled() ) {
-                               return;
-                       }
-
-                       // On occasion explicitly want to prevent the next hash from propogating because we only
-                       // with to alter the url to represent the new state do so here
-                       if( this.preventNextHashChange ){
-                               this.preventNextHashChange = false;
-                               event.stopImmediatePropagation();
-                               return;
-                       }
-
-                       history = this.history;
-                       hash = path.parseLocation().hash;
-
-                       // If this is a hashchange caused by the back or forward button
-                       // make sure to set the state of our history stack properly
-                       this.history.direct({
-                               url: hash,
-
-                               // When the url is either forward or backward in history include the entry
-                               // as data on the event object for merging as data in the navigate event
-                               present: function( historyEntry, direction ) {
-                                       // make sure to create a new object to pass down as the navigate event data
-                                       event.hashchangeState = $.extend({}, historyEntry);
-                                       event.hashchangeState.direction = direction;
-                               },
-
-                               // When we don't find a hash in our history clearly we're aiming to go there
-                               // record the entry as new for future traversal
-                               //
-                               // NOTE it's not entirely clear that this is the right thing to do given that we
-                               //      can't know the users intention. It might be better to explicitly _not_
-                               //      support location.hash assignment in preference to $.navigate calls
-                               // TODO first arg to add should be the href, but it causes issues in identifying
-                               //      embeded pages
-                               missing: function() {
-                                       history.add( hash, {
-                                               hash: hash,
-                                               title: document.title
-                                       });
-                               }
-                       });
-               }
-       });
-})( jQuery );
-
-
-
-(function( $, undefined ) {
-       // TODO consider queueing navigation activity until previous activities have completed
-       //      so that end users don't have to think about it. Punting for now
-       // TODO !! move the event bindings into callbacks on the navigate event
-       $.mobile.navigate = function( url, data, noEvents ) {
-               $.mobile.navigate.navigator.go( url, data, noEvents );
-       };
-
-       // expose the history on the navigate method in anticipation of full integration with
-       // existing navigation functionalty that is tightly coupled to the history information
-       $.mobile.navigate.history = new $.mobile.History();
-
-       // instantiate an instance of the navigator for use within the $.navigate method
-       $.mobile.navigate.navigator = new $.mobile.Navigator( $.mobile.navigate.history );
-
-       var loc = $.mobile.path.parseLocation();
-       $.mobile.navigate.history.add( loc.href, {hash: loc.hash} );
-})( jQuery );
-
-
-// This plugin is an experiment for abstracting away the touch and mouse
-// events so that developers don't have to worry about which method of input
-// the device their document is loaded on supports.
-//
-// The idea here is to allow the developer to register listeners for the
-// basic mouse events, such as mousedown, mousemove, mouseup, and click,
-// and the plugin will take care of registering the correct listeners
-// behind the scenes to invoke the listener at the fastest possible time
-// for that device, while still retaining the order of event firing in
-// the traditional mouse environment, should multiple handlers be registered
-// on the same element for different events.
-//
-// The current version exposes the following virtual events to jQuery bind methods:
-// "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel"
-
-(function( $, window, document, undefined ) {
-
-var dataPropertyName = "virtualMouseBindings",
-       touchTargetPropertyName = "virtualTouchID",
-       virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ),
-       touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ),
-       mouseHookProps = $.event.mouseHooks ? $.event.mouseHooks.props : [],
-       mouseEventProps = $.event.props.concat( mouseHookProps ),
-       activeDocHandlers = {},
-       resetTimerID = 0,
-       startX = 0,
-       startY = 0,
-       didScroll = false,
-       clickBlockList = [],
-       blockMouseTriggers = false,
-       blockTouchTriggers = false,
-       eventCaptureSupported = "addEventListener" in document,
-       $document = $( document ),
-       nextTouchID = 1,
-       lastTouchID = 0, threshold;
-
-$.vmouse = {
-       moveDistanceThreshold: 10,
-       clickDistanceThreshold: 10,
-       resetTimerDuration: 1500
-};
-
-function getNativeEvent( event ) {
-
-       while ( event && typeof event.originalEvent !== "undefined" ) {
-               event = event.originalEvent;
-       }
-       return event;
-}
-
-function createVirtualEvent( event, eventType ) {
-
-       var t = event.type,
-               oe, props, ne, prop, ct, touch, i, j, len;
-
-       event = $.Event( event );
-       event.type = eventType;
-
-       oe = event.originalEvent;
-       props = $.event.props;
-
-       // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280
-       // https://github.com/jquery/jquery-mobile/issues/3280
-       if ( t.search( /^(mouse|click)/ ) > -1 ) {
-               props = mouseEventProps;
-       }
-
-       // copy original event properties over to the new event
-       // this would happen if we could call $.event.fix instead of $.Event
-       // but we don't have a way to force an event to be fixed multiple times
-       if ( oe ) {
-               for ( i = props.length, prop; i; ) {
-                       prop = props[ --i ];
-                       event[ prop ] = oe[ prop ];
-               }
-       }
-
-       // make sure that if the mouse and click virtual events are generated
-       // without a .which one is defined
-       if ( t.search(/mouse(down|up)|click/) > -1 && !event.which ) {
-               event.which = 1;
-       }
-
-       if ( t.search(/^touch/) !== -1 ) {
-               ne = getNativeEvent( oe );
-               t = ne.touches;
-               ct = ne.changedTouches;
-               touch = ( t && t.length ) ? t[0] : ( ( ct && ct.length ) ? ct[ 0 ] : undefined );
-
-               if ( touch ) {
-                       for ( j = 0, len = touchEventProps.length; j < len; j++) {
-                               prop = touchEventProps[ j ];
-                               event[ prop ] = touch[ prop ];
-                       }
-               }
-       }
-
-       return event;
-}
-
-function getVirtualBindingFlags( element ) {
-
-       var flags = {},
-               b, k;
-
-       while ( element ) {
-
-               b = $.data( element, dataPropertyName );
-
-               for (  k in b ) {
-                       if ( b[ k ] ) {
-                               flags[ k ] = flags.hasVirtualBinding = true;
-                       }
-               }
-               element = element.parentNode;
-       }
-       return flags;
-}
-
-function getClosestElementWithVirtualBinding( element, eventType ) {
-       var b;
-       while ( element ) {
-
-               b = $.data( element, dataPropertyName );
-
-               if ( b && ( !eventType || b[ eventType ] ) ) {
-                       return element;
-               }
-               element = element.parentNode;
-       }
-       return null;
-}
-
-function enableTouchBindings() {
-       blockTouchTriggers = false;
-}
-
-function disableTouchBindings() {
-       blockTouchTriggers = true;
-}
-
-function enableMouseBindings() {
-       lastTouchID = 0;
-       clickBlockList.length = 0;
-       blockMouseTriggers = false;
-
-       // When mouse bindings are enabled, our
-       // touch bindings are disabled.
-       disableTouchBindings();
-}
-
-function disableMouseBindings() {
-       // When mouse bindings are disabled, our
-       // touch bindings are enabled.
-       enableTouchBindings();
-}
-
-function startResetTimer() {
-       clearResetTimer();
-       resetTimerID = setTimeout( function() {
-               resetTimerID = 0;
-               enableMouseBindings();
-       }, $.vmouse.resetTimerDuration );
-}
-
-function clearResetTimer() {
-       if ( resetTimerID ) {
-               clearTimeout( resetTimerID );
-               resetTimerID = 0;
-       }
-}
-
-function triggerVirtualEvent( eventType, event, flags ) {
-       var ve;
-
-       if ( ( flags && flags[ eventType ] ) ||
-                               ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) {
-
-               ve = createVirtualEvent( event, eventType );
-
-               $( event.target).trigger( ve );
-       }
-
-       return ve;
-}
-
-function mouseEventCallback( event ) {
-       var touchID = $.data( event.target, touchTargetPropertyName );
-
-       if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ) {
-               var ve = triggerVirtualEvent( "v" + event.type, event );
-               if ( ve ) {
-                       if ( ve.isDefaultPrevented() ) {
-                               event.preventDefault();
-                       }
-                       if ( ve.isPropagationStopped() ) {
-                               event.stopPropagation();
-                       }
-                       if ( ve.isImmediatePropagationStopped() ) {
-                               event.stopImmediatePropagation();
-                       }
-               }
-       }
-}
-
-function handleTouchStart( event ) {
-
-       var touches = getNativeEvent( event ).touches,
-               target, flags;
-
-       if ( touches && touches.length === 1 ) {
-
-               target = event.target;
-               flags = getVirtualBindingFlags( target );
-
-               if ( flags.hasVirtualBinding ) {
-
-                       lastTouchID = nextTouchID++;
-                       $.data( target, touchTargetPropertyName, lastTouchID );
-
-                       clearResetTimer();
-
-                       disableMouseBindings();
-                       didScroll = false;
-
-                       var t = getNativeEvent( event ).touches[ 0 ];
-                       startX = t.pageX;
-                       startY = t.pageY;
-
-                       triggerVirtualEvent( "vmouseover", event, flags );
-                       triggerVirtualEvent( "vmousedown", event, flags );
-               }
-       }
-}
-
-function handleScroll( event ) {
-       if ( blockTouchTriggers ) {
-               return;
-       }
-
-       if ( !didScroll ) {
-               triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) );
-       }
-
-       didScroll = true;
-       startResetTimer();
-}
-
-function handleTouchMove( event ) {
-       if ( blockTouchTriggers ) {
-               return;
-       }
-
-       var t = getNativeEvent( event ).touches[ 0 ],
-               didCancel = didScroll,
-               moveThreshold = $.vmouse.moveDistanceThreshold,
-               flags = getVirtualBindingFlags( event.target );
-
-               didScroll = didScroll ||
-                       ( Math.abs( t.pageX - startX ) > moveThreshold ||
-                               Math.abs( t.pageY - startY ) > moveThreshold );
-
-
-       if ( didScroll && !didCancel ) {
-               triggerVirtualEvent( "vmousecancel", event, flags );
-       }
-
-       triggerVirtualEvent( "vmousemove", event, flags );
-       startResetTimer();
-}
-
-function handleTouchEnd( event ) {
-       if ( blockTouchTriggers ) {
-               return;
-       }
-
-       disableTouchBindings();
-
-       var flags = getVirtualBindingFlags( event.target ),
-               t;
-       triggerVirtualEvent( "vmouseup", event, flags );
-
-       if ( !didScroll ) {
-               var ve = triggerVirtualEvent( "vclick", event, flags );
-               if ( ve && ve.isDefaultPrevented() ) {
-                       // The target of the mouse events that follow the touchend
-                       // event don't necessarily match the target used during the
-                       // touch. This means we need to rely on coordinates for blocking
-                       // any click that is generated.
-                       t = getNativeEvent( event ).changedTouches[ 0 ];
-                       clickBlockList.push({
-                               touchID: lastTouchID,
-                               x: t.clientX,
-                               y: t.clientY
-                       });
-
-                       // Prevent any mouse events that follow from triggering
-                       // virtual event notifications.
-                       blockMouseTriggers = true;
-               }
-       }
-       triggerVirtualEvent( "vmouseout", event, flags);
-       didScroll = false;
-
-       startResetTimer();
-}
-
-function hasVirtualBindings( ele ) {
-       var bindings = $.data( ele, dataPropertyName ),
-               k;
-
-       if ( bindings ) {
-               for ( k in bindings ) {
-                       if ( bindings[ k ] ) {
-                               return true;
-                       }
-               }
-       }
-       return false;
-}
-
-function dummyMouseHandler() {}
-
-function getSpecialEventObject( eventType ) {
-       var realType = eventType.substr( 1 );
-
-       return {
-               setup: function( data, namespace ) {
-                       // If this is the first virtual mouse binding for this element,
-                       // add a bindings object to its data.
-
-                       if ( !hasVirtualBindings( this ) ) {
-                               $.data( this, dataPropertyName, {} );
-                       }
-
-                       // If setup is called, we know it is the first binding for this
-                       // eventType, so initialize the count for the eventType to zero.
-                       var bindings = $.data( this, dataPropertyName );
-                       bindings[ eventType ] = true;
-
-                       // If this is the first virtual mouse event for this type,
-                       // register a global handler on the document.
-
-                       activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1;
-
-                       if ( activeDocHandlers[ eventType ] === 1 ) {
-                               $document.bind( realType, mouseEventCallback );
-                       }
-
-                       // Some browsers, like Opera Mini, won't dispatch mouse/click events
-                       // for elements unless they actually have handlers registered on them.
-                       // To get around this, we register dummy handlers on the elements.
-
-                       $( this ).bind( realType, dummyMouseHandler );
-
-                       // For now, if event capture is not supported, we rely on mouse handlers.
-                       if ( eventCaptureSupported ) {
-                               // If this is the first virtual mouse binding for the document,
-                               // register our touchstart handler on the document.
-
-                               activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0) + 1;
-
-                               if ( activeDocHandlers[ "touchstart" ] === 1 ) {
-                                       $document.bind( "touchstart", handleTouchStart )
-                                               .bind( "touchend", handleTouchEnd )
-
-                                               // On touch platforms, touching the screen and then dragging your finger
-                                               // causes the window content to scroll after some distance threshold is
-                                               // exceeded. On these platforms, a scroll prevents a click event from being
-                                               // dispatched, and on some platforms, even the touchend is suppressed. To
-                                               // mimic the suppression of the click event, we need to watch for a scroll
-                                               // event. Unfortunately, some platforms like iOS don't dispatch scroll
-                                               // events until *AFTER* the user lifts their finger (touchend). This means
-                                               // we need to watch both scroll and touchmove events to figure out whether
-                                               // or not a scroll happenens before the touchend event is fired.
-
-                                               .bind( "touchmove", handleTouchMove )
-                                               .bind( "scroll", handleScroll );
-                               }
-                       }
-               },
-
-               teardown: function( data, namespace ) {
-                       // If this is the last virtual binding for this eventType,
-                       // remove its global handler from the document.
-
-                       --activeDocHandlers[ eventType ];
-
-                       if ( !activeDocHandlers[ eventType ] ) {
-                               $document.unbind( realType, mouseEventCallback );
-                       }
-
-                       if ( eventCaptureSupported ) {
-                               // If this is the last virtual mouse binding in existence,
-                               // remove our document touchstart listener.
-
-                               --activeDocHandlers[ "touchstart" ];
-
-                               if ( !activeDocHandlers[ "touchstart" ] ) {
-                                       $document.unbind( "touchstart", handleTouchStart )
-                                               .unbind( "touchmove", handleTouchMove )
-                                               .unbind( "touchend", handleTouchEnd )
-                                               .unbind( "scroll", handleScroll );
-                               }
-                       }
-
-                       var $this = $( this ),
-                               bindings = $.data( this, dataPropertyName );
-
-                       // teardown may be called when an element was
-                       // removed from the DOM. If this is the case,
-                       // jQuery core may have already stripped the element
-                       // of any data bindings so we need to check it before
-                       // using it.
-                       if ( bindings ) {
-                               bindings[ eventType ] = false;
-                       }
-
-                       // Unregister the dummy event handler.
-
-                       $this.unbind( realType, dummyMouseHandler );
-
-                       // If this is the last virtual mouse binding on the
-                       // element, remove the binding data from the element.
-
-                       if ( !hasVirtualBindings( this ) ) {
-                               $this.removeData( dataPropertyName );
-                       }
-               }
-       };
-}
-
-// Expose our custom events to the jQuery bind/unbind mechanism.
-
-for ( var i = 0; i < virtualEventNames.length; i++ ) {
-       $.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] );
-}
-
-// Add a capture click handler to block clicks.
-// Note that we require event capture support for this so if the device
-// doesn't support it, we punt for now and rely solely on mouse events.
-if ( eventCaptureSupported ) {
-       document.addEventListener( "click", function( e ) {
-               var cnt = clickBlockList.length,
-                       target = e.target,
-                       x, y, ele, i, o, touchID;
-
-               if ( cnt ) {
-                       x = e.clientX;
-                       y = e.clientY;
-                       threshold = $.vmouse.clickDistanceThreshold;
-
-                       // The idea here is to run through the clickBlockList to see if
-                       // the current click event is in the proximity of one of our
-                       // vclick events that had preventDefault() called on it. If we find
-                       // one, then we block the click.
-                       //
-                       // Why do we have to rely on proximity?
-                       //
-                       // Because the target of the touch event that triggered the vclick
-                       // can be different from the target of the click event synthesized
-                       // by the browser. The target of a mouse/click event that is syntehsized
-                       // from a touch event seems to be implementation specific. For example,
-                       // some browsers will fire mouse/click events for a link that is near
-                       // a touch event, even though the target of the touchstart/touchend event
-                       // says the user touched outside the link. Also, it seems that with most
-                       // browsers, the target of the mouse/click event is not calculated until the
-                       // time it is dispatched, so if you replace an element that you touched
-                       // with another element, the target of the mouse/click will be the new
-                       // element underneath that point.
-                       //
-                       // Aside from proximity, we also check to see if the target and any
-                       // of its ancestors were the ones that blocked a click. This is necessary
-                       // because of the strange mouse/click target calculation done in the
-                       // Android 2.1 browser, where if you click on an element, and there is a
-                       // mouse/click handler on one of its ancestors, the target will be the
-                       // innermost child of the touched element, even if that child is no where
-                       // near the point of touch.
-
-                       ele = target;
-
-                       while ( ele ) {
-                               for ( i = 0; i < cnt; i++ ) {
-                                       o = clickBlockList[ i ];
-                                       touchID = 0;
-
-                                       if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) ||
-                                                               $.data( ele, touchTargetPropertyName ) === o.touchID ) {
-                                               // XXX: We may want to consider removing matches from the block list
-                                               //      instead of waiting for the reset timer to fire.
-                                               e.preventDefault();
-                                               e.stopPropagation();
-                                               return;
-                                       }
-                               }
-                               ele = ele.parentNode;
-                       }
-               }
-       }, true);
-}
-})( jQuery, window, document );
-
-
-(function( $, window, undefined ) {
-       var $document = $( document );
-
-       // add new event shortcuts
-       $.each( ( "touchstart touchmove touchend " +
-               "tap taphold " +
-               "swipe swipeleft swiperight " +
-               "scrollstart scrollstop" ).split( " " ), function( i, name ) {
-
-               $.fn[ name ] = function( fn ) {
-                       return fn ? this.bind( name, fn ) : this.trigger( name );
-               };
-
-               // jQuery < 1.8
-               if ( $.attrFn ) {
-                       $.attrFn[ name ] = true;
-               }
-       });
-
-       var supportTouch = $.mobile.support.touch,
-               scrollEvent = "touchmove scroll",
-               touchStartEvent = supportTouch ? "touchstart" : "mousedown",
-               touchStopEvent = supportTouch ? "touchend" : "mouseup",
-               touchMoveEvent = supportTouch ? "touchmove" : "mousemove";
-
-       function triggerCustomEvent( obj, eventType, event ) {
-               var originalType = event.type;
-               event.type = eventType;
-               $.event.dispatch.call( obj, event );
-               event.type = originalType;
-       }
-
-       // also handles scrollstop
-       $.event.special.scrollstart = {
-
-               enabled: true,
-
-               setup: function() {
-
-                       var thisObject = this,
-                               $this = $( thisObject ),
-                               scrolling,
-                               timer;
-
-                       function trigger( event, state ) {
-                               scrolling = state;
-                               triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
-                       }
-
-                       // iPhone triggers scroll after a small delay; use touchmove instead
-                       $this.bind( scrollEvent, function( event ) {
-
-                               if ( !$.event.special.scrollstart.enabled ) {
-                                       return;
-                               }
-
-                               if ( !scrolling ) {
-                                       trigger( event, true );
-                               }
-
-                               clearTimeout( timer );
-                               timer = setTimeout( function() {
-                                       trigger( event, false );
-                               }, 50 );
-                       });
-               }
-       };
-
-       // also handles taphold
-       $.event.special.tap = {
-               tapholdThreshold: 750,
-
-               setup: function() {
-                       var thisObject = this,
-                               $this = $( thisObject );
-
-                       $this.bind( "vmousedown", function( event ) {
-
-                               if ( event.which && event.which !== 1 ) {
-                                       return false;
-                               }
-
-                               var origTarget = event.target,
-                                       origEvent = event.originalEvent,
-                                       timer;
-
-                               function clearTapTimer() {
-                                       clearTimeout( timer );
-                               }
-
-                               function clearTapHandlers() {
-                                       clearTapTimer();
-
-                                       $this.unbind( "vclick", clickHandler )
-                                               .unbind( "vmouseup", clearTapTimer );
-                                       $document.unbind( "vmousecancel", clearTapHandlers );
-                               }
-
-                               function clickHandler( event ) {
-                                       clearTapHandlers();
-
-                                       // ONLY trigger a 'tap' event if the start target is
-                                       // the same as the stop target.
-                                       if ( origTarget === event.target ) {
-                                               triggerCustomEvent( thisObject, "tap", event );
-                                       }
-                               }
-
-                               $this.bind( "vmouseup", clearTapTimer )
-                                       .bind( "vclick", clickHandler );
-                               $document.bind( "vmousecancel", clearTapHandlers );
-
-                               timer = setTimeout( function() {
-                                       triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) );
-                               }, $.event.special.tap.tapholdThreshold );
-                       });
-               }
-       };
-
-       // also handles swipeleft, swiperight
-       $.event.special.swipe = {
-               scrollSupressionThreshold: 30, // More than this horizontal displacement, and we will suppress scrolling.
-
-               durationThreshold: 1000, // More time than this, and it isn't a swipe.
-
-               horizontalDistanceThreshold: 30,  // Swipe horizontal displacement must be more than this.
-
-               verticalDistanceThreshold: 75,  // Swipe vertical displacement must be less than this.
-
-               start: function( event ) {
-                       var data = event.originalEvent.touches ?
-                                       event.originalEvent.touches[ 0 ] : event;
-                       return {
-                                               time: ( new Date() ).getTime(),
-                                               coords: [ data.pageX, data.pageY ],
-                                               origin: $( event.target )
-                                       };
-               },
-
-               stop: function( event ) {
-                       var data = event.originalEvent.touches ?
-                                       event.originalEvent.touches[ 0 ] : event;
-                       return {
-                                               time: ( new Date() ).getTime(),
-                                               coords: [ data.pageX, data.pageY ]
-                                       };
-               },
-
-               handleSwipe: function( start, stop ) {
-                       if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
-                               Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
-                               Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {
-
-                               start.origin.trigger( "swipe" )
-                                       .trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );
-                       }
-               },
-
-               setup: function() {
-                       var thisObject = this,
-                               $this = $( thisObject );
-
-                       $this.bind( touchStartEvent, function( event ) {
-                               var start = $.event.special.swipe.start( event ),
-                                       stop;
-
-                               function moveHandler( event ) {
-                                       if ( !start ) {
-                                               return;
-                                       }
-
-                                       stop = $.event.special.swipe.stop( event );
-
-                                       // prevent scrolling
-                                       if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
-                                               event.preventDefault();
-                                       }
-                               }
-
-                               $this.bind( touchMoveEvent, moveHandler )
-                                       .one( touchStopEvent, function() {
-                                               $this.unbind( touchMoveEvent, moveHandler );
-
-                                               if ( start && stop ) {
-                                                       $.event.special.swipe.handleSwipe( start, stop );
-                                               }
-                                               start = stop = undefined;
-                                       });
-                       });
-               }
-       };
-       $.each({
-               scrollstop: "scrollstart",
-               taphold: "tap",
-               swipeleft: "swipe",
-               swiperight: "swipe"
-       }, function( event, sourceEvent ) {
-
-               $.event.special[ event ] = {
-                       setup: function() {
-                               $( this ).bind( sourceEvent, $.noop );
-                       }
-               };
-       });
-
-})( jQuery, this );
-
-
-       // throttled resize event
-       (function( $ ) {
-               $.event.special.throttledresize = {
-                       setup: function() {
-                               $( this ).bind( "resize", handler );
-                       },
-                       teardown: function() {
-                               $( this ).unbind( "resize", handler );
-                       }
-               };
-
-               var throttle = 250,
-                       handler = function() {
-                               curr = ( new Date() ).getTime();
-                               diff = curr - lastCall;
-
-                               if ( diff >= throttle ) {
-
-                                       lastCall = curr;
-                                       $( this ).trigger( "throttledresize" );
-
-                               } else {
-
-                                       if ( heldCall ) {
-                                               clearTimeout( heldCall );
-                                       }
-
-                                       // Promise a held call will still execute
-                                       heldCall = setTimeout( handler, throttle - diff );
-                               }
-                       },
-                       lastCall = 0,
-                       heldCall,
-                       curr,
-                       diff;
-       })( jQuery );
-
-(function( $, window ) {
-       var win = $( window ),
-               event_name = "orientationchange",
-               special_event,
-               get_orientation,
-               last_orientation,
-               initial_orientation_is_landscape,
-               initial_orientation_is_default,
-               portrait_map = { "0": true, "180": true };
-
-       // It seems that some device/browser vendors use window.orientation values 0 and 180 to
-       // denote the "default" orientation. For iOS devices, and most other smart-phones tested,
-       // the default orientation is always "portrait", but in some Android and RIM based tablets,
-       // the default orientation is "landscape". The following code attempts to use the window
-       // dimensions to figure out what the current orientation is, and then makes adjustments
-       // to the to the portrait_map if necessary, so that we can properly decode the
-       // window.orientation value whenever get_orientation() is called.
-       //
-       // Note that we used to use a media query to figure out what the orientation the browser
-       // thinks it is in:
-       //
-       //     initial_orientation_is_landscape = $.mobile.media("all and (orientation: landscape)");
-       //
-       // but there was an iPhone/iPod Touch bug beginning with iOS 4.2, up through iOS 5.1,
-       // where the browser *ALWAYS* applied the landscape media query. This bug does not
-       // happen on iPad.
-
-       if ( $.support.orientation ) {
-
-               // Check the window width and height to figure out what the current orientation
-               // of the device is at this moment. Note that we've initialized the portrait map
-               // values to 0 and 180, *AND* we purposely check for landscape so that if we guess
-               // wrong, , we default to the assumption that portrait is the default orientation.
-               // We use a threshold check below because on some platforms like iOS, the iPhone
-               // form-factor can report a larger width than height if the user turns on the
-               // developer console. The actual threshold value is somewhat arbitrary, we just
-               // need to make sure it is large enough to exclude the developer console case.
-
-               var ww = window.innerWidth || win.width(),
-                       wh = window.innerHeight || win.height(),
-                       landscape_threshold = 50;
-
-               initial_orientation_is_landscape = ww > wh && ( ww - wh ) > landscape_threshold;
-
-
-               // Now check to see if the current window.orientation is 0 or 180.
-               initial_orientation_is_default = portrait_map[ window.orientation ];
-
-               // If the initial orientation is landscape, but window.orientation reports 0 or 180, *OR*
-               // if the initial orientation is portrait, but window.orientation reports 90 or -90, we
-               // need to flip our portrait_map values because landscape is the default orientation for
-               // this device/browser.
-               if ( ( initial_orientation_is_landscape && initial_orientation_is_default ) || ( !initial_orientation_is_landscape && !initial_orientation_is_default ) ) {
-                       portrait_map = { "-90": true, "90": true };
-               }
-       }
-
-       $.event.special.orientationchange = $.extend( {}, $.event.special.orientationchange, {
-               setup: function() {
-                       // If the event is supported natively, return false so that jQuery
-                       // will bind to the event using DOM methods.
-                       if ( $.support.orientation && !$.event.special.orientationchange.disabled ) {
-                               return false;
-                       }
-
-                       // Get the current orientation to avoid initial double-triggering.
-                       last_orientation = get_orientation();
-
-                       // Because the orientationchange event doesn't exist, simulate the
-                       // event by testing window dimensions on resize.
-                       win.bind( "throttledresize", handler );
-               },
-               teardown: function() {
-                       // If the event is not supported natively, return false so that
-                       // jQuery will unbind the event using DOM methods.
-                       if ( $.support.orientation && !$.event.special.orientationchange.disabled ) {
-                               return false;
-                       }
-
-                       // Because the orientationchange event doesn't exist, unbind the
-                       // resize event handler.
-                       win.unbind( "throttledresize", handler );
-               },
-               add: function( handleObj ) {
-                       // Save a reference to the bound event handler.
-                       var old_handler = handleObj.handler;
-
-
-                       handleObj.handler = function( event ) {
-                               // Modify event object, adding the .orientation property.
-                               event.orientation = get_orientation();
-
-                               // Call the originally-bound event handler and return its result.
-                               return old_handler.apply( this, arguments );
-                       };
-               }
-       });
-
-       // If the event is not supported natively, this handler will be bound to
-       // the window resize event to simulate the orientationchange event.
-       function handler() {
-               // Get the current orientation.
-               var orientation = get_orientation();
-
-               if ( orientation !== last_orientation ) {
-                       // The orientation has changed, so trigger the orientationchange event.
-                       last_orientation = orientation;
-                       win.trigger( event_name );
-               }
-       }
-
-       // Get the current page orientation. This method is exposed publicly, should it
-       // be needed, as jQuery.event.special.orientationchange.orientation()
-       $.event.special.orientationchange.orientation = get_orientation = function() {
-               var isPortrait = true, elem = document.documentElement;
-
-               // prefer window orientation to the calculation based on screensize as
-               // the actual screen resize takes place before or after the orientation change event
-               // has been fired depending on implementation (eg android 2.3 is before, iphone after).
-               // More testing is required to determine if a more reliable method of determining the new screensize
-               // is possible when orientationchange is fired. (eg, use media queries + element + opacity)
-               if ( $.support.orientation ) {
-                       // if the window orientation registers as 0 or 180 degrees report
-                       // portrait, otherwise landscape
-                       isPortrait = portrait_map[ window.orientation ];
-               } else {
-                       isPortrait = elem && elem.clientWidth / elem.clientHeight < 1.1;
-               }
-
-               return isPortrait ? "portrait" : "landscape";
-       };
-
-       $.fn[ event_name ] = function( fn ) {
-               return fn ? this.bind( event_name, fn ) : this.trigger( event_name );
-       };
-
-       // jQuery < 1.8
-       if ( $.attrFn ) {
-               $.attrFn[ event_name ] = true;
-       }
-
-}( jQuery, this ));
-
-
-
-(function( $, undefined ) {
-
-$.widget( "mobile.page", $.mobile.widget, {
-       options: {
-               theme: "c",
-               domCache: false,
-               keepNativeDefault: ":jqmData(role='none'), :jqmData(role='nojs')"
-       },
-
-       _create: function() {
-               // if false is returned by the callbacks do not create the page
-               if ( this._trigger( "beforecreate" ) === false ) {
-                       return false;
-               }
-
-               this.element
-                       .attr( "tabindex", "0" )
-                       .addClass( "ui-page ui-body-" + this.options.theme );
-
-               this._on( this.element, {
-                       pagebeforehide: "removeContainerBackground",
-                       pagebeforeshow: "_handlePageBeforeShow"
-               });
-       },
-
-       _handlePageBeforeShow: function( e ) {
-               this.setContainerBackground();
-       },
-
-       removeContainerBackground: function() {
-               $.mobile.pageContainer.removeClass( "ui-overlay-" + $.mobile.getInheritedTheme( this.element.parent() ) );
-       },
-
-       // set the page container background to the page theme
-       setContainerBackground: function( theme ) {
-               if ( this.options.theme ) {
-                       $.mobile.pageContainer.addClass( "ui-overlay-" + ( theme || this.options.theme ) );
-               }
-       },
-
-       keepNativeSelector: function() {
-               var options = this.options,
-                       keepNativeDefined = options.keepNative && $.trim( options.keepNative );
-
-               if ( keepNativeDefined && options.keepNative !== options.keepNativeDefault ) {
-                       return [options.keepNative, options.keepNativeDefault].join( ", " );
-               }
-
-               return options.keepNativeDefault;
-       }
-});
-})( jQuery );
-
-(function( $, window, undefined ) {
-
-var createHandler = function( sequential ) {
-
-       // Default to sequential
-       if ( sequential === undefined ) {
-               sequential = true;
-       }
-
-       return function( name, reverse, $to, $from ) {
-
-               var deferred = new $.Deferred(),
-                       reverseClass = reverse ? " reverse" : "",
-                       active  = $.mobile.urlHistory.getActive(),
-                       toScroll = active.lastScroll || $.mobile.defaultHomeScroll,
-                       screenHeight = $.mobile.getScreenHeight(),
-                       maxTransitionOverride = $.mobile.maxTransitionWidth !== false && $.mobile.window.width() > $.mobile.maxTransitionWidth,
-                       none = !$.support.cssTransitions || maxTransitionOverride || !name || name === "none" || Math.max( $.mobile.window.scrollTop(), toScroll ) > $.mobile.getMaxScrollForTransition(),
-                       toPreClass = " ui-page-pre-in",
-                       toggleViewportClass = function() {
-                               $.mobile.pageContainer.toggleClass( "ui-mobile-viewport-transitioning viewport-" + name );
-                       },
-                       scrollPage = function() {
-                               // By using scrollTo instead of silentScroll, we can keep things better in order
-                               // Just to be precautios, disable scrollstart listening like silentScroll would
-                               $.event.special.scrollstart.enabled = false;
-
-                               window.scrollTo( 0, toScroll );
-
-                               // reenable scrollstart listening like silentScroll would
-                               setTimeout( function() {
-                                       $.event.special.scrollstart.enabled = true;
-                               }, 150 );
-                       },
-                       cleanFrom = function() {
-                               $from
-                                       .removeClass( $.mobile.activePageClass + " out in reverse " + name )
-                                       .height( "" );
-                       },
-                       startOut = function() {
-                               // if it's not sequential, call the doneOut transition to start the TO page animating in simultaneously
-                               if ( !sequential ) {
-                                       doneOut();
-                               }
-                               else {
-                                       $from.animationComplete( doneOut );
-                               }
-
-                               // Set the from page's height and start it transitioning out
-                               // Note: setting an explicit height helps eliminate tiling in the transitions
-                               $from
-                                       .height( screenHeight + $.mobile.window.scrollTop() )
-                                       .addClass( name + " out" + reverseClass );
-                       },
-
-                       doneOut = function() {
-
-                               if ( $from && sequential ) {
-                                       cleanFrom();
-                               }
-
-                               startIn();
-                       },
-
-                       startIn = function() {
-
-                               // Prevent flickering in phonegap container: see comments at #4024 regarding iOS
-                               $to.css( "z-index", -10 );
-
-                               $to.addClass( $.mobile.activePageClass + toPreClass );
-
-                               // Send focus to page as it is now display: block
-                               $.mobile.focusPage( $to );
-
-                               // Set to page height
-                               $to.height( screenHeight + toScroll );
-
-                               scrollPage();
-
-                               // Restores visibility of the new page: added together with $to.css( "z-index", -10 );
-                               $to.css( "z-index", "" );
-
-                               if ( !none ) {
-                                       $to.animationComplete( doneIn );
-                               }
-
-                               $to
-                                       .removeClass( toPreClass )
-                                       .addClass( name + " in" + reverseClass );
-
-                               if ( none ) {
-                                       doneIn();
-                               }
-
-                       },
-
-                       doneIn = function() {
-
-                               if ( !sequential ) {
-
-                                       if ( $from ) {
-                                               cleanFrom();
-                                       }
-                               }
-
-                               $to
-                                       .removeClass( "out in reverse " + name )
-                                       .height( "" );
-
-                               toggleViewportClass();
-
-                               // In some browsers (iOS5), 3D transitions block the ability to scroll to the desired location during transition
-                               // This ensures we jump to that spot after the fact, if we aren't there already.
-                               if ( $.mobile.window.scrollTop() !== toScroll ) {
-                                       scrollPage();
-                               }
-
-                               deferred.resolve( name, reverse, $to, $from, true );
-                       };
-
-               toggleViewportClass();
-
-               if ( $from && !none ) {
-                       startOut();
-               }
-               else {
-                       doneOut();
-               }
-
-               return deferred.promise();
-       };
-};
-
-// generate the handlers from the above
-var sequentialHandler = createHandler(),
-       simultaneousHandler = createHandler( false ),
-       defaultGetMaxScrollForTransition = function() {
-               return $.mobile.getScreenHeight() * 3;
-       };
-
-// Make our transition handler the public default.
-$.mobile.defaultTransitionHandler = sequentialHandler;
-
-//transition handler dictionary for 3rd party transitions
-$.mobile.transitionHandlers = {
-       "default": $.mobile.defaultTransitionHandler,
-       "sequential": sequentialHandler,
-       "simultaneous": simultaneousHandler
-};
-
-$.mobile.transitionFallbacks = {};
-
-// If transition is defined, check if css 3D transforms are supported, and if not, if a fallback is specified
-$.mobile._maybeDegradeTransition = function( transition ) {
-               if ( transition && !$.support.cssTransform3d && $.mobile.transitionFallbacks[ transition ] ) {
-                       transition = $.mobile.transitionFallbacks[ transition ];
-               }
-
-               return transition;
-};
-
-// Set the getMaxScrollForTransition to default if no implementation was set by user
-$.mobile.getMaxScrollForTransition = $.mobile.getMaxScrollForTransition || defaultGetMaxScrollForTransition;
-})( jQuery, this );
-
-(function( $, undefined ) {
-
-       //define vars for interal use
-       var $window = $.mobile.window,
-               $html = $( 'html' ),
-               $head = $( 'head' ),
-
-               // NOTE: path extensions dependent on core attributes. Moved here to remove deps from
-               //       $.mobile.path definition
-               path = $.extend($.mobile.path, {
-
-                       //return the substring of a filepath before the sub-page key, for making a server request
-                       getFilePath: function( path ) {
-                               var splitkey = '&' + $.mobile.subPageUrlKey;
-                               return path && path.split( splitkey )[0].split( dialogHashKey )[0];
-                       },
-
-                       //check if the specified url refers to the first page in the main application document.
-                       isFirstPageUrl: function( url ) {
-                               // We only deal with absolute paths.
-                               var u = path.parseUrl( path.makeUrlAbsolute( url, this.documentBase ) ),
-
-                                       // Does the url have the same path as the document?
-                                       samePath = u.hrefNoHash === this.documentUrl.hrefNoHash || ( this.documentBaseDiffers && u.hrefNoHash === this.documentBase.hrefNoHash ),
-
-                                       // Get the first page element.
-                                       fp = $.mobile.firstPage,
-
-                                       // Get the id of the first page element if it has one.
-                                       fpId = fp && fp[0] ? fp[0].id : undefined;
-
-                               // The url refers to the first page if the path matches the document and
-                               // it either has no hash value, or the hash is exactly equal to the id of the
-                               // first page element.
-                               return samePath && ( !u.hash || u.hash === "#" || ( fpId && u.hash.replace( /^#/, "" ) === fpId ) );
-                       },
-
-                       // Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR
-                       // requests if the document doing the request was loaded via the file:// protocol.
-                       // This is usually to allow the application to "phone home" and fetch app specific
-                       // data. We normally let the browser handle external/cross-domain urls, but if the
-                       // allowCrossDomainPages option is true, we will allow cross-domain http/https
-                       // requests to go through our page loading logic.
-                       isPermittedCrossDomainRequest: function( docUrl, reqUrl ) {
-                               return $.mobile.allowCrossDomainPages &&
-                                       docUrl.protocol === "file:" &&
-                                       reqUrl.search( /^https?:/ ) !== -1;
-                       }
-               }),
-
-               // used to track last vclicked element to make sure its value is added to form data
-               $lastVClicked = null,
-
-               //will be defined when a link is clicked and given an active class
-               $activeClickedLink = null,
-
-               // resolved on domready
-               domreadyDeferred = $.Deferred(),
-
-               //urlHistory is purely here to make guesses at whether the back or forward button was clicked
-               //and provide an appropriate transition
-               urlHistory = $.mobile.navigate.history,
-
-               //define first selector to receive focus when a page is shown
-               focusable = "[tabindex],a,button:visible,select:visible,input",
-
-               //queue to hold simultanious page transitions
-               pageTransitionQueue = [],
-
-               //indicates whether or not page is in process of transitioning
-               isPageTransitioning = false,
-
-               //nonsense hash change key for dialogs, so they create a history entry
-               dialogHashKey = "&ui-state=dialog",
-
-               //existing base tag?
-               $base = $head.children( "base" ),
-
-               //tuck away the original document URL minus any fragment.
-               documentUrl = path.documentUrl,
-
-               //if the document has an embedded base tag, documentBase is set to its
-               //initial value. If a base tag does not exist, then we default to the documentUrl.
-               documentBase = path.documentBase,
-
-               //cache the comparison once.
-               documentBaseDiffers = path.documentBaseDiffers,
-
-               getScreenHeight = $.mobile.getScreenHeight;
-
-               //base element management, defined depending on dynamic base tag support
-               var base = $.support.dynamicBaseTag ? {
-
-                       //define base element, for use in routing asset urls that are referenced in Ajax-requested markup
-                       element: ( $base.length ? $base : $( "<base>", { href: documentBase.hrefNoHash } ).prependTo( $head ) ),
-
-                       //set the generated BASE element's href attribute to a new page's base path
-                       set: function( href ) {
-                               href = path.parseUrl(href).hrefNoHash;
-                               base.element.attr( "href", path.makeUrlAbsolute( href, documentBase ) );
-                       },
-
-                       //set the generated BASE element's href attribute to a new page's base path
-                       reset: function() {
-                               base.element.attr( "href", documentBase.hrefNoSearch );
-                       }
-
-               } : undefined;
-
-
-       //return the original document url
-       $.mobile.getDocumentUrl = path.getDocumentUrl;
-
-       //return the original document base url
-       $.mobile.getDocumentBase = path.getDocumentBase;
-
-       /* internal utility functions */
-
-       // NOTE Issue #4950 Android phonegap doesn't navigate back properly
-       //      when a full page refresh has taken place. It appears that hashchange
-       //      and replacestate history alterations work fine but we need to support
-       //      both forms of history traversal in our code that uses backward history
-       //      movement
-       $.mobile.back = function() {
-               var nav = window.navigator;
-
-               // if the setting is on and the navigator object is
-               // available use the phonegap navigation capability
-               if( this.phonegapNavigationEnabled &&
-                       nav &&
-                       nav.app &&
-                       nav.app.backHistory ){
-                       nav.app.backHistory();
-               } else {
-                       window.history.back();
-               }
-       };
-
-       //direct focus to the page title, or otherwise first focusable element
-       $.mobile.focusPage = function ( page ) {
-               var autofocus = page.find( "[autofocus]" ),
-                       pageTitle = page.find( ".ui-title:eq(0)" );
-
-               if ( autofocus.length ) {
-                       autofocus.focus();
-                       return;
-               }
-
-               if ( pageTitle.length ) {
-                       pageTitle.focus();
-               } else{
-                       page.focus();
-               }
-       };
-
-       //remove active classes after page transition or error
-       function removeActiveLinkClass( forceRemoval ) {
-               if ( !!$activeClickedLink && ( !$activeClickedLink.closest( "." + $.mobile.activePageClass ).length || forceRemoval ) ) {
-                       $activeClickedLink.removeClass( $.mobile.activeBtnClass );
-               }
-               $activeClickedLink = null;
-       }
-
-       function releasePageTransitionLock() {
-               isPageTransitioning = false;
-               if ( pageTransitionQueue.length > 0 ) {
-                       $.mobile.changePage.apply( null, pageTransitionQueue.pop() );
-               }
-       }
-
-       // Save the last scroll distance per page, before it is hidden
-       var setLastScrollEnabled = true,
-               setLastScroll, delayedSetLastScroll;
-
-       setLastScroll = function() {
-               // this barrier prevents setting the scroll value based on the browser
-               // scrolling the window based on a hashchange
-               if ( !setLastScrollEnabled ) {
-                       return;
-               }
-
-               var active = $.mobile.urlHistory.getActive();
-
-               if ( active ) {
-                       var lastScroll = $window.scrollTop();
-
-                       // Set active page's lastScroll prop.
-                       // If the location we're scrolling to is less than minScrollBack, let it go.
-                       active.lastScroll = lastScroll < $.mobile.minScrollBack ? $.mobile.defaultHomeScroll : lastScroll;
-               }
-       };
-
-       // bind to scrollstop to gather scroll position. The delay allows for the hashchange
-       // event to fire and disable scroll recording in the case where the browser scrolls
-       // to the hash targets location (sometimes the top of the page). once pagechange fires
-       // getLastScroll is again permitted to operate
-       delayedSetLastScroll = function() {
-               setTimeout( setLastScroll, 100 );
-       };
-
-       // disable an scroll setting when a hashchange has been fired, this only works
-       // because the recording of the scroll position is delayed for 100ms after
-       // the browser might have changed the position because of the hashchange
-       $window.bind( $.support.pushState ? "popstate" : "hashchange", function() {
-               setLastScrollEnabled = false;
-       });
-
-       // handle initial hashchange from chrome :(
-       $window.one( $.support.pushState ? "popstate" : "hashchange", function() {
-               setLastScrollEnabled = true;
-       });
-
-       // wait until the mobile page container has been determined to bind to pagechange
-       $window.one( "pagecontainercreate", function() {
-               // once the page has changed, re-enable the scroll recording
-               $.mobile.pageContainer.bind( "pagechange", function() {
-
-                       setLastScrollEnabled = true;
-
-                       // remove any binding that previously existed on the get scroll
-                       // which may or may not be different than the scroll element determined for
-                       // this page previously
-                       $window.unbind( "scrollstop", delayedSetLastScroll );
-
-                       // determine and bind to the current scoll element which may be the window
-                       // or in the case of touch overflow the element with touch overflow
-                       $window.bind( "scrollstop", delayedSetLastScroll );
-               });
-       });
-
-       // bind to scrollstop for the first page as "pagechange" won't be fired in that case
-       $window.bind( "scrollstop", delayedSetLastScroll );
-
-       // No-op implementation of transition degradation
-       $.mobile._maybeDegradeTransition = $.mobile._maybeDegradeTransition || function( transition ) {
-               return transition;
-       };
-
-       //function for transitioning between two existing pages
-       function transitionPages( toPage, fromPage, transition, reverse ) {
-               if ( fromPage ) {
-                       //trigger before show/hide events
-                       fromPage.data( "mobile-page" )._trigger( "beforehide", null, { nextPage: toPage } );
-               }
-
-               toPage.data( "mobile-page" )._trigger( "beforeshow", null, { prevPage: fromPage || $( "" ) } );
-
-               //clear page loader
-               $.mobile.hidePageLoadingMsg();
-
-               transition = $.mobile._maybeDegradeTransition( transition );
-
-               //find the transition handler for the specified transition. If there
-               //isn't one in our transitionHandlers dictionary, use the default one.
-               //call the handler immediately to kick-off the transition.
-               var th = $.mobile.transitionHandlers[ transition || "default" ] || $.mobile.defaultTransitionHandler,
-                       promise = th( transition, reverse, toPage, fromPage );
-
-               promise.done(function() {
-                       //trigger show/hide events
-                       if ( fromPage ) {
-                               fromPage.data( "mobile-page" )._trigger( "hide", null, { nextPage: toPage } );
-                       }
-
-                       //trigger pageshow, define prevPage as either fromPage or empty jQuery obj
-                       toPage.data( "mobile-page" )._trigger( "show", null, { prevPage: fromPage || $( "" ) } );
-               });
-
-               return promise;
-       }
-
-       //simply set the active page's minimum height to screen height, depending on orientation
-       $.mobile.resetActivePageHeight = function resetActivePageHeight( height ) {
-               var aPage = $( "." + $.mobile.activePageClass ),
-                       aPagePadT = parseFloat( aPage.css( "padding-top" ) ),
-                       aPagePadB = parseFloat( aPage.css( "padding-bottom" ) ),
-                       aPageBorderT = parseFloat( aPage.css( "border-top-width" ) ),
-                       aPageBorderB = parseFloat( aPage.css( "border-bottom-width" ) );
-
-               height = ( typeof height === "number" )? height : getScreenHeight();
-               
-               aPage.css( "min-height", height - aPagePadT - aPagePadB - aPageBorderT - aPageBorderB );
-       };
-
-       //shared page enhancements
-       function enhancePage( $page, role ) {
-               // If a role was specified, make sure the data-role attribute
-               // on the page element is in sync.
-               if ( role ) {
-                       $page.attr( "data-" + $.mobile.ns + "role", role );
-               }
-
-               //run page plugin
-               $page.page();
-       }
-
-       // determine the current base url
-       function findBaseWithDefault() {
-               var closestBase = ( $.mobile.activePage && getClosestBaseUrl( $.mobile.activePage ) );
-               return closestBase || documentBase.hrefNoHash;
-       }
-
-       /* exposed $.mobile methods */
-
-       //animation complete callback
-       $.fn.animationComplete = function( callback ) {
-               if ( $.support.cssTransitions ) {
-                       return $( this ).one( 'webkitAnimationEnd animationend', callback );
-               }
-               else{
-                       // defer execution for consistency between webkit/non webkit
-                       setTimeout( callback, 0 );
-                       return $( this );
-               }
-       };
-
-       //expose path object on $.mobile
-       $.mobile.path = path;
-
-       //expose base object on $.mobile
-       $.mobile.base = base;
-
-       //history stack
-       $.mobile.urlHistory = urlHistory;
-
-       $.mobile.dialogHashKey = dialogHashKey;
-
-       //enable cross-domain page support
-       $.mobile.allowCrossDomainPages = false;
-
-       $.mobile._bindPageRemove = function() {
-               var page = $( this );
-
-               // when dom caching is not enabled or the page is embedded bind to remove the page on hide
-               if ( !page.data( "mobile-page" ).options.domCache &&
-                       page.is( ":jqmData(external-page='true')" ) ) {
-
-                       page.bind( 'pagehide.remove', function( e ) {
-                               var $this = $( this ),
-                                       prEvent = new $.Event( "pageremove" );
-
-                               $this.trigger( prEvent );
-
-                               if ( !prEvent.isDefaultPrevented() ) {
-                                       $this.removeWithDependents();
-                               }
-                       });
-               }
-       };
-
-       // Load a page into the DOM.
-       $.mobile.loadPage = function( url, options ) {
-               // This function uses deferred notifications to let callers
-               // know when the page is done loading, or if an error has occurred.
-               var deferred = $.Deferred(),
-
-                       // The default loadPage options with overrides specified by
-                       // the caller.
-                       settings = $.extend( {}, $.mobile.loadPage.defaults, options ),
-
-                       // The DOM element for the page after it has been loaded.
-                       page = null,
-
-                       // If the reloadPage option is true, and the page is already
-                       // in the DOM, dupCachedPage will be set to the page element
-                       // so that it can be removed after the new version of the
-                       // page is loaded off the network.
-                       dupCachedPage = null,
-
-                       // The absolute version of the URL passed into the function. This
-                       // version of the URL may contain dialog/subpage params in it.
-                       absUrl = path.makeUrlAbsolute( url, findBaseWithDefault() );
-
-               // If the caller provided data, and we're using "get" request,
-               // append the data to the URL.
-               if ( settings.data && settings.type === "get" ) {
-                       absUrl = path.addSearchParams( absUrl, settings.data );
-                       settings.data = undefined;
-               }
-
-               // If the caller is using a "post" request, reloadPage must be true
-               if ( settings.data && settings.type === "post" ) {
-                       settings.reloadPage = true;
-               }
-
-               // The absolute version of the URL minus any dialog/subpage params.
-               // In otherwords the real URL of the page to be loaded.
-               var fileUrl = path.getFilePath( absUrl ),
-
-                       // The version of the Url actually stored in the data-url attribute of
-                       // the page. For embedded pages, it is just the id of the page. For pages
-                       // within the same domain as the document base, it is the site relative
-                       // path. For cross-domain pages (Phone Gap only) the entire absolute Url
-                       // used to load the page.
-                       dataUrl = path.convertUrlToDataUrl( absUrl );
-
-               // Make sure we have a pageContainer to work with.
-               settings.pageContainer = settings.pageContainer || $.mobile.pageContainer;
-
-               // Check to see if the page already exists in the DOM.
-               // NOTE do _not_ use the :jqmData psuedo selector because parenthesis
-               //      are a valid url char and it breaks on the first occurence
-               page = settings.pageContainer.children( "[data-" + $.mobile.ns +"url='" + dataUrl + "']" );
-
-               // If we failed to find the page, check to see if the url is a
-               // reference to an embedded page. If so, it may have been dynamically
-               // injected by a developer, in which case it would be lacking a data-url
-               // attribute and in need of enhancement.
-               if ( page.length === 0 && dataUrl && !path.isPath( dataUrl ) ) {
-                       page = settings.pageContainer.children( "#" + dataUrl )
-                               .attr( "data-" + $.mobile.ns + "url", dataUrl )
-                               .jqmData( "url", dataUrl );
-               }
-
-               
-               // If we failed to find a page in the DOM, check the URL to see if it
-               // refers to the first page in the application. If it isn't a reference
-               // to the first page and refers to non-existent embedded page, error out.
-               if ( page.length === 0 ) {
-                       if ( $.mobile.firstPage && path.isFirstPageUrl( fileUrl ) ) {
-                               // Check to make sure our cached-first-page is actually
-                               // in the DOM. Some user deployed apps are pruning the first
-                               // page from the DOM for various reasons, we check for this
-                               // case here because we don't want a first-page with an id
-                               // falling through to the non-existent embedded page error
-                               // case. If the first-page is not in the DOM, then we let
-                               // things fall through to the ajax loading code below so
-                               // that it gets reloaded.
-                               if ( $.mobile.firstPage.parent().length ) {
-                                       page = $( $.mobile.firstPage );
-                               }
-                       } else if ( path.isEmbeddedPage( fileUrl )  ) {
-                               deferred.reject( absUrl, options );
-                               return deferred.promise();
-                       }
-               }
-               
-               // If the page we are interested in is already in the DOM,
-               // and the caller did not indicate that we should force a
-               // reload of the file, we are done. Otherwise, track the
-               // existing page as a duplicated.
-               if ( page.length ) {
-                       if ( !settings.reloadPage ) {
-                               enhancePage( page, settings.role );
-                               deferred.resolve( absUrl, options, page );
-                               //if we are reloading the page make sure we update the base if its not a prefetch 
-                               if( base && !options.prefetch ){
-                                       base.set(url);
-                               }
-                               return deferred.promise();
-                       }
-                       dupCachedPage = page;
-               }
-               var mpc = settings.pageContainer,
-                       pblEvent = new $.Event( "pagebeforeload" ),
-                       triggerData = { url: url, absUrl: absUrl, dataUrl: dataUrl, deferred: deferred, options: settings };
-
-               // Let listeners know we're about to load a page.
-               mpc.trigger( pblEvent, triggerData );
-
-               // If the default behavior is prevented, stop here!
-               if ( pblEvent.isDefaultPrevented() ) {
-                       return deferred.promise();
-               }
-
-               if ( settings.showLoadMsg ) {
-
-                       // This configurable timeout allows cached pages a brief delay to load without showing a message
-                       var loadMsgDelay = setTimeout(function() {
-                                       $.mobile.showPageLoadingMsg();
-                               }, settings.loadMsgDelay ),
-
-                               // Shared logic for clearing timeout and removing message.
-                               hideMsg = function() {
-
-                                       // Stop message show timer
-                                       clearTimeout( loadMsgDelay );
-
-                                       // Hide loading message
-                                       $.mobile.hidePageLoadingMsg();
-                               };
-               }
-               // Reset base to the default document base.
-               // only reset if we are not prefetching 
-               if ( base && typeof options.prefetch === "undefined" ) {
-                       base.reset();
-               }
-
-               if ( !( $.mobile.allowCrossDomainPages || path.isSameDomain( documentUrl, absUrl ) ) ) {
-                       deferred.reject( absUrl, options );
-               } else {
-                       // Load the new page.
-                       $.ajax({
-                               url: fileUrl,
-                               type: settings.type,
-                               data: settings.data,
-                               contentType: settings.contentType,
-                               dataType: "html",
-                               success: function( html, textStatus, xhr ) {
-                                       //pre-parse html to check for a data-url,
-                                       //use it as the new fileUrl, base path, etc
-                                       var all = $( "<div></div>" ),
-
-                                               //page title regexp
-                                               newPageTitle = html.match( /<title[^>]*>([^<]*)/ ) && RegExp.$1,
-
-                                               // TODO handle dialogs again
-                                               pageElemRegex = new RegExp( "(<[^>]+\\bdata-" + $.mobile.ns + "role=[\"']?page[\"']?[^>]*>)" ),
-                                               dataUrlRegex = new RegExp( "\\bdata-" + $.mobile.ns + "url=[\"']?([^\"'>]*)[\"']?" );
-
-
-                                       // data-url must be provided for the base tag so resource requests can be directed to the
-                                       // correct url. loading into a temprorary element makes these requests immediately
-                                       if ( pageElemRegex.test( html ) &&
-                                                       RegExp.$1 &&
-                                                       dataUrlRegex.test( RegExp.$1 ) &&
-                                                       RegExp.$1 ) {
-                                               url = fileUrl = path.getFilePath( $( "<div>" + RegExp.$1 + "</div>" ).text() );
-                                       }
-                                       //dont update the base tag if we are prefetching
-                                       if ( base && typeof options.prefetch === "undefined") {
-                                               base.set( fileUrl );
-                                       }
-
-                                       //workaround to allow scripts to execute when included in page divs
-                                       all.get( 0 ).innerHTML = html;
-                                       page = all.find( ":jqmData(role='page'), :jqmData(role='dialog')" ).first();
-
-                                       //if page elem couldn't be found, create one and insert the body element's contents
-                                       if ( !page.length ) {
-                                               page = $( "<div data-" + $.mobile.ns + "role='page'>" + ( html.split( /<\/?body[^>]*>/gmi )[1] || "" ) + "</div>" );
-                                       }
-
-                                       if ( newPageTitle && !page.jqmData( "title" ) ) {
-                                               if ( ~newPageTitle.indexOf( "&" ) ) {
-                                                       newPageTitle = $( "<div>" + newPageTitle + "</div>" ).text();
-                                               }
-                                               page.jqmData( "title", newPageTitle );
-                                       }
-
-                                       //rewrite src and href attrs to use a base url
-                                       if ( !$.support.dynamicBaseTag ) {
-                                               var newPath = path.get( fileUrl );
-                                               page.find( "[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]" ).each(function() {
-                                                       var thisAttr = $( this ).is( '[href]' ) ? 'href' :
-                                                                       $( this ).is( '[src]' ) ? 'src' : 'action',
-                                                               thisUrl = $( this ).attr( thisAttr );
-
-                                                       // XXX_jblas: We need to fix this so that it removes the document
-                                                       //            base URL, and then prepends with the new page URL.
-                                                       //if full path exists and is same, chop it - helps IE out
-                                                       thisUrl = thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' );
-
-                                                       if ( !/^(\w+:|#|\/)/.test( thisUrl ) ) {
-                                                               $( this ).attr( thisAttr, newPath + thisUrl );
-                                                       }
-                                               });
-                                       }
-
-                                       //append to page and enhance
-                                       // TODO taging a page with external to make sure that embedded pages aren't removed
-                                       //      by the various page handling code is bad. Having page handling code in many
-                                       //      places is bad. Solutions post 1.0
-                                       page
-                                               .attr( "data-" + $.mobile.ns + "url", path.convertUrlToDataUrl( fileUrl ) )
-                                               .attr( "data-" + $.mobile.ns + "external-page", true )
-                                               .appendTo( settings.pageContainer );
-
-                                       // wait for page creation to leverage options defined on widget
-                                       page.one( 'pagecreate', $.mobile._bindPageRemove );
-
-                                       enhancePage( page, settings.role );
-
-                                       // Enhancing the page may result in new dialogs/sub pages being inserted
-                                       // into the DOM. If the original absUrl refers to a sub-page, that is the
-                                       // real page we are interested in.
-                                       if ( absUrl.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ) {
-                                               page = settings.pageContainer.children( "[data-" + $.mobile.ns +"url='" + dataUrl + "']" );
-                                       }
-
-                                       // Remove loading message.
-                                       if ( settings.showLoadMsg ) {
-                                               hideMsg();
-                                       }
-
-                                       // Add the page reference and xhr to our triggerData.
-                                       triggerData.xhr = xhr;
-                                       triggerData.textStatus = textStatus;
-                                       triggerData.page = page;
-
-                                       // Let listeners know the page loaded successfully.
-                                       settings.pageContainer.trigger( "pageload", triggerData );
-
-                                       deferred.resolve( absUrl, options, page, dupCachedPage );
-                               },
-                               error: function( xhr, textStatus, errorThrown ) {
-                                       //set base back to current path
-                                       if ( base ) {
-                                               base.set( path.get() );
-                                       }
-
-                                       // Add error info to our triggerData.
-                                       triggerData.xhr = xhr;
-                                       triggerData.textStatus = textStatus;
-                                       triggerData.errorThrown = errorThrown;
-
-                                       var plfEvent = new $.Event( "pageloadfailed" );
-
-                                       // Let listeners know the page load failed.
-                                       settings.pageContainer.trigger( plfEvent, triggerData );
-
-                                       // If the default behavior is prevented, stop here!
-                                       // Note that it is the responsibility of the listener/handler
-                                       // that called preventDefault(), to resolve/reject the
-                                       // deferred object within the triggerData.
-                                       if ( plfEvent.isDefaultPrevented() ) {
-                                               return;
-                                       }
-
-                                       // Remove loading message.
-                                       if ( settings.showLoadMsg ) {
-
-                                               // Remove loading message.
-                                               hideMsg();
-
-                                               // show error message
-                                               $.mobile.showPageLoadingMsg( $.mobile.pageLoadErrorMessageTheme, $.mobile.pageLoadErrorMessage, true );
-
-                                               // hide after delay
-                                               setTimeout( $.mobile.hidePageLoadingMsg, 1500 );
-                                       }
-
-                                       deferred.reject( absUrl, options );
-                               }
-                       });
-               }
-
-               return deferred.promise();
-       };
-
-       $.mobile.loadPage.defaults = {
-               type: "get",
-               data: undefined,
-               reloadPage: false,
-               role: undefined, // By default we rely on the role defined by the @data-role attribute.
-               showLoadMsg: false,
-               pageContainer: undefined,
-               loadMsgDelay: 50 // This delay allows loads that pull from browser cache to occur without showing the loading message.
-       };
-
-       // Show a specific page in the page container.
-       $.mobile.changePage = function( toPage, options ) {
-               // If we are in the midst of a transition, queue the current request.
-               // We'll call changePage() once we're done with the current transition to
-               // service the request.
-               if ( isPageTransitioning ) {
-                       pageTransitionQueue.unshift( arguments );
-                       return;
-               }
-
-               var settings = $.extend( {}, $.mobile.changePage.defaults, options ), isToPageString;
-
-               // Make sure we have a pageContainer to work with.
-               settings.pageContainer = settings.pageContainer || $.mobile.pageContainer;
-
-               // Make sure we have a fromPage.
-               settings.fromPage = settings.fromPage || $.mobile.activePage;
-
-               isToPageString = (typeof toPage === "string");
-
-               var mpc = settings.pageContainer,
-                       pbcEvent = new $.Event( "pagebeforechange" ),
-                       triggerData = { toPage: toPage, options: settings };
-
-               // NOTE: preserve the original target as the dataUrl value will be simplified
-               //       eg, removing ui-state, and removing query params from the hash
-               //       this is so that users who want to use query params have access to them
-               //       in the event bindings for the page life cycle See issue #5085
-               if ( isToPageString ) {
-                       // if the toPage is a string simply convert it
-                       triggerData.absUrl = path.makeUrlAbsolute( toPage, findBaseWithDefault() );
-               } else {
-                       // if the toPage is a jQuery object grab the absolute url stored
-                       // in the loadPage callback where it exists
-                       triggerData.absUrl = toPage.data( 'absUrl' );
-               }
-
-               // Let listeners know we're about to change the current page.
-               mpc.trigger( pbcEvent, triggerData );
-
-               // If the default behavior is prevented, stop here!
-               if ( pbcEvent.isDefaultPrevented() ) {
-                       return;
-               }
-
-               // We allow "pagebeforechange" observers to modify the toPage in the trigger
-               // data to allow for redirects. Make sure our toPage is updated.
-               //
-               // We also need to re-evaluate whether it is a string, because an object can
-               // also be replaced by a string
-
-               toPage = triggerData.toPage;
-               isToPageString = (typeof toPage === "string");
-
-               // Set the isPageTransitioning flag to prevent any requests from
-               // entering this method while we are in the midst of loading a page
-               // or transitioning.
-               isPageTransitioning = true;
-
-               // If the caller passed us a url, call loadPage()
-               // to make sure it is loaded into the DOM. We'll listen
-               // to the promise object it returns so we know when
-               // it is done loading or if an error ocurred.
-               if ( isToPageString ) {
-                       // preserve the original target as the dataUrl value will be simplified
-                       // eg, removing ui-state, and removing query params from the hash
-                       // this is so that users who want to use query params have access to them
-                       // in the event bindings for the page life cycle See issue #5085
-                       settings.target = toPage;
-
-                       $.mobile.loadPage( toPage, settings )
-                               .done(function( url, options, newPage, dupCachedPage ) {
-                                       isPageTransitioning = false;
-                                       options.duplicateCachedPage = dupCachedPage;
-
-                                       // store the original absolute url so that it can be provided
-                                       // to events in the triggerData of the subsequent changePage call
-                                       newPage.data( 'absUrl', triggerData.absUrl );
-                                       $.mobile.changePage( newPage, options );
-                               })
-                               .fail(function( url, options ) {
-
-                                       //clear out the active button state
-                                       removeActiveLinkClass( true );
-
-                                       //release transition lock so navigation is free again
-                                       releasePageTransitionLock();
-                                       settings.pageContainer.trigger( "pagechangefailed", triggerData );
-                               });
-                       return;
-               }
-
-               // If we are going to the first-page of the application, we need to make
-               // sure settings.dataUrl is set to the application document url. This allows
-               // us to avoid generating a document url with an id hash in the case where the
-               // first-page of the document has an id attribute specified.
-               if ( toPage[ 0 ] === $.mobile.firstPage[ 0 ] && !settings.dataUrl ) {
-                       settings.dataUrl = documentUrl.hrefNoHash;
-               }
-
-               // The caller passed us a real page DOM element. Update our
-               // internal state and then trigger a transition to the page.
-               var fromPage = settings.fromPage,
-                       url = ( settings.dataUrl && path.convertUrlToDataUrl( settings.dataUrl ) ) || toPage.jqmData( "url" ),
-                       // The pageUrl var is usually the same as url, except when url is obscured as a dialog url. pageUrl always contains the file path
-                       pageUrl = url,
-                       fileUrl = path.getFilePath( url ),
-                       active = urlHistory.getActive(),
-                       activeIsInitialPage = urlHistory.activeIndex === 0,
-                       historyDir = 0,
-                       pageTitle = document.title,
-                       isDialog = settings.role === "dialog" || toPage.jqmData( "role" ) === "dialog";
-
-
-               // By default, we prevent changePage requests when the fromPage and toPage
-               // are the same element, but folks that generate content manually/dynamically
-               // and reuse pages want to be able to transition to the same page. To allow
-               // this, they will need to change the default value of allowSamePageTransition
-               // to true, *OR*, pass it in as an option when they manually call changePage().
-               // It should be noted that our default transition animations assume that the
-               // formPage and toPage are different elements, so they may behave unexpectedly.
-               // It is up to the developer that turns on the allowSamePageTransitiona option
-               // to either turn off transition animations, or make sure that an appropriate
-               // animation transition is used.
-               if ( fromPage && fromPage[0] === toPage[0] && !settings.allowSamePageTransition ) {
-                       isPageTransitioning = false;
-                       mpc.trigger( "pagechange", triggerData );
-
-                       // Even if there is no page change to be done, we should keep the urlHistory in sync with the hash changes
-                       if ( settings.fromHashChange ) {
-                               urlHistory.direct({ url: url });
-                       }
-
-                       return;
-               }
-
-               // We need to make sure the page we are given has already been enhanced.
-               enhancePage( toPage, settings.role );
-
-               // If the changePage request was sent from a hashChange event, check to see if the
-               // page is already within the urlHistory stack. If so, we'll assume the user hit
-               // the forward/back button and will try to match the transition accordingly.
-               if ( settings.fromHashChange ) {
-                       historyDir = options.direction === "back" ? -1 : 1;
-               }
-
-               // Kill the keyboard.
-               // XXX_jblas: We need to stop crawling the entire document to kill focus. Instead,
-               //            we should be tracking focus with a delegate() handler so we already have
-               //            the element in hand at this point.
-               // Wrap this in a try/catch block since IE9 throw "Unspecified error" if document.activeElement
-               // is undefined when we are in an IFrame.
-               try {
-                       if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== 'body' ) {
-                               $( document.activeElement ).blur();
-                       } else {
-                               $( "input:focus, textarea:focus, select:focus" ).blur();
-                       }
-               } catch( e ) {}
-
-               // Record whether we are at a place in history where a dialog used to be - if so, do not add a new history entry and do not change the hash either
-               var alreadyThere = false;
-
-               // If we're displaying the page as a dialog, we don't want the url
-               // for the dialog content to be used in the hash. Instead, we want
-               // to append the dialogHashKey to the url of the current page.
-               if ( isDialog && active ) {
-                       // on the initial page load active.url is undefined and in that case should
-                       // be an empty string. Moving the undefined -> empty string back into
-                       // urlHistory.addNew seemed imprudent given undefined better represents
-                       // the url state
-
-                       // If we are at a place in history that once belonged to a dialog, reuse
-                       // this state without adding to urlHistory and without modifying the hash.
-                       // However, if a dialog is already displayed at this point, and we're
-                       // about to display another dialog, then we must add another hash and
-                       // history entry on top so that one may navigate back to the original dialog
-                       if ( active.url &&
-                               active.url.indexOf( dialogHashKey ) > -1 &&
-                               $.mobile.activePage &&
-                               !$.mobile.activePage.is( ".ui-dialog" ) &&
<